Edit: include.tar
jpeglib.h 0000644 00000141323 15146341150 0006335 0 ustar 00 /* * jpeglib.h * * This file was part of the Independent JPEG Group's software: * Copyright (C) 1991-1998, Thomas G. Lane. * Modified 2002-2009 by Guido Vollbeding. * libjpeg-turbo Modifications: * Copyright (C) 2009-2011, 2013-2014, 2016, D. R. Commander. * Copyright (C) 2015, Google, Inc. * For conditions of distribution and use, see the accompanying README.ijg * file. * * This file defines the application interface for the JPEG library. * Most applications using the library need only include this file, * and perhaps jerror.h if they want to know the exact error codes. */ #ifndef JPEGLIB_H #define JPEGLIB_H /* * First we include the configuration files that record how this * installation of the JPEG library is set up. jconfig.h can be * generated automatically for many systems. jmorecfg.h contains * manual configuration options that most people need not worry about. */ #ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ #include "jconfig.h" /* widely used configuration options */ #endif #include "jmorecfg.h" /* seldom changed options */ #ifdef __cplusplus #ifndef DONT_USE_EXTERN_C extern "C" { #endif #endif /* Various constants determining the sizes of things. * All of these are specified by the JPEG standard, so don't change them * if you want to be compatible. */ #define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ #define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ #define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ #define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ #define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ #define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ #define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ /* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU * to handle it. We even let you do this from the jconfig.h file. However, * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe * sometimes emits noncompliant files doesn't mean you should too. */ #define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ #ifndef D_MAX_BLOCKS_IN_MCU #define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ #endif /* Data structures for images (arrays of samples and of DCT coefficients). */ typedef JSAMPLE *JSAMPROW; /* ptr to one image row of pixel samples. */ typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ typedef JBLOCK *JBLOCKROW; /* pointer to one row of coefficient blocks */ typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ typedef JCOEF *JCOEFPTR; /* useful in a couple of places */ /* Types for JPEG compression parameters and working tables. */ /* DCT coefficient quantization tables. */ typedef struct { /* This array gives the coefficient quantizers in natural array order * (not the zigzag order in which they are stored in a JPEG DQT marker). * CAUTION: IJG versions prior to v6a kept this array in zigzag order. */ UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ /* This field is used only during compression. It's initialized FALSE when * the table is created, and set TRUE when it's been output to the file. * You could suppress output of a table by setting this to TRUE. * (See jpeg_suppress_tables for an example.) */ boolean sent_table; /* TRUE when table has been output */ } JQUANT_TBL; /* Huffman coding tables. */ typedef struct { /* These two fields directly represent the contents of a JPEG DHT marker */ UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ /* length k bits; bits[0] is unused */ UINT8 huffval[256]; /* The symbols, in order of incr code length */ /* This field is used only during compression. It's initialized FALSE when * the table is created, and set TRUE when it's been output to the file. * You could suppress output of a table by setting this to TRUE. * (See jpeg_suppress_tables for an example.) */ boolean sent_table; /* TRUE when table has been output */ } JHUFF_TBL; /* Basic info about one component (color channel). */ typedef struct { /* These values are fixed over the whole image. */ /* For compression, they must be supplied by parameter setup; */ /* for decompression, they are read from the SOF marker. */ int component_id; /* identifier for this component (0..255) */ int component_index; /* its index in SOF or cinfo->comp_info[] */ int h_samp_factor; /* horizontal sampling factor (1..4) */ int v_samp_factor; /* vertical sampling factor (1..4) */ int quant_tbl_no; /* quantization table selector (0..3) */ /* These values may vary between scans. */ /* For compression, they must be supplied by parameter setup; */ /* for decompression, they are read from the SOS marker. */ /* The decompressor output side may not use these variables. */ int dc_tbl_no; /* DC entropy table selector (0..3) */ int ac_tbl_no; /* AC entropy table selector (0..3) */ /* Remaining fields should be treated as private by applications. */ /* These values are computed during compression or decompression startup: */ /* Component's size in DCT blocks. * Any dummy blocks added to complete an MCU are not counted; therefore * these values do not depend on whether a scan is interleaved or not. */ JDIMENSION width_in_blocks; JDIMENSION height_in_blocks; /* Size of a DCT block in samples. Always DCTSIZE for compression. * For decompression this is the size of the output from one DCT block, * reflecting any scaling we choose to apply during the IDCT step. * Values from 1 to 16 are supported. * Note that different components may receive different IDCT scalings. */ #if JPEG_LIB_VERSION >= 70 int DCT_h_scaled_size; int DCT_v_scaled_size; #else int DCT_scaled_size; #endif /* The downsampled dimensions are the component's actual, unpadded number * of samples at the main buffer (preprocessing/compression interface), thus * downsampled_width = ceil(image_width * Hi/Hmax) * and similarly for height. For decompression, IDCT scaling is included, so * downsampled_width = ceil(image_width * Hi/Hmax * DCT_[h_]scaled_size/DCTSIZE) */ JDIMENSION downsampled_width; /* actual width in samples */ JDIMENSION downsampled_height; /* actual height in samples */ /* This flag is used only for decompression. In cases where some of the * components will be ignored (eg grayscale output from YCbCr image), * we can skip most computations for the unused components. */ boolean component_needed; /* do we need the value of this component? */ /* These values are computed before starting a scan of the component. */ /* The decompressor output side may not use these variables. */ int MCU_width; /* number of blocks per MCU, horizontally */ int MCU_height; /* number of blocks per MCU, vertically */ int MCU_blocks; /* MCU_width * MCU_height */ int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_[h_]scaled_size */ int last_col_width; /* # of non-dummy blocks across in last MCU */ int last_row_height; /* # of non-dummy blocks down in last MCU */ /* Saved quantization table for component; NULL if none yet saved. * See jdinput.c comments about the need for this information. * This field is currently used only for decompression. */ JQUANT_TBL *quant_table; /* Private per-component storage for DCT or IDCT subsystem. */ void *dct_table; } jpeg_component_info; /* The script for encoding a multiple-scan file is an array of these: */ typedef struct { int comps_in_scan; /* number of components encoded in this scan */ int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ int Ss, Se; /* progressive JPEG spectral selection parms */ int Ah, Al; /* progressive JPEG successive approx. parms */ } jpeg_scan_info; /* The decompressor can save APPn and COM markers in a list of these: */ typedef struct jpeg_marker_struct *jpeg_saved_marker_ptr; struct jpeg_marker_struct { jpeg_saved_marker_ptr next; /* next in list, or NULL */ UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ unsigned int original_length; /* # bytes of data in the file */ unsigned int data_length; /* # bytes of data saved at data[] */ JOCTET *data; /* the data contained in the marker */ /* the marker length word is not counted in data_length or original_length */ }; /* Known color spaces. */ #define JCS_EXTENSIONS 1 #define JCS_ALPHA_EXTENSIONS 1 typedef enum { JCS_UNKNOWN, /* error/unspecified */ JCS_GRAYSCALE, /* monochrome */ JCS_RGB, /* red/green/blue as specified by the RGB_RED, RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE macros */ JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ JCS_CMYK, /* C/M/Y/K */ JCS_YCCK, /* Y/Cb/Cr/K */ JCS_EXT_RGB, /* red/green/blue */ JCS_EXT_RGBX, /* red/green/blue/x */ JCS_EXT_BGR, /* blue/green/red */ JCS_EXT_BGRX, /* blue/green/red/x */ JCS_EXT_XBGR, /* x/blue/green/red */ JCS_EXT_XRGB, /* x/red/green/blue */ /* When out_color_space it set to JCS_EXT_RGBX, JCS_EXT_BGRX, JCS_EXT_XBGR, or JCS_EXT_XRGB during decompression, the X byte is undefined, and in order to ensure the best performance, libjpeg-turbo can set that byte to whatever value it wishes. Use the following colorspace constants to ensure that the X byte is set to 0xFF, so that it can be interpreted as an opaque alpha channel. */ JCS_EXT_RGBA, /* red/green/blue/alpha */ JCS_EXT_BGRA, /* blue/green/red/alpha */ JCS_EXT_ABGR, /* alpha/blue/green/red */ JCS_EXT_ARGB, /* alpha/red/green/blue */ JCS_RGB565 /* 5-bit red/6-bit green/5-bit blue */ } J_COLOR_SPACE; /* DCT/IDCT algorithm options. */ typedef enum { JDCT_ISLOW, /* slow but accurate integer algorithm */ JDCT_IFAST, /* faster, less accurate integer method */ JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ } J_DCT_METHOD; #ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ #define JDCT_DEFAULT JDCT_ISLOW #endif #ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ #define JDCT_FASTEST JDCT_IFAST #endif /* Dithering options for decompression. */ typedef enum { JDITHER_NONE, /* no dithering */ JDITHER_ORDERED, /* simple ordered dither */ JDITHER_FS /* Floyd-Steinberg error diffusion dither */ } J_DITHER_MODE; /* Common fields between JPEG compression and decompression master structs. */ #define jpeg_common_fields \ struct jpeg_error_mgr *err; /* Error handler module */\ struct jpeg_memory_mgr *mem; /* Memory manager module */\ struct jpeg_progress_mgr *progress; /* Progress monitor, or NULL if none */\ void *client_data; /* Available for use by application */\ boolean is_decompressor; /* So common code can tell which is which */\ int global_state /* For checking call sequence validity */ /* Routines that are to be used by both halves of the library are declared * to receive a pointer to this structure. There are no actual instances of * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. */ struct jpeg_common_struct { jpeg_common_fields; /* Fields common to both master struct types */ /* Additional fields follow in an actual jpeg_compress_struct or * jpeg_decompress_struct. All three structs must agree on these * initial fields! (This would be a lot cleaner in C++.) */ }; typedef struct jpeg_common_struct *j_common_ptr; typedef struct jpeg_compress_struct *j_compress_ptr; typedef struct jpeg_decompress_struct *j_decompress_ptr; /* Master record for a compression instance */ struct jpeg_compress_struct { jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ /* Destination for compressed data */ struct jpeg_destination_mgr *dest; /* Description of source image --- these fields must be filled in by * outer application before starting compression. in_color_space must * be correct before you can even call jpeg_set_defaults(). */ JDIMENSION image_width; /* input image width */ JDIMENSION image_height; /* input image height */ int input_components; /* # of color components in input image */ J_COLOR_SPACE in_color_space; /* colorspace of input image */ double input_gamma; /* image gamma of input image */ /* Compression parameters --- these fields must be set before calling * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to * initialize everything to reasonable defaults, then changing anything * the application specifically wants to change. That way you won't get * burnt when new parameters are added. Also note that there are several * helper routines to simplify changing parameters. */ #if JPEG_LIB_VERSION >= 70 unsigned int scale_num, scale_denom; /* fraction by which to scale image */ JDIMENSION jpeg_width; /* scaled JPEG image width */ JDIMENSION jpeg_height; /* scaled JPEG image height */ /* Dimensions of actual JPEG image that will be written to file, * derived from input dimensions by scaling factors above. * These fields are computed by jpeg_start_compress(). * You can also use jpeg_calc_jpeg_dimensions() to determine these values * in advance of calling jpeg_start_compress(). */ #endif int data_precision; /* bits of precision in image data */ int num_components; /* # of color components in JPEG image */ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ jpeg_component_info *comp_info; /* comp_info[i] describes component that appears i'th in SOF */ JQUANT_TBL *quant_tbl_ptrs[NUM_QUANT_TBLS]; #if JPEG_LIB_VERSION >= 70 int q_scale_factor[NUM_QUANT_TBLS]; #endif /* ptrs to coefficient quantization tables, or NULL if not defined, * and corresponding scale factors (percentage, initialized 100). */ JHUFF_TBL *dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; JHUFF_TBL *ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; /* ptrs to Huffman coding tables, or NULL if not defined */ UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ int num_scans; /* # of entries in scan_info array */ const jpeg_scan_info *scan_info; /* script for multi-scan file, or NULL */ /* The default value of scan_info is NULL, which causes a single-scan * sequential JPEG file to be emitted. To create a multi-scan file, * set num_scans and scan_info to point to an array of scan definitions. */ boolean raw_data_in; /* TRUE=caller supplies downsampled data */ boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ boolean CCIR601_sampling; /* TRUE=first samples are cosited */ #if JPEG_LIB_VERSION >= 70 boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */ #endif int smoothing_factor; /* 1..100, or 0 for no input smoothing */ J_DCT_METHOD dct_method; /* DCT algorithm selector */ /* The restart interval can be specified in absolute MCUs by setting * restart_interval, or in MCU rows by setting restart_in_rows * (in which case the correct restart_interval will be figured * for each scan). */ unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ int restart_in_rows; /* if > 0, MCU rows per restart interval */ /* Parameters controlling emission of special markers. */ boolean write_JFIF_header; /* should a JFIF marker be written? */ UINT8 JFIF_major_version; /* What to write for the JFIF version number */ UINT8 JFIF_minor_version; /* These three values are not used by the JPEG code, merely copied */ /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ /* ratio is defined by X_density/Y_density even when density_unit=0. */ UINT8 density_unit; /* JFIF code for pixel size units */ UINT16 X_density; /* Horizontal pixel density */ UINT16 Y_density; /* Vertical pixel density */ boolean write_Adobe_marker; /* should an Adobe marker be written? */ /* State variable: index of next scanline to be written to * jpeg_write_scanlines(). Application may use this to control its * processing loop, e.g., "while (next_scanline < image_height)". */ JDIMENSION next_scanline; /* 0 .. image_height-1 */ /* Remaining fields are known throughout compressor, but generally * should not be touched by a surrounding application. */ /* * These fields are computed during compression startup */ boolean progressive_mode; /* TRUE if scan script uses progressive mode */ int max_h_samp_factor; /* largest h_samp_factor */ int max_v_samp_factor; /* largest v_samp_factor */ #if JPEG_LIB_VERSION >= 70 int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ #endif JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ /* The coefficient controller receives data in units of MCU rows as defined * for fully interleaved scans (whether the JPEG file is interleaved or not). * There are v_samp_factor * DCTSIZE sample rows of each component in an * "iMCU" (interleaved MCU) row. */ /* * These fields are valid during any one scan. * They describe the components and MCUs actually appearing in the scan. */ int comps_in_scan; /* # of JPEG components in this scan */ jpeg_component_info *cur_comp_info[MAX_COMPS_IN_SCAN]; /* *cur_comp_info[i] describes component that appears i'th in SOS */ JDIMENSION MCUs_per_row; /* # of MCUs across the image */ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ int blocks_in_MCU; /* # of DCT blocks per MCU */ int MCU_membership[C_MAX_BLOCKS_IN_MCU]; /* MCU_membership[i] is index in cur_comp_info of component owning */ /* i'th block in an MCU */ int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ #if JPEG_LIB_VERSION >= 80 int block_size; /* the basic DCT block size: 1..16 */ const int *natural_order; /* natural-order position array */ int lim_Se; /* min( Se, DCTSIZE2-1 ) */ #endif /* * Links to compression subobjects (methods and private variables of modules) */ struct jpeg_comp_master *master; struct jpeg_c_main_controller *main; struct jpeg_c_prep_controller *prep; struct jpeg_c_coef_controller *coef; struct jpeg_marker_writer *marker; struct jpeg_color_converter *cconvert; struct jpeg_downsampler *downsample; struct jpeg_forward_dct *fdct; struct jpeg_entropy_encoder *entropy; jpeg_scan_info *script_space; /* workspace for jpeg_simple_progression */ int script_space_size; }; /* Master record for a decompression instance */ struct jpeg_decompress_struct { jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ /* Source of compressed data */ struct jpeg_source_mgr *src; /* Basic description of image --- filled in by jpeg_read_header(). */ /* Application may inspect these values to decide how to process image. */ JDIMENSION image_width; /* nominal image width (from SOF marker) */ JDIMENSION image_height; /* nominal image height */ int num_components; /* # of color components in JPEG image */ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ /* Decompression processing parameters --- these fields must be set before * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes * them to default values. */ J_COLOR_SPACE out_color_space; /* colorspace for output */ unsigned int scale_num, scale_denom; /* fraction by which to scale image */ double output_gamma; /* image gamma wanted in output */ boolean buffered_image; /* TRUE=multiple output passes */ boolean raw_data_out; /* TRUE=downsampled data wanted */ J_DCT_METHOD dct_method; /* IDCT algorithm selector */ boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ boolean quantize_colors; /* TRUE=colormapped output wanted */ /* the following are ignored if not quantize_colors: */ J_DITHER_MODE dither_mode; /* type of color dithering to use */ boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ int desired_number_of_colors; /* max # colors to use in created colormap */ /* these are significant only in buffered-image mode: */ boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ boolean enable_external_quant;/* enable future use of external colormap */ boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ /* Description of actual output image that will be returned to application. * These fields are computed by jpeg_start_decompress(). * You can also use jpeg_calc_output_dimensions() to determine these values * in advance of calling jpeg_start_decompress(). */ JDIMENSION output_width; /* scaled image width */ JDIMENSION output_height; /* scaled image height */ int out_color_components; /* # of color components in out_color_space */ int output_components; /* # of color components returned */ /* output_components is 1 (a colormap index) when quantizing colors; * otherwise it equals out_color_components. */ int rec_outbuf_height; /* min recommended height of scanline buffer */ /* If the buffer passed to jpeg_read_scanlines() is less than this many rows * high, space and time will be wasted due to unnecessary data copying. * Usually rec_outbuf_height will be 1 or 2, at most 4. */ /* When quantizing colors, the output colormap is described by these fields. * The application can supply a colormap by setting colormap non-NULL before * calling jpeg_start_decompress; otherwise a colormap is created during * jpeg_start_decompress or jpeg_start_output. * The map has out_color_components rows and actual_number_of_colors columns. */ int actual_number_of_colors; /* number of entries in use */ JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ /* State variables: these variables indicate the progress of decompression. * The application may examine these but must not modify them. */ /* Row index of next scanline to be read from jpeg_read_scanlines(). * Application may use this to control its processing loop, e.g., * "while (output_scanline < output_height)". */ JDIMENSION output_scanline; /* 0 .. output_height-1 */ /* Current input scan number and number of iMCU rows completed in scan. * These indicate the progress of the decompressor input side. */ int input_scan_number; /* Number of SOS markers seen so far */ JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ /* The "output scan number" is the notional scan being displayed by the * output side. The decompressor will not allow output scan/row number * to get ahead of input scan/row, but it can fall arbitrarily far behind. */ int output_scan_number; /* Nominal scan number being displayed */ JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ /* Current progression status. coef_bits[c][i] indicates the precision * with which component c's DCT coefficient i (in zigzag order) is known. * It is -1 when no data has yet been received, otherwise it is the point * transform (shift) value for the most recent scan of the coefficient * (thus, 0 at completion of the progression). * This pointer is NULL when reading a non-progressive file. */ int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ /* Internal JPEG parameters --- the application usually need not look at * these fields. Note that the decompressor output side may not use * any parameters that can change between scans. */ /* Quantization and Huffman tables are carried forward across input * datastreams when processing abbreviated JPEG datastreams. */ JQUANT_TBL *quant_tbl_ptrs[NUM_QUANT_TBLS]; /* ptrs to coefficient quantization tables, or NULL if not defined */ JHUFF_TBL *dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; JHUFF_TBL *ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; /* ptrs to Huffman coding tables, or NULL if not defined */ /* These parameters are never carried across datastreams, since they * are given in SOF/SOS markers or defined to be reset by SOI. */ int data_precision; /* bits of precision in image data */ jpeg_component_info *comp_info; /* comp_info[i] describes component that appears i'th in SOF */ #if JPEG_LIB_VERSION >= 80 boolean is_baseline; /* TRUE if Baseline SOF0 encountered */ #endif boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ /* These fields record data obtained from optional markers recognized by * the JPEG library. */ boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ UINT8 JFIF_major_version; /* JFIF version number */ UINT8 JFIF_minor_version; UINT8 density_unit; /* JFIF code for pixel size units */ UINT16 X_density; /* Horizontal pixel density */ UINT16 Y_density; /* Vertical pixel density */ boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ UINT8 Adobe_transform; /* Color transform code from Adobe marker */ boolean CCIR601_sampling; /* TRUE=first samples are cosited */ /* Aside from the specific data retained from APPn markers known to the * library, the uninterpreted contents of any or all APPn and COM markers * can be saved in a list for examination by the application. */ jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ /* Remaining fields are known throughout decompressor, but generally * should not be touched by a surrounding application. */ /* * These fields are computed during decompression startup */ int max_h_samp_factor; /* largest h_samp_factor */ int max_v_samp_factor; /* largest v_samp_factor */ #if JPEG_LIB_VERSION >= 70 int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ #else int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ #endif JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ /* The coefficient controller's input and output progress is measured in * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows * in fully interleaved JPEG scans, but are used whether the scan is * interleaved or not. We define an iMCU row as v_samp_factor DCT block * rows of each component. Therefore, the IDCT output contains * v_samp_factor*DCT_[v_]scaled_size sample rows of a component per iMCU row. */ JSAMPLE *sample_range_limit; /* table for fast range-limiting */ /* * These fields are valid during any one scan. * They describe the components and MCUs actually appearing in the scan. * Note that the decompressor output side must not use these fields. */ int comps_in_scan; /* # of JPEG components in this scan */ jpeg_component_info *cur_comp_info[MAX_COMPS_IN_SCAN]; /* *cur_comp_info[i] describes component that appears i'th in SOS */ JDIMENSION MCUs_per_row; /* # of MCUs across the image */ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ int blocks_in_MCU; /* # of DCT blocks per MCU */ int MCU_membership[D_MAX_BLOCKS_IN_MCU]; /* MCU_membership[i] is index in cur_comp_info of component owning */ /* i'th block in an MCU */ int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ #if JPEG_LIB_VERSION >= 80 /* These fields are derived from Se of first SOS marker. */ int block_size; /* the basic DCT block size: 1..16 */ const int *natural_order; /* natural-order position array for entropy decode */ int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */ #endif /* This field is shared between entropy decoder and marker parser. * It is either zero or the code of a JPEG marker that has been * read from the data source, but has not yet been processed. */ int unread_marker; /* * Links to decompression subobjects (methods, private variables of modules) */ struct jpeg_decomp_master *master; struct jpeg_d_main_controller *main; struct jpeg_d_coef_controller *coef; struct jpeg_d_post_controller *post; struct jpeg_input_controller *inputctl; struct jpeg_marker_reader *marker; struct jpeg_entropy_decoder *entropy; struct jpeg_inverse_dct *idct; struct jpeg_upsampler *upsample; struct jpeg_color_deconverter *cconvert; struct jpeg_color_quantizer *cquantize; }; /* "Object" declarations for JPEG modules that may be supplied or called * directly by the surrounding application. * As with all objects in the JPEG library, these structs only define the * publicly visible methods and state variables of a module. Additional * private fields may exist after the public ones. */ /* Error handler object */ struct jpeg_error_mgr { /* Error exit handler: does not return to caller */ void (*error_exit) (j_common_ptr cinfo); /* Conditionally emit a trace or warning message */ void (*emit_message) (j_common_ptr cinfo, int msg_level); /* Routine that actually outputs a trace or error message */ void (*output_message) (j_common_ptr cinfo); /* Format a message string for the most recent JPEG error or message */ void (*format_message) (j_common_ptr cinfo, char *buffer); #define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ /* Reset error state variables at start of a new image */ void (*reset_error_mgr) (j_common_ptr cinfo); /* The message ID code and any parameters are saved here. * A message can have one string parameter or up to 8 int parameters. */ int msg_code; #define JMSG_STR_PARM_MAX 80 union { int i[8]; char s[JMSG_STR_PARM_MAX]; } msg_parm; /* Standard state variables for error facility */ int trace_level; /* max msg_level that will be displayed */ /* For recoverable corrupt-data errors, we emit a warning message, * but keep going unless emit_message chooses to abort. emit_message * should count warnings in num_warnings. The surrounding application * can check for bad data by seeing if num_warnings is nonzero at the * end of processing. */ long num_warnings; /* number of corrupt-data warnings */ /* These fields point to the table(s) of error message strings. * An application can change the table pointer to switch to a different * message list (typically, to change the language in which errors are * reported). Some applications may wish to add additional error codes * that will be handled by the JPEG library error mechanism; the second * table pointer is used for this purpose. * * First table includes all errors generated by JPEG library itself. * Error code 0 is reserved for a "no such error string" message. */ const char * const *jpeg_message_table; /* Library errors */ int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ /* Second table can be added by application (see cjpeg/djpeg for example). * It contains strings numbered first_addon_message..last_addon_message. */ const char * const *addon_message_table; /* Non-library errors */ int first_addon_message; /* code for first string in addon table */ int last_addon_message; /* code for last string in addon table */ }; /* Progress monitor object */ struct jpeg_progress_mgr { void (*progress_monitor) (j_common_ptr cinfo); long pass_counter; /* work units completed in this pass */ long pass_limit; /* total number of work units in this pass */ int completed_passes; /* passes completed so far */ int total_passes; /* total number of passes expected */ }; /* Data destination object for compression */ struct jpeg_destination_mgr { JOCTET *next_output_byte; /* => next byte to write in buffer */ size_t free_in_buffer; /* # of byte spaces remaining in buffer */ void (*init_destination) (j_compress_ptr cinfo); boolean (*empty_output_buffer) (j_compress_ptr cinfo); void (*term_destination) (j_compress_ptr cinfo); }; /* Data source object for decompression */ struct jpeg_source_mgr { const JOCTET *next_input_byte; /* => next byte to read from buffer */ size_t bytes_in_buffer; /* # of bytes remaining in buffer */ void (*init_source) (j_decompress_ptr cinfo); boolean (*fill_input_buffer) (j_decompress_ptr cinfo); void (*skip_input_data) (j_decompress_ptr cinfo, long num_bytes); boolean (*resync_to_restart) (j_decompress_ptr cinfo, int desired); void (*term_source) (j_decompress_ptr cinfo); }; /* Memory manager object. * Allocates "small" objects (a few K total), "large" objects (tens of K), * and "really big" objects (virtual arrays with backing store if needed). * The memory manager does not allow individual objects to be freed; rather, * each created object is assigned to a pool, and whole pools can be freed * at once. This is faster and more convenient than remembering exactly what * to free, especially where malloc()/free() are not too speedy. * NB: alloc routines never return NULL. They exit to error_exit if not * successful. */ #define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ #define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ #define JPOOL_NUMPOOLS 2 typedef struct jvirt_sarray_control *jvirt_sarray_ptr; typedef struct jvirt_barray_control *jvirt_barray_ptr; struct jpeg_memory_mgr { /* Method pointers */ void *(*alloc_small) (j_common_ptr cinfo, int pool_id, size_t sizeofobject); void *(*alloc_large) (j_common_ptr cinfo, int pool_id, size_t sizeofobject); JSAMPARRAY (*alloc_sarray) (j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow, JDIMENSION numrows); JBLOCKARRAY (*alloc_barray) (j_common_ptr cinfo, int pool_id, JDIMENSION blocksperrow, JDIMENSION numrows); jvirt_sarray_ptr (*request_virt_sarray) (j_common_ptr cinfo, int pool_id, boolean pre_zero, JDIMENSION samplesperrow, JDIMENSION numrows, JDIMENSION maxaccess); jvirt_barray_ptr (*request_virt_barray) (j_common_ptr cinfo, int pool_id, boolean pre_zero, JDIMENSION blocksperrow, JDIMENSION numrows, JDIMENSION maxaccess); void (*realize_virt_arrays) (j_common_ptr cinfo); JSAMPARRAY (*access_virt_sarray) (j_common_ptr cinfo, jvirt_sarray_ptr ptr, JDIMENSION start_row, JDIMENSION num_rows, boolean writable); JBLOCKARRAY (*access_virt_barray) (j_common_ptr cinfo, jvirt_barray_ptr ptr, JDIMENSION start_row, JDIMENSION num_rows, boolean writable); void (*free_pool) (j_common_ptr cinfo, int pool_id); void (*self_destruct) (j_common_ptr cinfo); /* Limit on memory allocation for this JPEG object. (Note that this is * merely advisory, not a guaranteed maximum; it only affects the space * used for virtual-array buffers.) May be changed by outer application * after creating the JPEG object. */ long max_memory_to_use; /* Maximum allocation request accepted by alloc_large. */ long max_alloc_chunk; }; /* Routine signature for application-supplied marker processing methods. * Need not pass marker code since it is stored in cinfo->unread_marker. */ typedef boolean (*jpeg_marker_parser_method) (j_decompress_ptr cinfo); /* Originally, this macro was used as a way of defining function prototypes * for both modern compilers as well as older compilers that did not support * prototype parameters. libjpeg-turbo has never supported these older, * non-ANSI compilers, but the macro is still included because there is some * software out there that uses it. */ #define JPP(arglist) arglist /* Default error-management setup */ EXTERN(struct jpeg_error_mgr *) jpeg_std_error (struct jpeg_error_mgr *err); /* Initialization of JPEG compression objects. * jpeg_create_compress() and jpeg_create_decompress() are the exported * names that applications should call. These expand to calls on * jpeg_CreateCompress and jpeg_CreateDecompress with additional information * passed for version mismatch checking. * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. */ #define jpeg_create_compress(cinfo) \ jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ (size_t) sizeof(struct jpeg_compress_struct)) #define jpeg_create_decompress(cinfo) \ jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ (size_t) sizeof(struct jpeg_decompress_struct)) EXTERN(void) jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize); EXTERN(void) jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize); /* Destruction of JPEG compression objects */ EXTERN(void) jpeg_destroy_compress (j_compress_ptr cinfo); EXTERN(void) jpeg_destroy_decompress (j_decompress_ptr cinfo); /* Standard data source and destination managers: stdio streams. */ /* Caller is responsible for opening the file before and closing after. */ EXTERN(void) jpeg_stdio_dest (j_compress_ptr cinfo, FILE *outfile); EXTERN(void) jpeg_stdio_src (j_decompress_ptr cinfo, FILE *infile); #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) /* Data source and destination managers: memory buffers. */ EXTERN(void) jpeg_mem_dest (j_compress_ptr cinfo, unsigned char **outbuffer, unsigned long *outsize); EXTERN(void) jpeg_mem_src (j_decompress_ptr cinfo, const unsigned char *inbuffer, unsigned long insize); #endif /* Default parameter setup for compression */ EXTERN(void) jpeg_set_defaults (j_compress_ptr cinfo); /* Compression parameter setup aids */ EXTERN(void) jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace); EXTERN(void) jpeg_default_colorspace (j_compress_ptr cinfo); EXTERN(void) jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline); EXTERN(void) jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, boolean force_baseline); #if JPEG_LIB_VERSION >= 70 EXTERN(void) jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline); #endif EXTERN(void) jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, const unsigned int *basic_table, int scale_factor, boolean force_baseline); EXTERN(int) jpeg_quality_scaling (int quality); EXTERN(void) jpeg_simple_progression (j_compress_ptr cinfo); EXTERN(void) jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress); EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table (j_common_ptr cinfo); EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table (j_common_ptr cinfo); /* Main entry points for compression */ EXTERN(void) jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables); EXTERN(JDIMENSION) jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION num_lines); EXTERN(void) jpeg_finish_compress (j_compress_ptr cinfo); #if JPEG_LIB_VERSION >= 70 /* Precalculate JPEG dimensions for current compression parameters. */ EXTERN(void) jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo); #endif /* Replaces jpeg_write_scanlines when writing raw downsampled data. */ EXTERN(JDIMENSION) jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, JDIMENSION num_lines); /* Write a special marker. See libjpeg.txt concerning safe usage. */ EXTERN(void) jpeg_write_marker (j_compress_ptr cinfo, int marker, const JOCTET *dataptr, unsigned int datalen); /* Same, but piecemeal. */ EXTERN(void) jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen); EXTERN(void) jpeg_write_m_byte (j_compress_ptr cinfo, int val); /* Alternate compression function: just write an abbreviated table file */ EXTERN(void) jpeg_write_tables (j_compress_ptr cinfo); /* Decompression startup: read start of JPEG datastream to see what's there */ EXTERN(int) jpeg_read_header (j_decompress_ptr cinfo, boolean require_image); /* Return value is one of: */ #define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ #define JPEG_HEADER_OK 1 /* Found valid image datastream */ #define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ /* If you pass require_image = TRUE (normal case), you need not check for * a TABLES_ONLY return code; an abbreviated file will cause an error exit. * JPEG_SUSPENDED is only possible if you use a data source module that can * give a suspension return (the stdio source module doesn't). */ /* Main entry points for decompression */ EXTERN(boolean) jpeg_start_decompress (j_decompress_ptr cinfo); EXTERN(JDIMENSION) jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION max_lines); EXTERN(JDIMENSION) jpeg_skip_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines); EXTERN(void) jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset, JDIMENSION *width); EXTERN(boolean) jpeg_finish_decompress (j_decompress_ptr cinfo); /* Replaces jpeg_read_scanlines when reading raw downsampled data. */ EXTERN(JDIMENSION) jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, JDIMENSION max_lines); /* Additional entry points for buffered-image mode. */ EXTERN(boolean) jpeg_has_multiple_scans (j_decompress_ptr cinfo); EXTERN(boolean) jpeg_start_output (j_decompress_ptr cinfo, int scan_number); EXTERN(boolean) jpeg_finish_output (j_decompress_ptr cinfo); EXTERN(boolean) jpeg_input_complete (j_decompress_ptr cinfo); EXTERN(void) jpeg_new_colormap (j_decompress_ptr cinfo); EXTERN(int) jpeg_consume_input (j_decompress_ptr cinfo); /* Return value is one of: */ /* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ #define JPEG_REACHED_SOS 1 /* Reached start of new scan */ #define JPEG_REACHED_EOI 2 /* Reached end of image */ #define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ #define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ /* Precalculate output dimensions for current decompression parameters. */ #if JPEG_LIB_VERSION >= 80 EXTERN(void) jpeg_core_output_dimensions (j_decompress_ptr cinfo); #endif EXTERN(void) jpeg_calc_output_dimensions (j_decompress_ptr cinfo); /* Control saving of COM and APPn markers into marker_list. */ EXTERN(void) jpeg_save_markers (j_decompress_ptr cinfo, int marker_code, unsigned int length_limit); /* Install a special processing method for COM or APPn markers. */ EXTERN(void) jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code, jpeg_marker_parser_method routine); /* Read or write raw DCT coefficients --- useful for lossless transcoding. */ EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients (j_decompress_ptr cinfo); EXTERN(void) jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr *coef_arrays); EXTERN(void) jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, j_compress_ptr dstinfo); /* If you choose to abort compression or decompression before completing * jpeg_finish_(de)compress, then you need to clean up to release memory, * temporary files, etc. You can just call jpeg_destroy_(de)compress * if you're done with the JPEG object, but if you want to clean it up and * reuse it, call this: */ EXTERN(void) jpeg_abort_compress (j_compress_ptr cinfo); EXTERN(void) jpeg_abort_decompress (j_decompress_ptr cinfo); /* Generic versions of jpeg_abort and jpeg_destroy that work on either * flavor of JPEG object. These may be more convenient in some places. */ EXTERN(void) jpeg_abort (j_common_ptr cinfo); EXTERN(void) jpeg_destroy (j_common_ptr cinfo); /* Default restart-marker-resync procedure for use by data source modules */ EXTERN(boolean) jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired); /* These marker codes are exported since applications and data source modules * are likely to want to use them. */ #define JPEG_RST0 0xD0 /* RST0 marker code */ #define JPEG_EOI 0xD9 /* EOI marker code */ #define JPEG_APP0 0xE0 /* APP0 marker code */ #define JPEG_COM 0xFE /* COM marker code */ /* If we have a brain-damaged compiler that emits warnings (or worse, errors) * for structure definitions that are never filled in, keep it quiet by * supplying dummy definitions for the various substructures. */ #ifdef INCOMPLETE_TYPES_BROKEN #ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ struct jvirt_sarray_control { long dummy; }; struct jvirt_barray_control { long dummy; }; struct jpeg_comp_master { long dummy; }; struct jpeg_c_main_controller { long dummy; }; struct jpeg_c_prep_controller { long dummy; }; struct jpeg_c_coef_controller { long dummy; }; struct jpeg_marker_writer { long dummy; }; struct jpeg_color_converter { long dummy; }; struct jpeg_downsampler { long dummy; }; struct jpeg_forward_dct { long dummy; }; struct jpeg_entropy_encoder { long dummy; }; struct jpeg_decomp_master { long dummy; }; struct jpeg_d_main_controller { long dummy; }; struct jpeg_d_coef_controller { long dummy; }; struct jpeg_d_post_controller { long dummy; }; struct jpeg_input_controller { long dummy; }; struct jpeg_marker_reader { long dummy; }; struct jpeg_entropy_decoder { long dummy; }; struct jpeg_inverse_dct { long dummy; }; struct jpeg_upsampler { long dummy; }; struct jpeg_color_deconverter { long dummy; }; struct jpeg_color_quantizer { long dummy; }; #endif /* JPEG_INTERNALS */ #endif /* INCOMPLETE_TYPES_BROKEN */ /* * The JPEG library modules define JPEG_INTERNALS before including this file. * The internal structure declarations are read only when that is true. * Applications using the library should not include jpegint.h, but may wish * to include jerror.h. */ #ifdef JPEG_INTERNALS #include "jpegint.h" /* fetch private declarations */ #include "jerror.h" /* fetch error codes too */ #endif #ifdef __cplusplus #ifndef DONT_USE_EXTERN_C } #endif #endif #endif /* JPEGLIB_H */ profile.h 0000644 00000027572 15146341150 0006372 0 ustar 00 /* * profile.h */ #ifndef _KRB5_PROFILE_H #define _KRB5_PROFILE_H #if defined(_WIN32) #include <win-mac.h> #endif #if defined(__MACH__) && defined(__APPLE__) # include <TargetConditionals.h> # if TARGET_RT_MAC_CFM # error "Use KfM 4.0 SDK headers for CFM compilation." # endif #endif #ifndef KRB5_CALLCONV #define KRB5_CALLCONV #define KRB5_CALLCONV_C #endif typedef struct _profile_t *profile_t; /* Used by profile_init_flags(). */ #define PROFILE_INIT_ALLOW_MODULE 0x0001 /* Allow module declaration */ /* * Used by the profile iterator in prof_get.c */ #define PROFILE_ITER_LIST_SECTION 0x0001 #define PROFILE_ITER_SECTIONS_ONLY 0x0002 #define PROFILE_ITER_RELATIONS_ONLY 0x0004 #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef char* profile_filespec_t; /* path as C string */ typedef char* profile_filespec_list_t; /* list of : separated paths, C string */ typedef const char * const_profile_filespec_t; /* path as C string */ typedef const char * const_profile_filespec_list_t; /* list of : separated paths, C string */ long KRB5_CALLCONV profile_init (const_profile_filespec_t *files, profile_t *ret_profile); long KRB5_CALLCONV profile_init_flags (const_profile_filespec_t *files, int flags, profile_t *ret_profile); long KRB5_CALLCONV profile_init_path (const_profile_filespec_list_t filelist, profile_t *ret_profile); long KRB5_CALLCONV profile_flush (profile_t profile); long KRB5_CALLCONV profile_flush_to_file (profile_t profile, const_profile_filespec_t outfile); long KRB5_CALLCONV profile_flush_to_buffer (profile_t profile, char **bufp); void KRB5_CALLCONV profile_free_buffer (profile_t profile, char *buf); long KRB5_CALLCONV profile_is_writable (profile_t profile, int *writable); long KRB5_CALLCONV profile_is_modified (profile_t profile, int *modified); void KRB5_CALLCONV profile_abandon (profile_t profile); void KRB5_CALLCONV profile_release (profile_t profile); long KRB5_CALLCONV profile_get_values (profile_t profile, const char *const *names, char ***ret_values); void KRB5_CALLCONV profile_free_list (char **list); long KRB5_CALLCONV profile_get_string (profile_t profile, const char *name, const char *subname, const char *subsubname, const char *def_val, char **ret_string); long KRB5_CALLCONV profile_get_integer (profile_t profile, const char *name, const char *subname, const char *subsubname, int def_val, int *ret_default); long KRB5_CALLCONV profile_get_boolean (profile_t profile, const char *name, const char *subname, const char *subsubname, int def_val, int *ret_default); long KRB5_CALLCONV profile_get_relation_names (profile_t profile, const char **names, char ***ret_names); long KRB5_CALLCONV profile_get_subsection_names (profile_t profile, const char **names, char ***ret_names); long KRB5_CALLCONV profile_iterator_create (profile_t profile, const char *const *names, int flags, void **ret_iter); void KRB5_CALLCONV profile_iterator_free (void **iter_p); long KRB5_CALLCONV profile_iterator (void **iter_p, char **ret_name, char **ret_value); void KRB5_CALLCONV profile_release_string (char *str); long KRB5_CALLCONV profile_update_relation (profile_t profile, const char **names, const char *old_value, const char *new_value); long KRB5_CALLCONV profile_clear_relation (profile_t profile, const char **names); long KRB5_CALLCONV profile_rename_section (profile_t profile, const char **names, const char *new_name); long KRB5_CALLCONV profile_add_relation (profile_t profile, const char **names, const char *new_value); /* * profile_init_vtable allows a caller to create a profile-compatible object * with a different back end. */ /* * Mandatory: Look up all of the relations for names, placing the resulting * values in *ret_values. If no relations exist, return PROF_NO_RELATION, or * PROF_NO_SECTION to indicate that one of the intermediate names does not * exist as a section. The list will be freed with free_values. */ typedef long (*profile_get_values_fn)(void *cbdata, const char *const *names, char ***ret_values); /* Mandatory: Free a list of strings returned by get_values. */ typedef void (*profile_free_values_fn)(void *cbdata, char **values); /* Optional: Release any data associated with the profile. */ typedef void (*profile_cleanup_fn)(void *cbdata); /* * Optional (mandatory if cleanup is defined): Generate a new cbdata pointer * for a copy of the profile. If not implemented, the new profile will receive * the same cbdata pointer as the old one. */ typedef long (*profile_copy_fn)(void *cbdata, void **ret_cbdata); /* * Optional: Create an iterator handle. * * If flags contains PROFILE_ITER_LIST_SECTION, iterate over all of the * relations and sections within names. Otherwise, iterate over the relation * values for names, or produce a single section result if names is a section. * * If flags contains PROFILE_ITER_SECTIONS_ONLY, produce only sections. * * If flags contains PROFILE_ITER_RELATIONS_ONLY, produce only relations. */ typedef long (*profile_iterator_create_fn)(void *cbdata, const char *const *names, int flags, void **ret_iter); /* * Optional (mandatory if iterator_create is defined): Produce the next * relation or section in an iteration. If producing a section result, set * *ret_value to NULL. The returned strings will be freed with free_string. */ typedef long (*profile_iterator_fn)(void *cbdata, void *iter, char **ret_name, char **ret_value); /* * Optional (mandatory if iterator_create is defined): Free the memory for an * iterator. */ typedef void (*profile_iterator_free_fn)(void *cbdata, void *iter); /* Optional (mandatory if iterator is defined): Free a string value. */ typedef void (*profile_free_string_fn)(void *cbdata, char *string); /* * Optional: Determine if a profile is writable. If not implemented, the * profile is never writable. */ typedef long (*profile_writable_fn)(void *cbdata, int *writable); /* * Optional: Determine if a profile is modified in memory relative to the * persistent store. If not implemented, the profile is assumed to never be * modified. */ typedef long (*profile_modified_fn)(void *cbdata, int *modified); /* * Optional: Change the value of a relation, or remove it if new_value is NULL. * If old_value is set and the relation does not have that value, return * PROF_NO_RELATION. */ typedef long (*profile_update_relation_fn)(void *cbdata, const char **names, const char *old_value, const char *new_value); /* * Optional: Rename a section to new_name, or remove the section if new_name is * NULL. */ typedef long (*profile_rename_section_fn)(void *cbdata, const char **names, const char *new_name); /* * Optional: Add a new relation, or a new section if new_value is NULL. Add * any intermediate sections as necessary. */ typedef long (*profile_add_relation_fn)(void *cbdata, const char **names, const char *new_value); /* * Optional: Flush any pending memory updates to the persistent store. If * implemented, this function will be called by profile_release as well as * profile_flush, so make sure it's not inefficient to flush an unmodified * profile. */ typedef long (*profile_flush_fn)(void *cbdata); struct profile_vtable { int minor_ver; /* Set to structure minor version (currently 1) * if calling profile_init_vtable. */ /* Methods needed for a basic read-only non-iterable profile (cleanup is * optional). */ profile_get_values_fn get_values; profile_free_values_fn free_values; profile_cleanup_fn cleanup; profile_copy_fn copy; /* Methods for iterable profiles. */ profile_iterator_create_fn iterator_create; profile_iterator_fn iterator; profile_iterator_free_fn iterator_free; profile_free_string_fn free_string; /* Methods for writable profiles. */ profile_writable_fn writable; profile_modified_fn modified; profile_update_relation_fn update_relation; profile_rename_section_fn rename_section; profile_add_relation_fn add_relation; profile_flush_fn flush; /* End of minor version 1. */ }; /* * Create a profile object whose operations will be performed using the * function pointers in vtable. cbdata will be supplied to each vtable * function as the first argument. */ long KRB5_CALLCONV profile_init_vtable (struct profile_vtable *vtable, void *cbdata, profile_t *ret_profile); /* * Dynamically loadable profile modules should define a function named * "profile_module_init" matching the following signature. The function should * initialize the methods of the provided vtable structure, stopping at the * field corresponding to vtable->minor_ver. Do not change the value of * vtable->minor_ver. Unimplemented methods can be left uninitialized. The * function should supply a callback data pointer in *cb_ret; this pointer can * be cleaned up via the vtable cleanup method. */ typedef long (*profile_module_init_fn)(const char *residual, struct profile_vtable *vtable, void **cb_ret); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _KRB5_PROFILE_H */ /* * et-h-prof_err.h: * This file is automatically generated; please do not edit it. */ #include <et/com_err.h> #define PROF_VERSION (-1429577728L) #define PROF_MAGIC_NODE (-1429577727L) #define PROF_NO_SECTION (-1429577726L) #define PROF_NO_RELATION (-1429577725L) #define PROF_ADD_NOT_SECTION (-1429577724L) #define PROF_SECTION_WITH_VALUE (-1429577723L) #define PROF_BAD_LINK_LIST (-1429577722L) #define PROF_BAD_GROUP_LVL (-1429577721L) #define PROF_BAD_PARENT_PTR (-1429577720L) #define PROF_MAGIC_ITERATOR (-1429577719L) #define PROF_SET_SECTION_VALUE (-1429577718L) #define PROF_EINVAL (-1429577717L) #define PROF_READ_ONLY (-1429577716L) #define PROF_SECTION_NOTOP (-1429577715L) #define PROF_SECTION_SYNTAX (-1429577714L) #define PROF_RELATION_SYNTAX (-1429577713L) #define PROF_EXTRA_CBRACE (-1429577712L) #define PROF_MISSING_OBRACE (-1429577711L) #define PROF_MAGIC_PROFILE (-1429577710L) #define PROF_MAGIC_SECTION (-1429577709L) #define PROF_TOPSECTION_ITER_NOSUPP (-1429577708L) #define PROF_INVALID_SECTION (-1429577707L) #define PROF_END_OF_SECTIONS (-1429577706L) #define PROF_BAD_NAMESET (-1429577705L) #define PROF_NO_PROFILE (-1429577704L) #define PROF_MAGIC_FILE (-1429577703L) #define PROF_FAIL_OPEN (-1429577702L) #define PROF_EXISTS (-1429577701L) #define PROF_BAD_BOOLEAN (-1429577700L) #define PROF_BAD_INTEGER (-1429577699L) #define PROF_MAGIC_FILE_DATA (-1429577698L) #define PROF_FAIL_INCLUDE_FILE (-1429577697L) #define PROF_FAIL_INCLUDE_DIR (-1429577696L) #define PROF_UNSUPPORTED (-1429577695L) #define PROF_MAGIC_NODE_ITERATOR (-1429577694L) #define PROF_MODULE (-1429577693L) #define PROF_MODULE_SYNTAX (-1429577692L) #define PROF_MODULE_INVALID (-1429577691L) extern const struct error_table et_prof_error_table; extern void initialize_prof_error_table(void); /* For compatibility with Heimdal */ extern void initialize_prof_error_table_r(struct et_list **list); #define ERROR_TABLE_BASE_prof (-1429577728L) /* for compatibility with older versions... */ #define init_prof_err_tbl initialize_prof_error_table #define prof_err_base ERROR_TABLE_BASE_prof netrose/rose.h 0000644 00000006157 15146341150 0007355 0 ustar 00 /* Definitions for Rose packet radio address family. Copyright (C) 1998-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* What follows is copied from the 2.1.93 <linux/rose.h>. */ #ifndef _NETROSE_ROSE_H #define _NETROSE_ROSE_H 1 #include <sys/socket.h> #include <netax25/ax25.h> /* Socket level values. */ #define SOL_ROSE 260 /* These are the public elements of the Linux kernel Rose implementation. For kernel AX.25 see the file ax25.h. This file requires ax25.h for the definition of the ax25_address structure. */ #define ROSE_MTU 251 #define ROSE_MAX_DIGIS 6 #define ROSE_DEFER 1 #define ROSE_T1 2 #define ROSE_T2 3 #define ROSE_T3 4 #define ROSE_IDLE 5 #define ROSE_QBITINCL 6 #define ROSE_HOLDBACK 7 #define SIOCRSGCAUSE (SIOCPROTOPRIVATE + 0) #define SIOCRSSCAUSE (SIOCPROTOPRIVATE + 1) #define SIOCRSL2CALL (SIOCPROTOPRIVATE + 2) #define SIOCRSSL2CALL (SIOCPROTOPRIVATE + 2) #define SIOCRSACCEPT (SIOCPROTOPRIVATE + 3) #define SIOCRSCLRRT (SIOCPROTOPRIVATE + 4) #define SIOCRSGL2CALL (SIOCPROTOPRIVATE + 5) #define SIOCRSGFACILITIES (SIOCPROTOPRIVATE + 6) #define ROSE_DTE_ORIGINATED 0x00 #define ROSE_NUMBER_BUSY 0x01 #define ROSE_INVALID_FACILITY 0x03 #define ROSE_NETWORK_CONGESTION 0x05 #define ROSE_OUT_OF_ORDER 0x09 #define ROSE_ACCESS_BARRED 0x0B #define ROSE_NOT_OBTAINABLE 0x0D #define ROSE_REMOTE_PROCEDURE 0x11 #define ROSE_LOCAL_PROCEDURE 0x13 #define ROSE_SHIP_ABSENT 0x39 typedef struct { char rose_addr[5]; } rose_address; struct sockaddr_rose { sa_family_t srose_family; rose_address srose_addr; ax25_address srose_call; int srose_ndigis; ax25_address srose_digi; }; struct full_sockaddr_rose { sa_family_t srose_family; rose_address srose_addr; ax25_address srose_call; unsigned int srose_ndigis; ax25_address srose_digis[ROSE_MAX_DIGIS]; }; struct rose_route_struct { rose_address address; unsigned short int mask; ax25_address neighbour; char device[16]; unsigned char ndigis; ax25_address digipeaters[AX25_MAX_DIGIS]; }; struct rose_cause_struct { unsigned char cause; unsigned char diagnostic; }; struct rose_facilities_struct { rose_address source_addr, dest_addr; ax25_address source_call, dest_call; unsigned char source_ndigis, dest_ndigis; ax25_address source_digis[ROSE_MAX_DIGIS]; ax25_address dest_digis[ROSE_MAX_DIGIS]; unsigned int rand; rose_address fail_addr; ax25_address fail_call; }; #endif /* netrose/rose.h */ lber_types.h 0000644 00000002674 15146341150 0007076 0 ustar 00 /* include/lber_types.h. Generated from lber_types.hin by configure. */ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 1998-2018 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in file LICENSE in the * top-level directory of the distribution or, alternatively, at * <http://www.OpenLDAP.org/license.html>. */ /* * LBER types */ #ifndef _LBER_TYPES_H #define _LBER_TYPES_H #include <ldap_cdefs.h> LDAP_BEGIN_DECL /* LBER boolean, enum, integers (32 bits or larger) */ #define LBER_INT_T int /* LBER tags (32 bits or larger) */ #define LBER_TAG_T long /* LBER socket descriptor */ #define LBER_SOCKET_T int /* LBER lengths (32 bits or larger) */ #define LBER_LEN_T long /* ------------------------------------------------------------ */ /* booleans, enumerations, and integers */ typedef LBER_INT_T ber_int_t; /* signed and unsigned versions */ typedef signed LBER_INT_T ber_sint_t; typedef unsigned LBER_INT_T ber_uint_t; /* tags */ typedef unsigned LBER_TAG_T ber_tag_t; /* "socket" descriptors */ typedef LBER_SOCKET_T ber_socket_t; /* lengths */ typedef unsigned LBER_LEN_T ber_len_t; /* signed lengths */ typedef signed LBER_LEN_T ber_slen_t; LDAP_END_DECL #endif /* _LBER_TYPES_H */ shadow.h 0000644 00000012537 15146341150 0006212 0 ustar 00 /* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* Declaration of types and functions for "shadow" storage of hashed passphrases. The shadow database is like the user database, but is only accessible with special privileges, so that malicious users cannot retrieve everyone else's hashed passphrase to brute-force at their convenience. */ #ifndef _SHADOW_H #define _SHADOW_H 1 #include <features.h> #include <paths.h> #define __need_size_t #include <stddef.h> #include <bits/types/FILE.h> /* Paths to the user database files. */ #define SHADOW _PATH_SHADOW __BEGIN_DECLS /* A record in the shadow database. */ struct spwd { char *sp_namp; /* Login name. */ char *sp_pwdp; /* Hashed passphrase. */ long int sp_lstchg; /* Date of last change. */ long int sp_min; /* Minimum number of days between changes. */ long int sp_max; /* Maximum number of days between changes. */ long int sp_warn; /* Number of days to warn user to change the password. */ long int sp_inact; /* Number of days the account may be inactive. */ long int sp_expire; /* Number of days since 1970-01-01 until account expires. */ unsigned long int sp_flag; /* Reserved. */ }; /* Open database for reading. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern void setspent (void); /* Close database. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern void endspent (void); /* Get next entry from database, perhaps after opening the file. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern struct spwd *getspent (void); /* Get shadow entry matching NAME. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern struct spwd *getspnam (const char *__name); /* Read shadow entry from STRING. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern struct spwd *sgetspent (const char *__string); /* Read next shadow entry from STREAM. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern struct spwd *fgetspent (FILE *__stream); /* Write line containing shadow entry to stream. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int putspent (const struct spwd *__p, FILE *__stream); #ifdef __USE_MISC /* Reentrant versions of some of the functions above. These functions are not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation they are cancellation points and therefore not marked with __THROW. */ extern int getspent_r (struct spwd *__result_buf, char *__buffer, size_t __buflen, struct spwd **__result); extern int getspnam_r (const char *__name, struct spwd *__result_buf, char *__buffer, size_t __buflen, struct spwd **__result); extern int sgetspent_r (const char *__string, struct spwd *__result_buf, char *__buffer, size_t __buflen, struct spwd **__result); extern int fgetspent_r (FILE *__stream, struct spwd *__result_buf, char *__buffer, size_t __buflen, struct spwd **__result); #endif /* misc */ /* The simple locking functionality provided here is not suitable for multi-threaded applications. */ /* Request exclusive access to /etc/passwd and /etc/shadow. */ extern int lckpwdf (void) __THROW; /* Release exclusive access to /etc/passwd and /etc/shadow. */ extern int ulckpwdf (void) __THROW; __END_DECLS #endif /* shadow.h */ byteswap.h 0000644 00000002574 15146341150 0006563 0 ustar 00 /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _BYTESWAP_H #define _BYTESWAP_H 1 #include <features.h> /* Get the machine specific, optimized definitions. */ #include <bits/byteswap.h> /* The following definitions must all be macros since otherwise some of the possible optimizations are not possible. */ /* Return a value with all bytes in the 16 bit argument swapped. */ #define bswap_16(x) __bswap_16 (x) /* Return a value with all bytes in the 32 bit argument swapped. */ #define bswap_32(x) __bswap_32 (x) /* Return a value with all bytes in the 64 bit argument swapped. */ #define bswap_64(x) __bswap_64 (x) #endif /* byteswap.h */ argp.h 0000644 00000061506 15146341150 0005656 0 ustar 00 /* Hierarchial argument parsing, layered over getopt. Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _ARGP_H #define _ARGP_H #include <stdio.h> #include <ctype.h> #include <getopt.h> #include <limits.h> #include <errno.h> __BEGIN_DECLS /* error_t may or may not be available from errno.h, depending on the operating system. */ #ifndef __error_t_defined # define __error_t_defined 1 typedef int error_t; #endif /* A description of a particular option. A pointer to an array of these is passed in the OPTIONS field of an argp structure. Each option entry can correspond to one long option and/or one short option; more names for the same option can be added by following an entry in an option array with options having the OPTION_ALIAS flag set. */ struct argp_option { /* The long option name. For more than one name for the same option, you can use following options with the OPTION_ALIAS flag set. */ const char *name; /* What key is returned for this option. If > 0 and printable, then it's also accepted as a short option. */ int key; /* If non-NULL, this is the name of the argument associated with this option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */ const char *arg; /* OPTION_ flags. */ int flags; /* The doc string for this option. If both NAME and KEY are 0, This string will be printed outdented from the normal option column, making it useful as a group header (it will be the first thing printed in its group); in this usage, it's conventional to end the string with a `:'. */ const char *doc; /* The group this option is in. In a long help message, options are sorted alphabetically within each group, and the groups presented in the order 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with if this field 0 will inherit the group number of the previous entry, or zero if it's the first one, unless its a group header (NAME and KEY both 0), in which case, the previous entry + 1 is the default. Automagic options such as --help are put into group -1. */ int group; }; /* The argument associated with this option is optional. */ #define OPTION_ARG_OPTIONAL 0x1 /* This option isn't displayed in any help messages. */ #define OPTION_HIDDEN 0x2 /* This option is an alias for the closest previous non-alias option. This means that it will be displayed in the same help entry, and will inherit fields other than NAME and KEY from the aliased option. */ #define OPTION_ALIAS 0x4 /* This option isn't actually an option (and so should be ignored by the actual option parser), but rather an arbitrary piece of documentation that should be displayed in much the same manner as the options. If this flag is set, then the option NAME field is displayed unmodified (e.g., no `--' prefix is added) at the left-margin (where a *short* option would normally be displayed), and the documentation string in the normal place. For purposes of sorting, any leading whitespace and punctuation is ignored, except that if the first non-whitespace character is not `-', this entry is displayed after all options (and OPTION_DOC entries with a leading `-') in the same group. */ #define OPTION_DOC 0x8 /* This option shouldn't be included in `long' usage messages (but is still included in help messages). This is mainly intended for options that are completely documented in an argp's ARGS_DOC field, in which case including the option in the generic usage list would be redundant. For instance, if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to distinguish these two cases, -x should probably be marked OPTION_NO_USAGE. */ #define OPTION_NO_USAGE 0x10 struct argp; /* fwd declare this type */ struct argp_state; /* " */ struct argp_child; /* " */ /* The type of a pointer to an argp parsing function. */ typedef error_t (*argp_parser_t) (int __key, char *__arg, struct argp_state *__state); /* What to return for unrecognized keys. For special ARGP_KEY_ keys, such returns will simply be ignored. For user keys, this error will be turned into EINVAL (if the call to argp_parse is such that errors are propagated back to the user instead of exiting); returning EINVAL itself would result in an immediate stop to parsing in *all* cases. */ #define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */ /* Special values for the KEY argument to an argument parsing function. ARGP_ERR_UNKNOWN should be returned if they aren't understood. The sequence of keys to a parsing function is either (where each uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key): INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized The third case is where every parser returned ARGP_KEY_UNKNOWN for an argument, in which case parsing stops at that argument (returning the unparsed arguments to the caller of argp_parse if requested, or stopping with an error message if not). If an error occurs (either detected by argp, or because the parsing function returned an error value), then the parser is called with ARGP_KEY_ERROR, and no further calls are made. */ /* This is not an option at all, but rather a command line argument. If a parser receiving this key returns success, the fact is recorded, and the ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the argument, a parser function decrements the NEXT field of the state it's passed, the option won't be considered processed; this is to allow you to actually modify the argument (perhaps into an option), and have it processed again. */ #define ARGP_KEY_ARG 0 /* There are remaining arguments not parsed by any parser, which may be found starting at (STATE->argv + STATE->next). If success is returned, but STATE->next left untouched, it's assumed that all arguments were consume, otherwise, the parser should adjust STATE->next to reflect any arguments consumed. */ #define ARGP_KEY_ARGS 0x1000006 /* There are no more command line arguments at all. */ #define ARGP_KEY_END 0x1000001 /* Because it's common to want to do some special processing if there aren't any non-option args, user parsers are called with this key if they didn't successfully process any non-option arguments. Called just before ARGP_KEY_END (where more general validity checks on previously parsed arguments can take place). */ #define ARGP_KEY_NO_ARGS 0x1000002 /* Passed in before any parsing is done. Afterwards, the values of each element of the CHILD_INPUT field, if any, in the state structure is copied to each child's state to be the initial value of the INPUT field. */ #define ARGP_KEY_INIT 0x1000003 /* Use after all other keys, including SUCCESS & END. */ #define ARGP_KEY_FINI 0x1000007 /* Passed in when parsing has successfully been completed (even if there are still arguments remaining). */ #define ARGP_KEY_SUCCESS 0x1000004 /* Passed in if an error occurs. */ #define ARGP_KEY_ERROR 0x1000005 /* An argp structure contains a set of options declarations, a function to deal with parsing one, documentation string, a possible vector of child argp's, and perhaps a function to filter help output. When actually parsing options, getopt is called with the union of all the argp structures chained together through their CHILD pointers, with conflicts being resolved in favor of the first occurrence in the chain. */ struct argp { /* An array of argp_option structures, terminated by an entry with both NAME and KEY having a value of 0. */ const struct argp_option *options; /* What to do with an option from this structure. KEY is the key associated with the option, and ARG is any associated argument (NULL if none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then parsing is stopped immediately, and that value is returned from argp_parse(). For special (non-user-supplied) values of KEY, see the ARGP_KEY_ definitions below. */ argp_parser_t parser; /* A string describing what other arguments are wanted by this program. It is only used by argp_usage to print the `Usage:' message. If it contains newlines, the strings separated by them are considered alternative usage patterns, and printed on separate lines (lines after the first are prefix by ` or: ' instead of `Usage:'). */ const char *args_doc; /* If non-NULL, a string containing extra text to be printed before and after the options in a long help message (separated by a vertical tab `\v' character). */ const char *doc; /* A vector of argp_children structures, terminated by a member with a 0 argp field, pointing to child argps should be parsed with this one. Any conflicts are resolved in favor of this argp, or early argps in the CHILDREN list. This field is useful if you use libraries that supply their own argp structure, which you want to use in conjunction with your own. */ const struct argp_child *children; /* If non-zero, this should be a function to filter the output of help messages. KEY is either a key from an option, in which case TEXT is that option's help text, or a special key from the ARGP_KEY_HELP_ defines, below, describing which other help text TEXT is. The function should return either TEXT, if it should be used as-is, a replacement string, which should be malloced, and will be freed by argp, or NULL, meaning `print nothing'. The value for TEXT is *after* any translation has been done, so if any of the replacement text also needs translation, that should be done by the filter function. INPUT is either the input supplied to argp_parse, or NULL, if argp_help was called directly. */ char *(*help_filter) (int __key, const char *__text, void *__input); /* If non-zero the strings used in the argp library are translated using the domain described by this string. Otherwise the currently installed default domain is used. */ const char *argp_domain; }; /* Possible KEY arguments to a help filter function. */ #define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */ #define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */ #define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */ #define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation; TEXT is NULL for this key. */ /* Explanatory note emitted when duplicate option arguments have been suppressed. */ #define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005 #define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */ /* When an argp has a non-zero CHILDREN field, it should point to a vector of argp_child structures, each of which describes a subsidiary argp. */ struct argp_child { /* The child parser. */ const struct argp *argp; /* Flags for this child. */ int flags; /* If non-zero, an optional header to be printed in help output before the child options. As a side-effect, a non-zero value forces the child options to be grouped together; to achieve this effect without actually printing a header string, use a value of "". */ const char *header; /* Where to group the child options relative to the other (`consolidated') options in the parent argp; the values are the same as the GROUP field in argp_option structs, but all child-groupings follow parent options at a particular group level. If both this field and HEADER are zero, then they aren't grouped at all, but rather merged with the parent options (merging the child's grouping levels with the parents). */ int group; }; /* Parsing state. This is provided to parsing functions called by argp, which may examine and, as noted, modify fields. */ struct argp_state { /* The top level ARGP being parsed. */ const struct argp *root_argp; /* The argument vector being parsed. May be modified. */ int argc; char **argv; /* The index in ARGV of the next arg that to be parsed. May be modified. */ int next; /* The flags supplied to argp_parse. May be modified. */ unsigned flags; /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the number of the current arg, starting at zero, and incremented after each such call returns. At all other times, this is the number of such arguments that have been processed. */ unsigned arg_num; /* If non-zero, the index in ARGV of the first argument following a special `--' argument (which prevents anything following being interpreted as an option). Only set once argument parsing has proceeded past this point. */ int quoted; /* An arbitrary pointer passed in from the user. */ void *input; /* Values to pass to child parsers. This vector will be the same length as the number of children for the current parser. */ void **child_inputs; /* For the parser's use. Initialized to 0. */ void *hook; /* The name used when printing messages. This is initialized to ARGV[0], or PROGRAM_INVOCATION_NAME if that is unavailable. */ char *name; /* Streams used when argp prints something. */ FILE *err_stream; /* For errors; initialized to stderr. */ FILE *out_stream; /* For information; initialized to stdout. */ void *pstate; /* Private, for use by argp. */ }; /* Flags for argp_parse (note that the defaults are those that are convenient for program command line parsing): */ /* Don't ignore the first element of ARGV. Normally (and always unless ARGP_NO_ERRS is set) the first element of the argument vector is skipped for option parsing purposes, as it corresponds to the program name in a command line. */ #define ARGP_PARSE_ARGV0 0x01 /* Don't print error messages for unknown options to stderr; unless this flag is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program name in the error messages. This flag implies ARGP_NO_EXIT (on the assumption that silent exiting upon errors is bad behaviour). */ #define ARGP_NO_ERRS 0x02 /* Don't parse any non-option args. Normally non-option args are parsed by calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg as the value. Since it's impossible to know which parse function wants to handle it, each one is called in turn, until one returns 0 or an error other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the argp_parse returns prematurely (but with a return value of 0). If all args have been parsed without error, all parsing functions are called one last time with a key of ARGP_KEY_END. This flag needn't normally be set, as the normal behavior is to stop parsing as soon as some argument can't be handled. */ #define ARGP_NO_ARGS 0x04 /* Parse options and arguments in the same order they occur on the command line -- normally they're rearranged so that all options come first. */ #define ARGP_IN_ORDER 0x08 /* Don't provide the standard long option --help, which causes usage and option help information to be output to stdout, and exit (0) called. */ #define ARGP_NO_HELP 0x10 /* Don't exit on errors (they may still result in error messages). */ #define ARGP_NO_EXIT 0x20 /* Use the gnu getopt `long-only' rules for parsing arguments. */ #define ARGP_LONG_ONLY 0x40 /* Turns off any message-printing/exiting options. */ #define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP) /* Parse the options strings in ARGC & ARGV according to the options in ARGP. FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the index in ARGV of the first unparsed option is returned in it. If an unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser routine returned a non-zero value, it is returned; otherwise 0 is returned. This function may also call exit unless the ARGP_NO_HELP flag is set. INPUT is a pointer to a value to be passed in to the parser. */ extern error_t argp_parse (const struct argp *__restrict __argp, int __argc, char **__restrict __argv, unsigned __flags, int *__restrict __arg_index, void *__restrict __input); extern error_t __argp_parse (const struct argp *__restrict __argp, int __argc, char **__restrict __argv, unsigned __flags, int *__restrict __arg_index, void *__restrict __input); /* Global variables. */ /* If defined or set by the user program to a non-zero value, then a default option --version is added (unless the ARGP_NO_HELP flag is used), which will print this string followed by a newline and exit (unless the ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ extern const char *argp_program_version; /* If defined or set by the user program to a non-zero value, then a default option --version is added (unless the ARGP_NO_HELP flag is used), which calls this function with a stream to print the version to and a pointer to the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ extern void (*argp_program_version_hook) (FILE *__restrict __stream, struct argp_state *__restrict __state); /* If defined or set by the user program, it should point to string that is the bug-reporting address for the program. It will be printed by argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help messages), embedded in a sentence that says something like `Report bugs to ADDR.'. */ extern const char *argp_program_bug_address; /* The exit status that argp will use when exiting due to a parsing error. If not defined or set by the user program, this defaults to EX_USAGE from <sysexits.h>. */ extern error_t argp_err_exit_status; /* Flags for argp_help. */ #define ARGP_HELP_USAGE 0x01 /* a Usage: message. */ #define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */ #define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */ #define ARGP_HELP_LONG 0x08 /* a long help message. */ #define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */ #define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */ #define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC) #define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */ #define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to reflect ARGP_LONG_ONLY mode. */ /* These ARGP_HELP flags are only understood by argp_state_help. */ #define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */ #define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */ /* The standard thing to do after a program command line parsing error, if an error message has already been printed. */ #define ARGP_HELP_STD_ERR \ (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) /* The standard thing to do after a program command line parsing error, if no more specific error message has been printed. */ #define ARGP_HELP_STD_USAGE \ (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) /* The standard thing to do in response to a --help option. */ #define ARGP_HELP_STD_HELP \ (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \ | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR) /* Output a usage message for ARGP to STREAM. FLAGS are from the set ARGP_HELP_*. */ extern void argp_help (const struct argp *__restrict __argp, FILE *__restrict __stream, unsigned __flags, char *__restrict __name); extern void __argp_help (const struct argp *__restrict __argp, FILE *__restrict __stream, unsigned __flags, char *__name); /* The following routines are intended to be called from within an argp parsing routine (thus taking an argp_state structure as the first argument). They may or may not print an error message and exit, depending on the flags in STATE -- in any case, the caller should be prepared for them *not* to exit, and should return an appropiate error after calling them. [argp_usage & argp_error should probably be called argp_state_..., but they're used often enough that they should be short] */ /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are from the set ARGP_HELP_*. */ extern void argp_state_help (const struct argp_state *__restrict __state, FILE *__restrict __stream, unsigned int __flags); extern void __argp_state_help (const struct argp_state *__restrict __state, FILE *__restrict __stream, unsigned int __flags); /* Possibly output the standard usage message for ARGP to stderr and exit. */ extern void argp_usage (const struct argp_state *__state); extern void __argp_usage (const struct argp_state *__state); /* If appropriate, print the printf string FMT and following args, preceded by the program name and `:', to stderr, and followed by a `Try ... --help' message, then exit (1). */ extern void argp_error (const struct argp_state *__restrict __state, const char *__restrict __fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); extern void __argp_error (const struct argp_state *__restrict __state, const char *__restrict __fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); /* Similar to the standard gnu error-reporting function error(), but will respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print to STATE->err_stream. This is useful for argument parsing code that is shared between program startup (when exiting is desired) and runtime option parsing (when typically an error code is returned instead). The difference between this function and argp_error is that the latter is for *parsing errors*, and the former is for other problems that occur during parsing but don't reflect a (syntactic) problem with the input. */ extern void argp_failure (const struct argp_state *__restrict __state, int __status, int __errnum, const char *__restrict __fmt, ...) __attribute__ ((__format__ (__printf__, 4, 5))); extern void __argp_failure (const struct argp_state *__restrict __state, int __status, int __errnum, const char *__restrict __fmt, ...) __attribute__ ((__format__ (__printf__, 4, 5))); /* Returns true if the option OPT is a valid short option. */ extern int _option_is_short (const struct argp_option *__opt) __THROW; extern int __option_is_short (const struct argp_option *__opt) __THROW; /* Returns true if the option OPT is in fact the last (unused) entry in an options array. */ extern int _option_is_end (const struct argp_option *__opt) __THROW; extern int __option_is_end (const struct argp_option *__opt) __THROW; /* Return the input field for ARGP in the parser corresponding to STATE; used by the help routines. */ extern void *_argp_input (const struct argp *__restrict __argp, const struct argp_state *__restrict __state) __THROW; extern void *__argp_input (const struct argp *__restrict __argp, const struct argp_state *__restrict __state) __THROW; #ifdef __USE_EXTERN_INLINES # if !(defined _LIBC && _LIBC) # define __argp_usage argp_usage # define __argp_state_help argp_state_help # define __option_is_short _option_is_short # define __option_is_end _option_is_end # endif # ifndef ARGP_EI # define ARGP_EI __extern_inline # endif ARGP_EI void __argp_usage (const struct argp_state *__state) { __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE); } ARGP_EI int __NTH (__option_is_short (const struct argp_option *__opt)) { if (__opt->flags & OPTION_DOC) return 0; else { int __key = __opt->key; return __key > 0 && __key <= UCHAR_MAX && isprint (__key); } } ARGP_EI int __NTH (__option_is_end (const struct argp_option *__opt)) { return !__opt->key && !__opt->name && !__opt->doc && !__opt->group; } # if !(defined _LIBC && _LIBC) # undef __argp_usage # undef __argp_state_help # undef __option_is_short # undef __option_is_end # endif #endif /* Use extern inlines. */ __END_DECLS #endif /* argp.h */ wchar.h 0000644 00000074607 15146341150 0006037 0 ustar 00 /* Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* * ISO C99 Standard: 7.24 * Extended multibyte and wide character utilities <wchar.h> */ #ifndef _WCHAR_H #define _WCHAR_H 1 #define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION #include <bits/libc-header-start.h> /* Gather machine dependent type support. */ #include <bits/floatn.h> #define __need_size_t #define __need_wchar_t #define __need_NULL #include <stddef.h> #define __need___va_list #include <stdarg.h> #include <bits/wchar.h> #include <bits/types/wint_t.h> #include <bits/types/mbstate_t.h> #include <bits/types/__FILE.h> #if defined __USE_UNIX98 || defined __USE_XOPEN2K # include <bits/types/FILE.h> #endif #ifdef __USE_XOPEN2K8 # include <bits/types/locale_t.h> #endif /* Tell the caller that we provide correct C++ prototypes. */ #if defined __cplusplus && __GNUC_PREREQ (4, 4) # define __CORRECT_ISO_CPP_WCHAR_H_PROTO #endif #ifndef WCHAR_MIN /* These constants might also be defined in <inttypes.h>. */ # define WCHAR_MIN __WCHAR_MIN # define WCHAR_MAX __WCHAR_MAX #endif #ifndef WEOF # define WEOF (0xffffffffu) #endif /* All versions of XPG prior to the publication of ISO C99 required the bulk of <wctype.h>'s declarations to appear in this header (because <wctype.h> did not exist prior to C99). In POSIX.1-2001 those declarations were marked as XSI extensions; in -2008 they were additionally marked as obsolescent. _GNU_SOURCE mode anticipates the removal of these declarations in the next revision of POSIX. */ #if (defined __USE_XOPEN && !defined __USE_GNU \ && !(defined __USE_XOPEN2K && !defined __USE_XOPEN2KXSI)) # include <bits/wctype-wchar.h> #endif __BEGIN_DECLS /* This incomplete type is defined in <time.h> but needed here because of `wcsftime'. */ struct tm; /* Copy SRC to DEST. */ extern wchar_t *wcscpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src) __THROW __nonnull ((1, 2)); /* Copy no more than N wide-characters of SRC to DEST. */ extern wchar_t *wcsncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, size_t __n) __THROW __nonnull ((1, 2)); /* Append SRC onto DEST. */ extern wchar_t *wcscat (wchar_t *__restrict __dest, const wchar_t *__restrict __src) __THROW __nonnull ((1, 2)); /* Append no more than N wide-characters of SRC onto DEST. */ extern wchar_t *wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src, size_t __n) __THROW __nonnull ((1, 2)); /* Compare S1 and S2. */ extern int wcscmp (const wchar_t *__s1, const wchar_t *__s2) __THROW __attribute_pure__ __nonnull ((1, 2)); /* Compare N wide-characters of S1 and S2. */ extern int wcsncmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) __THROW __attribute_pure__ __nonnull ((1, 2)); #ifdef __USE_XOPEN2K8 /* Compare S1 and S2, ignoring case. */ extern int wcscasecmp (const wchar_t *__s1, const wchar_t *__s2) __THROW; /* Compare no more than N chars of S1 and S2, ignoring case. */ extern int wcsncasecmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) __THROW; /* Similar to the two functions above but take the information from the provided locale and not the global locale. */ extern int wcscasecmp_l (const wchar_t *__s1, const wchar_t *__s2, locale_t __loc) __THROW; extern int wcsncasecmp_l (const wchar_t *__s1, const wchar_t *__s2, size_t __n, locale_t __loc) __THROW; #endif /* Compare S1 and S2, both interpreted as appropriate to the LC_COLLATE category of the current locale. */ extern int wcscoll (const wchar_t *__s1, const wchar_t *__s2) __THROW; /* Transform S2 into array pointed to by S1 such that if wcscmp is applied to two transformed strings the result is the as applying `wcscoll' to the original strings. */ extern size_t wcsxfrm (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, size_t __n) __THROW; #ifdef __USE_XOPEN2K8 /* Similar to the two functions above but take the information from the provided locale and not the global locale. */ /* Compare S1 and S2, both interpreted as appropriate to the LC_COLLATE category of the given locale. */ extern int wcscoll_l (const wchar_t *__s1, const wchar_t *__s2, locale_t __loc) __THROW; /* Transform S2 into array pointed to by S1 such that if wcscmp is applied to two transformed strings the result is the as applying `wcscoll' to the original strings. */ extern size_t wcsxfrm_l (wchar_t *__s1, const wchar_t *__s2, size_t __n, locale_t __loc) __THROW; /* Duplicate S, returning an identical malloc'd string. */ extern wchar_t *wcsdup (const wchar_t *__s) __THROW __attribute_malloc__; #endif /* Find the first occurrence of WC in WCS. */ #ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO extern "C++" wchar_t *wcschr (wchar_t *__wcs, wchar_t __wc) __THROW __asm ("wcschr") __attribute_pure__; extern "C++" const wchar_t *wcschr (const wchar_t *__wcs, wchar_t __wc) __THROW __asm ("wcschr") __attribute_pure__; #else extern wchar_t *wcschr (const wchar_t *__wcs, wchar_t __wc) __THROW __attribute_pure__; #endif /* Find the last occurrence of WC in WCS. */ #ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO extern "C++" wchar_t *wcsrchr (wchar_t *__wcs, wchar_t __wc) __THROW __asm ("wcsrchr") __attribute_pure__; extern "C++" const wchar_t *wcsrchr (const wchar_t *__wcs, wchar_t __wc) __THROW __asm ("wcsrchr") __attribute_pure__; #else extern wchar_t *wcsrchr (const wchar_t *__wcs, wchar_t __wc) __THROW __attribute_pure__; #endif #ifdef __USE_GNU /* This function is similar to `wcschr'. But it returns a pointer to the closing NUL wide character in case C is not found in S. */ extern wchar_t *wcschrnul (const wchar_t *__s, wchar_t __wc) __THROW __attribute_pure__; #endif /* Return the length of the initial segmet of WCS which consists entirely of wide characters not in REJECT. */ extern size_t wcscspn (const wchar_t *__wcs, const wchar_t *__reject) __THROW __attribute_pure__; /* Return the length of the initial segmet of WCS which consists entirely of wide characters in ACCEPT. */ extern size_t wcsspn (const wchar_t *__wcs, const wchar_t *__accept) __THROW __attribute_pure__; /* Find the first occurrence in WCS of any character in ACCEPT. */ #ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO extern "C++" wchar_t *wcspbrk (wchar_t *__wcs, const wchar_t *__accept) __THROW __asm ("wcspbrk") __attribute_pure__; extern "C++" const wchar_t *wcspbrk (const wchar_t *__wcs, const wchar_t *__accept) __THROW __asm ("wcspbrk") __attribute_pure__; #else extern wchar_t *wcspbrk (const wchar_t *__wcs, const wchar_t *__accept) __THROW __attribute_pure__; #endif /* Find the first occurrence of NEEDLE in HAYSTACK. */ #ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO extern "C++" wchar_t *wcsstr (wchar_t *__haystack, const wchar_t *__needle) __THROW __asm ("wcsstr") __attribute_pure__; extern "C++" const wchar_t *wcsstr (const wchar_t *__haystack, const wchar_t *__needle) __THROW __asm ("wcsstr") __attribute_pure__; #else extern wchar_t *wcsstr (const wchar_t *__haystack, const wchar_t *__needle) __THROW __attribute_pure__; #endif /* Divide WCS into tokens separated by characters in DELIM. */ extern wchar_t *wcstok (wchar_t *__restrict __s, const wchar_t *__restrict __delim, wchar_t **__restrict __ptr) __THROW; /* Return the number of wide characters in S. */ extern size_t wcslen (const wchar_t *__s) __THROW __attribute_pure__; #ifdef __USE_XOPEN /* Another name for `wcsstr' from XPG4. */ # ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO extern "C++" wchar_t *wcswcs (wchar_t *__haystack, const wchar_t *__needle) __THROW __asm ("wcswcs") __attribute_pure__; extern "C++" const wchar_t *wcswcs (const wchar_t *__haystack, const wchar_t *__needle) __THROW __asm ("wcswcs") __attribute_pure__; # else extern wchar_t *wcswcs (const wchar_t *__haystack, const wchar_t *__needle) __THROW __attribute_pure__; # endif #endif #ifdef __USE_XOPEN2K8 /* Return the number of wide characters in S, but at most MAXLEN. */ extern size_t wcsnlen (const wchar_t *__s, size_t __maxlen) __THROW __attribute_pure__; #endif /* Search N wide characters of S for C. */ #ifdef __CORRECT_ISO_CPP_WCHAR_H_PROTO extern "C++" wchar_t *wmemchr (wchar_t *__s, wchar_t __c, size_t __n) __THROW __asm ("wmemchr") __attribute_pure__; extern "C++" const wchar_t *wmemchr (const wchar_t *__s, wchar_t __c, size_t __n) __THROW __asm ("wmemchr") __attribute_pure__; #else extern wchar_t *wmemchr (const wchar_t *__s, wchar_t __c, size_t __n) __THROW __attribute_pure__; #endif /* Compare N wide characters of S1 and S2. */ extern int wmemcmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) __THROW __attribute_pure__; /* Copy N wide characters of SRC to DEST. */ extern wchar_t *wmemcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, size_t __n) __THROW; /* Copy N wide characters of SRC to DEST, guaranteeing correct behavior for overlapping strings. */ extern wchar_t *wmemmove (wchar_t *__s1, const wchar_t *__s2, size_t __n) __THROW; /* Set N wide characters of S to C. */ extern wchar_t *wmemset (wchar_t *__s, wchar_t __c, size_t __n) __THROW; #ifdef __USE_GNU /* Copy N wide characters of SRC to DEST and return pointer to following wide character. */ extern wchar_t *wmempcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, size_t __n) __THROW; #endif /* Determine whether C constitutes a valid (one-byte) multibyte character. */ extern wint_t btowc (int __c) __THROW; /* Determine whether C corresponds to a member of the extended character set whose multibyte representation is a single byte. */ extern int wctob (wint_t __c) __THROW; /* Determine whether PS points to an object representing the initial state. */ extern int mbsinit (const mbstate_t *__ps) __THROW __attribute_pure__; /* Write wide character representation of multibyte character pointed to by S to PWC. */ extern size_t mbrtowc (wchar_t *__restrict __pwc, const char *__restrict __s, size_t __n, mbstate_t *__restrict __p) __THROW; /* Write multibyte representation of wide character WC to S. */ extern size_t wcrtomb (char *__restrict __s, wchar_t __wc, mbstate_t *__restrict __ps) __THROW; /* Return number of bytes in multibyte character pointed to by S. */ extern size_t __mbrlen (const char *__restrict __s, size_t __n, mbstate_t *__restrict __ps) __THROW; extern size_t mbrlen (const char *__restrict __s, size_t __n, mbstate_t *__restrict __ps) __THROW; #ifdef __USE_EXTERN_INLINES /* Define inline function as optimization. */ /* We can use the BTOWC and WCTOB optimizations since we know that all locales must use ASCII encoding for the values in the ASCII range and because the wchar_t encoding is always ISO 10646. */ extern wint_t __btowc_alias (int __c) __asm ("btowc"); __extern_inline wint_t __NTH (btowc (int __c)) { return (__builtin_constant_p (__c) && __c >= '\0' && __c <= '\x7f' ? (wint_t) __c : __btowc_alias (__c)); } extern int __wctob_alias (wint_t __c) __asm ("wctob"); __extern_inline int __NTH (wctob (wint_t __wc)) { return (__builtin_constant_p (__wc) && __wc >= L'\0' && __wc <= L'\x7f' ? (int) __wc : __wctob_alias (__wc)); } __extern_inline size_t __NTH (mbrlen (const char *__restrict __s, size_t __n, mbstate_t *__restrict __ps)) { return (__ps != NULL ? mbrtowc (NULL, __s, __n, __ps) : __mbrlen (__s, __n, NULL)); } #endif /* Write wide character representation of multibyte character string SRC to DST. */ extern size_t mbsrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, size_t __len, mbstate_t *__restrict __ps) __THROW; /* Write multibyte character representation of wide character string SRC to DST. */ extern size_t wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src, size_t __len, mbstate_t *__restrict __ps) __THROW; #ifdef __USE_XOPEN2K8 /* Write wide character representation of at most NMC bytes of the multibyte character string SRC to DST. */ extern size_t mbsnrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, size_t __nmc, size_t __len, mbstate_t *__restrict __ps) __THROW; /* Write multibyte character representation of at most NWC characters from the wide character string SRC to DST. */ extern size_t wcsnrtombs (char *__restrict __dst, const wchar_t **__restrict __src, size_t __nwc, size_t __len, mbstate_t *__restrict __ps) __THROW; #endif /* use POSIX 2008 */ /* The following functions are extensions found in X/Open CAE. */ #ifdef __USE_XOPEN /* Determine number of column positions required for C. */ extern int wcwidth (wchar_t __c) __THROW; /* Determine number of column positions required for first N wide characters (or fewer if S ends before this) in S. */ extern int wcswidth (const wchar_t *__s, size_t __n) __THROW; #endif /* Use X/Open. */ /* Convert initial portion of the wide string NPTR to `double' representation. */ extern double wcstod (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr) __THROW; #ifdef __USE_ISOC99 /* Likewise for `float' and `long double' sizes of floating-point numbers. */ extern float wcstof (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr) __THROW; extern long double wcstold (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr) __THROW; #endif /* C99 */ /* Likewise for `_FloatN' and `_FloatNx' when support is enabled. */ #if __HAVE_FLOAT16 && defined __USE_GNU extern _Float16 wcstof16 (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr) __THROW; #endif #if __HAVE_FLOAT32 && defined __USE_GNU extern _Float32 wcstof32 (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr) __THROW; #endif #if __HAVE_FLOAT64 && defined __USE_GNU extern _Float64 wcstof64 (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr) __THROW; #endif #if __HAVE_FLOAT128 && defined __USE_GNU extern _Float128 wcstof128 (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr) __THROW; #endif #if __HAVE_FLOAT32X && defined __USE_GNU extern _Float32x wcstof32x (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr) __THROW; #endif #if __HAVE_FLOAT64X && defined __USE_GNU extern _Float64x wcstof64x (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr) __THROW; #endif #if __HAVE_FLOAT128X && defined __USE_GNU extern _Float128x wcstof128x (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr) __THROW; #endif /* Convert initial portion of wide string NPTR to `long int' representation. */ extern long int wcstol (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base) __THROW; /* Convert initial portion of wide string NPTR to `unsigned long int' representation. */ extern unsigned long int wcstoul (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base) __THROW; #ifdef __USE_ISOC99 /* Convert initial portion of wide string NPTR to `long long int' representation. */ __extension__ extern long long int wcstoll (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base) __THROW; /* Convert initial portion of wide string NPTR to `unsigned long long int' representation. */ __extension__ extern unsigned long long int wcstoull (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base) __THROW; #endif /* ISO C99. */ #ifdef __USE_GNU /* Convert initial portion of wide string NPTR to `long long int' representation. */ __extension__ extern long long int wcstoq (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base) __THROW; /* Convert initial portion of wide string NPTR to `unsigned long long int' representation. */ __extension__ extern unsigned long long int wcstouq (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base) __THROW; #endif /* Use GNU. */ #ifdef __USE_GNU /* Parallel versions of the functions above which take the locale to use as an additional parameter. These are GNU extensions inspired by the POSIX.1-2008 extended locale API. */ extern long int wcstol_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base, locale_t __loc) __THROW; extern unsigned long int wcstoul_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base, locale_t __loc) __THROW; __extension__ extern long long int wcstoll_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base, locale_t __loc) __THROW; __extension__ extern unsigned long long int wcstoull_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, int __base, locale_t __loc) __THROW; extern double wcstod_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, locale_t __loc) __THROW; extern float wcstof_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, locale_t __loc) __THROW; extern long double wcstold_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, locale_t __loc) __THROW; # if __HAVE_FLOAT16 extern _Float16 wcstof16_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, locale_t __loc) __THROW; # endif # if __HAVE_FLOAT32 extern _Float32 wcstof32_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, locale_t __loc) __THROW; # endif # if __HAVE_FLOAT64 extern _Float64 wcstof64_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, locale_t __loc) __THROW; # endif # if __HAVE_FLOAT128 extern _Float128 wcstof128_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, locale_t __loc) __THROW; # endif # if __HAVE_FLOAT32X extern _Float32x wcstof32x_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, locale_t __loc) __THROW; # endif # if __HAVE_FLOAT64X extern _Float64x wcstof64x_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, locale_t __loc) __THROW; # endif # if __HAVE_FLOAT128X extern _Float128x wcstof128x_l (const wchar_t *__restrict __nptr, wchar_t **__restrict __endptr, locale_t __loc) __THROW; # endif #endif /* use GNU */ #ifdef __USE_XOPEN2K8 /* Copy SRC to DEST, returning the address of the terminating L'\0' in DEST. */ extern wchar_t *wcpcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src) __THROW; /* Copy no more than N characters of SRC to DEST, returning the address of the last character written into DEST. */ extern wchar_t *wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, size_t __n) __THROW; #endif /* Wide character I/O functions. */ #if defined __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2) /* Like OPEN_MEMSTREAM, but the stream is wide oriented and produces a wide character string. */ extern __FILE *open_wmemstream (wchar_t **__bufloc, size_t *__sizeloc) __THROW; #endif #if defined __USE_ISOC95 || defined __USE_UNIX98 /* Select orientation for stream. */ extern int fwide (__FILE *__fp, int __mode) __THROW; /* Write formatted output to STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fwprintf (__FILE *__restrict __stream, const wchar_t *__restrict __format, ...) /* __attribute__ ((__format__ (__wprintf__, 2, 3))) */; /* Write formatted output to stdout. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int wprintf (const wchar_t *__restrict __format, ...) /* __attribute__ ((__format__ (__wprintf__, 1, 2))) */; /* Write formatted output of at most N characters to S. */ extern int swprintf (wchar_t *__restrict __s, size_t __n, const wchar_t *__restrict __format, ...) __THROW /* __attribute__ ((__format__ (__wprintf__, 3, 4))) */; /* Write formatted output to S from argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int vfwprintf (__FILE *__restrict __s, const wchar_t *__restrict __format, __gnuc_va_list __arg) /* __attribute__ ((__format__ (__wprintf__, 2, 0))) */; /* Write formatted output to stdout from argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int vwprintf (const wchar_t *__restrict __format, __gnuc_va_list __arg) /* __attribute__ ((__format__ (__wprintf__, 1, 0))) */; /* Write formatted output of at most N character to S from argument list ARG. */ extern int vswprintf (wchar_t *__restrict __s, size_t __n, const wchar_t *__restrict __format, __gnuc_va_list __arg) __THROW /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */; /* Read formatted input from STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fwscanf (__FILE *__restrict __stream, const wchar_t *__restrict __format, ...) /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; /* Read formatted input from stdin. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int wscanf (const wchar_t *__restrict __format, ...) /* __attribute__ ((__format__ (__wscanf__, 1, 2))) */; /* Read formatted input from S. */ extern int swscanf (const wchar_t *__restrict __s, const wchar_t *__restrict __format, ...) __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; # if defined __USE_ISOC99 && !defined __USE_GNU \ && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) # ifdef __REDIRECT /* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ GNU extension which conflicts with valid %a followed by letter s, S or [. */ extern int __REDIRECT (fwscanf, (__FILE *__restrict __stream, const wchar_t *__restrict __format, ...), __isoc99_fwscanf) /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; extern int __REDIRECT (wscanf, (const wchar_t *__restrict __format, ...), __isoc99_wscanf) /* __attribute__ ((__format__ (__wscanf__, 1, 2))) */; extern int __REDIRECT_NTH (swscanf, (const wchar_t *__restrict __s, const wchar_t *__restrict __format, ...), __isoc99_swscanf) /* __attribute__ ((__format__ (__wscanf__, 2, 3))) */; # else extern int __isoc99_fwscanf (__FILE *__restrict __stream, const wchar_t *__restrict __format, ...); extern int __isoc99_wscanf (const wchar_t *__restrict __format, ...); extern int __isoc99_swscanf (const wchar_t *__restrict __s, const wchar_t *__restrict __format, ...) __THROW; # define fwscanf __isoc99_fwscanf # define wscanf __isoc99_wscanf # define swscanf __isoc99_swscanf # endif # endif #endif /* Use ISO C95, C99 and Unix98. */ #ifdef __USE_ISOC99 /* Read formatted input from S into argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int vfwscanf (__FILE *__restrict __s, const wchar_t *__restrict __format, __gnuc_va_list __arg) /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; /* Read formatted input from stdin into argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int vwscanf (const wchar_t *__restrict __format, __gnuc_va_list __arg) /* __attribute__ ((__format__ (__wscanf__, 1, 0))) */; /* Read formatted input from S into argument list ARG. */ extern int vswscanf (const wchar_t *__restrict __s, const wchar_t *__restrict __format, __gnuc_va_list __arg) __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; # if !defined __USE_GNU \ && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) # ifdef __REDIRECT extern int __REDIRECT (vfwscanf, (__FILE *__restrict __s, const wchar_t *__restrict __format, __gnuc_va_list __arg), __isoc99_vfwscanf) /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; extern int __REDIRECT (vwscanf, (const wchar_t *__restrict __format, __gnuc_va_list __arg), __isoc99_vwscanf) /* __attribute__ ((__format__ (__wscanf__, 1, 0))) */; extern int __REDIRECT_NTH (vswscanf, (const wchar_t *__restrict __s, const wchar_t *__restrict __format, __gnuc_va_list __arg), __isoc99_vswscanf) /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */; # else extern int __isoc99_vfwscanf (__FILE *__restrict __s, const wchar_t *__restrict __format, __gnuc_va_list __arg); extern int __isoc99_vwscanf (const wchar_t *__restrict __format, __gnuc_va_list __arg); extern int __isoc99_vswscanf (const wchar_t *__restrict __s, const wchar_t *__restrict __format, __gnuc_va_list __arg) __THROW; # define vfwscanf __isoc99_vfwscanf # define vwscanf __isoc99_vwscanf # define vswscanf __isoc99_vswscanf # endif # endif #endif /* Use ISO C99. */ /* Read a character from STREAM. These functions are possible cancellation points and therefore not marked with __THROW. */ extern wint_t fgetwc (__FILE *__stream); extern wint_t getwc (__FILE *__stream); /* Read a character from stdin. This function is a possible cancellation point and therefore not marked with __THROW. */ extern wint_t getwchar (void); /* Write a character to STREAM. These functions are possible cancellation points and therefore not marked with __THROW. */ extern wint_t fputwc (wchar_t __wc, __FILE *__stream); extern wint_t putwc (wchar_t __wc, __FILE *__stream); /* Write a character to stdout. This function is a possible cancellation point and therefore not marked with __THROW. */ extern wint_t putwchar (wchar_t __wc); /* Get a newline-terminated wide character string of finite length from STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern wchar_t *fgetws (wchar_t *__restrict __ws, int __n, __FILE *__restrict __stream); /* Write a string to STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fputws (const wchar_t *__restrict __ws, __FILE *__restrict __stream); /* Push a character back onto the input buffer of STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern wint_t ungetwc (wint_t __wc, __FILE *__stream); #ifdef __USE_GNU /* These are defined to be equivalent to the `char' functions defined in POSIX.1:1996. These functions are not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation they are cancellation points and therefore not marked with __THROW. */ extern wint_t getwc_unlocked (__FILE *__stream); extern wint_t getwchar_unlocked (void); /* This is the wide character version of a GNU extension. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern wint_t fgetwc_unlocked (__FILE *__stream); /* Faster version when locking is not necessary. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern wint_t fputwc_unlocked (wchar_t __wc, __FILE *__stream); /* These are defined to be equivalent to the `char' functions defined in POSIX.1:1996. These functions are not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation they are cancellation points and therefore not marked with __THROW. */ extern wint_t putwc_unlocked (wchar_t __wc, __FILE *__stream); extern wint_t putwchar_unlocked (wchar_t __wc); /* This function does the same as `fgetws' but does not lock the stream. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern wchar_t *fgetws_unlocked (wchar_t *__restrict __ws, int __n, __FILE *__restrict __stream); /* This function does the same as `fputws' but does not lock the stream. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int fputws_unlocked (const wchar_t *__restrict __ws, __FILE *__restrict __stream); #endif /* Format TP into S according to FORMAT. Write no more than MAXSIZE wide characters and return the number of wide characters written, or 0 if it would exceed MAXSIZE. */ extern size_t wcsftime (wchar_t *__restrict __s, size_t __maxsize, const wchar_t *__restrict __format, const struct tm *__restrict __tp) __THROW; # ifdef __USE_GNU /* Similar to `wcsftime' but takes the information from the provided locale and not the global locale. */ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize, const wchar_t *__restrict __format, const struct tm *__restrict __tp, locale_t __loc) __THROW; # endif /* Define some macros helping to catch buffer overflows. */ #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function # include <bits/wchar2.h> #endif #ifdef __LDBL_COMPAT # include <bits/wchar-ldbl.h> #endif __END_DECLS #endif /* wchar.h */ libgen.h 0000644 00000002551 15146341150 0006160 0 ustar 00 /* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _LIBGEN_H #define _LIBGEN_H 1 #include <features.h> __BEGIN_DECLS /* Return directory part of PATH or "." if none is available. */ extern char *dirname (char *__path) __THROW; /* Return final component of PATH. This is the weird XPG version of this function. It sometimes will modify its argument. Therefore we normally use the GNU version (in <string.h>) and only if this header is included make the XPG version available under the real name. */ extern char *__xpg_basename (char *__path) __THROW; #define basename __xpg_basename __END_DECLS #endif /* libgen.h */ utime.h 0000644 00000002735 15146341150 0006047 0 ustar 00 /* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* * POSIX Standard: 5.6.6 Set File Access and Modification Times <utime.h> */ #ifndef _UTIME_H #define _UTIME_H 1 #include <features.h> __BEGIN_DECLS #include <bits/types.h> #if defined __USE_XOPEN || defined __USE_XOPEN2K # include <bits/types/time_t.h> #endif /* Structure describing file times. */ struct utimbuf { __time_t actime; /* Access time. */ __time_t modtime; /* Modification time. */ }; /* Set the access and modification times of FILE to those given in *FILE_TIMES. If FILE_TIMES is NULL, set them to the current time. */ extern int utime (const char *__file, const struct utimbuf *__file_times) __THROW __nonnull ((1)); __END_DECLS #endif /* utime.h */ mcheck.h 0000644 00000004602 15146341150 0006151 0 ustar 00 /* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _MCHECK_H #define _MCHECK_H 1 #include <features.h> __BEGIN_DECLS /* Return values for `mprobe': these are the kinds of inconsistencies that `mcheck' enables detection of. */ enum mcheck_status { MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */ MCHECK_OK, /* Block is fine. */ MCHECK_FREE, /* Block freed twice. */ MCHECK_HEAD, /* Memory before the block was clobbered. */ MCHECK_TAIL /* Memory after the block was clobbered. */ }; /* Activate a standard collection of debugging hooks. This must be called before `malloc' is ever called. ABORTFUNC is called with an error code (see enum above) when an inconsistency is detected. If ABORTFUNC is null, the standard function prints on stderr and then calls `abort'. */ extern int mcheck (void (*__abortfunc)(enum mcheck_status)) __THROW; /* Similar to `mcheck' but performs checks for all block whenever one of the memory handling functions is called. This can be very slow. */ extern int mcheck_pedantic (void (*__abortfunc)(enum mcheck_status)) __THROW; /* Force check of all blocks now. */ extern void mcheck_check_all (void); /* Check for aberrations in a particular malloc'd block. You must have called `mcheck' already. These are the same checks that `mcheck' does when you free or reallocate a block. */ extern enum mcheck_status mprobe (void *__ptr) __THROW; /* Activate a standard collection of tracing hooks. */ extern void mtrace (void) __THROW; extern void muntrace (void) __THROW; __END_DECLS #endif /* mcheck.h */ re_comp.h 0000644 00000001702 15146341150 0006341 0 ustar 00 /* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _RE_COMP_H #define _RE_COMP_H 1 /* This is only a wrapper around the <regex.h> file. XPG4.2 mentions this name. */ #include <regex.h> #endif /* re_comp.h */ pcrecpp.h 0000644 00000063641 15146341150 0006363 0 ustar 00 // Copyright (c) 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * 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. // * Neither the name of Google Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT // OWNER 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. // // Author: Sanjay Ghemawat // Support for PCRE_XXX modifiers added by Giuseppe Maxia, July 2005 #ifndef _PCRECPP_H #define _PCRECPP_H // C++ interface to the pcre regular-expression library. RE supports // Perl-style regular expressions (with extensions like \d, \w, \s, // ...). // // ----------------------------------------------------------------------- // REGEXP SYNTAX: // // This module is part of the pcre library and hence supports its syntax // for regular expressions. // // The syntax is pretty similar to Perl's. For those not familiar // with Perl's regular expressions, here are some examples of the most // commonly used extensions: // // "hello (\\w+) world" -- \w matches a "word" character // "version (\\d+)" -- \d matches a digit // "hello\\s+world" -- \s matches any whitespace character // "\\b(\\w+)\\b" -- \b matches empty string at a word boundary // "(?i)hello" -- (?i) turns on case-insensitive matching // "/\\*(.*?)\\*/" -- .*? matches . minimum no. of times possible // // ----------------------------------------------------------------------- // MATCHING INTERFACE: // // The "FullMatch" operation checks that supplied text matches a // supplied pattern exactly. // // Example: successful match // pcrecpp::RE re("h.*o"); // re.FullMatch("hello"); // // Example: unsuccessful match (requires full match): // pcrecpp::RE re("e"); // !re.FullMatch("hello"); // // Example: creating a temporary RE object: // pcrecpp::RE("h.*o").FullMatch("hello"); // // You can pass in a "const char*" or a "string" for "text". The // examples below tend to use a const char*. // // You can, as in the different examples above, store the RE object // explicitly in a variable or use a temporary RE object. The // examples below use one mode or the other arbitrarily. Either // could correctly be used for any of these examples. // // ----------------------------------------------------------------------- // MATCHING WITH SUB-STRING EXTRACTION: // // You can supply extra pointer arguments to extract matched subpieces. // // Example: extracts "ruby" into "s" and 1234 into "i" // int i; // string s; // pcrecpp::RE re("(\\w+):(\\d+)"); // re.FullMatch("ruby:1234", &s, &i); // // Example: does not try to extract any extra sub-patterns // re.FullMatch("ruby:1234", &s); // // Example: does not try to extract into NULL // re.FullMatch("ruby:1234", NULL, &i); // // Example: integer overflow causes failure // !re.FullMatch("ruby:1234567891234", NULL, &i); // // Example: fails because there aren't enough sub-patterns: // !pcrecpp::RE("\\w+:\\d+").FullMatch("ruby:1234", &s); // // Example: fails because string cannot be stored in integer // !pcrecpp::RE("(.*)").FullMatch("ruby", &i); // // The provided pointer arguments can be pointers to any scalar numeric // type, or one of // string (matched piece is copied to string) // StringPiece (StringPiece is mutated to point to matched piece) // T (where "bool T::ParseFrom(const char*, int)" exists) // NULL (the corresponding matched sub-pattern is not copied) // // CAVEAT: An optional sub-pattern that does not exist in the matched // string is assigned the empty string. Therefore, the following will // return false (because the empty string is not a valid number): // int number; // pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number); // // ----------------------------------------------------------------------- // DO_MATCH // // The matching interface supports at most 16 arguments per call. // If you need more, consider using the more general interface // pcrecpp::RE::DoMatch(). See pcrecpp.h for the signature for DoMatch. // // ----------------------------------------------------------------------- // PARTIAL MATCHES // // You can use the "PartialMatch" operation when you want the pattern // to match any substring of the text. // // Example: simple search for a string: // pcrecpp::RE("ell").PartialMatch("hello"); // // Example: find first number in a string: // int number; // pcrecpp::RE re("(\\d+)"); // re.PartialMatch("x*100 + 20", &number); // assert(number == 100); // // ----------------------------------------------------------------------- // UTF-8 AND THE MATCHING INTERFACE: // // By default, pattern and text are plain text, one byte per character. // The UTF8 flag, passed to the constructor, causes both pattern // and string to be treated as UTF-8 text, still a byte stream but // potentially multiple bytes per character. In practice, the text // is likelier to be UTF-8 than the pattern, but the match returned // may depend on the UTF8 flag, so always use it when matching // UTF8 text. E.g., "." will match one byte normally but with UTF8 // set may match up to three bytes of a multi-byte character. // // Example: // pcrecpp::RE_Options options; // options.set_utf8(); // pcrecpp::RE re(utf8_pattern, options); // re.FullMatch(utf8_string); // // Example: using the convenience function UTF8(): // pcrecpp::RE re(utf8_pattern, pcrecpp::UTF8()); // re.FullMatch(utf8_string); // // NOTE: The UTF8 option is ignored if pcre was not configured with the // --enable-utf8 flag. // // ----------------------------------------------------------------------- // PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE // // PCRE defines some modifiers to change the behavior of the regular // expression engine. // The C++ wrapper defines an auxiliary class, RE_Options, as a vehicle // to pass such modifiers to a RE class. // // Currently, the following modifiers are supported // // modifier description Perl corresponding // // PCRE_CASELESS case insensitive match /i // PCRE_MULTILINE multiple lines match /m // PCRE_DOTALL dot matches newlines /s // PCRE_DOLLAR_ENDONLY $ matches only at end N/A // PCRE_EXTRA strict escape parsing N/A // PCRE_EXTENDED ignore whitespaces /x // PCRE_UTF8 handles UTF8 chars built-in // PCRE_UNGREEDY reverses * and *? N/A // PCRE_NO_AUTO_CAPTURE disables matching parens N/A (*) // // (For a full account on how each modifier works, please check the // PCRE API reference manual). // // (*) Both Perl and PCRE allow non matching parentheses by means of the // "?:" modifier within the pattern itself. e.g. (?:ab|cd) does not // capture, while (ab|cd) does. // // For each modifier, there are two member functions whose name is made // out of the modifier in lowercase, without the "PCRE_" prefix. For // instance, PCRE_CASELESS is handled by // bool caseless(), // which returns true if the modifier is set, and // RE_Options & set_caseless(bool), // which sets or unsets the modifier. // // Moreover, PCRE_EXTRA_MATCH_LIMIT can be accessed through the // set_match_limit() and match_limit() member functions. // Setting match_limit to a non-zero value will limit the executation of // pcre to keep it from doing bad things like blowing the stack or taking // an eternity to return a result. A value of 5000 is good enough to stop // stack blowup in a 2MB thread stack. Setting match_limit to zero will // disable match limiting. Alternately, you can set match_limit_recursion() // which uses PCRE_EXTRA_MATCH_LIMIT_RECURSION to limit how much pcre // recurses. match_limit() caps the number of matches pcre does; // match_limit_recrusion() caps the depth of recursion. // // Normally, to pass one or more modifiers to a RE class, you declare // a RE_Options object, set the appropriate options, and pass this // object to a RE constructor. Example: // // RE_options opt; // opt.set_caseless(true); // // if (RE("HELLO", opt).PartialMatch("hello world")) ... // // RE_options has two constructors. The default constructor takes no // arguments and creates a set of flags that are off by default. // // The optional parameter 'option_flags' is to facilitate transfer // of legacy code from C programs. This lets you do // RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); // // But new code is better off doing // RE(pattern, // RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str); // (See below) // // If you are going to pass one of the most used modifiers, there are some // convenience functions that return a RE_Options class with the // appropriate modifier already set: // CASELESS(), UTF8(), MULTILINE(), DOTALL(), EXTENDED() // // If you need to set several options at once, and you don't want to go // through the pains of declaring a RE_Options object and setting several // options, there is a parallel method that give you such ability on the // fly. You can concatenate several set_xxxxx member functions, since each // of them returns a reference to its class object. e.g.: to pass // PCRE_CASELESS, PCRE_EXTENDED, and PCRE_MULTILINE to a RE with one // statement, you may write // // RE(" ^ xyz \\s+ .* blah$", RE_Options() // .set_caseless(true) // .set_extended(true) // .set_multiline(true)).PartialMatch(sometext); // // ----------------------------------------------------------------------- // SCANNING TEXT INCREMENTALLY // // The "Consume" operation may be useful if you want to repeatedly // match regular expressions at the front of a string and skip over // them as they match. This requires use of the "StringPiece" type, // which represents a sub-range of a real string. Like RE, StringPiece // is defined in the pcrecpp namespace. // // Example: read lines of the form "var = value" from a string. // string contents = ...; // Fill string somehow // pcrecpp::StringPiece input(contents); // Wrap in a StringPiece // // string var; // int value; // pcrecpp::RE re("(\\w+) = (\\d+)\n"); // while (re.Consume(&input, &var, &value)) { // ...; // } // // Each successful call to "Consume" will set "var/value", and also // advance "input" so it points past the matched text. // // The "FindAndConsume" operation is similar to "Consume" but does not // anchor your match at the beginning of the string. For example, you // could extract all words from a string by repeatedly calling // pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word) // // ----------------------------------------------------------------------- // PARSING HEX/OCTAL/C-RADIX NUMBERS // // By default, if you pass a pointer to a numeric value, the // corresponding text is interpreted as a base-10 number. You can // instead wrap the pointer with a call to one of the operators Hex(), // Octal(), or CRadix() to interpret the text in another base. The // CRadix operator interprets C-style "0" (base-8) and "0x" (base-16) // prefixes, but defaults to base-10. // // Example: // int a, b, c, d; // pcrecpp::RE re("(.*) (.*) (.*) (.*)"); // re.FullMatch("100 40 0100 0x40", // pcrecpp::Octal(&a), pcrecpp::Hex(&b), // pcrecpp::CRadix(&c), pcrecpp::CRadix(&d)); // will leave 64 in a, b, c, and d. // // ----------------------------------------------------------------------- // REPLACING PARTS OF STRINGS // // You can replace the first match of "pattern" in "str" with // "rewrite". Within "rewrite", backslash-escaped digits (\1 to \9) // can be used to insert text matching corresponding parenthesized // group from the pattern. \0 in "rewrite" refers to the entire // matching text. E.g., // // string s = "yabba dabba doo"; // pcrecpp::RE("b+").Replace("d", &s); // // will leave "s" containing "yada dabba doo". The result is true if // the pattern matches and a replacement occurs, or false otherwise. // // GlobalReplace() is like Replace(), except that it replaces all // occurrences of the pattern in the string with the rewrite. // Replacements are not subject to re-matching. E.g., // // string s = "yabba dabba doo"; // pcrecpp::RE("b+").GlobalReplace("d", &s); // // will leave "s" containing "yada dada doo". It returns the number // of replacements made. // // Extract() is like Replace(), except that if the pattern matches, // "rewrite" is copied into "out" (an additional argument) with // substitutions. The non-matching portions of "text" are ignored. // Returns true iff a match occurred and the extraction happened // successfully. If no match occurs, the string is left unaffected. #include <string> #include <pcre.h> #include <pcrecpparg.h> // defines the Arg class // This isn't technically needed here, but we include it // anyway so folks who include pcrecpp.h don't have to. #include <pcre_stringpiece.h> namespace pcrecpp { #define PCRE_SET_OR_CLEAR(b, o) \ if (b) all_options_ |= (o); else all_options_ &= ~(o); \ return *this #define PCRE_IS_SET(o) \ (all_options_ & o) == o /***** Compiling regular expressions: the RE class *****/ // RE_Options allow you to set options to be passed along to pcre, // along with other options we put on top of pcre. // Only 9 modifiers, plus match_limit and match_limit_recursion, // are supported now. class PCRECPP_EXP_DEFN RE_Options { public: // constructor RE_Options() : match_limit_(0), match_limit_recursion_(0), all_options_(0) {} // alternative constructor. // To facilitate transfer of legacy code from C programs // // This lets you do // RE(pattern, RE_Options(PCRE_CASELESS|PCRE_MULTILINE)).PartialMatch(str); // But new code is better off doing // RE(pattern, // RE_Options().set_caseless(true).set_multiline(true)).PartialMatch(str); RE_Options(int option_flags) : match_limit_(0), match_limit_recursion_(0), all_options_(option_flags) {} // we're fine with the default destructor, copy constructor, etc. // accessors and mutators int match_limit() const { return match_limit_; }; RE_Options &set_match_limit(int limit) { match_limit_ = limit; return *this; } int match_limit_recursion() const { return match_limit_recursion_; }; RE_Options &set_match_limit_recursion(int limit) { match_limit_recursion_ = limit; return *this; } bool caseless() const { return PCRE_IS_SET(PCRE_CASELESS); } RE_Options &set_caseless(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_CASELESS); } bool multiline() const { return PCRE_IS_SET(PCRE_MULTILINE); } RE_Options &set_multiline(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_MULTILINE); } bool dotall() const { return PCRE_IS_SET(PCRE_DOTALL); } RE_Options &set_dotall(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_DOTALL); } bool extended() const { return PCRE_IS_SET(PCRE_EXTENDED); } RE_Options &set_extended(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_EXTENDED); } bool dollar_endonly() const { return PCRE_IS_SET(PCRE_DOLLAR_ENDONLY); } RE_Options &set_dollar_endonly(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_DOLLAR_ENDONLY); } bool extra() const { return PCRE_IS_SET(PCRE_EXTRA); } RE_Options &set_extra(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_EXTRA); } bool ungreedy() const { return PCRE_IS_SET(PCRE_UNGREEDY); } RE_Options &set_ungreedy(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_UNGREEDY); } bool utf8() const { return PCRE_IS_SET(PCRE_UTF8); } RE_Options &set_utf8(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_UTF8); } bool no_auto_capture() const { return PCRE_IS_SET(PCRE_NO_AUTO_CAPTURE); } RE_Options &set_no_auto_capture(bool x) { PCRE_SET_OR_CLEAR(x, PCRE_NO_AUTO_CAPTURE); } RE_Options &set_all_options(int opt) { all_options_ = opt; return *this; } int all_options() const { return all_options_ ; } // TODO: add other pcre flags private: int match_limit_; int match_limit_recursion_; int all_options_; }; // These functions return some common RE_Options static inline RE_Options UTF8() { return RE_Options().set_utf8(true); } static inline RE_Options CASELESS() { return RE_Options().set_caseless(true); } static inline RE_Options MULTILINE() { return RE_Options().set_multiline(true); } static inline RE_Options DOTALL() { return RE_Options().set_dotall(true); } static inline RE_Options EXTENDED() { return RE_Options().set_extended(true); } // Interface for regular expression matching. Also corresponds to a // pre-compiled regular expression. An "RE" object is safe for // concurrent use by multiple threads. class PCRECPP_EXP_DEFN RE { public: // We provide implicit conversions from strings so that users can // pass in a string or a "const char*" wherever an "RE" is expected. RE(const string& pat) { Init(pat, NULL); } RE(const string& pat, const RE_Options& option) { Init(pat, &option); } RE(const char* pat) { Init(pat, NULL); } RE(const char* pat, const RE_Options& option) { Init(pat, &option); } RE(const unsigned char* pat) { Init(reinterpret_cast<const char*>(pat), NULL); } RE(const unsigned char* pat, const RE_Options& option) { Init(reinterpret_cast<const char*>(pat), &option); } // Copy constructor & assignment - note that these are expensive // because they recompile the expression. RE(const RE& re) { Init(re.pattern_, &re.options_); } const RE& operator=(const RE& re) { if (this != &re) { Cleanup(); // This is the code that originally came from Google // Init(re.pattern_.c_str(), &re.options_); // This is the replacement from Ari Pollak Init(re.pattern_, &re.options_); } return *this; } ~RE(); // The string specification for this RE. E.g. // RE re("ab*c?d+"); // re.pattern(); // "ab*c?d+" const string& pattern() const { return pattern_; } // If RE could not be created properly, returns an error string. // Else returns the empty string. const string& error() const { return *error_; } /***** The useful part: the matching interface *****/ // This is provided so one can do pattern.ReplaceAll() just as // easily as ReplaceAll(pattern-text, ....) bool FullMatch(const StringPiece& text, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool PartialMatch(const StringPiece& text, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool Consume(StringPiece* input, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool FindAndConsume(StringPiece* input, const Arg& ptr1 = no_arg, const Arg& ptr2 = no_arg, const Arg& ptr3 = no_arg, const Arg& ptr4 = no_arg, const Arg& ptr5 = no_arg, const Arg& ptr6 = no_arg, const Arg& ptr7 = no_arg, const Arg& ptr8 = no_arg, const Arg& ptr9 = no_arg, const Arg& ptr10 = no_arg, const Arg& ptr11 = no_arg, const Arg& ptr12 = no_arg, const Arg& ptr13 = no_arg, const Arg& ptr14 = no_arg, const Arg& ptr15 = no_arg, const Arg& ptr16 = no_arg) const; bool Replace(const StringPiece& rewrite, string *str) const; int GlobalReplace(const StringPiece& rewrite, string *str) const; bool Extract(const StringPiece &rewrite, const StringPiece &text, string *out) const; // Escapes all potentially meaningful regexp characters in // 'unquoted'. The returned string, used as a regular expression, // will exactly match the original string. For example, // 1.5-2.0? // may become: // 1\.5\-2\.0\? // Note QuoteMeta behaves the same as perl's QuoteMeta function, // *except* that it escapes the NUL character (\0) as backslash + 0, // rather than backslash + NUL. static string QuoteMeta(const StringPiece& unquoted); /***** Generic matching interface *****/ // Type of match (TODO: Should be restructured as part of RE_Options) enum Anchor { UNANCHORED, // No anchoring ANCHOR_START, // Anchor at start only ANCHOR_BOTH // Anchor at start and end }; // General matching routine. Stores the length of the match in // "*consumed" if successful. bool DoMatch(const StringPiece& text, Anchor anchor, int* consumed, const Arg* const* args, int n) const; // Return the number of capturing subpatterns, or -1 if the // regexp wasn't valid on construction. int NumberOfCapturingGroups() const; // The default value for an argument, to indicate the end of the argument // list. This must be used only in optional argument defaults. It should NOT // be passed explicitly. Some people have tried to use it like this: // // FullMatch(x, y, &z, no_arg, &w); // // This is a mistake, and will not work. static Arg no_arg; private: void Init(const string& pattern, const RE_Options* options); void Cleanup(); // Match against "text", filling in "vec" (up to "vecsize" * 2/3) with // pairs of integers for the beginning and end positions of matched // text. The first pair corresponds to the entire matched text; // subsequent pairs correspond, in order, to parentheses-captured // matches. Returns the number of pairs (one more than the number of // the last subpattern with a match) if matching was successful // and zero if the match failed. // I.e. for RE("(foo)|(bar)|(baz)") it will return 2, 3, and 4 when matching // against "foo", "bar", and "baz" respectively. // When matching RE("(foo)|hello") against "hello", it will return 1. // But the values for all subpattern are filled in into "vec". int TryMatch(const StringPiece& text, int startpos, Anchor anchor, bool empty_ok, int *vec, int vecsize) const; // Append the "rewrite" string, with backslash subsitutions from "text" // and "vec", to string "out". bool Rewrite(string *out, const StringPiece& rewrite, const StringPiece& text, int *vec, int veclen) const; // internal implementation for DoMatch bool DoMatchImpl(const StringPiece& text, Anchor anchor, int* consumed, const Arg* const args[], int n, int* vec, int vecsize) const; // Compile the regexp for the specified anchoring mode pcre* Compile(Anchor anchor); string pattern_; RE_Options options_; pcre* re_full_; // For full matches pcre* re_partial_; // For partial matches const string* error_; // Error indicator (or points to empty string) }; } // namespace pcrecpp #endif /* _PCRECPP_H */ setjmp.h 0000644 00000007125 15146341150 0006224 0 ustar 00 /* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* * ISO C99 Standard: 7.13 Nonlocal jumps <setjmp.h> */ #ifndef _SETJMP_H #define _SETJMP_H 1 #include <features.h> __BEGIN_DECLS #include <bits/setjmp.h> /* Get `__jmp_buf'. */ #include <bits/types/__sigset_t.h> /* Calling environment, plus possibly a saved signal mask. */ struct __jmp_buf_tag { /* NOTE: The machine-dependent definitions of `__sigsetjmp' assume that a `jmp_buf' begins with a `__jmp_buf' and that `__mask_was_saved' follows it. Do not move these members or add others before it. */ __jmp_buf __jmpbuf; /* Calling environment. */ int __mask_was_saved; /* Saved the signal mask? */ __sigset_t __saved_mask; /* Saved signal mask. */ }; typedef struct __jmp_buf_tag jmp_buf[1]; /* Store the calling environment in ENV, also saving the signal mask. Return 0. */ extern int setjmp (jmp_buf __env) __THROWNL; /* Store the calling environment in ENV, also saving the signal mask if SAVEMASK is nonzero. Return 0. This is the internal name for `sigsetjmp'. */ extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) __THROWNL; /* Store the calling environment in ENV, not saving the signal mask. Return 0. */ extern int _setjmp (struct __jmp_buf_tag __env[1]) __THROWNL; /* Do not save the signal mask. This is equivalent to the `_setjmp' BSD function. */ #define setjmp(env) _setjmp (env) /* Jump to the environment saved in ENV, making the `setjmp' call there return VAL, or 1 if VAL is 0. */ extern void longjmp (struct __jmp_buf_tag __env[1], int __val) __THROWNL __attribute__ ((__noreturn__)); #if defined __USE_MISC || defined __USE_XOPEN /* Same. Usually `_longjmp' is used with `_setjmp', which does not save the signal mask. But it is how ENV was saved that determines whether `longjmp' restores the mask; `_longjmp' is just an alias. */ extern void _longjmp (struct __jmp_buf_tag __env[1], int __val) __THROWNL __attribute__ ((__noreturn__)); #endif #ifdef __USE_POSIX /* Use the same type for `jmp_buf' and `sigjmp_buf'. The `__mask_was_saved' flag determines whether or not `longjmp' will restore the signal mask. */ typedef struct __jmp_buf_tag sigjmp_buf[1]; /* Store the calling environment in ENV, also saving the signal mask if SAVEMASK is nonzero. Return 0. */ # define sigsetjmp(env, savemask) __sigsetjmp (env, savemask) /* Jump to the environment saved in ENV, making the sigsetjmp call there return VAL, or 1 if VAL is 0. Restore the signal mask if that sigsetjmp call saved it. This is just an alias `longjmp'. */ extern void siglongjmp (sigjmp_buf __env, int __val) __THROWNL __attribute__ ((__noreturn__)); #endif /* Use POSIX. */ /* Define helper functions to catch unsafe code. */ #if __USE_FORTIFY_LEVEL > 0 # include <bits/setjmp2.h> #endif __END_DECLS #endif /* setjmp.h */ syslog.h 0000644 00000000030 15146341150 0006226 0 ustar 00 #include <sys/syslog.h> stdio.h 0000644 00000072730 15146341150 0006050 0 ustar 00 /* Define ISO C stdio on top of C++ iostreams. Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* * ISO C99 Standard: 7.19 Input/output <stdio.h> */ #ifndef _STDIO_H #define _STDIO_H 1 #define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION #include <bits/libc-header-start.h> __BEGIN_DECLS #define __need_size_t #define __need_NULL #include <stddef.h> #define __need___va_list #include <stdarg.h> #include <bits/types.h> #include <bits/types/__fpos_t.h> #include <bits/types/__fpos64_t.h> #include <bits/types/__FILE.h> #include <bits/types/FILE.h> #include <bits/types/struct_FILE.h> #ifdef __USE_GNU # include <bits/types/cookie_io_functions_t.h> #endif #if defined __USE_XOPEN || defined __USE_XOPEN2K8 # ifdef __GNUC__ # ifndef _VA_LIST_DEFINED typedef __gnuc_va_list va_list; # define _VA_LIST_DEFINED # endif # else # include <stdarg.h> # endif #endif #if defined __USE_UNIX98 || defined __USE_XOPEN2K # ifndef __off_t_defined # ifndef __USE_FILE_OFFSET64 typedef __off_t off_t; # else typedef __off64_t off_t; # endif # define __off_t_defined # endif # if defined __USE_LARGEFILE64 && !defined __off64_t_defined typedef __off64_t off64_t; # define __off64_t_defined # endif #endif #ifdef __USE_XOPEN2K8 # ifndef __ssize_t_defined typedef __ssize_t ssize_t; # define __ssize_t_defined # endif #endif /* The type of the second argument to `fgetpos' and `fsetpos'. */ #ifndef __USE_FILE_OFFSET64 typedef __fpos_t fpos_t; #else typedef __fpos64_t fpos_t; #endif #ifdef __USE_LARGEFILE64 typedef __fpos64_t fpos64_t; #endif /* The possibilities for the third argument to `setvbuf'. */ #define _IOFBF 0 /* Fully buffered. */ #define _IOLBF 1 /* Line buffered. */ #define _IONBF 2 /* No buffering. */ /* Default buffer size. */ #define BUFSIZ 8192 /* The value returned by fgetc and similar functions to indicate the end of the file. */ #define EOF (-1) /* The possibilities for the third argument to `fseek'. These values should not be changed. */ #define SEEK_SET 0 /* Seek from beginning of file. */ #define SEEK_CUR 1 /* Seek from current position. */ #define SEEK_END 2 /* Seek from end of file. */ #ifdef __USE_GNU # define SEEK_DATA 3 /* Seek to next data. */ # define SEEK_HOLE 4 /* Seek to next hole. */ #endif #if defined __USE_MISC || defined __USE_XOPEN /* Default path prefix for `tempnam' and `tmpnam'. */ # define P_tmpdir "/tmp" #endif /* Get the values: L_tmpnam How long an array of chars must be to be passed to `tmpnam'. TMP_MAX The minimum number of unique filenames generated by tmpnam (and tempnam when it uses tmpnam's name space), or tempnam (the two are separate). L_ctermid How long an array to pass to `ctermid'. L_cuserid How long an array to pass to `cuserid'. FOPEN_MAX Minimum number of files that can be open at once. FILENAME_MAX Maximum length of a filename. */ #include <bits/stdio_lim.h> /* Standard streams. */ extern FILE *stdin; /* Standard input stream. */ extern FILE *stdout; /* Standard output stream. */ extern FILE *stderr; /* Standard error output stream. */ /* C89/C99 say they're macros. Make them happy. */ #define stdin stdin #define stdout stdout #define stderr stderr /* Remove file FILENAME. */ extern int remove (const char *__filename) __THROW; /* Rename file OLD to NEW. */ extern int rename (const char *__old, const char *__new) __THROW; #ifdef __USE_ATFILE /* Rename file OLD relative to OLDFD to NEW relative to NEWFD. */ extern int renameat (int __oldfd, const char *__old, int __newfd, const char *__new) __THROW; #endif #ifdef __USE_GNU /* Flags for renameat2. */ # define RENAME_NOREPLACE (1 << 0) # define RENAME_EXCHANGE (1 << 1) # define RENAME_WHITEOUT (1 << 2) /* Rename file OLD relative to OLDFD to NEW relative to NEWFD, with additional flags. */ extern int renameat2 (int __oldfd, const char *__old, int __newfd, const char *__new, unsigned int __flags) __THROW; #endif /* Create a temporary file and open it read/write. This function is a possible cancellation point and therefore not marked with __THROW. */ #ifndef __USE_FILE_OFFSET64 extern FILE *tmpfile (void) __wur; #else # ifdef __REDIRECT extern FILE *__REDIRECT (tmpfile, (void), tmpfile64) __wur; # else # define tmpfile tmpfile64 # endif #endif #ifdef __USE_LARGEFILE64 extern FILE *tmpfile64 (void) __wur; #endif /* Generate a temporary filename. */ extern char *tmpnam (char *__s) __THROW __wur; #ifdef __USE_MISC /* This is the reentrant variant of `tmpnam'. The only difference is that it does not allow S to be NULL. */ extern char *tmpnam_r (char *__s) __THROW __wur; #endif #if defined __USE_MISC || defined __USE_XOPEN /* Generate a unique temporary filename using up to five characters of PFX if it is not NULL. The directory to put this file in is searched for as follows: First the environment variable "TMPDIR" is checked. If it contains the name of a writable directory, that directory is used. If not and if DIR is not NULL, that value is checked. If that fails, P_tmpdir is tried and finally "/tmp". The storage for the filename is allocated by `malloc'. */ extern char *tempnam (const char *__dir, const char *__pfx) __THROW __attribute_malloc__ __wur; #endif /* Close STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fclose (FILE *__stream); /* Flush STREAM, or all streams if STREAM is NULL. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fflush (FILE *__stream); #ifdef __USE_MISC /* Faster versions when locking is not required. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int fflush_unlocked (FILE *__stream); #endif #ifdef __USE_GNU /* Close all streams. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int fcloseall (void); #endif #ifndef __USE_FILE_OFFSET64 /* Open a file and create a new stream for it. This function is a possible cancellation point and therefore not marked with __THROW. */ extern FILE *fopen (const char *__restrict __filename, const char *__restrict __modes) __wur; /* Open a file, replacing an existing stream with it. This function is a possible cancellation point and therefore not marked with __THROW. */ extern FILE *freopen (const char *__restrict __filename, const char *__restrict __modes, FILE *__restrict __stream) __wur; #else # ifdef __REDIRECT extern FILE *__REDIRECT (fopen, (const char *__restrict __filename, const char *__restrict __modes), fopen64) __wur; extern FILE *__REDIRECT (freopen, (const char *__restrict __filename, const char *__restrict __modes, FILE *__restrict __stream), freopen64) __wur; # else # define fopen fopen64 # define freopen freopen64 # endif #endif #ifdef __USE_LARGEFILE64 extern FILE *fopen64 (const char *__restrict __filename, const char *__restrict __modes) __wur; extern FILE *freopen64 (const char *__restrict __filename, const char *__restrict __modes, FILE *__restrict __stream) __wur; #endif #ifdef __USE_POSIX /* Create a new stream that refers to an existing system file descriptor. */ extern FILE *fdopen (int __fd, const char *__modes) __THROW __wur; #endif #ifdef __USE_GNU /* Create a new stream that refers to the given magic cookie, and uses the given functions for input and output. */ extern FILE *fopencookie (void *__restrict __magic_cookie, const char *__restrict __modes, cookie_io_functions_t __io_funcs) __THROW __wur; #endif #if defined __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2) /* Create a new stream that refers to a memory buffer. */ extern FILE *fmemopen (void *__s, size_t __len, const char *__modes) __THROW __wur; /* Open a stream that writes into a malloc'd buffer that is expanded as necessary. *BUFLOC and *SIZELOC are updated with the buffer's location and the number of characters written on fflush or fclose. */ extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __THROW __wur; #endif /* If BUF is NULL, make STREAM unbuffered. Else make it use buffer BUF, of size BUFSIZ. */ extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __THROW; /* Make STREAM use buffering mode MODE. If BUF is not NULL, use N bytes of it for buffering; else allocate an internal buffer N bytes long. */ extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, int __modes, size_t __n) __THROW; #ifdef __USE_MISC /* If BUF is NULL, make STREAM unbuffered. Else make it use SIZE bytes of BUF for buffering. */ extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf, size_t __size) __THROW; /* Make STREAM line-buffered. */ extern void setlinebuf (FILE *__stream) __THROW; #endif /* Write formatted output to STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fprintf (FILE *__restrict __stream, const char *__restrict __format, ...); /* Write formatted output to stdout. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int printf (const char *__restrict __format, ...); /* Write formatted output to S. */ extern int sprintf (char *__restrict __s, const char *__restrict __format, ...) __THROWNL; /* Write formatted output to S from argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int vfprintf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg); /* Write formatted output to stdout from argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg); /* Write formatted output to S from argument list ARG. */ extern int vsprintf (char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __THROWNL; #if defined __USE_ISOC99 || defined __USE_UNIX98 /* Maximum chars of output to write in MAXLEN. */ extern int snprintf (char *__restrict __s, size_t __maxlen, const char *__restrict __format, ...) __THROWNL __attribute__ ((__format__ (__printf__, 3, 4))); extern int vsnprintf (char *__restrict __s, size_t __maxlen, const char *__restrict __format, __gnuc_va_list __arg) __THROWNL __attribute__ ((__format__ (__printf__, 3, 0))); #endif #if __GLIBC_USE (LIB_EXT2) /* Write formatted output to a string dynamically allocated with `malloc'. Store the address of the string in *PTR. */ extern int vasprintf (char **__restrict __ptr, const char *__restrict __f, __gnuc_va_list __arg) __THROWNL __attribute__ ((__format__ (__printf__, 2, 0))) __wur; extern int __asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...) __THROWNL __attribute__ ((__format__ (__printf__, 2, 3))) __wur; extern int asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...) __THROWNL __attribute__ ((__format__ (__printf__, 2, 3))) __wur; #endif #ifdef __USE_XOPEN2K8 /* Write formatted output to a file descriptor. */ extern int vdprintf (int __fd, const char *__restrict __fmt, __gnuc_va_list __arg) __attribute__ ((__format__ (__printf__, 2, 0))); extern int dprintf (int __fd, const char *__restrict __fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); #endif /* Read formatted input from STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __wur; /* Read formatted input from stdin. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int scanf (const char *__restrict __format, ...) __wur; /* Read formatted input from S. */ extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __THROW; #if defined __USE_ISOC99 && !defined __USE_GNU \ && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) # ifdef __REDIRECT /* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ GNU extension which conflicts with valid %a followed by letter s, S or [. */ extern int __REDIRECT (fscanf, (FILE *__restrict __stream, const char *__restrict __format, ...), __isoc99_fscanf) __wur; extern int __REDIRECT (scanf, (const char *__restrict __format, ...), __isoc99_scanf) __wur; extern int __REDIRECT_NTH (sscanf, (const char *__restrict __s, const char *__restrict __format, ...), __isoc99_sscanf); # else extern int __isoc99_fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __wur; extern int __isoc99_scanf (const char *__restrict __format, ...) __wur; extern int __isoc99_sscanf (const char *__restrict __s, const char *__restrict __format, ...) __THROW; # define fscanf __isoc99_fscanf # define scanf __isoc99_scanf # define sscanf __isoc99_sscanf # endif #endif #ifdef __USE_ISOC99 /* Read formatted input from S into argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __attribute__ ((__format__ (__scanf__, 2, 0))) __wur; /* Read formatted input from stdin into argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __attribute__ ((__format__ (__scanf__, 1, 0))) __wur; /* Read formatted input from S into argument list ARG. */ extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __THROW __attribute__ ((__format__ (__scanf__, 2, 0))); # if !defined __USE_GNU \ && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) # ifdef __REDIRECT /* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ GNU extension which conflicts with valid %a followed by letter s, S or [. */ extern int __REDIRECT (vfscanf, (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg), __isoc99_vfscanf) __attribute__ ((__format__ (__scanf__, 2, 0))) __wur; extern int __REDIRECT (vscanf, (const char *__restrict __format, __gnuc_va_list __arg), __isoc99_vscanf) __attribute__ ((__format__ (__scanf__, 1, 0))) __wur; extern int __REDIRECT_NTH (vsscanf, (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg), __isoc99_vsscanf) __attribute__ ((__format__ (__scanf__, 2, 0))); # else extern int __isoc99_vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __wur; extern int __isoc99_vscanf (const char *__restrict __format, __gnuc_va_list __arg) __wur; extern int __isoc99_vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __THROW; # define vfscanf __isoc99_vfscanf # define vscanf __isoc99_vscanf # define vsscanf __isoc99_vsscanf # endif # endif #endif /* Use ISO C9x. */ /* Read a character from STREAM. These functions are possible cancellation points and therefore not marked with __THROW. */ extern int fgetc (FILE *__stream); extern int getc (FILE *__stream); /* Read a character from stdin. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int getchar (void); #ifdef __USE_POSIX199506 /* These are defined in POSIX.1:1996. These functions are possible cancellation points and therefore not marked with __THROW. */ extern int getc_unlocked (FILE *__stream); extern int getchar_unlocked (void); #endif /* Use POSIX. */ #ifdef __USE_MISC /* Faster version when locking is not necessary. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int fgetc_unlocked (FILE *__stream); #endif /* Use MISC. */ /* Write a character to STREAM. These functions are possible cancellation points and therefore not marked with __THROW. These functions is a possible cancellation point and therefore not marked with __THROW. */ extern int fputc (int __c, FILE *__stream); extern int putc (int __c, FILE *__stream); /* Write a character to stdout. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int putchar (int __c); #ifdef __USE_MISC /* Faster version when locking is not necessary. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int fputc_unlocked (int __c, FILE *__stream); #endif /* Use MISC. */ #ifdef __USE_POSIX199506 /* These are defined in POSIX.1:1996. These functions are possible cancellation points and therefore not marked with __THROW. */ extern int putc_unlocked (int __c, FILE *__stream); extern int putchar_unlocked (int __c); #endif /* Use POSIX. */ #if defined __USE_MISC \ || (defined __USE_XOPEN && !defined __USE_XOPEN2K) /* Get a word (int) from STREAM. */ extern int getw (FILE *__stream); /* Write a word (int) to STREAM. */ extern int putw (int __w, FILE *__stream); #endif /* Get a newline-terminated string of finite length from STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) __wur; #if __GLIBC_USE (DEPRECATED_GETS) /* Get a newline-terminated string from stdin, removing the newline. This function is impossible to use safely. It has been officially removed from ISO C11 and ISO C++14, and we have also removed it from the _GNU_SOURCE feature list. It remains available when explicitly using an old ISO C, Unix, or POSIX standard. This function is a possible cancellation point and therefore not marked with __THROW. */ extern char *gets (char *__s) __wur __attribute_deprecated__; #endif #ifdef __USE_GNU /* This function does the same as `fgets' but does not lock the stream. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern char *fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) __wur; #endif #if defined __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2) /* Read up to (and including) a DELIMITER from STREAM into *LINEPTR (and null-terminate it). *LINEPTR is a pointer returned from malloc (or NULL), pointing to *N characters of space. It is realloc'd as necessary. Returns the number of characters read (not including the null terminator), or -1 on error or EOF. These functions are not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation they are cancellation points and therefore not marked with __THROW. */ extern __ssize_t __getdelim (char **__restrict __lineptr, size_t *__restrict __n, int __delimiter, FILE *__restrict __stream) __wur; extern __ssize_t getdelim (char **__restrict __lineptr, size_t *__restrict __n, int __delimiter, FILE *__restrict __stream) __wur; /* Like `getdelim', but reads up to a newline. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern __ssize_t getline (char **__restrict __lineptr, size_t *__restrict __n, FILE *__restrict __stream) __wur; #endif /* Write a string to STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fputs (const char *__restrict __s, FILE *__restrict __stream); /* Write a string, followed by a newline, to stdout. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int puts (const char *__s); /* Push a character back onto the input buffer of STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int ungetc (int __c, FILE *__stream); /* Read chunks of generic data from STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern size_t fread (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) __wur; /* Write chunks of generic data to STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern size_t fwrite (const void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __s); #ifdef __USE_GNU /* This function does the same as `fputs' but does not lock the stream. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int fputs_unlocked (const char *__restrict __s, FILE *__restrict __stream); #endif #ifdef __USE_MISC /* Faster versions when locking is not necessary. These functions are not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation they are cancellation points and therefore not marked with __THROW. */ extern size_t fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) __wur; extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream); #endif /* Seek to a certain position on STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fseek (FILE *__stream, long int __off, int __whence); /* Return the current position of STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern long int ftell (FILE *__stream) __wur; /* Rewind to the beginning of STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void rewind (FILE *__stream); /* The Single Unix Specification, Version 2, specifies an alternative, more adequate interface for the two functions above which deal with file offset. `long int' is not the right type. These definitions are originally defined in the Large File Support API. */ #if defined __USE_LARGEFILE || defined __USE_XOPEN2K # ifndef __USE_FILE_OFFSET64 /* Seek to a certain position on STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fseeko (FILE *__stream, __off_t __off, int __whence); /* Return the current position of STREAM. This function is a possible cancellation point and therefore not marked with __THROW. */ extern __off_t ftello (FILE *__stream) __wur; # else # ifdef __REDIRECT extern int __REDIRECT (fseeko, (FILE *__stream, __off64_t __off, int __whence), fseeko64); extern __off64_t __REDIRECT (ftello, (FILE *__stream), ftello64); # else # define fseeko fseeko64 # define ftello ftello64 # endif # endif #endif #ifndef __USE_FILE_OFFSET64 /* Get STREAM's position. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos); /* Set STREAM's position. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fsetpos (FILE *__stream, const fpos_t *__pos); #else # ifdef __REDIRECT extern int __REDIRECT (fgetpos, (FILE *__restrict __stream, fpos_t *__restrict __pos), fgetpos64); extern int __REDIRECT (fsetpos, (FILE *__stream, const fpos_t *__pos), fsetpos64); # else # define fgetpos fgetpos64 # define fsetpos fsetpos64 # endif #endif #ifdef __USE_LARGEFILE64 extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence); extern __off64_t ftello64 (FILE *__stream) __wur; extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos); extern int fsetpos64 (FILE *__stream, const fpos64_t *__pos); #endif /* Clear the error and EOF indicators for STREAM. */ extern void clearerr (FILE *__stream) __THROW; /* Return the EOF indicator for STREAM. */ extern int feof (FILE *__stream) __THROW __wur; /* Return the error indicator for STREAM. */ extern int ferror (FILE *__stream) __THROW __wur; #ifdef __USE_MISC /* Faster versions when locking is not required. */ extern void clearerr_unlocked (FILE *__stream) __THROW; extern int feof_unlocked (FILE *__stream) __THROW __wur; extern int ferror_unlocked (FILE *__stream) __THROW __wur; #endif /* Print a message describing the meaning of the value of errno. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void perror (const char *__s); /* Provide the declarations for `sys_errlist' and `sys_nerr' if they are available on this system. Even if available, these variables should not be used directly. The `strerror' function provides all the necessary functionality. */ #include <bits/sys_errlist.h> #ifdef __USE_POSIX /* Return the system file descriptor for STREAM. */ extern int fileno (FILE *__stream) __THROW __wur; #endif /* Use POSIX. */ #ifdef __USE_MISC /* Faster version when locking is not required. */ extern int fileno_unlocked (FILE *__stream) __THROW __wur; #endif #ifdef __USE_POSIX2 /* Create a new stream connected to a pipe running the given command. This function is a possible cancellation point and therefore not marked with __THROW. */ extern FILE *popen (const char *__command, const char *__modes) __wur; /* Close a stream opened by popen and return the status of its child. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int pclose (FILE *__stream); #endif #ifdef __USE_POSIX /* Return the name of the controlling terminal. */ extern char *ctermid (char *__s) __THROW; #endif /* Use POSIX. */ #if (defined __USE_XOPEN && !defined __USE_XOPEN2K) || defined __USE_GNU /* Return the name of the current user. */ extern char *cuserid (char *__s); #endif /* Use X/Open, but not issue 6. */ #ifdef __USE_GNU struct obstack; /* See <obstack.h>. */ /* Write formatted output to an obstack. */ extern int obstack_printf (struct obstack *__restrict __obstack, const char *__restrict __format, ...) __THROWNL __attribute__ ((__format__ (__printf__, 2, 3))); extern int obstack_vprintf (struct obstack *__restrict __obstack, const char *__restrict __format, __gnuc_va_list __args) __THROWNL __attribute__ ((__format__ (__printf__, 2, 0))); #endif /* Use GNU. */ #ifdef __USE_POSIX199506 /* These are defined in POSIX.1:1996. */ /* Acquire ownership of STREAM. */ extern void flockfile (FILE *__stream) __THROW; /* Try to acquire ownership of STREAM but do not block if it is not possible. */ extern int ftrylockfile (FILE *__stream) __THROW __wur; /* Relinquish the ownership granted for STREAM. */ extern void funlockfile (FILE *__stream) __THROW; #endif /* POSIX */ #if defined __USE_XOPEN && !defined __USE_XOPEN2K && !defined __USE_GNU /* X/Open Issues 1-5 required getopt to be declared in this header. It was removed in Issue 6. GNU follows Issue 6. */ # include <bits/getopt_posix.h> #endif /* Slow-path routines used by the optimized inline functions in bits/stdio.h. */ extern int __uflow (FILE *); extern int __overflow (FILE *, int); /* If we are compiling with optimizing read this file. It contains several optimizing inline functions and macros. */ #ifdef __USE_EXTERN_INLINES # include <bits/stdio.h> #endif #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function # include <bits/stdio2.h> #endif #ifdef __LDBL_COMPAT # include <bits/stdio-ldbl.h> #endif __END_DECLS #endif /* <stdio.h> included. */ magic.h 0000644 00000012724 15146341150 0006003 0 ustar 00 /* * Copyright (c) Christos Zoulas 2003. * 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 immediately at the beginning of the file, without modification, * 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. */ #ifndef _MAGIC_H #define _MAGIC_H #include <sys/types.h> #define MAGIC_NONE 0x0000000 /* No flags */ #define MAGIC_DEBUG 0x0000001 /* Turn on debugging */ #define MAGIC_SYMLINK 0x0000002 /* Follow symlinks */ #define MAGIC_COMPRESS 0x0000004 /* Check inside compressed files */ #define MAGIC_DEVICES 0x0000008 /* Look at the contents of devices */ #define MAGIC_MIME_TYPE 0x0000010 /* Return the MIME type */ #define MAGIC_CONTINUE 0x0000020 /* Return all matches */ #define MAGIC_CHECK 0x0000040 /* Print warnings to stderr */ #define MAGIC_PRESERVE_ATIME 0x0000080 /* Restore access time on exit */ #define MAGIC_RAW 0x0000100 /* Don't convert unprintable chars */ #define MAGIC_ERROR 0x0000200 /* Handle ENOENT etc as real errors */ #define MAGIC_MIME_ENCODING 0x0000400 /* Return the MIME encoding */ #define MAGIC_MIME (MAGIC_MIME_TYPE|MAGIC_MIME_ENCODING) #define MAGIC_APPLE 0x0000800 /* Return the Apple creator/type */ #define MAGIC_EXTENSION 0x1000000 /* Return a /-separated list of * extensions */ #define MAGIC_COMPRESS_TRANSP 0x2000000 /* Check inside compressed files * but not report compression */ #define MAGIC_NODESC (MAGIC_EXTENSION|MAGIC_MIME|MAGIC_APPLE) #define MAGIC_NO_CHECK_COMPRESS 0x0001000 /* Don't check for compressed files */ #define MAGIC_NO_CHECK_TAR 0x0002000 /* Don't check for tar files */ #define MAGIC_NO_CHECK_SOFT 0x0004000 /* Don't check magic entries */ #define MAGIC_NO_CHECK_APPTYPE 0x0008000 /* Don't check application type */ #define MAGIC_NO_CHECK_ELF 0x0010000 /* Don't check for elf details */ #define MAGIC_NO_CHECK_TEXT 0x0020000 /* Don't check for text files */ #define MAGIC_NO_CHECK_CDF 0x0040000 /* Don't check for cdf files */ #define MAGIC_NO_CHECK_TOKENS 0x0100000 /* Don't check tokens */ #define MAGIC_NO_CHECK_ENCODING 0x0200000 /* Don't check text encodings */ /* No built-in tests; only consult the magic file */ #define MAGIC_NO_CHECK_BUILTIN ( \ MAGIC_NO_CHECK_COMPRESS | \ MAGIC_NO_CHECK_TAR | \ /* MAGIC_NO_CHECK_SOFT | */ \ MAGIC_NO_CHECK_APPTYPE | \ MAGIC_NO_CHECK_ELF | \ MAGIC_NO_CHECK_TEXT | \ MAGIC_NO_CHECK_CDF | \ MAGIC_NO_CHECK_TOKENS | \ MAGIC_NO_CHECK_ENCODING | \ 0 \ ) #define MAGIC_SNPRINTB "\177\020\ b\0debug\0\ b\1symlink\0\ b\2compress\0\ b\3devices\0\ b\4mime_type\0\ b\5continue\0\ b\6check\0\ b\7preserve_atime\0\ b\10raw\0\ b\11error\0\ b\12mime_encoding\0\ b\13apple\0\ b\14no_check_compress\0\ b\15no_check_tar\0\ b\16no_check_soft\0\ b\17no_check_sapptype\0\ b\20no_check_elf\0\ b\21no_check_text\0\ b\22no_check_cdf\0\ b\23no_check_reserved0\0\ b\24no_check_tokens\0\ b\25no_check_encoding\0\ b\26no_check_reserved1\0\ b\27no_check_reserved2\0\ b\30extension\0\ b\31transp_compression\0\ " /* Defined for backwards compatibility (renamed) */ #define MAGIC_NO_CHECK_ASCII MAGIC_NO_CHECK_TEXT /* Defined for backwards compatibility; do nothing */ #define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */ #define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */ #define MAGIC_VERSION 533 /* This implementation */ #ifdef __cplusplus extern "C" { #endif typedef struct magic_set *magic_t; magic_t magic_open(int); void magic_close(magic_t); const char *magic_getpath(const char *, int); const char *magic_file(magic_t, const char *); const char *magic_descriptor(magic_t, int); const char *magic_buffer(magic_t, const void *, size_t); const char *magic_error(magic_t); int magic_getflags(magic_t); int magic_setflags(magic_t, int); int magic_version(void); int magic_load(magic_t, const char *); int magic_load_buffers(magic_t, void **, size_t *, size_t); int magic_compile(magic_t, const char *); int magic_check(magic_t, const char *); int magic_list(magic_t, const char *); int magic_errno(magic_t); #define MAGIC_PARAM_INDIR_MAX 0 #define MAGIC_PARAM_NAME_MAX 1 #define MAGIC_PARAM_ELF_PHNUM_MAX 2 #define MAGIC_PARAM_ELF_SHNUM_MAX 3 #define MAGIC_PARAM_ELF_NOTES_MAX 4 #define MAGIC_PARAM_REGEX_MAX 5 #define MAGIC_PARAM_BYTES_MAX 6 int magic_setparam(magic_t, int, const void *); int magic_getparam(magic_t, int, void *); #ifdef __cplusplus }; #endif #endif /* _MAGIC_H */ ncurses_dll.h 0000644 00000010265 15146341150 0007236 0 ustar 00 /**************************************************************************** * Copyright (c) 1998-2009,2014 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, distribute with modifications, sublicense, and/or sell * * copies of the Software, and to permit persons to whom the Software is * * furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included * * in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * * * Except as contained in this notice, the name(s) of the above copyright * * holders shall not be used in advertising or otherwise to promote the * * sale, use or other dealings in this Software without prior written * * authorization. * ****************************************************************************/ /* $Id: ncurses_dll.h.in,v 1.9 2014/08/02 21:30:20 tom Exp $ */ #ifndef NCURSES_DLL_H_incl #define NCURSES_DLL_H_incl 1 /* 2014-08-02 workaround for broken MinGW compiler. * Oddly, only TRACE is mapped to trace - the other -D's are okay. * suggest TDM as an alternative. */ #if defined(__MINGW64__) #elif defined(__MINGW32__) #if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) #ifdef trace #undef trace #define TRACE #endif #endif /* broken compiler */ #endif /* MingW */ /* * For reentrant code, we map the various global variables into SCREEN by * using functions to access them. */ #define NCURSES_PUBLIC_VAR(name) _nc_##name #define NCURSES_WRAPPED_VAR(type,name) extern type NCURSES_PUBLIC_VAR(name)(void) /* no longer needed on cygwin or mingw, thanks to auto-import */ /* but this structure may be useful at some point for an MSVC build */ /* so, for now unconditionally define the important flags */ /* "the right way" for proper static and dll+auto-import behavior */ #undef NCURSES_DLL #define NCURSES_STATIC #if defined(__CYGWIN__) || defined(__MINGW32__) # if defined(NCURSES_DLL) # if defined(NCURSES_STATIC) # undef NCURSES_STATIC # endif # endif # undef NCURSES_IMPEXP # undef NCURSES_API # undef NCURSES_EXPORT # undef NCURSES_EXPORT_VAR # if defined(NCURSES_DLL) /* building a DLL */ # define NCURSES_IMPEXP __declspec(dllexport) # elif defined(NCURSES_STATIC) /* building or linking to a static library */ # define NCURSES_IMPEXP /* nothing */ # else /* linking to the DLL */ # define NCURSES_IMPEXP __declspec(dllimport) # endif # define NCURSES_API __cdecl # define NCURSES_EXPORT(type) NCURSES_IMPEXP type NCURSES_API # define NCURSES_EXPORT_VAR(type) NCURSES_IMPEXP type #endif /* Take care of non-cygwin platforms */ #if !defined(NCURSES_IMPEXP) # define NCURSES_IMPEXP /* nothing */ #endif #if !defined(NCURSES_API) # define NCURSES_API /* nothing */ #endif #if !defined(NCURSES_EXPORT) # define NCURSES_EXPORT(type) NCURSES_IMPEXP type NCURSES_API #endif #if !defined(NCURSES_EXPORT_VAR) # define NCURSES_EXPORT_VAR(type) NCURSES_IMPEXP type #endif #endif /* NCURSES_DLL_H_incl */ scsi/cxlflash_ioctl.h 0000644 00000023670 15146341150 0010664 0 ustar 00 /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * CXL Flash Device Driver * * Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation * Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation * * Copyright (C) 2015 IBM Corporation * * This program 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 * 2 of the License, or (at your option) any later version. */ #ifndef _CXLFLASH_IOCTL_H #define _CXLFLASH_IOCTL_H #include <linux/types.h> /* * Structure and definitions for all CXL Flash ioctls */ #define CXLFLASH_WWID_LEN 16 /* * Structure and flag definitions CXL Flash superpipe ioctls */ #define DK_CXLFLASH_VERSION_0 0 struct dk_cxlflash_hdr { __u16 version; /* Version data */ __u16 rsvd[3]; /* Reserved for future use */ __u64 flags; /* Input flags */ __u64 return_flags; /* Returned flags */ }; /* * Return flag definitions available to all superpipe ioctls * * Similar to the input flags, these are grown from the bottom-up with the * intention that ioctl-specific return flag definitions would grow from the * top-down, allowing the two sets to co-exist. While not required/enforced * at this time, this provides future flexibility. */ #define DK_CXLFLASH_ALL_PORTS_ACTIVE 0x0000000000000001ULL #define DK_CXLFLASH_APP_CLOSE_ADAP_FD 0x0000000000000002ULL #define DK_CXLFLASH_CONTEXT_SQ_CMD_MODE 0x0000000000000004ULL /* * General Notes: * ------------- * The 'context_id' field of all ioctl structures contains the context * identifier for a context in the lower 32-bits (upper 32-bits are not * to be used when identifying a context to the AFU). That said, the value * in its entirety (all 64-bits) is to be treated as an opaque cookie and * should be presented as such when issuing ioctls. */ /* * DK_CXLFLASH_ATTACH Notes: * ------------------------ * Read/write access permissions are specified via the O_RDONLY, O_WRONLY, * and O_RDWR flags defined in the fcntl.h header file. * * A valid adapter file descriptor (fd >= 0) is only returned on the initial * attach (successful) of a context. When a context is shared(reused), the user * is expected to already 'know' the adapter file descriptor associated with the * context. */ #define DK_CXLFLASH_ATTACH_REUSE_CONTEXT 0x8000000000000000ULL struct dk_cxlflash_attach { struct dk_cxlflash_hdr hdr; /* Common fields */ __u64 num_interrupts; /* Requested number of interrupts */ __u64 context_id; /* Returned context */ __u64 mmio_size; /* Returned size of MMIO area */ __u64 block_size; /* Returned block size, in bytes */ __u64 adap_fd; /* Returned adapter file descriptor */ __u64 last_lba; /* Returned last LBA on the device */ __u64 max_xfer; /* Returned max transfer size, blocks */ __u64 reserved[8]; /* Reserved for future use */ }; struct dk_cxlflash_detach { struct dk_cxlflash_hdr hdr; /* Common fields */ __u64 context_id; /* Context to detach */ __u64 reserved[8]; /* Reserved for future use */ }; struct dk_cxlflash_udirect { struct dk_cxlflash_hdr hdr; /* Common fields */ __u64 context_id; /* Context to own physical resources */ __u64 rsrc_handle; /* Returned resource handle */ __u64 last_lba; /* Returned last LBA on the device */ __u64 reserved[8]; /* Reserved for future use */ }; #define DK_CXLFLASH_UVIRTUAL_NEED_WRITE_SAME 0x8000000000000000ULL struct dk_cxlflash_uvirtual { struct dk_cxlflash_hdr hdr; /* Common fields */ __u64 context_id; /* Context to own virtual resources */ __u64 lun_size; /* Requested size, in 4K blocks */ __u64 rsrc_handle; /* Returned resource handle */ __u64 last_lba; /* Returned last LBA of LUN */ __u64 reserved[8]; /* Reserved for future use */ }; struct dk_cxlflash_release { struct dk_cxlflash_hdr hdr; /* Common fields */ __u64 context_id; /* Context owning resources */ __u64 rsrc_handle; /* Resource handle to release */ __u64 reserved[8]; /* Reserved for future use */ }; struct dk_cxlflash_resize { struct dk_cxlflash_hdr hdr; /* Common fields */ __u64 context_id; /* Context owning resources */ __u64 rsrc_handle; /* Resource handle of LUN to resize */ __u64 req_size; /* New requested size, in 4K blocks */ __u64 last_lba; /* Returned last LBA of LUN */ __u64 reserved[8]; /* Reserved for future use */ }; struct dk_cxlflash_clone { struct dk_cxlflash_hdr hdr; /* Common fields */ __u64 context_id_src; /* Context to clone from */ __u64 context_id_dst; /* Context to clone to */ __u64 adap_fd_src; /* Source context adapter fd */ __u64 reserved[8]; /* Reserved for future use */ }; #define DK_CXLFLASH_VERIFY_SENSE_LEN 18 #define DK_CXLFLASH_VERIFY_HINT_SENSE 0x8000000000000000ULL struct dk_cxlflash_verify { struct dk_cxlflash_hdr hdr; /* Common fields */ __u64 context_id; /* Context owning resources to verify */ __u64 rsrc_handle; /* Resource handle of LUN */ __u64 hint; /* Reasons for verify */ __u64 last_lba; /* Returned last LBA of device */ __u8 sense_data[DK_CXLFLASH_VERIFY_SENSE_LEN]; /* SCSI sense data */ __u8 pad[6]; /* Pad to next 8-byte boundary */ __u64 reserved[8]; /* Reserved for future use */ }; #define DK_CXLFLASH_RECOVER_AFU_CONTEXT_RESET 0x8000000000000000ULL struct dk_cxlflash_recover_afu { struct dk_cxlflash_hdr hdr; /* Common fields */ __u64 reason; /* Reason for recovery request */ __u64 context_id; /* Context to recover / updated ID */ __u64 mmio_size; /* Returned size of MMIO area */ __u64 adap_fd; /* Returned adapter file descriptor */ __u64 reserved[8]; /* Reserved for future use */ }; #define DK_CXLFLASH_MANAGE_LUN_WWID_LEN CXLFLASH_WWID_LEN #define DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE 0x8000000000000000ULL #define DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE 0x4000000000000000ULL #define DK_CXLFLASH_MANAGE_LUN_ALL_PORTS_ACCESSIBLE 0x2000000000000000ULL struct dk_cxlflash_manage_lun { struct dk_cxlflash_hdr hdr; /* Common fields */ __u8 wwid[DK_CXLFLASH_MANAGE_LUN_WWID_LEN]; /* Page83 WWID, NAA-6 */ __u64 reserved[8]; /* Rsvd, future use */ }; union cxlflash_ioctls { struct dk_cxlflash_attach attach; struct dk_cxlflash_detach detach; struct dk_cxlflash_udirect udirect; struct dk_cxlflash_uvirtual uvirtual; struct dk_cxlflash_release release; struct dk_cxlflash_resize resize; struct dk_cxlflash_clone clone; struct dk_cxlflash_verify verify; struct dk_cxlflash_recover_afu recover_afu; struct dk_cxlflash_manage_lun manage_lun; }; #define MAX_CXLFLASH_IOCTL_SZ (sizeof(union cxlflash_ioctls)) #define CXL_MAGIC 0xCA #define CXL_IOWR(_n, _s) _IOWR(CXL_MAGIC, _n, struct _s) /* * CXL Flash superpipe ioctls start at base of the reserved CXL_MAGIC * region (0x80) and grow upwards. */ #define DK_CXLFLASH_ATTACH CXL_IOWR(0x80, dk_cxlflash_attach) #define DK_CXLFLASH_USER_DIRECT CXL_IOWR(0x81, dk_cxlflash_udirect) #define DK_CXLFLASH_RELEASE CXL_IOWR(0x82, dk_cxlflash_release) #define DK_CXLFLASH_DETACH CXL_IOWR(0x83, dk_cxlflash_detach) #define DK_CXLFLASH_VERIFY CXL_IOWR(0x84, dk_cxlflash_verify) #define DK_CXLFLASH_RECOVER_AFU CXL_IOWR(0x85, dk_cxlflash_recover_afu) #define DK_CXLFLASH_MANAGE_LUN CXL_IOWR(0x86, dk_cxlflash_manage_lun) #define DK_CXLFLASH_USER_VIRTUAL CXL_IOWR(0x87, dk_cxlflash_uvirtual) #define DK_CXLFLASH_VLUN_RESIZE CXL_IOWR(0x88, dk_cxlflash_resize) #define DK_CXLFLASH_VLUN_CLONE CXL_IOWR(0x89, dk_cxlflash_clone) /* * Structure and flag definitions CXL Flash host ioctls */ #define HT_CXLFLASH_VERSION_0 0 struct ht_cxlflash_hdr { __u16 version; /* Version data */ __u16 subcmd; /* Sub-command */ __u16 rsvd[2]; /* Reserved for future use */ __u64 flags; /* Input flags */ __u64 return_flags; /* Returned flags */ }; /* * Input flag definitions available to all host ioctls * * These are grown from the bottom-up with the intention that ioctl-specific * input flag definitions would grow from the top-down, allowing the two sets * to co-exist. While not required/enforced at this time, this provides future * flexibility. */ #define HT_CXLFLASH_HOST_READ 0x0000000000000000ULL #define HT_CXLFLASH_HOST_WRITE 0x0000000000000001ULL #define HT_CXLFLASH_LUN_PROVISION_SUBCMD_CREATE_LUN 0x0001 #define HT_CXLFLASH_LUN_PROVISION_SUBCMD_DELETE_LUN 0x0002 #define HT_CXLFLASH_LUN_PROVISION_SUBCMD_QUERY_PORT 0x0003 struct ht_cxlflash_lun_provision { struct ht_cxlflash_hdr hdr; /* Common fields */ __u16 port; /* Target port for provision request */ __u16 reserved16[3]; /* Reserved for future use */ __u64 size; /* Size of LUN (4K blocks) */ __u64 lun_id; /* SCSI LUN ID */ __u8 wwid[CXLFLASH_WWID_LEN];/* Page83 WWID, NAA-6 */ __u64 max_num_luns; /* Maximum number of LUNs provisioned */ __u64 cur_num_luns; /* Current number of LUNs provisioned */ __u64 max_cap_port; /* Total capacity for port (4K blocks) */ __u64 cur_cap_port; /* Current capacity for port (4K blocks) */ __u64 reserved[8]; /* Reserved for future use */ }; #define HT_CXLFLASH_AFU_DEBUG_MAX_DATA_LEN 262144 /* 256K */ #define HT_CXLFLASH_AFU_DEBUG_SUBCMD_LEN 12 struct ht_cxlflash_afu_debug { struct ht_cxlflash_hdr hdr; /* Common fields */ __u8 reserved8[4]; /* Reserved for future use */ __u8 afu_subcmd[HT_CXLFLASH_AFU_DEBUG_SUBCMD_LEN]; /* AFU subcommand, * (pass through) */ __u64 data_ea; /* Data buffer effective address */ __u32 data_len; /* Data buffer length */ __u32 reserved32; /* Reserved for future use */ __u64 reserved[8]; /* Reserved for future use */ }; union cxlflash_ht_ioctls { struct ht_cxlflash_lun_provision lun_provision; struct ht_cxlflash_afu_debug afu_debug; }; #define MAX_HT_CXLFLASH_IOCTL_SZ (sizeof(union cxlflash_ht_ioctls)) /* * CXL Flash host ioctls start at the top of the reserved CXL_MAGIC * region (0xBF) and grow downwards. */ #define HT_CXLFLASH_LUN_PROVISION CXL_IOWR(0xBF, ht_cxlflash_lun_provision) #define HT_CXLFLASH_AFU_DEBUG CXL_IOWR(0xBE, ht_cxlflash_afu_debug) #endif /* ifndef _CXLFLASH_IOCTL_H */ scsi/scsi_bsg_fc.h 0000644 00000021161 15146341150 0010123 0 ustar 00 /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * FC Transport BSG Interface * * Copyright (C) 2008 James Smart, Emulex Corporation * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef SCSI_BSG_FC_H #define SCSI_BSG_FC_H /* * This file intended to be included by both kernel and user space */ /* * FC Transport SGIO v4 BSG Message Support */ /* Default BSG request timeout (in seconds) */ #define FC_DEFAULT_BSG_TIMEOUT (10 * HZ) /* * Request Message Codes supported by the FC Transport */ /* define the class masks for the message codes */ #define FC_BSG_CLS_MASK 0xF0000000 /* find object class */ #define FC_BSG_HST_MASK 0x80000000 /* fc host class */ #define FC_BSG_RPT_MASK 0x40000000 /* fc rport class */ /* fc_host Message Codes */ #define FC_BSG_HST_ADD_RPORT (FC_BSG_HST_MASK | 0x00000001) #define FC_BSG_HST_DEL_RPORT (FC_BSG_HST_MASK | 0x00000002) #define FC_BSG_HST_ELS_NOLOGIN (FC_BSG_HST_MASK | 0x00000003) #define FC_BSG_HST_CT (FC_BSG_HST_MASK | 0x00000004) #define FC_BSG_HST_VENDOR (FC_BSG_HST_MASK | 0x000000FF) /* fc_rport Message Codes */ #define FC_BSG_RPT_ELS (FC_BSG_RPT_MASK | 0x00000001) #define FC_BSG_RPT_CT (FC_BSG_RPT_MASK | 0x00000002) /* * FC Address Identifiers in Message Structures : * * Whenever a command payload contains a FC Address Identifier * (aka port_id), the value is effectively in big-endian * order, thus the array elements are decoded as follows: * element [0] is bits 23:16 of the FC Address Identifier * element [1] is bits 15:8 of the FC Address Identifier * element [2] is bits 7:0 of the FC Address Identifier */ /* * FC Host Messages */ /* FC_BSG_HST_ADDR_PORT : */ /* Request: * This message requests the FC host to login to the remote port * at the specified N_Port_Id. The remote port is to be enumerated * with the transport upon completion of the login. */ struct fc_bsg_host_add_rport { uint8_t reserved; /* FC Address Identier of the remote port to login to */ uint8_t port_id[3]; }; /* Response: * There is no additional response data - fc_bsg_reply->result is sufficient */ /* FC_BSG_HST_DEL_RPORT : */ /* Request: * This message requests the FC host to remove an enumerated * remote port and to terminate the login to it. * * Note: The driver is free to reject this request if it desires to * remain logged in with the remote port. */ struct fc_bsg_host_del_rport { uint8_t reserved; /* FC Address Identier of the remote port to logout of */ uint8_t port_id[3]; }; /* Response: * There is no additional response data - fc_bsg_reply->result is sufficient */ /* FC_BSG_HST_ELS_NOLOGIN : */ /* Request: * This message requests the FC_Host to send an ELS to a specific * N_Port_ID. The host does not need to log into the remote port, * nor does it need to enumerate the rport for further traffic * (although, the FC host is free to do so if it desires). */ struct fc_bsg_host_els { /* * ELS Command Code being sent (must be the same as byte 0 * of the payload) */ uint8_t command_code; /* FC Address Identier of the remote port to send the ELS to */ uint8_t port_id[3]; }; /* Response: */ /* fc_bsg_ctels_reply->status values */ #define FC_CTELS_STATUS_OK 0x00000000 #define FC_CTELS_STATUS_REJECT 0x00000001 #define FC_CTELS_STATUS_P_RJT 0x00000002 #define FC_CTELS_STATUS_F_RJT 0x00000003 #define FC_CTELS_STATUS_P_BSY 0x00000004 #define FC_CTELS_STATUS_F_BSY 0x00000006 struct fc_bsg_ctels_reply { /* * Note: An ELS LS_RJT may be reported in 2 ways: * a) A status of FC_CTELS_STATUS_OK is returned. The caller * is to look into the ELS receive payload to determine * LS_ACC or LS_RJT (by contents of word 0). The reject * data will be in word 1. * b) A status of FC_CTELS_STATUS_REJECT is returned, The * rjt_data field will contain valid data. * * Note: ELS LS_ACC is determined by an FC_CTELS_STATUS_OK, and * the receive payload word 0 indicates LS_ACC * (e.g. value is 0x02xxxxxx). * * Note: Similarly, a CT Reject may be reported in 2 ways: * a) A status of FC_CTELS_STATUS_OK is returned. The caller * is to look into the CT receive payload to determine * Accept or Reject (by contents of word 2). The reject * data will be in word 3. * b) A status of FC_CTELS_STATUS_REJECT is returned, The * rjt_data field will contain valid data. * * Note: x_RJT/BSY status will indicae that the rjt_data field * is valid and contains the reason/explanation values. */ uint32_t status; /* See FC_CTELS_STATUS_xxx */ /* valid if status is not FC_CTELS_STATUS_OK */ struct { uint8_t action; /* fragment_id for CT REJECT */ uint8_t reason_code; uint8_t reason_explanation; uint8_t vendor_unique; } rjt_data; }; /* FC_BSG_HST_CT : */ /* Request: * This message requests that a CT Request be performed with the * indicated N_Port_ID. The driver is responsible for logging in with * the fabric and/or N_Port_ID, etc as per FC rules. This request does * not mandate that the driver must enumerate the destination in the * transport. The driver is allowed to decide whether to enumerate it, * and whether to tear it down after the request. */ struct fc_bsg_host_ct { uint8_t reserved; /* FC Address Identier of the remote port to send the ELS to */ uint8_t port_id[3]; /* * We need words 0-2 of the generic preamble for the LLD's */ uint32_t preamble_word0; /* revision & IN_ID */ uint32_t preamble_word1; /* GS_Type, GS_SubType, Options, Rsvd */ uint32_t preamble_word2; /* Cmd Code, Max Size */ }; /* Response: * * The reply structure is an fc_bsg_ctels_reply structure */ /* FC_BSG_HST_VENDOR : */ /* Request: * Note: When specifying vendor_id, be sure to read the Vendor Type and ID * formatting requirements specified in scsi_netlink.h */ struct fc_bsg_host_vendor { /* * Identifies the vendor that the message is formatted for. This * should be the recipient of the message. */ uint64_t vendor_id; /* start of vendor command area */ uint32_t vendor_cmd[0]; }; /* Response: */ struct fc_bsg_host_vendor_reply { /* start of vendor response area */ uint32_t vendor_rsp[0]; }; /* * FC Remote Port Messages */ /* FC_BSG_RPT_ELS : */ /* Request: * This message requests that an ELS be performed with the rport. */ struct fc_bsg_rport_els { /* * ELS Command Code being sent (must be the same as * byte 0 of the payload) */ uint8_t els_code; }; /* Response: * * The reply structure is an fc_bsg_ctels_reply structure */ /* FC_BSG_RPT_CT : */ /* Request: * This message requests that a CT Request be performed with the rport. */ struct fc_bsg_rport_ct { /* * We need words 0-2 of the generic preamble for the LLD's */ uint32_t preamble_word0; /* revision & IN_ID */ uint32_t preamble_word1; /* GS_Type, GS_SubType, Options, Rsvd */ uint32_t preamble_word2; /* Cmd Code, Max Size */ }; /* Response: * * The reply structure is an fc_bsg_ctels_reply structure */ /* request (CDB) structure of the sg_io_v4 */ struct fc_bsg_request { uint32_t msgcode; union { struct fc_bsg_host_add_rport h_addrport; struct fc_bsg_host_del_rport h_delrport; struct fc_bsg_host_els h_els; struct fc_bsg_host_ct h_ct; struct fc_bsg_host_vendor h_vendor; struct fc_bsg_rport_els r_els; struct fc_bsg_rport_ct r_ct; } rqst_data; } __attribute__((packed)); /* response (request sense data) structure of the sg_io_v4 */ struct fc_bsg_reply { /* * The completion result. Result exists in two forms: * if negative, it is an -Exxx system errno value. There will * be no further reply information supplied. * else, it's the 4-byte scsi error result, with driver, host, * msg and status fields. The per-msgcode reply structure * will contain valid data. */ uint32_t result; /* If there was reply_payload, how much was recevied ? */ uint32_t reply_payload_rcv_len; union { struct fc_bsg_host_vendor_reply vendor_reply; struct fc_bsg_ctels_reply ctels_reply; } reply_data; }; #endif /* SCSI_BSG_FC_H */ scsi/scsi_bsg_mpi3mr.h 0000644 00000036247 15146341150 0010755 0 ustar 00 /* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */ /* * Driver for Broadcom MPI3 Storage Controllers * * Copyright (C) 2017-2022 Broadcom Inc. * (mailto: mpi3mr-linuxdrv.pdl@broadcom.com) * */ #ifndef SCSI_BSG_MPI3MR_H_INCLUDED #define SCSI_BSG_MPI3MR_H_INCLUDED #include <linux/types.h> /* Definitions for BSG commands */ #define MPI3MR_IOCTL_VERSION 0x06 #define MPI3MR_APP_DEFAULT_TIMEOUT (60) /*seconds*/ #define MPI3MR_BSG_ADPTYPE_UNKNOWN 0 #define MPI3MR_BSG_ADPTYPE_AVGFAMILY 1 #define MPI3MR_BSG_ADPSTATE_UNKNOWN 0 #define MPI3MR_BSG_ADPSTATE_OPERATIONAL 1 #define MPI3MR_BSG_ADPSTATE_FAULT 2 #define MPI3MR_BSG_ADPSTATE_IN_RESET 3 #define MPI3MR_BSG_ADPSTATE_UNRECOVERABLE 4 #define MPI3MR_BSG_ADPRESET_UNKNOWN 0 #define MPI3MR_BSG_ADPRESET_SOFT 1 #define MPI3MR_BSG_ADPRESET_DIAG_FAULT 2 #define MPI3MR_BSG_LOGDATA_MAX_ENTRIES 400 #define MPI3MR_BSG_LOGDATA_ENTRY_HEADER_SZ 4 #define MPI3MR_DRVBSG_OPCODE_UNKNOWN 0 #define MPI3MR_DRVBSG_OPCODE_ADPINFO 1 #define MPI3MR_DRVBSG_OPCODE_ADPRESET 2 #define MPI3MR_DRVBSG_OPCODE_ALLTGTDEVINFO 4 #define MPI3MR_DRVBSG_OPCODE_GETCHGCNT 5 #define MPI3MR_DRVBSG_OPCODE_LOGDATAENABLE 6 #define MPI3MR_DRVBSG_OPCODE_PELENABLE 7 #define MPI3MR_DRVBSG_OPCODE_GETLOGDATA 8 #define MPI3MR_DRVBSG_OPCODE_QUERY_HDB 9 #define MPI3MR_DRVBSG_OPCODE_REPOST_HDB 10 #define MPI3MR_DRVBSG_OPCODE_UPLOAD_HDB 11 #define MPI3MR_DRVBSG_OPCODE_REFRESH_HDB_TRIGGERS 12 #define MPI3MR_BSG_BUFTYPE_UNKNOWN 0 #define MPI3MR_BSG_BUFTYPE_RAIDMGMT_CMD 1 #define MPI3MR_BSG_BUFTYPE_RAIDMGMT_RESP 2 #define MPI3MR_BSG_BUFTYPE_DATA_IN 3 #define MPI3MR_BSG_BUFTYPE_DATA_OUT 4 #define MPI3MR_BSG_BUFTYPE_MPI_REPLY 5 #define MPI3MR_BSG_BUFTYPE_ERR_RESPONSE 6 #define MPI3MR_BSG_BUFTYPE_MPI_REQUEST 0xFE #define MPI3MR_BSG_MPI_REPLY_BUFTYPE_UNKNOWN 0 #define MPI3MR_BSG_MPI_REPLY_BUFTYPE_STATUS 1 #define MPI3MR_BSG_MPI_REPLY_BUFTYPE_ADDRESS 2 #define MPI3MR_HDB_BUFTYPE_UNKNOWN 0 #define MPI3MR_HDB_BUFTYPE_TRACE 1 #define MPI3MR_HDB_BUFTYPE_FIRMWARE 2 #define MPI3MR_HDB_BUFTYPE_RESERVED 3 #define MPI3MR_HDB_BUFSTATUS_UNKNOWN 0 #define MPI3MR_HDB_BUFSTATUS_NOT_ALLOCATED 1 #define MPI3MR_HDB_BUFSTATUS_POSTED_UNPAUSED 2 #define MPI3MR_HDB_BUFSTATUS_POSTED_PAUSED 3 #define MPI3MR_HDB_BUFSTATUS_RELEASED 4 #define MPI3MR_HDB_TRIGGER_TYPE_UNKNOWN 0 #define MPI3MR_HDB_TRIGGER_TYPE_DIAGFAULT 1 #define MPI3MR_HDB_TRIGGER_TYPE_ELEMENT 2 #define MPI3MR_HDB_TRIGGER_TYPE_MASTER 3 /* Supported BSG commands */ enum command { MPI3MR_DRV_CMD = 1, MPI3MR_MPT_CMD = 2, }; /** * struct mpi3_driver_info_layout - Information about driver * * @information_length: Length of this structure in bytes * @driver_signature: Driver Vendor name * @os_name: Operating System Name * @driver_name: Driver name * @driver_version: Driver version * @driver_release_date: Driver release date * @driver_capabilities: Driver capabilities */ struct mpi3_driver_info_layout { __le32 information_length; __u8 driver_signature[12]; __u8 os_name[16]; __u8 os_version[12]; __u8 driver_name[20]; __u8 driver_version[32]; __u8 driver_release_date[20]; __le32 driver_capabilities; }; /** * struct mpi3mr_bsg_in_adpinfo - Adapter information request * data returned by the driver. * * @adp_type: Adapter type * @rsvd1: Reserved * @pci_dev_id: PCI device ID of the adapter * @pci_dev_hw_rev: PCI revision of the adapter * @pci_subsys_dev_id: PCI subsystem device ID of the adapter * @pci_subsys_ven_id: PCI subsystem vendor ID of the adapter * @pci_dev: PCI device * @pci_func: PCI function * @pci_bus: PCI bus * @rsvd2: Reserved * @pci_seg_id: PCI segment ID * @app_intfc_ver: version of the application interface definition * @rsvd3: Reserved * @rsvd4: Reserved * @rsvd5: Reserved * @driver_info: Driver Information (Version/Name) */ struct mpi3mr_bsg_in_adpinfo { __u32 adp_type; __u32 rsvd1; __u32 pci_dev_id; __u32 pci_dev_hw_rev; __u32 pci_subsys_dev_id; __u32 pci_subsys_ven_id; __u32 pci_dev:5; __u32 pci_func:3; __u32 pci_bus:8; __u16 rsvd2; __u32 pci_seg_id; __u32 app_intfc_ver; __u8 adp_state; __u8 rsvd3; __u16 rsvd4; __u32 rsvd5[2]; struct mpi3_driver_info_layout driver_info; }; /** * struct mpi3mr_bsg_adp_reset - Adapter reset request * payload data to the driver. * * @reset_type: Reset type * @rsvd1: Reserved * @rsvd2: Reserved */ struct mpi3mr_bsg_adp_reset { __u8 reset_type; __u8 rsvd1; __u16 rsvd2; }; /** * struct mpi3mr_change_count - Topology change count * returned by the driver. * * @change_count: Topology change count * @rsvd: Reserved */ struct mpi3mr_change_count { __u16 change_count; __u16 rsvd; }; /** * struct mpi3mr_device_map_info - Target device mapping * information * * @handle: Firmware device handle * @perst_id: Persistent ID assigned by the firmware * @target_id: Target ID assigned by the driver * @bus_id: Bus ID assigned by the driver * @rsvd1: Reserved * @rsvd2: Reserved */ struct mpi3mr_device_map_info { __u16 handle; __u16 perst_id; __u32 target_id; __u8 bus_id; __u8 rsvd1; __u16 rsvd2; }; /** * struct mpi3mr_all_tgt_info - Target device mapping * information returned by the driver * * @num_devices: The number of devices in driver's inventory * @rsvd1: Reserved * @rsvd2: Reserved * @dmi: Variable length array of mapping information of targets */ struct mpi3mr_all_tgt_info { __u16 num_devices; __u16 rsvd1; __u32 rsvd2; struct mpi3mr_device_map_info dmi[1]; }; /** * struct mpi3mr_logdata_enable - Number of log data * entries saved by the driver returned as payload data for * enable logdata BSG request by the driver. * * @max_entries: Number of log data entries cached by the driver * @rsvd: Reserved */ struct mpi3mr_logdata_enable { __u16 max_entries; __u16 rsvd; }; /** * struct mpi3mr_bsg_out_pel_enable - PEL enable request payload * data to the driver. * * @pel_locale: PEL locale to the firmware * @pel_class: PEL class to the firmware * @rsvd: Reserved */ struct mpi3mr_bsg_out_pel_enable { __u16 pel_locale; __u8 pel_class; __u8 rsvd; }; /** * struct mpi3mr_logdata_entry - Log data entry cached by the * driver. * * @valid_entry: Is the entry valid * @rsvd1: Reserved * @rsvd2: Reserved * @data: Variable length Log entry data */ struct mpi3mr_logdata_entry { __u8 valid_entry; __u8 rsvd1; __u16 rsvd2; __u8 data[1]; /* Variable length Array */ }; /** * struct mpi3mr_bsg_in_log_data - Log data entries saved by * the driver returned as payload data for Get logdata request * by the driver. * * @entry: Variable length Log data entry array */ struct mpi3mr_bsg_in_log_data { struct mpi3mr_logdata_entry entry[1]; }; /** * struct mpi3mr_hdb_entry - host diag buffer entry. * * @buf_type: Buffer type * @status: Buffer status * @trigger_type: Trigger type * @rsvd1: Reserved * @size: Buffer size * @rsvd2: Reserved * @trigger_data: Trigger specific data * @rsvd3: Reserved * @rsvd4: Reserved */ struct mpi3mr_hdb_entry { __u8 buf_type; __u8 status; __u8 trigger_type; __u8 rsvd1; __u16 size; __u16 rsvd2; __u64 trigger_data; __u32 rsvd3; __u32 rsvd4; }; /** * struct mpi3mr_bsg_in_hdb_status - This structure contains * return data for the BSG request to retrieve the number of host * diagnostic buffers supported by the driver and their current * status and additional status specific data if any in forms of * multiple hdb entries. * * @num_hdb_types: Number of host diag buffer types supported * @rsvd1: Reserved * @rsvd2: Reserved * @rsvd3: Reserved * @entry: Variable length Diag buffer status entry array */ struct mpi3mr_bsg_in_hdb_status { __u8 num_hdb_types; __u8 rsvd1; __u16 rsvd2; __u32 rsvd3; struct mpi3mr_hdb_entry entry[1]; }; /** * struct mpi3mr_bsg_out_repost_hdb - Repost host diagnostic * buffer request payload data to the driver. * * @buf_type: Buffer type * @rsvd1: Reserved * @rsvd2: Reserved */ struct mpi3mr_bsg_out_repost_hdb { __u8 buf_type; __u8 rsvd1; __u16 rsvd2; }; /** * struct mpi3mr_bsg_out_upload_hdb - Upload host diagnostic * buffer request payload data to the driver. * * @buf_type: Buffer type * @rsvd1: Reserved * @rsvd2: Reserved * @start_offset: Start offset of the buffer from where to copy * @length: Length of the buffer to copy */ struct mpi3mr_bsg_out_upload_hdb { __u8 buf_type; __u8 rsvd1; __u16 rsvd2; __u32 start_offset; __u32 length; }; /** * struct mpi3mr_bsg_out_refresh_hdb_triggers - Refresh host * diagnostic buffer triggers request payload data to the driver. * * @page_type: Page type * @rsvd1: Reserved * @rsvd2: Reserved */ struct mpi3mr_bsg_out_refresh_hdb_triggers { __u8 page_type; __u8 rsvd1; __u16 rsvd2; }; /** * struct mpi3mr_bsg_drv_cmd - Generic bsg data * structure for all driver specific requests. * * @mrioc_id: Controller ID * @opcode: Driver specific opcode * @rsvd1: Reserved * @rsvd2: Reserved */ struct mpi3mr_bsg_drv_cmd { __u8 mrioc_id; __u8 opcode; __u16 rsvd1; __u32 rsvd2[4]; }; /** * struct mpi3mr_bsg_in_reply_buf - MPI reply buffer returned * for MPI Passthrough request . * * @mpi_reply_type: Type of MPI reply * @rsvd1: Reserved * @rsvd2: Reserved * @reply_buf: Variable Length buffer based on mpirep type */ struct mpi3mr_bsg_in_reply_buf { __u8 mpi_reply_type; __u8 rsvd1; __u16 rsvd2; __u8 reply_buf[]; }; /** * struct mpi3mr_buf_entry - User buffer descriptor for MPI * Passthrough requests. * * @buf_type: Buffer type * @rsvd1: Reserved * @rsvd2: Reserved * @buf_len: Buffer length */ struct mpi3mr_buf_entry { __u8 buf_type; __u8 rsvd1; __u16 rsvd2; __u32 buf_len; }; /** * struct mpi3mr_bsg_buf_entry_list - list of user buffer * descriptor for MPI Passthrough requests. * * @num_of_entries: Number of buffer descriptors * @rsvd1: Reserved * @rsvd2: Reserved * @rsvd3: Reserved * @buf_entry: Variable length array of buffer descriptors */ struct mpi3mr_buf_entry_list { __u8 num_of_entries; __u8 rsvd1; __u16 rsvd2; __u32 rsvd3; struct mpi3mr_buf_entry buf_entry[1]; }; /** * struct mpi3mr_bsg_mptcmd - Generic bsg data * structure for all MPI Passthrough requests . * * @mrioc_id: Controller ID * @rsvd1: Reserved * @timeout: MPI request timeout * @buf_entry_list: Buffer descriptor list */ struct mpi3mr_bsg_mptcmd { __u8 mrioc_id; __u8 rsvd1; __u16 timeout; __u32 rsvd2; struct mpi3mr_buf_entry_list buf_entry_list; }; /** * struct mpi3mr_bsg_packet - Generic bsg data * structure for all supported requests . * * @cmd_type: represents drvrcmd or mptcmd * @rsvd1: Reserved * @rsvd2: Reserved * @drvrcmd: driver request structure * @mptcmd: mpt request structure */ struct mpi3mr_bsg_packet { __u8 cmd_type; __u8 rsvd1; __u16 rsvd2; __u32 rsvd3; union { struct mpi3mr_bsg_drv_cmd drvrcmd; struct mpi3mr_bsg_mptcmd mptcmd; } cmd; }; /* MPI3: NVMe Encasulation related definitions */ #ifndef MPI3_NVME_ENCAP_CMD_MAX #define MPI3_NVME_ENCAP_CMD_MAX (1) #endif struct mpi3_nvme_encapsulated_request { __le16 host_tag; __u8 ioc_use_only02; __u8 function; __le16 ioc_use_only04; __u8 ioc_use_only06; __u8 msg_flags; __le16 change_count; __le16 dev_handle; __le16 encapsulated_command_length; __le16 flags; __le32 data_length; __le32 reserved14[3]; __le32 command[MPI3_NVME_ENCAP_CMD_MAX]; }; struct mpi3_nvme_encapsulated_error_reply { __le16 host_tag; __u8 ioc_use_only02; __u8 function; __le16 ioc_use_only04; __u8 ioc_use_only06; __u8 msg_flags; __le16 ioc_use_only08; __le16 ioc_status; __le32 ioc_log_info; __le32 nvme_completion_entry[4]; }; #define MPI3MR_NVME_PRP_SIZE 8 /* PRP size */ #define MPI3MR_NVME_CMD_PRP1_OFFSET 24 /* PRP1 offset in NVMe cmd */ #define MPI3MR_NVME_CMD_PRP2_OFFSET 32 /* PRP2 offset in NVMe cmd */ #define MPI3MR_NVME_CMD_SGL_OFFSET 24 /* SGL offset in NVMe cmd */ #define MPI3MR_NVME_DATA_FORMAT_PRP 0 #define MPI3MR_NVME_DATA_FORMAT_SGL1 1 #define MPI3MR_NVME_DATA_FORMAT_SGL2 2 /* MPI3: task management related definitions */ struct mpi3_scsi_task_mgmt_request { __le16 host_tag; __u8 ioc_use_only02; __u8 function; __le16 ioc_use_only04; __u8 ioc_use_only06; __u8 msg_flags; __le16 change_count; __le16 dev_handle; __le16 task_host_tag; __u8 task_type; __u8 reserved0f; __le16 task_request_queue_id; __le16 reserved12; __le32 reserved14; __u8 lun[8]; }; #define MPI3_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x08) #define MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x01) #define MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK_SET (0x02) #define MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03) #define MPI3_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) #define MPI3_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) #define MPI3_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) #define MPI3_SCSITASKMGMT_TASKTYPE_CLEAR_ACA (0x08) #define MPI3_SCSITASKMGMT_TASKTYPE_QUERY_TASK_SET (0x09) #define MPI3_SCSITASKMGMT_TASKTYPE_QUERY_ASYNC_EVENT (0x0a) #define MPI3_SCSITASKMGMT_TASKTYPE_I_T_NEXUS_RESET (0x0b) struct mpi3_scsi_task_mgmt_reply { __le16 host_tag; __u8 ioc_use_only02; __u8 function; __le16 ioc_use_only04; __u8 ioc_use_only06; __u8 msg_flags; __le16 ioc_use_only08; __le16 ioc_status; __le32 ioc_log_info; __le32 termination_count; __le32 response_data; __le32 reserved18; }; #define MPI3_SCSITASKMGMT_RSPCODE_TM_COMPLETE (0x00) #define MPI3_SCSITASKMGMT_RSPCODE_INVALID_FRAME (0x02) #define MPI3_SCSITASKMGMT_RSPCODE_TM_FUNCTION_NOT_SUPPORTED (0x04) #define MPI3_SCSITASKMGMT_RSPCODE_TM_FAILED (0x05) #define MPI3_SCSITASKMGMT_RSPCODE_TM_SUCCEEDED (0x08) #define MPI3_SCSITASKMGMT_RSPCODE_TM_INVALID_LUN (0x09) #define MPI3_SCSITASKMGMT_RSPCODE_TM_OVERLAPPED_TAG (0x0a) #define MPI3_SCSITASKMGMT_RSPCODE_IO_QUEUED_ON_IOC (0x80) #define MPI3_SCSITASKMGMT_RSPCODE_TM_NVME_DENIED (0x81) /* MPI3: PEL related definitions */ #define MPI3_PEL_LOCALE_FLAGS_NON_BLOCKING_BOOT_EVENT (0x0200) #define MPI3_PEL_LOCALE_FLAGS_BLOCKING_BOOT_EVENT (0x0100) #define MPI3_PEL_LOCALE_FLAGS_PCIE (0x0080) #define MPI3_PEL_LOCALE_FLAGS_CONFIGURATION (0x0040) #define MPI3_PEL_LOCALE_FLAGS_CONTROLER (0x0020) #define MPI3_PEL_LOCALE_FLAGS_SAS (0x0010) #define MPI3_PEL_LOCALE_FLAGS_EPACK (0x0008) #define MPI3_PEL_LOCALE_FLAGS_ENCLOSURE (0x0004) #define MPI3_PEL_LOCALE_FLAGS_PD (0x0002) #define MPI3_PEL_LOCALE_FLAGS_VD (0x0001) #define MPI3_PEL_CLASS_DEBUG (0x00) #define MPI3_PEL_CLASS_PROGRESS (0x01) #define MPI3_PEL_CLASS_INFORMATIONAL (0x02) #define MPI3_PEL_CLASS_WARNING (0x03) #define MPI3_PEL_CLASS_CRITICAL (0x04) #define MPI3_PEL_CLASS_FATAL (0x05) #define MPI3_PEL_CLASS_FAULT (0x06) /* MPI3: Function definitions */ #define MPI3_BSG_FUNCTION_MGMT_PASSTHROUGH (0x0a) #define MPI3_BSG_FUNCTION_SCSI_IO (0x20) #define MPI3_BSG_FUNCTION_SCSI_TASK_MGMT (0x21) #define MPI3_BSG_FUNCTION_SMP_PASSTHROUGH (0x22) #define MPI3_BSG_FUNCTION_NVME_ENCAPSULATED (0x24) #endif scsi/scsi_ioctl.h 0000644 00000002443 15146341150 0010014 0 ustar 00 /* Copyright (C) 1999-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _SCSI_IOCTL_H #define _SCSI_IOCTL_H /* IOCTLs for SCSI. */ #define SCSI_IOCTL_SEND_COMMAND 1 /* Send a command to the SCSI host. */ #define SCSI_IOCTL_TEST_UNIT_READY 2 /* Test if unit is ready. */ #define SCSI_IOCTL_BENCHMARK_COMMAND 3 #define SCSI_IOCTL_SYNC 4 /* Request synchronous parameters. */ #define SCSI_IOCTL_START_UNIT 5 #define SCSI_IOCTL_STOP_UNIT 6 #define SCSI_IOCTL_DOORLOCK 0x5380 /* Lock the eject mechanism. */ #define SCSI_IOCTL_DOORUNLOCK 0x5381 /* Unlock the mechanism. */ #endif scsi/fc/fc_fs.h 0000644 00000030117 15146341150 0007330 0 ustar 00 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright(c) 2007 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * Maintained at www.Open-FCoE.org */ #ifndef _FC_FS_H_ #define _FC_FS_H_ #include <linux/types.h> /* * Fibre Channel Framing and Signalling definitions. * From T11 FC-FS-2 Rev 0.90 - 9 August 2005. */ /* * Frame header */ struct fc_frame_header { __u8 fh_r_ctl; /* routing control */ __u8 fh_d_id[3]; /* Destination ID */ __u8 fh_cs_ctl; /* class of service control / pri */ __u8 fh_s_id[3]; /* Source ID */ __u8 fh_type; /* see enum fc_fh_type below */ __u8 fh_f_ctl[3]; /* frame control */ __u8 fh_seq_id; /* sequence ID */ __u8 fh_df_ctl; /* data field control */ __be16 fh_seq_cnt; /* sequence count */ __be16 fh_ox_id; /* originator exchange ID */ __be16 fh_rx_id; /* responder exchange ID */ __be32 fh_parm_offset; /* parameter or relative offset */ }; #define FC_FRAME_HEADER_LEN 24 /* expected length of structure */ #define FC_MAX_PAYLOAD 2112U /* max payload length in bytes */ #define FC_MIN_MAX_PAYLOAD 256U /* lower limit on max payload */ #define FC_MAX_FRAME (FC_MAX_PAYLOAD + FC_FRAME_HEADER_LEN) #define FC_MIN_MAX_FRAME (FC_MIN_MAX_PAYLOAD + FC_FRAME_HEADER_LEN) /* * fh_r_ctl - Routing control definitions. */ /* * FC-4 device_data. */ enum fc_rctl { FC_RCTL_DD_UNCAT = 0x00, /* uncategorized information */ FC_RCTL_DD_SOL_DATA = 0x01, /* solicited data */ FC_RCTL_DD_UNSOL_CTL = 0x02, /* unsolicited control */ FC_RCTL_DD_SOL_CTL = 0x03, /* solicited control or reply */ FC_RCTL_DD_UNSOL_DATA = 0x04, /* unsolicited data */ FC_RCTL_DD_DATA_DESC = 0x05, /* data descriptor */ FC_RCTL_DD_UNSOL_CMD = 0x06, /* unsolicited command */ FC_RCTL_DD_CMD_STATUS = 0x07, /* command status */ #define FC_RCTL_ILS_REQ FC_RCTL_DD_UNSOL_CTL /* ILS request */ #define FC_RCTL_ILS_REP FC_RCTL_DD_SOL_CTL /* ILS reply */ /* * Extended Link_Data */ FC_RCTL_ELS_REQ = 0x22, /* extended link services request */ FC_RCTL_ELS_REP = 0x23, /* extended link services reply */ FC_RCTL_ELS4_REQ = 0x32, /* FC-4 ELS request */ FC_RCTL_ELS4_REP = 0x33, /* FC-4 ELS reply */ /* * Optional Extended Headers */ FC_RCTL_VFTH = 0x50, /* virtual fabric tagging header */ FC_RCTL_IFRH = 0x51, /* inter-fabric routing header */ FC_RCTL_ENCH = 0x52, /* encapsulation header */ /* * Basic Link Services fh_r_ctl values. */ FC_RCTL_BA_NOP = 0x80, /* basic link service NOP */ FC_RCTL_BA_ABTS = 0x81, /* basic link service abort */ FC_RCTL_BA_RMC = 0x82, /* remove connection */ FC_RCTL_BA_ACC = 0x84, /* basic accept */ FC_RCTL_BA_RJT = 0x85, /* basic reject */ FC_RCTL_BA_PRMT = 0x86, /* dedicated connection preempted */ /* * Link Control Information. */ FC_RCTL_ACK_1 = 0xc0, /* acknowledge_1 */ FC_RCTL_ACK_0 = 0xc1, /* acknowledge_0 */ FC_RCTL_P_RJT = 0xc2, /* port reject */ FC_RCTL_F_RJT = 0xc3, /* fabric reject */ FC_RCTL_P_BSY = 0xc4, /* port busy */ FC_RCTL_F_BSY = 0xc5, /* fabric busy to data frame */ FC_RCTL_F_BSYL = 0xc6, /* fabric busy to link control frame */ FC_RCTL_LCR = 0xc7, /* link credit reset */ FC_RCTL_END = 0xc9, /* end */ }; /* incomplete list of definitions */ /* * R_CTL names initializer. * Please keep this matching the above definitions. */ #define FC_RCTL_NAMES_INIT { \ [FC_RCTL_DD_UNCAT] = "uncat", \ [FC_RCTL_DD_SOL_DATA] = "sol data", \ [FC_RCTL_DD_UNSOL_CTL] = "unsol ctl", \ [FC_RCTL_DD_SOL_CTL] = "sol ctl/reply", \ [FC_RCTL_DD_UNSOL_DATA] = "unsol data", \ [FC_RCTL_DD_DATA_DESC] = "data desc", \ [FC_RCTL_DD_UNSOL_CMD] = "unsol cmd", \ [FC_RCTL_DD_CMD_STATUS] = "cmd status", \ [FC_RCTL_ELS_REQ] = "ELS req", \ [FC_RCTL_ELS_REP] = "ELS rep", \ [FC_RCTL_ELS4_REQ] = "FC-4 ELS req", \ [FC_RCTL_ELS4_REP] = "FC-4 ELS rep", \ [FC_RCTL_BA_NOP] = "BLS NOP", \ [FC_RCTL_BA_ABTS] = "BLS abort", \ [FC_RCTL_BA_RMC] = "BLS remove connection", \ [FC_RCTL_BA_ACC] = "BLS accept", \ [FC_RCTL_BA_RJT] = "BLS reject", \ [FC_RCTL_BA_PRMT] = "BLS dedicated connection preempted", \ [FC_RCTL_ACK_1] = "LC ACK_1", \ [FC_RCTL_ACK_0] = "LC ACK_0", \ [FC_RCTL_P_RJT] = "LC port reject", \ [FC_RCTL_F_RJT] = "LC fabric reject", \ [FC_RCTL_P_BSY] = "LC port busy", \ [FC_RCTL_F_BSY] = "LC fabric busy to data frame", \ [FC_RCTL_F_BSYL] = "LC fabric busy to link control frame",\ [FC_RCTL_LCR] = "LC link credit reset", \ [FC_RCTL_END] = "LC end", \ } /* * Well-known fabric addresses. */ enum fc_well_known_fid { FC_FID_NONE = 0x000000, /* No destination */ FC_FID_BCAST = 0xffffff, /* broadcast */ FC_FID_FLOGI = 0xfffffe, /* fabric login */ FC_FID_FCTRL = 0xfffffd, /* fabric controller */ FC_FID_DIR_SERV = 0xfffffc, /* directory server */ FC_FID_TIME_SERV = 0xfffffb, /* time server */ FC_FID_MGMT_SERV = 0xfffffa, /* management server */ FC_FID_QOS = 0xfffff9, /* QoS Facilitator */ FC_FID_ALIASES = 0xfffff8, /* alias server (FC-PH2) */ FC_FID_SEC_KEY = 0xfffff7, /* Security key dist. server */ FC_FID_CLOCK = 0xfffff6, /* clock synch server */ FC_FID_MCAST_SERV = 0xfffff5, /* multicast server */ }; #define FC_FID_WELL_KNOWN_MAX 0xffffff /* highest well-known fabric ID */ #define FC_FID_WELL_KNOWN_BASE 0xfffff5 /* start of well-known fabric ID */ /* * Other well-known addresses, outside the above contiguous range. */ #define FC_FID_DOM_MGR 0xfffc00 /* domain manager base */ /* * Fabric ID bytes. */ #define FC_FID_DOMAIN 0 #define FC_FID_PORT 1 #define FC_FID_LINK 2 /* * fh_type codes */ enum fc_fh_type { FC_TYPE_BLS = 0x00, /* basic link service */ FC_TYPE_ELS = 0x01, /* extended link service */ FC_TYPE_IP = 0x05, /* IP over FC, RFC 4338 */ FC_TYPE_FCP = 0x08, /* SCSI FCP */ FC_TYPE_CT = 0x20, /* Fibre Channel Services (FC-CT) */ FC_TYPE_ILS = 0x22, /* internal link service */ FC_TYPE_NVME = 0x28, /* FC-NVME */ }; /* * FC_TYPE names initializer. * Please keep this matching the above definitions. */ #define FC_TYPE_NAMES_INIT { \ [FC_TYPE_BLS] = "BLS", \ [FC_TYPE_ELS] = "ELS", \ [FC_TYPE_IP] = "IP", \ [FC_TYPE_FCP] = "FCP", \ [FC_TYPE_CT] = "CT", \ [FC_TYPE_ILS] = "ILS", \ [FC_TYPE_NVME] = "NVME", \ } /* * Exchange IDs. */ #define FC_XID_UNKNOWN 0xffff /* unknown exchange ID */ #define FC_XID_MIN 0x0 /* supported min exchange ID */ #define FC_XID_MAX 0xfffe /* supported max exchange ID */ /* * fh_f_ctl - Frame control flags. */ #define FC_FC_EX_CTX (1 << 23) /* sent by responder to exchange */ #define FC_FC_SEQ_CTX (1 << 22) /* sent by responder to sequence */ #define FC_FC_FIRST_SEQ (1 << 21) /* first sequence of this exchange */ #define FC_FC_LAST_SEQ (1 << 20) /* last sequence of this exchange */ #define FC_FC_END_SEQ (1 << 19) /* last frame of sequence */ #define FC_FC_END_CONN (1 << 18) /* end of class 1 connection pending */ #define FC_FC_RES_B17 (1 << 17) /* reserved */ #define FC_FC_SEQ_INIT (1 << 16) /* transfer of sequence initiative */ #define FC_FC_X_ID_REASS (1 << 15) /* exchange ID has been changed */ #define FC_FC_X_ID_INVAL (1 << 14) /* exchange ID invalidated */ #define FC_FC_ACK_1 (1 << 12) /* 13:12 = 1: ACK_1 expected */ #define FC_FC_ACK_N (2 << 12) /* 13:12 = 2: ACK_N expected */ #define FC_FC_ACK_0 (3 << 12) /* 13:12 = 3: ACK_0 expected */ #define FC_FC_RES_B11 (1 << 11) /* reserved */ #define FC_FC_RES_B10 (1 << 10) /* reserved */ #define FC_FC_RETX_SEQ (1 << 9) /* retransmitted sequence */ #define FC_FC_UNI_TX (1 << 8) /* unidirectional transmit (class 1) */ #define FC_FC_CONT_SEQ(i) ((i) << 6) #define FC_FC_ABT_SEQ(i) ((i) << 4) #define FC_FC_REL_OFF (1 << 3) /* parameter is relative offset */ #define FC_FC_RES2 (1 << 2) /* reserved */ #define FC_FC_FILL(i) ((i) & 3) /* 1:0: bytes of trailing fill */ /* * BA_ACC payload. */ struct fc_ba_acc { __u8 ba_seq_id_val; /* SEQ_ID validity */ #define FC_BA_SEQ_ID_VAL 0x80 __u8 ba_seq_id; /* SEQ_ID of seq last deliverable */ __u8 ba_resvd[2]; /* reserved */ __be16 ba_ox_id; /* OX_ID for aborted seq or exch */ __be16 ba_rx_id; /* RX_ID for aborted seq or exch */ __be16 ba_low_seq_cnt; /* low SEQ_CNT of aborted seq */ __be16 ba_high_seq_cnt; /* high SEQ_CNT of aborted seq */ }; /* * BA_RJT: Basic Reject payload. */ struct fc_ba_rjt { __u8 br_resvd; /* reserved */ __u8 br_reason; /* reason code */ __u8 br_explan; /* reason explanation */ __u8 br_vendor; /* vendor unique code */ }; /* * BA_RJT reason codes. * From FS-2. */ enum fc_ba_rjt_reason { FC_BA_RJT_NONE = 0, /* in software this means no reject */ FC_BA_RJT_INVL_CMD = 0x01, /* invalid command code */ FC_BA_RJT_LOG_ERR = 0x03, /* logical error */ FC_BA_RJT_LOG_BUSY = 0x05, /* logical busy */ FC_BA_RJT_PROTO_ERR = 0x07, /* protocol error */ FC_BA_RJT_UNABLE = 0x09, /* unable to perform request */ FC_BA_RJT_VENDOR = 0xff, /* vendor-specific (see br_vendor) */ }; /* * BA_RJT reason code explanations. */ enum fc_ba_rjt_explan { FC_BA_RJT_EXP_NONE = 0x00, /* no additional expanation */ FC_BA_RJT_INV_XID = 0x03, /* invalid OX_ID-RX_ID combination */ FC_BA_RJT_ABT = 0x05, /* sequence aborted, no seq info */ }; /* * P_RJT or F_RJT: Port Reject or Fabric Reject parameter field. */ struct fc_pf_rjt { __u8 rj_action; /* reserved */ __u8 rj_reason; /* reason code */ __u8 rj_resvd; /* reserved */ __u8 rj_vendor; /* vendor unique code */ }; /* * P_RJT and F_RJT reject reason codes. */ enum fc_pf_rjt_reason { FC_RJT_NONE = 0, /* non-reject (reserved by standard) */ FC_RJT_INVL_DID = 0x01, /* invalid destination ID */ FC_RJT_INVL_SID = 0x02, /* invalid source ID */ FC_RJT_P_UNAV_T = 0x03, /* port unavailable, temporary */ FC_RJT_P_UNAV = 0x04, /* port unavailable, permanent */ FC_RJT_CLS_UNSUP = 0x05, /* class not supported */ FC_RJT_DEL_USAGE = 0x06, /* delimiter usage error */ FC_RJT_TYPE_UNSUP = 0x07, /* type not supported */ FC_RJT_LINK_CTL = 0x08, /* invalid link control */ FC_RJT_R_CTL = 0x09, /* invalid R_CTL field */ FC_RJT_F_CTL = 0x0a, /* invalid F_CTL field */ FC_RJT_OX_ID = 0x0b, /* invalid originator exchange ID */ FC_RJT_RX_ID = 0x0c, /* invalid responder exchange ID */ FC_RJT_SEQ_ID = 0x0d, /* invalid sequence ID */ FC_RJT_DF_CTL = 0x0e, /* invalid DF_CTL field */ FC_RJT_SEQ_CNT = 0x0f, /* invalid SEQ_CNT field */ FC_RJT_PARAM = 0x10, /* invalid parameter field */ FC_RJT_EXCH_ERR = 0x11, /* exchange error */ FC_RJT_PROTO = 0x12, /* protocol error */ FC_RJT_LEN = 0x13, /* incorrect length */ FC_RJT_UNEXP_ACK = 0x14, /* unexpected ACK */ FC_RJT_FAB_CLASS = 0x15, /* class unsupported by fabric entity */ FC_RJT_LOGI_REQ = 0x16, /* login required */ FC_RJT_SEQ_XS = 0x17, /* excessive sequences attempted */ FC_RJT_EXCH_EST = 0x18, /* unable to establish exchange */ FC_RJT_FAB_UNAV = 0x1a, /* fabric unavailable */ FC_RJT_VC_ID = 0x1b, /* invalid VC_ID (class 4) */ FC_RJT_CS_CTL = 0x1c, /* invalid CS_CTL field */ FC_RJT_INSUF_RES = 0x1d, /* insuff. resources for VC (Class 4) */ FC_RJT_INVL_CLS = 0x1f, /* invalid class of service */ FC_RJT_PREEMT_RJT = 0x20, /* preemption request rejected */ FC_RJT_PREEMT_DIS = 0x21, /* preemption not enabled */ FC_RJT_MCAST_ERR = 0x22, /* multicast error */ FC_RJT_MCAST_ET = 0x23, /* multicast error terminate */ FC_RJT_PRLI_REQ = 0x24, /* process login required */ FC_RJT_INVL_ATT = 0x25, /* invalid attachment */ FC_RJT_VENDOR = 0xff, /* vendor specific reject */ }; /* default timeout values */ #define FC_DEF_E_D_TOV 2000UL #define FC_DEF_R_A_TOV 10000UL #endif /* _FC_FS_H_ */ scsi/fc/fc_ns.h 0000644 00000011565 15146341150 0007346 0 ustar 00 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright(c) 2007 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * Maintained at www.Open-FCoE.org */ #ifndef _FC_NS_H_ #define _FC_NS_H_ #include <linux/types.h> /* * Fibre Channel Services - Name Service (dNS) * From T11.org FC-GS-2 Rev 5.3 November 1998. */ /* * Common-transport sub-type for Name Server. */ #define FC_NS_SUBTYPE 2 /* fs_ct_hdr.ct_fs_subtype */ /* * Name server Requests. * Note: this is an incomplete list, some unused requests are omitted. */ enum fc_ns_req { FC_NS_GA_NXT = 0x0100, /* get all next */ FC_NS_GI_A = 0x0101, /* get identifiers - scope */ FC_NS_GPN_ID = 0x0112, /* get port name by ID */ FC_NS_GNN_ID = 0x0113, /* get node name by ID */ FC_NS_GSPN_ID = 0x0118, /* get symbolic port name */ FC_NS_GID_PN = 0x0121, /* get ID for port name */ FC_NS_GID_NN = 0x0131, /* get IDs for node name */ FC_NS_GID_FT = 0x0171, /* get IDs by FC4 type */ FC_NS_GPN_FT = 0x0172, /* get port names by FC4 type */ FC_NS_GID_PT = 0x01a1, /* get IDs by port type */ FC_NS_RPN_ID = 0x0212, /* reg port name for ID */ FC_NS_RNN_ID = 0x0213, /* reg node name for ID */ FC_NS_RFT_ID = 0x0217, /* reg FC4 type for ID */ FC_NS_RSPN_ID = 0x0218, /* reg symbolic port name */ FC_NS_RFF_ID = 0x021f, /* reg FC4 Features for ID */ FC_NS_RSNN_NN = 0x0239, /* reg symbolic node name */ }; /* * Port type values. */ enum fc_ns_pt { FC_NS_UNID_PORT = 0x00, /* unidentified */ FC_NS_N_PORT = 0x01, /* N port */ FC_NS_NL_PORT = 0x02, /* NL port */ FC_NS_FNL_PORT = 0x03, /* F/NL port */ FC_NS_NX_PORT = 0x7f, /* Nx port */ FC_NS_F_PORT = 0x81, /* F port */ FC_NS_FL_PORT = 0x82, /* FL port */ FC_NS_E_PORT = 0x84, /* E port */ FC_NS_B_PORT = 0x85, /* B port */ }; /* * Port type object. */ struct fc_ns_pt_obj { __u8 pt_type; }; /* * Port ID object */ struct fc_ns_fid { __u8 fp_flags; /* flags for responses only */ __u8 fp_fid[3]; }; /* * fp_flags in port ID object, for responses only. */ #define FC_NS_FID_LAST 0x80 /* last object */ /* * FC4-types object. */ #define FC_NS_TYPES 256 /* number of possible FC-4 types */ #define FC_NS_BPW 32 /* bits per word in bitmap */ struct fc_ns_fts { __be32 ff_type_map[FC_NS_TYPES / FC_NS_BPW]; /* bitmap of FC-4 types */ }; /* * FC4-features object. */ struct fc_ns_ff { __be32 fd_feat[FC_NS_TYPES * 4 / FC_NS_BPW]; /* 4-bits per FC-type */ }; /* * GID_PT request. */ struct fc_ns_gid_pt { __u8 fn_pt_type; __u8 fn_domain_id_scope; __u8 fn_area_id_scope; __u8 fn_resvd; }; /* * GID_FT or GPN_FT request. */ struct fc_ns_gid_ft { __u8 fn_resvd; __u8 fn_domain_id_scope; __u8 fn_area_id_scope; __u8 fn_fc4_type; }; /* * GPN_FT response. */ struct fc_gpn_ft_resp { __u8 fp_flags; /* see fp_flags definitions above */ __u8 fp_fid[3]; /* port ID */ __be32 fp_resvd; __be64 fp_wwpn; /* port name */ }; /* * GID_PN request */ struct fc_ns_gid_pn { __be64 fn_wwpn; /* port name */ }; /* * GID_PN response or GSPN_ID request */ struct fc_gid_pn_resp { __u8 fp_resvd; __u8 fp_fid[3]; /* port ID */ }; /* * GSPN_ID response */ struct fc_gspn_resp { __u8 fp_name_len; char fp_name[]; }; /* * RFT_ID request - register FC-4 types for ID. */ struct fc_ns_rft_id { struct fc_ns_fid fr_fid; /* port ID object */ struct fc_ns_fts fr_fts; /* FC-4 types object */ }; /* * RPN_ID request - register port name for ID. * RNN_ID request - register node name for ID. */ struct fc_ns_rn_id { struct fc_ns_fid fr_fid; /* port ID object */ __be64 fr_wwn; /* node name or port name */ } __attribute__((__packed__)); /* * RSNN_NN request - register symbolic node name */ struct fc_ns_rsnn { __be64 fr_wwn; /* node name */ __u8 fr_name_len; char fr_name[]; } __attribute__((__packed__)); /* * RSPN_ID request - register symbolic port name */ struct fc_ns_rspn { struct fc_ns_fid fr_fid; /* port ID object */ __u8 fr_name_len; char fr_name[]; } __attribute__((__packed__)); /* * RFF_ID request - register FC-4 Features for ID. */ struct fc_ns_rff_id { struct fc_ns_fid fr_fid; /* port ID object */ __u8 fr_resvd[2]; __u8 fr_feat; /* FC-4 Feature bits */ __u8 fr_type; /* FC-4 type */ } __attribute__((__packed__)); #endif /* _FC_NS_H_ */ scsi/fc/fc_els.h 0000644 00000115256 15146341150 0007513 0 ustar 00 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright(c) 2007 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * Maintained at www.Open-FCoE.org */ #ifndef _FC_ELS_H_ #define _FC_ELS_H_ #include <linux/types.h> #include <asm/byteorder.h> /* * Fibre Channel Switch - Enhanced Link Services definitions. * From T11 FC-LS Rev 1.2 June 7, 2005. */ /* * ELS Command codes - byte 0 of the frame payload */ enum fc_els_cmd { ELS_LS_RJT = 0x01, /* ESL reject */ ELS_LS_ACC = 0x02, /* ESL Accept */ ELS_PLOGI = 0x03, /* N_Port login */ ELS_FLOGI = 0x04, /* F_Port login */ ELS_LOGO = 0x05, /* Logout */ ELS_ABTX = 0x06, /* Abort exchange - obsolete */ ELS_RCS = 0x07, /* read connection status */ ELS_RES = 0x08, /* read exchange status block */ ELS_RSS = 0x09, /* read sequence status block */ ELS_RSI = 0x0a, /* read sequence initiative */ ELS_ESTS = 0x0b, /* establish streaming */ ELS_ESTC = 0x0c, /* estimate credit */ ELS_ADVC = 0x0d, /* advise credit */ ELS_RTV = 0x0e, /* read timeout value */ ELS_RLS = 0x0f, /* read link error status block */ ELS_ECHO = 0x10, /* echo */ ELS_TEST = 0x11, /* test */ ELS_RRQ = 0x12, /* reinstate recovery qualifier */ ELS_REC = 0x13, /* read exchange concise */ ELS_SRR = 0x14, /* sequence retransmission request */ ELS_FPIN = 0x16, /* Fabric Performance Impact Notification */ ELS_EDC = 0x17, /* Exchange Diagnostic Capabilities */ ELS_RDP = 0x18, /* Read Diagnostic Parameters */ ELS_RDF = 0x19, /* Register Diagnostic Functions */ ELS_PRLI = 0x20, /* process login */ ELS_PRLO = 0x21, /* process logout */ ELS_SCN = 0x22, /* state change notification */ ELS_TPLS = 0x23, /* test process login state */ ELS_TPRLO = 0x24, /* third party process logout */ ELS_LCLM = 0x25, /* login control list mgmt (obs) */ ELS_GAID = 0x30, /* get alias_ID */ ELS_FACT = 0x31, /* fabric activate alias_id */ ELS_FDACDT = 0x32, /* fabric deactivate alias_id */ ELS_NACT = 0x33, /* N-port activate alias_id */ ELS_NDACT = 0x34, /* N-port deactivate alias_id */ ELS_QOSR = 0x40, /* quality of service request */ ELS_RVCS = 0x41, /* read virtual circuit status */ ELS_PDISC = 0x50, /* discover N_port service params */ ELS_FDISC = 0x51, /* discover F_port service params */ ELS_ADISC = 0x52, /* discover address */ ELS_RNC = 0x53, /* report node cap (obs) */ ELS_FARP_REQ = 0x54, /* FC ARP request */ ELS_FARP_REPL = 0x55, /* FC ARP reply */ ELS_RPS = 0x56, /* read port status block */ ELS_RPL = 0x57, /* read port list */ ELS_RPBC = 0x58, /* read port buffer condition */ ELS_FAN = 0x60, /* fabric address notification */ ELS_RSCN = 0x61, /* registered state change notification */ ELS_SCR = 0x62, /* state change registration */ ELS_RNFT = 0x63, /* report node FC-4 types */ ELS_CSR = 0x68, /* clock synch. request */ ELS_CSU = 0x69, /* clock synch. update */ ELS_LINIT = 0x70, /* loop initialize */ ELS_LSTS = 0x72, /* loop status */ ELS_RNID = 0x78, /* request node ID data */ ELS_RLIR = 0x79, /* registered link incident report */ ELS_LIRR = 0x7a, /* link incident record registration */ ELS_SRL = 0x7b, /* scan remote loop */ ELS_SBRP = 0x7c, /* set bit-error reporting params */ ELS_RPSC = 0x7d, /* report speed capabilities */ ELS_QSA = 0x7e, /* query security attributes */ ELS_EVFP = 0x7f, /* exchange virt. fabrics params */ ELS_LKA = 0x80, /* link keep-alive */ ELS_AUTH_ELS = 0x90, /* authentication ELS */ }; /* * Initializer useful for decoding table. * Please keep this in sync with the above definitions. */ #define FC_ELS_CMDS_INIT { \ [ELS_LS_RJT] = "LS_RJT", \ [ELS_LS_ACC] = "LS_ACC", \ [ELS_PLOGI] = "PLOGI", \ [ELS_FLOGI] = "FLOGI", \ [ELS_LOGO] = "LOGO", \ [ELS_ABTX] = "ABTX", \ [ELS_RCS] = "RCS", \ [ELS_RES] = "RES", \ [ELS_RSS] = "RSS", \ [ELS_RSI] = "RSI", \ [ELS_ESTS] = "ESTS", \ [ELS_ESTC] = "ESTC", \ [ELS_ADVC] = "ADVC", \ [ELS_RTV] = "RTV", \ [ELS_RLS] = "RLS", \ [ELS_ECHO] = "ECHO", \ [ELS_TEST] = "TEST", \ [ELS_RRQ] = "RRQ", \ [ELS_REC] = "REC", \ [ELS_SRR] = "SRR", \ [ELS_FPIN] = "FPIN", \ [ELS_EDC] = "EDC", \ [ELS_RDP] = "RDP", \ [ELS_RDF] = "RDF", \ [ELS_PRLI] = "PRLI", \ [ELS_PRLO] = "PRLO", \ [ELS_SCN] = "SCN", \ [ELS_TPLS] = "TPLS", \ [ELS_TPRLO] = "TPRLO", \ [ELS_LCLM] = "LCLM", \ [ELS_GAID] = "GAID", \ [ELS_FACT] = "FACT", \ [ELS_FDACDT] = "FDACDT", \ [ELS_NACT] = "NACT", \ [ELS_NDACT] = "NDACT", \ [ELS_QOSR] = "QOSR", \ [ELS_RVCS] = "RVCS", \ [ELS_PDISC] = "PDISC", \ [ELS_FDISC] = "FDISC", \ [ELS_ADISC] = "ADISC", \ [ELS_RNC] = "RNC", \ [ELS_FARP_REQ] = "FARP_REQ", \ [ELS_FARP_REPL] = "FARP_REPL", \ [ELS_RPS] = "RPS", \ [ELS_RPL] = "RPL", \ [ELS_RPBC] = "RPBC", \ [ELS_FAN] = "FAN", \ [ELS_RSCN] = "RSCN", \ [ELS_SCR] = "SCR", \ [ELS_RNFT] = "RNFT", \ [ELS_CSR] = "CSR", \ [ELS_CSU] = "CSU", \ [ELS_LINIT] = "LINIT", \ [ELS_LSTS] = "LSTS", \ [ELS_RNID] = "RNID", \ [ELS_RLIR] = "RLIR", \ [ELS_LIRR] = "LIRR", \ [ELS_SRL] = "SRL", \ [ELS_SBRP] = "SBRP", \ [ELS_RPSC] = "RPSC", \ [ELS_QSA] = "QSA", \ [ELS_EVFP] = "EVFP", \ [ELS_LKA] = "LKA", \ [ELS_AUTH_ELS] = "AUTH_ELS", \ } /* * LS_ACC payload. */ struct fc_els_ls_acc { __u8 la_cmd; /* command code ELS_LS_ACC */ __u8 la_resv[3]; /* reserved */ }; /* * ELS reject payload. */ struct fc_els_ls_rjt { __u8 er_cmd; /* command code ELS_LS_RJT */ __u8 er_resv[4]; /* reserved must be zero */ __u8 er_reason; /* reason (enum fc_els_rjt_reason below) */ __u8 er_explan; /* explanation (enum fc_els_rjt_explan below) */ __u8 er_vendor; /* vendor specific code */ }; /* * ELS reject reason codes (er_reason). */ enum fc_els_rjt_reason { ELS_RJT_NONE = 0, /* no reject - not to be sent */ ELS_RJT_INVAL = 0x01, /* invalid ELS command code */ ELS_RJT_LOGIC = 0x03, /* logical error */ ELS_RJT_BUSY = 0x05, /* logical busy */ ELS_RJT_PROT = 0x07, /* protocol error */ ELS_RJT_UNAB = 0x09, /* unable to perform command request */ ELS_RJT_UNSUP = 0x0b, /* command not supported */ ELS_RJT_INPROG = 0x0e, /* command already in progress */ ELS_RJT_FIP = 0x20, /* FIP error */ ELS_RJT_VENDOR = 0xff, /* vendor specific error */ }; /* * reason code explanation (er_explan). */ enum fc_els_rjt_explan { ELS_EXPL_NONE = 0x00, /* No additional explanation */ ELS_EXPL_SPP_OPT_ERR = 0x01, /* service parameter error - options */ ELS_EXPL_SPP_ICTL_ERR = 0x03, /* service parm error - initiator ctl */ ELS_EXPL_AH = 0x11, /* invalid association header */ ELS_EXPL_AH_REQ = 0x13, /* association_header required */ ELS_EXPL_SID = 0x15, /* invalid originator S_ID */ ELS_EXPL_OXID_RXID = 0x17, /* invalid OX_ID-RX_ID combination */ ELS_EXPL_INPROG = 0x19, /* Request already in progress */ ELS_EXPL_PLOGI_REQD = 0x1e, /* N_Port login required */ ELS_EXPL_INSUF_RES = 0x29, /* insufficient resources */ ELS_EXPL_UNAB_DATA = 0x2a, /* unable to supply requested data */ ELS_EXPL_UNSUPR = 0x2c, /* Request not supported */ ELS_EXPL_INV_LEN = 0x2d, /* Invalid payload length */ ELS_EXPL_NOT_NEIGHBOR = 0x62, /* VN2VN_Port not in neighbor set */ /* TBD - above definitions incomplete */ }; /* * Link Service TLV Descriptor Tag Values */ enum fc_ls_tlv_dtag { ELS_DTAG_LS_REQ_INFO = 0x00000001, /* Link Service Request Information Descriptor */ ELS_DTAG_LNK_FAULT_CAP = 0x0001000D, /* Link Fault Capability Descriptor */ ELS_DTAG_CG_SIGNAL_CAP = 0x0001000F, /* Congestion Signaling Capability Descriptor */ ELS_DTAG_LNK_INTEGRITY = 0x00020001, /* Link Integrity Notification Descriptor */ ELS_DTAG_DELIVERY = 0x00020002, /* Delivery Notification Descriptor */ ELS_DTAG_PEER_CONGEST = 0x00020003, /* Peer Congestion Notification Descriptor */ ELS_DTAG_CONGESTION = 0x00020004, /* Congestion Notification Descriptor */ ELS_DTAG_FPIN_REGISTER = 0x00030001, /* FPIN Registration Descriptor */ }; /* * Initializer useful for decoding table. * Please keep this in sync with the above definitions. */ #define FC_LS_TLV_DTAG_INIT { \ { ELS_DTAG_LS_REQ_INFO, "Link Service Request Information" }, \ { ELS_DTAG_LNK_FAULT_CAP, "Link Fault Capability" }, \ { ELS_DTAG_CG_SIGNAL_CAP, "Congestion Signaling Capability" }, \ { ELS_DTAG_LNK_INTEGRITY, "Link Integrity Notification" }, \ { ELS_DTAG_DELIVERY, "Delivery Notification Present" }, \ { ELS_DTAG_PEER_CONGEST, "Peer Congestion Notification" }, \ { ELS_DTAG_CONGESTION, "Congestion Notification" }, \ { ELS_DTAG_FPIN_REGISTER, "FPIN Registration" }, \ } /* * Generic Link Service TLV Descriptor format * * This structure, as it defines no payload, will also be referred to * as the "tlv header" - which contains the tag and len fields. */ struct fc_tlv_desc { __be32 desc_tag; /* Notification Descriptor Tag */ __be32 desc_len; /* Length of Descriptor (in bytes). * Size of descriptor excluding * desc_tag and desc_len fields. */ __u8 desc_value[0]; /* Descriptor Value */ }; /* Descriptor tag and len fields are considered the mandatory header * for a descriptor */ #define FC_TLV_DESC_HDR_SZ sizeof(struct fc_tlv_desc) /* * Macro, used when initializing payloads, to return the descriptor length. * Length is size of descriptor minus the tag and len fields. */ #define FC_TLV_DESC_LENGTH_FROM_SZ(desc) \ (sizeof(desc) - FC_TLV_DESC_HDR_SZ) /* Macro, used on received payloads, to return the descriptor length */ #define FC_TLV_DESC_SZ_FROM_LENGTH(tlv) \ (__be32_to_cpu((tlv)->desc_len) + FC_TLV_DESC_HDR_SZ) /* * This helper is used to walk descriptors in a descriptor list. * Given the address of the current descriptor, which minimally contains a * tag and len field, calculate the address of the next descriptor based * on the len field. */ static __inline__ void *fc_tlv_next_desc(void *desc) { struct fc_tlv_desc *tlv = desc; return (desc + FC_TLV_DESC_SZ_FROM_LENGTH(tlv)); } /* * Link Service Request Information Descriptor */ struct fc_els_lsri_desc { __be32 desc_tag; /* descriptor tag (0x0000 0001) */ __be32 desc_len; /* Length of Descriptor (in bytes) (4). * Size of descriptor excluding * desc_tag and desc_len fields. */ struct { __u8 cmd; /* ELS cmd byte */ __u8 bytes[3]; /* bytes 1..3 */ } rqst_w0; /* Request word 0 */ }; /* * Common service parameters (N ports). */ struct fc_els_csp { __u8 sp_hi_ver; /* highest version supported (obs.) */ __u8 sp_lo_ver; /* highest version supported (obs.) */ __be16 sp_bb_cred; /* buffer-to-buffer credits */ __be16 sp_features; /* common feature flags */ __be16 sp_bb_data; /* b-b state number and data field sz */ union { struct { __be16 _sp_tot_seq; /* total concurrent sequences */ __be16 _sp_rel_off; /* rel. offset by info cat */ } sp_plogi; struct { __be32 _sp_r_a_tov; /* resource alloc. timeout msec */ } sp_flogi_acc; } sp_u; __be32 sp_e_d_tov; /* error detect timeout value */ }; #define sp_tot_seq sp_u.sp_plogi._sp_tot_seq #define sp_rel_off sp_u.sp_plogi._sp_rel_off #define sp_r_a_tov sp_u.sp_flogi_acc._sp_r_a_tov #define FC_SP_BB_DATA_MASK 0xfff /* mask for data field size in sp_bb_data */ /* * Minimum and maximum values for max data field size in service parameters. */ #define FC_SP_MIN_MAX_PAYLOAD FC_MIN_MAX_PAYLOAD #define FC_SP_MAX_MAX_PAYLOAD FC_MAX_PAYLOAD /* * sp_features */ #define FC_SP_FT_NPIV 0x8000 /* multiple N_Port_ID support (FLOGI) */ #define FC_SP_FT_CIRO 0x8000 /* continuously increasing rel off (PLOGI) */ #define FC_SP_FT_CLAD 0x8000 /* clean address (in FLOGI LS_ACC) */ #define FC_SP_FT_RAND 0x4000 /* random relative offset */ #define FC_SP_FT_VAL 0x2000 /* valid vendor version level */ #define FC_SP_FT_NPIV_ACC 0x2000 /* NPIV assignment (FLOGI LS_ACC) */ #define FC_SP_FT_FPORT 0x1000 /* F port (1) vs. N port (0) */ #define FC_SP_FT_ABB 0x0800 /* alternate BB_credit management */ #define FC_SP_FT_EDTR 0x0400 /* E_D_TOV Resolution is nanoseconds */ #define FC_SP_FT_MCAST 0x0200 /* multicast */ #define FC_SP_FT_BCAST 0x0100 /* broadcast */ #define FC_SP_FT_HUNT 0x0080 /* hunt group */ #define FC_SP_FT_SIMP 0x0040 /* dedicated simplex */ #define FC_SP_FT_SEC 0x0020 /* reserved for security */ #define FC_SP_FT_CSYN 0x0010 /* clock synch. supported */ #define FC_SP_FT_RTTOV 0x0008 /* R_T_TOV value 100 uS, else 100 mS */ #define FC_SP_FT_HALF 0x0004 /* dynamic half duplex */ #define FC_SP_FT_SEQC 0x0002 /* SEQ_CNT */ #define FC_SP_FT_PAYL 0x0001 /* FLOGI payload length 256, else 116 */ /* * Class-specific service parameters. */ struct fc_els_cssp { __be16 cp_class; /* class flags */ __be16 cp_init; /* initiator flags */ __be16 cp_recip; /* recipient flags */ __be16 cp_rdfs; /* receive data field size */ __be16 cp_con_seq; /* concurrent sequences */ __be16 cp_ee_cred; /* N-port end-to-end credit */ __u8 cp_resv1; /* reserved */ __u8 cp_open_seq; /* open sequences per exchange */ __u8 _cp_resv2[2]; /* reserved */ }; /* * cp_class flags. */ #define FC_CPC_VALID 0x8000 /* class valid */ #define FC_CPC_IMIX 0x4000 /* intermix mode */ #define FC_CPC_SEQ 0x0800 /* sequential delivery */ #define FC_CPC_CAMP 0x0200 /* camp-on */ #define FC_CPC_PRI 0x0080 /* priority */ /* * cp_init flags. * (TBD: not all flags defined here). */ #define FC_CPI_CSYN 0x0010 /* clock synch. capable */ /* * cp_recip flags. */ #define FC_CPR_CSYN 0x0008 /* clock synch. capable */ /* * NFC_ELS_FLOGI: Fabric login request. * NFC_ELS_PLOGI: Port login request (same format). */ struct fc_els_flogi { __u8 fl_cmd; /* command */ __u8 _fl_resvd[3]; /* must be zero */ struct fc_els_csp fl_csp; /* common service parameters */ __be64 fl_wwpn; /* port name */ __be64 fl_wwnn; /* node name */ struct fc_els_cssp fl_cssp[4]; /* class 1-4 service parameters */ __u8 fl_vend[16]; /* vendor version level */ } __attribute__((__packed__)); /* * Process login service parameter page. */ struct fc_els_spp { __u8 spp_type; /* type code or common service params */ __u8 spp_type_ext; /* type code extension */ __u8 spp_flags; __u8 _spp_resvd; __be32 spp_orig_pa; /* originator process associator */ __be32 spp_resp_pa; /* responder process associator */ __be32 spp_params; /* service parameters */ }; /* * spp_flags. */ #define FC_SPP_OPA_VAL 0x80 /* originator proc. assoc. valid */ #define FC_SPP_RPA_VAL 0x40 /* responder proc. assoc. valid */ #define FC_SPP_EST_IMG_PAIR 0x20 /* establish image pair */ #define FC_SPP_RESP_MASK 0x0f /* mask for response code (below) */ /* * SPP response code in spp_flags - lower 4 bits. */ enum fc_els_spp_resp { FC_SPP_RESP_ACK = 1, /* request executed */ FC_SPP_RESP_RES = 2, /* unable due to lack of resources */ FC_SPP_RESP_INIT = 3, /* initialization not complete */ FC_SPP_RESP_NO_PA = 4, /* unknown process associator */ FC_SPP_RESP_CONF = 5, /* configuration precludes image pair */ FC_SPP_RESP_COND = 6, /* request completed conditionally */ FC_SPP_RESP_MULT = 7, /* unable to handle multiple SPPs */ FC_SPP_RESP_INVL = 8, /* SPP is invalid */ }; /* * ELS_RRQ - Reinstate Recovery Qualifier */ struct fc_els_rrq { __u8 rrq_cmd; /* command (0x12) */ __u8 rrq_zero[3]; /* specified as zero - part of cmd */ __u8 rrq_resvd; /* reserved */ __u8 rrq_s_id[3]; /* originator FID */ __be16 rrq_ox_id; /* originator exchange ID */ __be16 rrq_rx_id; /* responders exchange ID */ }; /* * ELS_REC - Read exchange concise. */ struct fc_els_rec { __u8 rec_cmd; /* command (0x13) */ __u8 rec_zero[3]; /* specified as zero - part of cmd */ __u8 rec_resvd; /* reserved */ __u8 rec_s_id[3]; /* originator FID */ __be16 rec_ox_id; /* originator exchange ID */ __be16 rec_rx_id; /* responders exchange ID */ }; /* * ELS_REC LS_ACC payload. */ struct fc_els_rec_acc { __u8 reca_cmd; /* accept (0x02) */ __u8 reca_zero[3]; /* specified as zero - part of cmd */ __be16 reca_ox_id; /* originator exchange ID */ __be16 reca_rx_id; /* responders exchange ID */ __u8 reca_resvd1; /* reserved */ __u8 reca_ofid[3]; /* originator FID */ __u8 reca_resvd2; /* reserved */ __u8 reca_rfid[3]; /* responder FID */ __be32 reca_fc4value; /* FC4 value */ __be32 reca_e_stat; /* ESB (exchange status block) status */ }; /* * ELS_PRLI - Process login request and response. */ struct fc_els_prli { __u8 prli_cmd; /* command */ __u8 prli_spp_len; /* length of each serv. parm. page */ __be16 prli_len; /* length of entire payload */ /* service parameter pages follow */ }; /* * ELS_PRLO - Process logout request and response. */ struct fc_els_prlo { __u8 prlo_cmd; /* command */ __u8 prlo_obs; /* obsolete, but shall be set to 10h */ __be16 prlo_len; /* payload length */ }; /* * ELS_ADISC payload */ struct fc_els_adisc { __u8 adisc_cmd; __u8 adisc_resv[3]; __u8 adisc_resv1; __u8 adisc_hard_addr[3]; __be64 adisc_wwpn; __be64 adisc_wwnn; __u8 adisc_resv2; __u8 adisc_port_id[3]; } __attribute__((__packed__)); /* * ELS_LOGO - process or fabric logout. */ struct fc_els_logo { __u8 fl_cmd; /* command code */ __u8 fl_zero[3]; /* specified as zero - part of cmd */ __u8 fl_resvd; /* reserved */ __u8 fl_n_port_id[3];/* N port ID */ __be64 fl_n_port_wwn; /* port name */ }; /* * ELS_RTV - read timeout value. */ struct fc_els_rtv { __u8 rtv_cmd; /* command code 0x0e */ __u8 rtv_zero[3]; /* specified as zero - part of cmd */ }; /* * LS_ACC for ELS_RTV - read timeout value. */ struct fc_els_rtv_acc { __u8 rtv_cmd; /* command code 0x02 */ __u8 rtv_zero[3]; /* specified as zero - part of cmd */ __be32 rtv_r_a_tov; /* resource allocation timeout value */ __be32 rtv_e_d_tov; /* error detection timeout value */ __be32 rtv_toq; /* timeout qualifier (see below) */ }; /* * rtv_toq bits. */ #define FC_ELS_RTV_EDRES (1 << 26) /* E_D_TOV resolution is nS else mS */ #define FC_ELS_RTV_RTTOV (1 << 19) /* R_T_TOV is 100 uS else 100 mS */ /* * ELS_SCR - state change registration payload. */ struct fc_els_scr { __u8 scr_cmd; /* command code */ __u8 scr_resv[6]; /* reserved */ __u8 scr_reg_func; /* registration function (see below) */ }; enum fc_els_scr_func { ELS_SCRF_FAB = 1, /* fabric-detected registration */ ELS_SCRF_NPORT = 2, /* Nx_Port-detected registration */ ELS_SCRF_FULL = 3, /* full registration */ ELS_SCRF_CLEAR = 255, /* remove any current registrations */ }; /* * ELS_RSCN - registered state change notification payload. */ struct fc_els_rscn { __u8 rscn_cmd; /* RSCN opcode (0x61) */ __u8 rscn_page_len; /* page length (4) */ __be16 rscn_plen; /* payload length including this word */ /* followed by 4-byte generic affected Port_ID pages */ }; struct fc_els_rscn_page { __u8 rscn_page_flags; /* event and address format */ __u8 rscn_fid[3]; /* fabric ID */ }; #define ELS_RSCN_EV_QUAL_BIT 2 /* shift count for event qualifier */ #define ELS_RSCN_EV_QUAL_MASK 0xf /* mask for event qualifier */ #define ELS_RSCN_ADDR_FMT_BIT 0 /* shift count for address format */ #define ELS_RSCN_ADDR_FMT_MASK 0x3 /* mask for address format */ enum fc_els_rscn_ev_qual { ELS_EV_QUAL_NONE = 0, /* unspecified */ ELS_EV_QUAL_NS_OBJ = 1, /* changed name server object */ ELS_EV_QUAL_PORT_ATTR = 2, /* changed port attribute */ ELS_EV_QUAL_SERV_OBJ = 3, /* changed service object */ ELS_EV_QUAL_SW_CONFIG = 4, /* changed switch configuration */ ELS_EV_QUAL_REM_OBJ = 5, /* removed object */ }; enum fc_els_rscn_addr_fmt { ELS_ADDR_FMT_PORT = 0, /* rscn_fid is a port address */ ELS_ADDR_FMT_AREA = 1, /* rscn_fid is a area address */ ELS_ADDR_FMT_DOM = 2, /* rscn_fid is a domain address */ ELS_ADDR_FMT_FAB = 3, /* anything on fabric may have changed */ }; /* * ELS_RNID - request Node ID. */ struct fc_els_rnid { __u8 rnid_cmd; /* RNID opcode (0x78) */ __u8 rnid_resv[3]; /* reserved */ __u8 rnid_fmt; /* data format */ __u8 rnid_resv2[3]; /* reserved */ }; /* * Node Identification Data formats (rnid_fmt) */ enum fc_els_rnid_fmt { ELS_RNIDF_NONE = 0, /* no specific identification data */ ELS_RNIDF_GEN = 0xdf, /* general topology discovery format */ }; /* * ELS_RNID response. */ struct fc_els_rnid_resp { __u8 rnid_cmd; /* response code (LS_ACC) */ __u8 rnid_resv[3]; /* reserved */ __u8 rnid_fmt; /* data format */ __u8 rnid_cid_len; /* common ID data length */ __u8 rnid_resv2; /* reserved */ __u8 rnid_sid_len; /* specific ID data length */ }; struct fc_els_rnid_cid { __be64 rnid_wwpn; /* N port name */ __be64 rnid_wwnn; /* node name */ }; struct fc_els_rnid_gen { __u8 rnid_vend_id[16]; /* vendor-unique ID */ __be32 rnid_atype; /* associated type (see below) */ __be32 rnid_phys_port; /* physical port number */ __be32 rnid_att_nodes; /* number of attached nodes */ __u8 rnid_node_mgmt; /* node management (see below) */ __u8 rnid_ip_ver; /* IP version (see below) */ __be16 rnid_prot_port; /* UDP / TCP port number */ __be32 rnid_ip_addr[4]; /* IP address */ __u8 rnid_resvd[2]; /* reserved */ __be16 rnid_vend_spec; /* vendor-specific field */ }; enum fc_els_rnid_atype { ELS_RNIDA_UNK = 0x01, /* unknown */ ELS_RNIDA_OTHER = 0x02, /* none of the following */ ELS_RNIDA_HUB = 0x03, ELS_RNIDA_SWITCH = 0x04, ELS_RNIDA_GATEWAY = 0x05, ELS_RNIDA_CONV = 0x06, /* Obsolete, do not use this value */ ELS_RNIDA_HBA = 0x07, /* Obsolete, do not use this value */ ELS_RNIDA_PROXY = 0x08, /* Obsolete, do not use this value */ ELS_RNIDA_STORAGE = 0x09, ELS_RNIDA_HOST = 0x0a, ELS_RNIDA_SUBSYS = 0x0b, /* storage subsystem (e.g., RAID) */ ELS_RNIDA_ACCESS = 0x0e, /* access device (e.g. media changer) */ ELS_RNIDA_NAS = 0x11, /* NAS server */ ELS_RNIDA_BRIDGE = 0x12, /* bridge */ ELS_RNIDA_VIRT = 0x13, /* virtualization device */ ELS_RNIDA_MF = 0xff, /* multifunction device (bits below) */ ELS_RNIDA_MF_HUB = 1UL << 31, /* hub */ ELS_RNIDA_MF_SW = 1UL << 30, /* switch */ ELS_RNIDA_MF_GW = 1UL << 29, /* gateway */ ELS_RNIDA_MF_ST = 1UL << 28, /* storage */ ELS_RNIDA_MF_HOST = 1UL << 27, /* host */ ELS_RNIDA_MF_SUB = 1UL << 26, /* storage subsystem */ ELS_RNIDA_MF_ACC = 1UL << 25, /* storage access dev */ ELS_RNIDA_MF_WDM = 1UL << 24, /* wavelength division mux */ ELS_RNIDA_MF_NAS = 1UL << 23, /* NAS server */ ELS_RNIDA_MF_BR = 1UL << 22, /* bridge */ ELS_RNIDA_MF_VIRT = 1UL << 21, /* virtualization device */ }; enum fc_els_rnid_mgmt { ELS_RNIDM_SNMP = 0, ELS_RNIDM_TELNET = 1, ELS_RNIDM_HTTP = 2, ELS_RNIDM_HTTPS = 3, ELS_RNIDM_XML = 4, /* HTTP + XML */ }; enum fc_els_rnid_ipver { ELS_RNIDIP_NONE = 0, /* no IP support or node mgmt. */ ELS_RNIDIP_V4 = 1, /* IPv4 */ ELS_RNIDIP_V6 = 2, /* IPv6 */ }; /* * ELS RPL - Read Port List. */ struct fc_els_rpl { __u8 rpl_cmd; /* command */ __u8 rpl_resv[5]; /* reserved - must be zero */ __be16 rpl_max_size; /* maximum response size or zero */ __u8 rpl_resv1; /* reserved - must be zero */ __u8 rpl_index[3]; /* starting index */ }; /* * Port number block in RPL response. */ struct fc_els_pnb { __be32 pnb_phys_pn; /* physical port number */ __u8 pnb_resv; /* reserved */ __u8 pnb_port_id[3]; /* port ID */ __be64 pnb_wwpn; /* port name */ }; /* * RPL LS_ACC response. */ struct fc_els_rpl_resp { __u8 rpl_cmd; /* ELS_LS_ACC */ __u8 rpl_resv1; /* reserved - must be zero */ __be16 rpl_plen; /* payload length */ __u8 rpl_resv2; /* reserved - must be zero */ __u8 rpl_llen[3]; /* list length */ __u8 rpl_resv3; /* reserved - must be zero */ __u8 rpl_index[3]; /* starting index */ struct fc_els_pnb rpl_pnb[1]; /* variable number of PNBs */ }; /* * Link Error Status Block. */ struct fc_els_lesb { __be32 lesb_link_fail; /* link failure count */ __be32 lesb_sync_loss; /* loss of synchronization count */ __be32 lesb_sig_loss; /* loss of signal count */ __be32 lesb_prim_err; /* primitive sequence error count */ __be32 lesb_inv_word; /* invalid transmission word count */ __be32 lesb_inv_crc; /* invalid CRC count */ }; /* * ELS RPS - Read Port Status Block request. */ struct fc_els_rps { __u8 rps_cmd; /* command */ __u8 rps_resv[2]; /* reserved - must be zero */ __u8 rps_flag; /* flag - see below */ __be64 rps_port_spec; /* port selection */ }; enum fc_els_rps_flag { FC_ELS_RPS_DID = 0x00, /* port identified by D_ID of req. */ FC_ELS_RPS_PPN = 0x01, /* port_spec is physical port number */ FC_ELS_RPS_WWPN = 0x02, /* port_spec is port WWN */ }; /* * ELS RPS LS_ACC response. */ struct fc_els_rps_resp { __u8 rps_cmd; /* command - LS_ACC */ __u8 rps_resv[2]; /* reserved - must be zero */ __u8 rps_flag; /* flag - see below */ __u8 rps_resv2[2]; /* reserved */ __be16 rps_status; /* port status - see below */ struct fc_els_lesb rps_lesb; /* link error status block */ }; enum fc_els_rps_resp_flag { FC_ELS_RPS_LPEV = 0x01, /* L_port extension valid */ }; enum fc_els_rps_resp_status { FC_ELS_RPS_PTP = 1 << 5, /* point-to-point connection */ FC_ELS_RPS_LOOP = 1 << 4, /* loop mode */ FC_ELS_RPS_FAB = 1 << 3, /* fabric present */ FC_ELS_RPS_NO_SIG = 1 << 2, /* loss of signal */ FC_ELS_RPS_NO_SYNC = 1 << 1, /* loss of synchronization */ FC_ELS_RPS_RESET = 1 << 0, /* in link reset protocol */ }; /* * ELS LIRR - Link Incident Record Registration request. */ struct fc_els_lirr { __u8 lirr_cmd; /* command */ __u8 lirr_resv[3]; /* reserved - must be zero */ __u8 lirr_func; /* registration function */ __u8 lirr_fmt; /* FC-4 type of RLIR requested */ __u8 lirr_resv2[2]; /* reserved - must be zero */ }; enum fc_els_lirr_func { ELS_LIRR_SET_COND = 0x01, /* set - conditionally receive */ ELS_LIRR_SET_UNCOND = 0x02, /* set - unconditionally receive */ ELS_LIRR_CLEAR = 0xff /* clear registration */ }; /* * ELS SRL - Scan Remote Loop request. */ struct fc_els_srl { __u8 srl_cmd; /* command */ __u8 srl_resv[3]; /* reserved - must be zero */ __u8 srl_flag; /* flag - see below */ __u8 srl_flag_param[3]; /* flag parameter */ }; enum fc_els_srl_flag { FC_ELS_SRL_ALL = 0x00, /* scan all FL ports */ FC_ELS_SRL_ONE = 0x01, /* scan specified loop */ FC_ELS_SRL_EN_PER = 0x02, /* enable periodic scanning (param) */ FC_ELS_SRL_DIS_PER = 0x03, /* disable periodic scanning */ }; /* * ELS RLS - Read Link Error Status Block request. */ struct fc_els_rls { __u8 rls_cmd; /* command */ __u8 rls_resv[4]; /* reserved - must be zero */ __u8 rls_port_id[3]; /* port ID */ }; /* * ELS RLS LS_ACC Response. */ struct fc_els_rls_resp { __u8 rls_cmd; /* ELS_LS_ACC */ __u8 rls_resv[3]; /* reserved - must be zero */ struct fc_els_lesb rls_lesb; /* link error status block */ }; /* * ELS RLIR - Registered Link Incident Report. * This is followed by the CLIR and the CLID, described below. */ struct fc_els_rlir { __u8 rlir_cmd; /* command */ __u8 rlir_resv[3]; /* reserved - must be zero */ __u8 rlir_fmt; /* format (FC4-type if type specific) */ __u8 rlir_clr_len; /* common link incident record length */ __u8 rlir_cld_len; /* common link incident desc. length */ __u8 rlir_slr_len; /* spec. link incident record length */ }; /* * CLIR - Common Link Incident Record Data. - Sent via RLIR. */ struct fc_els_clir { __be64 clir_wwpn; /* incident port name */ __be64 clir_wwnn; /* incident port node name */ __u8 clir_port_type; /* incident port type */ __u8 clir_port_id[3]; /* incident port ID */ __be64 clir_conn_wwpn; /* connected port name */ __be64 clir_conn_wwnn; /* connected node name */ __be64 clir_fab_name; /* fabric name */ __be32 clir_phys_port; /* physical port number */ __be32 clir_trans_id; /* transaction ID */ __u8 clir_resv[3]; /* reserved */ __u8 clir_ts_fmt; /* time stamp format */ __be64 clir_timestamp; /* time stamp */ }; /* * CLIR clir_ts_fmt - time stamp format values. */ enum fc_els_clir_ts_fmt { ELS_CLIR_TS_UNKNOWN = 0, /* time stamp field unknown */ ELS_CLIR_TS_SEC_FRAC = 1, /* time in seconds and fractions */ ELS_CLIR_TS_CSU = 2, /* time in clock synch update format */ }; /* * Common Link Incident Descriptor - sent via RLIR. */ struct fc_els_clid { __u8 clid_iq; /* incident qualifier flags */ __u8 clid_ic; /* incident code */ __be16 clid_epai; /* domain/area of ISL */ }; /* * CLID incident qualifier flags. */ enum fc_els_clid_iq { ELS_CLID_SWITCH = 0x20, /* incident port is a switch node */ ELS_CLID_E_PORT = 0x10, /* incident is an ISL (E) port */ ELS_CLID_SEV_MASK = 0x0c, /* severity 2-bit field mask */ ELS_CLID_SEV_INFO = 0x00, /* report is informational */ ELS_CLID_SEV_INOP = 0x08, /* link not operational */ ELS_CLID_SEV_DEG = 0x04, /* link degraded but operational */ ELS_CLID_LASER = 0x02, /* subassembly is a laser */ ELS_CLID_FRU = 0x01, /* format can identify a FRU */ }; /* * CLID incident code. */ enum fc_els_clid_ic { ELS_CLID_IC_IMPL = 1, /* implicit incident */ ELS_CLID_IC_BER = 2, /* bit-error-rate threshold exceeded */ ELS_CLID_IC_LOS = 3, /* loss of synch or signal */ ELS_CLID_IC_NOS = 4, /* non-operational primitive sequence */ ELS_CLID_IC_PST = 5, /* primitive sequence timeout */ ELS_CLID_IC_INVAL = 6, /* invalid primitive sequence */ ELS_CLID_IC_LOOP_TO = 7, /* loop initialization time out */ ELS_CLID_IC_LIP = 8, /* receiving LIP */ }; /* * Link Integrity event types */ enum fc_fpin_li_event_types { FPIN_LI_UNKNOWN = 0x0, FPIN_LI_LINK_FAILURE = 0x1, FPIN_LI_LOSS_OF_SYNC = 0x2, FPIN_LI_LOSS_OF_SIG = 0x3, FPIN_LI_PRIM_SEQ_ERR = 0x4, FPIN_LI_INVALID_TX_WD = 0x5, FPIN_LI_INVALID_CRC = 0x6, FPIN_LI_DEVICE_SPEC = 0xF, }; /* * Initializer useful for decoding table. * Please keep this in sync with the above definitions. */ #define FC_FPIN_LI_EVT_TYPES_INIT { \ { FPIN_LI_UNKNOWN, "Unknown" }, \ { FPIN_LI_LINK_FAILURE, "Link Failure" }, \ { FPIN_LI_LOSS_OF_SYNC, "Loss of Synchronization" }, \ { FPIN_LI_LOSS_OF_SIG, "Loss of Signal" }, \ { FPIN_LI_PRIM_SEQ_ERR, "Primitive Sequence Protocol Error" }, \ { FPIN_LI_INVALID_TX_WD, "Invalid Transmission Word" }, \ { FPIN_LI_INVALID_CRC, "Invalid CRC" }, \ { FPIN_LI_DEVICE_SPEC, "Device Specific" }, \ } /* * Delivery event types */ enum fc_fpin_deli_event_types { FPIN_DELI_UNKNOWN = 0x0, FPIN_DELI_TIMEOUT = 0x1, FPIN_DELI_UNABLE_TO_ROUTE = 0x2, FPIN_DELI_DEVICE_SPEC = 0xF, }; /* * Initializer useful for decoding table. * Please keep this in sync with the above definitions. */ #define FC_FPIN_DELI_EVT_TYPES_INIT { \ { FPIN_DELI_UNKNOWN, "Unknown" }, \ { FPIN_DELI_TIMEOUT, "Timeout" }, \ { FPIN_DELI_UNABLE_TO_ROUTE, "Unable to Route" }, \ { FPIN_DELI_DEVICE_SPEC, "Device Specific" }, \ } /* * Congestion event types */ enum fc_fpin_congn_event_types { FPIN_CONGN_CLEAR = 0x0, FPIN_CONGN_LOST_CREDIT = 0x1, FPIN_CONGN_CREDIT_STALL = 0x2, FPIN_CONGN_OVERSUBSCRIPTION = 0x3, FPIN_CONGN_DEVICE_SPEC = 0xF, }; /* * Initializer useful for decoding table. * Please keep this in sync with the above definitions. */ #define FC_FPIN_CONGN_EVT_TYPES_INIT { \ { FPIN_CONGN_CLEAR, "Clear" }, \ { FPIN_CONGN_LOST_CREDIT, "Lost Credit" }, \ { FPIN_CONGN_CREDIT_STALL, "Credit Stall" }, \ { FPIN_CONGN_OVERSUBSCRIPTION, "Oversubscription" }, \ { FPIN_CONGN_DEVICE_SPEC, "Device Specific" }, \ } enum fc_fpin_congn_severity_types { FPIN_CONGN_SEVERITY_WARNING = 0xF1, FPIN_CONGN_SEVERITY_ERROR = 0xF7, }; /* * Link Integrity Notification Descriptor */ struct fc_fn_li_desc { __be32 desc_tag; /* Descriptor Tag (0x00020001) */ __be32 desc_len; /* Length of Descriptor (in bytes). * Size of descriptor excluding * desc_tag and desc_len fields. */ __be64 detecting_wwpn; /* Port Name that detected event */ __be64 attached_wwpn; /* Port Name of device attached to * detecting Port Name */ __be16 event_type; /* see enum fc_fpin_li_event_types */ __be16 event_modifier; /* Implementation specific value * describing the event type */ __be32 event_threshold;/* duration in ms of the link * integrity detection cycle */ __be32 event_count; /* minimum number of event * occurrences during the event * threshold to caause the LI event */ __be32 pname_count; /* number of portname_list elements */ __be64 pname_list[0]; /* list of N_Port_Names accessible * through the attached port */ }; /* * Delivery Notification Descriptor */ struct fc_fn_deli_desc { __be32 desc_tag; /* Descriptor Tag (0x00020002) */ __be32 desc_len; /* Length of Descriptor (in bytes). * Size of descriptor excluding * desc_tag and desc_len fields. */ __be64 detecting_wwpn; /* Port Name that detected event */ __be64 attached_wwpn; /* Port Name of device attached to * detecting Port Name */ __be32 deli_reason_code;/* see enum fc_fpin_deli_event_types */ }; /* * Peer Congestion Notification Descriptor */ struct fc_fn_peer_congn_desc { __be32 desc_tag; /* Descriptor Tag (0x00020003) */ __be32 desc_len; /* Length of Descriptor (in bytes). * Size of descriptor excluding * desc_tag and desc_len fields. */ __be64 detecting_wwpn; /* Port Name that detected event */ __be64 attached_wwpn; /* Port Name of device attached to * detecting Port Name */ __be16 event_type; /* see enum fc_fpin_congn_event_types */ __be16 event_modifier; /* Implementation specific value * describing the event type */ __be32 event_period; /* duration (ms) of the detected * congestion event */ __be32 pname_count; /* number of portname_list elements */ __be64 pname_list[0]; /* list of N_Port_Names accessible * through the attached port */ }; /* * Congestion Notification Descriptor */ struct fc_fn_congn_desc { __be32 desc_tag; /* Descriptor Tag (0x00020004) */ __be32 desc_len; /* Length of Descriptor (in bytes). * Size of descriptor excluding * desc_tag and desc_len fields. */ __be16 event_type; /* see enum fc_fpin_congn_event_types */ __be16 event_modifier; /* Implementation specific value * describing the event type */ __be32 event_period; /* duration (ms) of the detected * congestion event */ __u8 severity; /* command */ __u8 resv[3]; /* reserved - must be zero */ }; /* * ELS_FPIN - Fabric Performance Impact Notification */ struct fc_els_fpin { __u8 fpin_cmd; /* command (0x16) */ __u8 fpin_zero[3]; /* specified as zero - part of cmd */ __be32 desc_len; /* Length of Descriptor List (in bytes). * Size of ELS excluding fpin_cmd, * fpin_zero and desc_len fields. */ struct fc_tlv_desc fpin_desc[0]; /* Descriptor list */ }; /* Diagnostic Function Descriptor - FPIN Registration */ struct fc_df_desc_fpin_reg { __be32 desc_tag; /* FPIN Registration (0x00030001) */ __be32 desc_len; /* Length of Descriptor (in bytes). * Size of descriptor excluding * desc_tag and desc_len fields. */ __be32 count; /* Number of desc_tags elements */ __be32 desc_tags[0]; /* Array of Descriptor Tags. * Each tag indicates a function * supported by the N_Port (request) * or by the N_Port and Fabric * Controller (reply; may be a subset * of the request). * See ELS_FN_DTAG_xxx for tag values. */ }; /* * ELS_RDF - Register Diagnostic Functions */ struct fc_els_rdf { __u8 fpin_cmd; /* command (0x19) */ __u8 fpin_zero[3]; /* specified as zero - part of cmd */ __be32 desc_len; /* Length of Descriptor List (in bytes). * Size of ELS excluding fpin_cmd, * fpin_zero and desc_len fields. */ struct fc_tlv_desc desc[0]; /* Descriptor list */ }; /* * ELS RDF LS_ACC Response. */ struct fc_els_rdf_resp { struct fc_els_ls_acc acc_hdr; __be32 desc_list_len; /* Length of response (in * bytes). Excludes acc_hdr * and desc_list_len fields. */ struct fc_els_lsri_desc lsri; struct fc_tlv_desc desc[0]; /* Supported Descriptor list */ }; /* * Diagnostic Capability Descriptors for EDC ELS */ /* * Diagnostic: Link Fault Capability Descriptor */ struct fc_diag_lnkflt_desc { __be32 desc_tag; /* Descriptor Tag (0x0001000D) */ __be32 desc_len; /* Length of Descriptor (in bytes). * Size of descriptor excluding * desc_tag and desc_len fields. * 12 bytes */ __be32 degrade_activate_threshold; __be32 degrade_deactivate_threshold; __be32 fec_degrade_interval; }; enum fc_edc_cg_signal_cap_types { /* Note: Capability: bits 31:4 Rsvd; bits 3:0 are capabilities */ EDC_CG_SIG_NOTSUPPORTED = 0x00, /* neither supported */ EDC_CG_SIG_WARN_ONLY = 0x01, EDC_CG_SIG_WARN_ALARM = 0x02, /* both supported */ }; /* * Initializer useful for decoding table. * Please keep this in sync with the above definitions. */ #define FC_EDC_CG_SIGNAL_CAP_TYPES_INIT { \ { EDC_CG_SIG_NOTSUPPORTED, "Signaling Not Supported" }, \ { EDC_CG_SIG_WARN_ONLY, "Warning Signal" }, \ { EDC_CG_SIG_WARN_ALARM, "Warning and Alarm Signals" }, \ } enum fc_diag_cg_sig_freq_types { EDC_CG_SIGFREQ_CNT_MIN = 1, /* Min Frequency Count */ EDC_CG_SIGFREQ_CNT_MAX = 999, /* Max Frequency Count */ EDC_CG_SIGFREQ_SEC = 0x1, /* Units: seconds */ EDC_CG_SIGFREQ_MSEC = 0x2, /* Units: milliseconds */ }; struct fc_diag_cg_sig_freq { __be16 count; /* Time between signals * note: upper 6 bits rsvd */ __be16 units; /* Time unit for count * note: upper 12 bits rsvd */ }; /* * Diagnostic: Congestion Signaling Capability Descriptor */ struct fc_diag_cg_sig_desc { __be32 desc_tag; /* Descriptor Tag (0x0001000F) */ __be32 desc_len; /* Length of Descriptor (in bytes). * Size of descriptor excluding * desc_tag and desc_len fields. * 16 bytes */ __be32 xmt_signal_capability; struct fc_diag_cg_sig_freq xmt_signal_frequency; __be32 rcv_signal_capability; struct fc_diag_cg_sig_freq rcv_signal_frequency; }; /* * ELS_EDC - Exchange Diagnostic Capabilities */ struct fc_els_edc { __u8 edc_cmd; /* command (0x17) */ __u8 edc_zero[3]; /* specified as zero - part of cmd */ __be32 desc_len; /* Length of Descriptor List (in bytes). * Size of ELS excluding edc_cmd, * edc_zero and desc_len fields. */ struct fc_tlv_desc desc[0]; /* Diagnostic Descriptor list */ }; /* * ELS EDC LS_ACC Response. */ struct fc_els_edc_resp { struct fc_els_ls_acc acc_hdr; __be32 desc_list_len; /* Length of response (in * bytes). Excludes acc_hdr * and desc_list_len fields. */ struct fc_els_lsri_desc lsri; struct fc_tlv_desc desc[0]; /* Supported Diagnostic Descriptor list */ }; #endif /* _FC_ELS_H_ */ scsi/fc/fc_gs.h 0000644 00000005517 15146341150 0007337 0 ustar 00 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright(c) 2007 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * * Maintained at www.Open-FCoE.org */ #ifndef _FC_GS_H_ #define _FC_GS_H_ #include <linux/types.h> /* * Fibre Channel Services - Common Transport. * From T11.org FC-GS-2 Rev 5.3 November 1998. */ struct fc_ct_hdr { __u8 ct_rev; /* revision */ __u8 ct_in_id[3]; /* N_Port ID of original requestor */ __u8 ct_fs_type; /* type of fibre channel service */ __u8 ct_fs_subtype; /* subtype */ __u8 ct_options; __u8 _ct_resvd1; __be16 ct_cmd; /* command / response code */ __be16 ct_mr_size; /* maximum / residual size */ __u8 _ct_resvd2; __u8 ct_reason; /* reject reason */ __u8 ct_explan; /* reason code explanation */ __u8 ct_vendor; /* vendor unique data */ }; #define FC_CT_HDR_LEN 16 /* expected sizeof (struct fc_ct_hdr) */ enum fc_ct_rev { FC_CT_REV = 1 /* common transport revision */ }; /* * ct_fs_type values. */ enum fc_ct_fs_type { FC_FST_ALIAS = 0xf8, /* alias service */ FC_FST_MGMT = 0xfa, /* management service */ FC_FST_TIME = 0xfb, /* time service */ FC_FST_DIR = 0xfc, /* directory service */ }; /* * ct_cmd: Command / response codes */ enum fc_ct_cmd { FC_FS_RJT = 0x8001, /* reject */ FC_FS_ACC = 0x8002, /* accept */ }; /* * FS_RJT reason codes. */ enum fc_ct_reason { FC_FS_RJT_CMD = 0x01, /* invalid command code */ FC_FS_RJT_VER = 0x02, /* invalid version level */ FC_FS_RJT_LOG = 0x03, /* logical error */ FC_FS_RJT_IUSIZ = 0x04, /* invalid IU size */ FC_FS_RJT_BSY = 0x05, /* logical busy */ FC_FS_RJT_PROTO = 0x07, /* protocol error */ FC_FS_RJT_UNABL = 0x09, /* unable to perform command request */ FC_FS_RJT_UNSUP = 0x0b, /* command not supported */ }; /* * FS_RJT reason code explanations. */ enum fc_ct_explan { FC_FS_EXP_NONE = 0x00, /* no additional explanation */ FC_FS_EXP_PID = 0x01, /* port ID not registered */ FC_FS_EXP_PNAM = 0x02, /* port name not registered */ FC_FS_EXP_NNAM = 0x03, /* node name not registered */ FC_FS_EXP_COS = 0x04, /* class of service not registered */ FC_FS_EXP_FTNR = 0x07, /* FC-4 types not registered */ /* definitions not complete */ }; #endif /* _FC_GS_H_ */ scsi/scsi_netlink_fc.h 0000644 00000003711 15146341150 0011015 0 ustar 00 /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * FC Transport Netlink Interface * * Copyright (C) 2006 James Smart, Emulex Corporation * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef SCSI_NETLINK_FC_H #define SCSI_NETLINK_FC_H #include <scsi/scsi_netlink.h> /* * This file intended to be included by both kernel and user space */ /* * FC Transport Message Types */ /* kernel -> user */ #define FC_NL_ASYNC_EVENT 0x0100 /* user -> kernel */ /* none */ /* * Message Structures : */ /* macro to round up message lengths to 8byte boundary */ #define FC_NL_MSGALIGN(len) (((len) + 7) & ~7) /* * FC Transport Broadcast Event Message : * FC_NL_ASYNC_EVENT * * Note: if Vendor Unique message, &event_data will be start of * vendor unique payload, and the length of the payload is * per event_datalen * * Note: When specifying vendor_id, be sure to read the Vendor Type and ID * formatting requirements specified in scsi_netlink.h */ struct fc_nl_event { struct scsi_nl_hdr snlh; /* must be 1st element ! */ uint64_t seconds; uint64_t vendor_id; uint16_t host_no; uint16_t event_datalen; uint32_t event_num; uint32_t event_code; uint32_t event_data; } __attribute__((aligned(sizeof(uint64_t)))); #endif /* SCSI_NETLINK_FC_H */ scsi/scsi.h 0000644 00000015471 15146341150 0006627 0 ustar 00 /* Copyright (C) 1998-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* * This header file contains public constants and structures used by * the scsi code for linux. */ #ifndef _SCSI_SCSI_H #define _SCSI_SCSI_H 1 #include <features.h> /* * SCSI opcodes */ #define TEST_UNIT_READY 0x00 #define REZERO_UNIT 0x01 #define REQUEST_SENSE 0x03 #define FORMAT_UNIT 0x04 #define READ_BLOCK_LIMITS 0x05 #define REASSIGN_BLOCKS 0x07 #define READ_6 0x08 #define WRITE_6 0x0a #define SEEK_6 0x0b #define READ_REVERSE 0x0f #define WRITE_FILEMARKS 0x10 #define SPACE 0x11 #define INQUIRY 0x12 #define RECOVER_BUFFERED_DATA 0x14 #define MODE_SELECT 0x15 #define RESERVE 0x16 #define RELEASE 0x17 #define COPY 0x18 #define ERASE 0x19 #define MODE_SENSE 0x1a #define START_STOP 0x1b #define RECEIVE_DIAGNOSTIC 0x1c #define SEND_DIAGNOSTIC 0x1d #define ALLOW_MEDIUM_REMOVAL 0x1e #define SET_WINDOW 0x24 #define READ_CAPACITY 0x25 #define READ_10 0x28 #define WRITE_10 0x2a #define SEEK_10 0x2b #define WRITE_VERIFY 0x2e #define VERIFY 0x2f #define SEARCH_HIGH 0x30 #define SEARCH_EQUAL 0x31 #define SEARCH_LOW 0x32 #define SET_LIMITS 0x33 #define PRE_FETCH 0x34 #define READ_POSITION 0x34 #define SYNCHRONIZE_CACHE 0x35 #define LOCK_UNLOCK_CACHE 0x36 #define READ_DEFECT_DATA 0x37 #define MEDIUM_SCAN 0x38 #define COMPARE 0x39 #define COPY_VERIFY 0x3a #define WRITE_BUFFER 0x3b #define READ_BUFFER 0x3c #define UPDATE_BLOCK 0x3d #define READ_LONG 0x3e #define WRITE_LONG 0x3f #define CHANGE_DEFINITION 0x40 #define WRITE_SAME 0x41 #define READ_TOC 0x43 #define LOG_SELECT 0x4c #define LOG_SENSE 0x4d #define MODE_SELECT_10 0x55 #define RESERVE_10 0x56 #define RELEASE_10 0x57 #define MODE_SENSE_10 0x5a #define PERSISTENT_RESERVE_IN 0x5e #define PERSISTENT_RESERVE_OUT 0x5f #define MOVE_MEDIUM 0xa5 #define READ_12 0xa8 #define WRITE_12 0xaa #define WRITE_VERIFY_12 0xae #define SEARCH_HIGH_12 0xb0 #define SEARCH_EQUAL_12 0xb1 #define SEARCH_LOW_12 0xb2 #define READ_ELEMENT_STATUS 0xb8 #define SEND_VOLUME_TAG 0xb6 #define WRITE_LONG_2 0xea /* * Status codes */ #define GOOD 0x00 #define CHECK_CONDITION 0x01 #define CONDITION_GOOD 0x02 #define BUSY 0x04 #define INTERMEDIATE_GOOD 0x08 #define INTERMEDIATE_C_GOOD 0x0a #define RESERVATION_CONFLICT 0x0c #define COMMAND_TERMINATED 0x11 #define QUEUE_FULL 0x14 #define STATUS_MASK 0x3e /* * SENSE KEYS */ #define NO_SENSE 0x00 #define RECOVERED_ERROR 0x01 #define NOT_READY 0x02 #define MEDIUM_ERROR 0x03 #define HARDWARE_ERROR 0x04 #define ILLEGAL_REQUEST 0x05 #define UNIT_ATTENTION 0x06 #define DATA_PROTECT 0x07 #define BLANK_CHECK 0x08 #define COPY_ABORTED 0x0a #define ABORTED_COMMAND 0x0b #define VOLUME_OVERFLOW 0x0d #define MISCOMPARE 0x0e /* * DEVICE TYPES */ #define TYPE_DISK 0x00 #define TYPE_TAPE 0x01 #define TYPE_PROCESSOR 0x03 /* HP scanners use this */ #define TYPE_WORM 0x04 /* Treated as ROM by our system */ #define TYPE_ROM 0x05 #define TYPE_SCANNER 0x06 #define TYPE_MOD 0x07 /* Magneto-optical disk - * - treated as TYPE_DISK */ #define TYPE_MEDIUM_CHANGER 0x08 #define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ #define TYPE_NO_LUN 0x7f /* * standard mode-select header prepended to all mode-select commands * * moved here from cdrom.h -- kraxel */ struct ccs_modesel_head { unsigned char _r1; /* reserved. */ unsigned char medium; /* device-specific medium type. */ unsigned char _r2; /* reserved. */ unsigned char block_desc_length; /* block descriptor length. */ unsigned char density; /* device-specific density code. */ unsigned char number_blocks_hi; /* number of blocks in this block desc. */ unsigned char number_blocks_med; unsigned char number_blocks_lo; unsigned char _r3; unsigned char block_length_hi; /* block length for blocks in this desc. */ unsigned char block_length_med; unsigned char block_length_lo; }; /* * MESSAGE CODES */ #define COMMAND_COMPLETE 0x00 #define EXTENDED_MESSAGE 0x01 #define EXTENDED_MODIFY_DATA_POINTER 0x00 #define EXTENDED_SDTR 0x01 #define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */ #define EXTENDED_WDTR 0x03 #define SAVE_POINTERS 0x02 #define RESTORE_POINTERS 0x03 #define DISCONNECT 0x04 #define INITIATOR_ERROR 0x05 #define ABORT 0x06 #define MESSAGE_REJECT 0x07 #define NOP 0x08 #define MSG_PARITY_ERROR 0x09 #define LINKED_CMD_COMPLETE 0x0a #define LINKED_FLG_CMD_COMPLETE 0x0b #define BUS_DEVICE_RESET 0x0c #define INITIATE_RECOVERY 0x0f /* SCSI-II only */ #define RELEASE_RECOVERY 0x10 /* SCSI-II only */ #define SIMPLE_QUEUE_TAG 0x20 #define HEAD_OF_QUEUE_TAG 0x21 #define ORDERED_QUEUE_TAG 0x22 /* * Here are some scsi specific ioctl commands which are sometimes useful. */ /* These are a few other constants only used by scsi devices. */ #define SCSI_IOCTL_GET_IDLUN 0x5382 /* Used to turn on and off tagged queuing for scsi devices. */ #define SCSI_IOCTL_TAGGED_ENABLE 0x5383 #define SCSI_IOCTL_TAGGED_DISABLE 0x5384 /* Used to obtain the host number of a device. */ #define SCSI_IOCTL_PROBE_HOST 0x5385 /* Used to get the bus number for a device. */ #define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 #endif /* scsi/scsi.h */ scsi/scsi_netlink.h 0000644 00000007122 15146341150 0010345 0 ustar 00 /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * SCSI Transport Netlink Interface * Used for the posting of outbound SCSI transport events * * Copyright (C) 2006 James Smart, Emulex Corporation * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef SCSI_NETLINK_H #define SCSI_NETLINK_H #include <linux/netlink.h> #include <linux/types.h> /* * This file intended to be included by both kernel and user space */ /* Single Netlink Message type to send all SCSI Transport messages */ #define SCSI_TRANSPORT_MSG NLMSG_MIN_TYPE + 1 /* SCSI Transport Broadcast Groups */ /* leaving groups 0 and 1 unassigned */ #define SCSI_NL_GRP_FC_EVENTS (1<<2) /* Group 2 */ #define SCSI_NL_GRP_CNT 3 /* SCSI_TRANSPORT_MSG event message header */ struct scsi_nl_hdr { uint8_t version; uint8_t transport; uint16_t magic; uint16_t msgtype; uint16_t msglen; } __attribute__((aligned(sizeof(uint64_t)))); /* scsi_nl_hdr->version value */ #define SCSI_NL_VERSION 1 /* scsi_nl_hdr->magic value */ #define SCSI_NL_MAGIC 0xA1B2 /* scsi_nl_hdr->transport value */ #define SCSI_NL_TRANSPORT 0 #define SCSI_NL_TRANSPORT_FC 1 #define SCSI_NL_MAX_TRANSPORTS 2 /* Transport-based scsi_nl_hdr->msgtype values are defined in each transport */ /* * GENERIC SCSI scsi_nl_hdr->msgtype Values */ /* kernel -> user */ #define SCSI_NL_SHOST_VENDOR 0x0001 /* user -> kernel */ /* SCSI_NL_SHOST_VENDOR msgtype is kernel->user and user->kernel */ /* * Message Structures : */ /* macro to round up message lengths to 8byte boundary */ #define SCSI_NL_MSGALIGN(len) (((len) + 7) & ~7) /* * SCSI HOST Vendor Unique messages : * SCSI_NL_SHOST_VENDOR * * Note: The Vendor Unique message payload will begin directly after * this structure, with the length of the payload per vmsg_datalen. * * Note: When specifying vendor_id, be sure to read the Vendor Type and ID * formatting requirements specified below */ struct scsi_nl_host_vendor_msg { struct scsi_nl_hdr snlh; /* must be 1st element ! */ uint64_t vendor_id; uint16_t host_no; uint16_t vmsg_datalen; } __attribute__((aligned(sizeof(uint64_t)))); /* * Vendor ID: * If transports post vendor-unique events, they must pass a well-known * 32-bit vendor identifier. This identifier consists of 8 bits indicating * the "type" of identifier contained, and 24 bits of id data. * * Identifiers for each type: * PCI : ID data is the 16 bit PCI Registered Vendor ID */ #define SCSI_NL_VID_TYPE_SHIFT 56 #define SCSI_NL_VID_TYPE_MASK ((__u64)0xFF << SCSI_NL_VID_TYPE_SHIFT) #define SCSI_NL_VID_TYPE_PCI ((__u64)0x01 << SCSI_NL_VID_TYPE_SHIFT) #define SCSI_NL_VID_ID_MASK (~ SCSI_NL_VID_TYPE_MASK) #define INIT_SCSI_NL_HDR(hdr, t, mtype, mlen) \ { \ (hdr)->version = SCSI_NL_VERSION; \ (hdr)->transport = t; \ (hdr)->magic = SCSI_NL_MAGIC; \ (hdr)->msgtype = mtype; \ (hdr)->msglen = mlen; \ } #endif /* SCSI_NETLINK_H */ scsi/sg.h 0000644 00000026615 15146341150 0006301 0 ustar 00 /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* History: Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user process control of SCSI devices. Development Sponsored by Killy Corp. NY NY */ #ifndef _SCSI_SG_H #define _SCSI_SG_H 1 #include <features.h> #define __need_size_t #include <stddef.h> /* New interface introduced in the 3.x SG drivers follows */ /* Same structure as used by readv() Linux system call. It defines one scatter-gather element. */ typedef struct sg_iovec { void * iov_base; /* Starting address */ size_t iov_len; /* Length in bytes */ } sg_iovec_t; typedef struct sg_io_hdr { int interface_id; /* [i] 'S' for SCSI generic (required) */ int dxfer_direction; /* [i] data transfer direction */ unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ unsigned char mx_sb_len; /* [i] max length to write to sbp */ unsigned short int iovec_count; /* [i] 0 implies no scatter gather */ unsigned int dxfer_len; /* [i] byte count of data transfer */ void * dxferp; /* [i], [*io] points to data transfer memory or scatter gather list */ unsigned char * cmdp; /* [i], [*i] points to command to perform */ unsigned char * sbp; /* [i], [*o] points to sense_buffer memory */ unsigned int timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ unsigned int flags; /* [i] 0 -> default, see SG_FLAG... */ int pack_id; /* [i->o] unused internally (normally) */ void * usr_ptr; /* [i->o] unused internally */ unsigned char status; /* [o] scsi status */ unsigned char masked_status;/* [o] shifted, masked scsi status */ unsigned char msg_status; /* [o] messaging level data (optional) */ unsigned char sb_len_wr; /* [o] byte count actually written to sbp */ unsigned short int host_status; /* [o] errors from host adapter */ unsigned short int driver_status;/* [o] errors from software driver */ int resid; /* [o] dxfer_len - actual_transferred */ unsigned int duration; /* [o] time taken by cmd (unit: millisec) */ unsigned int info; /* [o] auxiliary information */ } sg_io_hdr_t; /* Use negative values to flag difference from original sg_header structure. */ #define SG_DXFER_NONE -1 /* e.g. a SCSI Test Unit Ready command */ #define SG_DXFER_TO_DEV -2 /* e.g. a SCSI WRITE command */ #define SG_DXFER_FROM_DEV -3 /* e.g. a SCSI READ command */ #define SG_DXFER_TO_FROM_DEV -4 /* treated like SG_DXFER_FROM_DEV with the additional property than during indirect IO the user buffer is copied into the kernel buffers before the transfer */ /* following flag values can be "or"-ed together */ #define SG_FLAG_DIRECT_IO 1 /* default is indirect IO */ #define SG_FLAG_LUN_INHIBIT 2 /* default is to put device's lun into */ /* the 2nd byte of SCSI command */ #define SG_FLAG_NO_DXFER 0x10000 /* no transfer of kernel buffers to/from */ /* user space (debug indirect IO) */ /* The following 'info' values are "or"-ed together. */ #define SG_INFO_OK_MASK 0x1 #define SG_INFO_OK 0x0 /* no sense, host nor driver "noise" */ #define SG_INFO_CHECK 0x1 /* something abnormal happened */ #define SG_INFO_DIRECT_IO_MASK 0x6 #define SG_INFO_INDIRECT_IO 0x0 /* data xfer via kernel buffers (or no xfer) */ #define SG_INFO_DIRECT_IO 0x2 /* direct IO requested and performed */ #define SG_INFO_MIXED_IO 0x4 /* part direct, part indirect IO */ /* Request information about a specific SG device, used by SG_GET_SCSI_ID ioctl (). */ struct sg_scsi_id { /* Host number as in "scsi<n>" where 'n' is one of 0, 1, 2 etc. */ int host_no; int channel; /* SCSI id of target device. */ int scsi_id; int lun; /* TYPE_... defined in <scsi/scsi.h>. */ int scsi_type; /* Host (adapter) maximum commands per lun. */ short int h_cmd_per_lun; /* Device (or adapter) maximum queue length. */ short int d_queue_depth; /* Unused, set to 0 for now. */ int unused[2]; }; /* Used by SG_GET_REQUEST_TABLE ioctl(). */ typedef struct sg_req_info { char req_state; /* 0 -> not used, 1 -> written, 2 -> ready to read */ char orphan; /* 0 -> normal request, 1 -> from interruped SG_IO */ char sg_io_owned; /* 0 -> complete with read(), 1 -> owned by SG_IO */ char problem; /* 0 -> no problem detected, 1 -> error to report */ int pack_id; /* pack_id associated with request */ void * usr_ptr; /* user provided pointer (in new interface) */ unsigned int duration; /* millisecs elapsed since written (req_state==1) or request duration (req_state==2) */ int unused; } sg_req_info_t; /* IOCTLs: Those ioctls that are relevant to the SG 3.x drivers follow. [Those that only apply to the SG 2.x drivers are at the end of the file.] (_GET_s yield result via 'int *' 3rd argument unless otherwise indicated) */ #define SG_EMULATED_HOST 0x2203 /* true for emulated host adapter (ATAPI) */ /* Used to configure SCSI command transformation layer for ATAPI devices */ /* Only supported by the ide-scsi driver */ #define SG_SET_TRANSFORM 0x2204 /* N.B. 3rd arg is not pointer but value: */ /* 3rd arg = 0 to disable transform, 1 to enable it */ #define SG_GET_TRANSFORM 0x2205 #define SG_SET_RESERVED_SIZE 0x2275 /* request a new reserved buffer size */ #define SG_GET_RESERVED_SIZE 0x2272 /* actual size of reserved buffer */ /* The following ioctl has a 'sg_scsi_id_t *' object as its 3rd argument. */ #define SG_GET_SCSI_ID 0x2276 /* Yields fd's bus, chan, dev, lun + type */ /* SCSI id information can also be obtained from SCSI_IOCTL_GET_IDLUN */ /* Override host setting and always DMA using low memory ( <16MB on i386) */ #define SG_SET_FORCE_LOW_DMA 0x2279 /* 0-> use adapter setting, 1-> force */ #define SG_GET_LOW_DMA 0x227a /* 0-> use all ram for dma; 1-> low dma ram */ /* When SG_SET_FORCE_PACK_ID set to 1, pack_id is input to read() which tries to fetch a packet with a matching pack_id, waits, or returns EAGAIN. If pack_id is -1 then read oldest waiting. When ...FORCE_PACK_ID set to 0 then pack_id ignored by read() and oldest readable fetched. */ #define SG_SET_FORCE_PACK_ID 0x227b #define SG_GET_PACK_ID 0x227c /* Yields oldest readable pack_id (or -1) */ #define SG_GET_NUM_WAITING 0x227d /* Number of commands awaiting read() */ /* Yields max scatter gather tablesize allowed by current host adapter */ #define SG_GET_SG_TABLESIZE 0x227F /* 0 implies can't do scatter gather */ #define SG_GET_VERSION_NUM 0x2282 /* Example: version 2.1.34 yields 20134 */ /* Returns -EBUSY if occupied. 3rd argument pointer to int (see next) */ #define SG_SCSI_RESET 0x2284 /* Associated values that can be given to SG_SCSI_RESET follow */ #define SG_SCSI_RESET_NOTHING 0 #define SG_SCSI_RESET_DEVICE 1 #define SG_SCSI_RESET_BUS 2 #define SG_SCSI_RESET_HOST 3 /* synchronous SCSI command ioctl, (only in version 3 interface) */ #define SG_IO 0x2285 /* similar effect as write() followed by read() */ #define SG_GET_REQUEST_TABLE 0x2286 /* yields table of active requests */ /* How to treat EINTR during SG_IO ioctl(), only in SG 3.x series */ #define SG_SET_KEEP_ORPHAN 0x2287 /* 1 -> hold for read(), 0 -> drop (def) */ #define SG_GET_KEEP_ORPHAN 0x2288 #define SG_SCATTER_SZ (8 * 4096) /* PAGE_SIZE not available to user */ /* Largest size (in bytes) a single scatter-gather list element can have. The value must be a power of 2 and <= (PAGE_SIZE * 32) [131072 bytes on i386]. The minimum value is PAGE_SIZE. If scatter-gather not supported by adapter then this value is the largest data block that can be read/written by a single scsi command. The user can find the value of PAGE_SIZE by calling getpagesize() defined in unistd.h . */ #define SG_DEFAULT_RETRIES 1 /* Defaults, commented if they differ from original sg driver */ #define SG_DEF_FORCE_LOW_DMA 0 /* was 1 -> memory below 16MB on i386 */ #define SG_DEF_FORCE_PACK_ID 0 #define SG_DEF_KEEP_ORPHAN 0 #define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ /* load time option */ /* maximum outstanding requests, write() yields EDOM if exceeded */ #define SG_MAX_QUEUE 16 #define SG_BIG_BUFF SG_DEF_RESERVED_SIZE /* for backward compatibility */ /* Alternate style type names, "..._t" variants preferred */ typedef struct sg_io_hdr Sg_io_hdr; typedef struct sg_io_vec Sg_io_vec; typedef struct sg_scsi_id Sg_scsi_id; typedef struct sg_req_info Sg_req_info; /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ /* The older SG interface based on the 'sg_header' structure follows. */ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ #define SG_MAX_SENSE 16 /* this only applies to the sg_header interface */ struct sg_header { /* Length of incoming packet (including header). */ int pack_len; /* Maximal length of expected reply. */ int reply_len; /* Id number of packet. */ int pack_id; /* 0==ok, otherwise error number. */ int result; /* Force 12 byte command length for group 6 & 7 commands. */ unsigned int twelve_byte:1; /* SCSI status from target. */ unsigned int target_status:5; /* Host status (see "DID" codes). */ unsigned int host_status:8; /* Driver status+suggestion. */ unsigned int driver_status:8; /* Unused. */ unsigned int other_flags:10; /* Output in 3 cases: when target_status is CHECK_CONDITION or when target_status is COMMAND_TERMINATED or when (driver_status & DRIVER_SENSE) is true. */ unsigned char sense_buffer[SG_MAX_SENSE]; }; /* IOCTLs: The following are not required (or ignored) when the sg_io_hdr_t interface is used. They are kept for backward compatibility with the original and version 2 drivers. */ #define SG_SET_TIMEOUT 0x2201 /* Set timeout; *(int *)arg==timeout. */ #define SG_GET_TIMEOUT 0x2202 /* Get timeout; return timeout. */ /* Get/set command queuing state per fd (default is SG_DEF_COMMAND_Q). */ #define SG_GET_COMMAND_Q 0x2270 /* Yields 0 (queuing off) or 1 (on). */ #define SG_SET_COMMAND_Q 0x2271 /* Change queuing state with 0 or 1. */ /* Turn on error sense trace (1..8), dump this device to log/console (9) or dump all sg device states ( >9 ) to log/console. */ #define SG_SET_DEBUG 0x227e /* 0 -> turn off debug */ #define SG_NEXT_CMD_LEN 0x2283 /* Override SCSI command length with given number on the next write() on this file descriptor. */ /* Defaults, commented if they differ from original sg driver */ #define SG_DEFAULT_TIMEOUT (60*HZ) /* HZ == 'jiffies in 1 second' */ #define SG_DEF_COMMAND_Q 0 /* command queuing is always on when the new interface is used */ #define SG_DEF_UNDERRUN_FLAG 0 #endif /* scsi/sg.h */ sched.h 0000644 00000011174 15146341150 0006007 0 ustar 00 /* Definitions for POSIX 1003.1b-1993 (aka POSIX.4) scheduling interface. Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _SCHED_H #define _SCHED_H 1 #include <features.h> /* Get type definitions. */ #include <bits/types.h> #define __need_size_t #define __need_NULL #include <stddef.h> #include <bits/types/time_t.h> #include <bits/types/struct_timespec.h> #ifndef __USE_XOPEN2K # include <time.h> #endif #ifndef __pid_t_defined typedef __pid_t pid_t; # define __pid_t_defined #endif /* Get system specific constant and data structure definitions. */ #include <bits/sched.h> #include <bits/cpu-set.h> /* Backward compatibility. */ #define sched_priority sched_priority #define __sched_priority sched_priority __BEGIN_DECLS /* Set scheduling parameters for a process. */ extern int sched_setparam (__pid_t __pid, const struct sched_param *__param) __THROW; /* Retrieve scheduling parameters for a particular process. */ extern int sched_getparam (__pid_t __pid, struct sched_param *__param) __THROW; /* Set scheduling algorithm and/or parameters for a process. */ extern int sched_setscheduler (__pid_t __pid, int __policy, const struct sched_param *__param) __THROW; /* Retrieve scheduling algorithm for a particular purpose. */ extern int sched_getscheduler (__pid_t __pid) __THROW; /* Yield the processor. */ extern int sched_yield (void) __THROW; /* Get maximum priority value for a scheduler. */ extern int sched_get_priority_max (int __algorithm) __THROW; /* Get minimum priority value for a scheduler. */ extern int sched_get_priority_min (int __algorithm) __THROW; /* Get the SCHED_RR interval for the named process. */ extern int sched_rr_get_interval (__pid_t __pid, struct timespec *__t) __THROW; #ifdef __USE_GNU /* Access macros for `cpu_set'. */ # define CPU_SETSIZE __CPU_SETSIZE # define CPU_SET(cpu, cpusetp) __CPU_SET_S (cpu, sizeof (cpu_set_t), cpusetp) # define CPU_CLR(cpu, cpusetp) __CPU_CLR_S (cpu, sizeof (cpu_set_t), cpusetp) # define CPU_ISSET(cpu, cpusetp) __CPU_ISSET_S (cpu, sizeof (cpu_set_t), \ cpusetp) # define CPU_ZERO(cpusetp) __CPU_ZERO_S (sizeof (cpu_set_t), cpusetp) # define CPU_COUNT(cpusetp) __CPU_COUNT_S (sizeof (cpu_set_t), cpusetp) # define CPU_SET_S(cpu, setsize, cpusetp) __CPU_SET_S (cpu, setsize, cpusetp) # define CPU_CLR_S(cpu, setsize, cpusetp) __CPU_CLR_S (cpu, setsize, cpusetp) # define CPU_ISSET_S(cpu, setsize, cpusetp) __CPU_ISSET_S (cpu, setsize, \ cpusetp) # define CPU_ZERO_S(setsize, cpusetp) __CPU_ZERO_S (setsize, cpusetp) # define CPU_COUNT_S(setsize, cpusetp) __CPU_COUNT_S (setsize, cpusetp) # define CPU_EQUAL(cpusetp1, cpusetp2) \ __CPU_EQUAL_S (sizeof (cpu_set_t), cpusetp1, cpusetp2) # define CPU_EQUAL_S(setsize, cpusetp1, cpusetp2) \ __CPU_EQUAL_S (setsize, cpusetp1, cpusetp2) # define CPU_AND(destset, srcset1, srcset2) \ __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, &) # define CPU_OR(destset, srcset1, srcset2) \ __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, |) # define CPU_XOR(destset, srcset1, srcset2) \ __CPU_OP_S (sizeof (cpu_set_t), destset, srcset1, srcset2, ^) # define CPU_AND_S(setsize, destset, srcset1, srcset2) \ __CPU_OP_S (setsize, destset, srcset1, srcset2, &) # define CPU_OR_S(setsize, destset, srcset1, srcset2) \ __CPU_OP_S (setsize, destset, srcset1, srcset2, |) # define CPU_XOR_S(setsize, destset, srcset1, srcset2) \ __CPU_OP_S (setsize, destset, srcset1, srcset2, ^) # define CPU_ALLOC_SIZE(count) __CPU_ALLOC_SIZE (count) # define CPU_ALLOC(count) __CPU_ALLOC (count) # define CPU_FREE(cpuset) __CPU_FREE (cpuset) /* Set the CPU affinity for a task */ extern int sched_setaffinity (__pid_t __pid, size_t __cpusetsize, const cpu_set_t *__cpuset) __THROW; /* Get the CPU affinity for a task */ extern int sched_getaffinity (__pid_t __pid, size_t __cpusetsize, cpu_set_t *__cpuset) __THROW; #endif __END_DECLS #endif /* sched.h */ evutil.h 0000644 00000003366 15146341150 0006235 0 ustar 00 /* * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson * * 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. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. */ #ifndef EVENT1_EVUTIL_H_INCLUDED_ #define EVENT1_EVUTIL_H_INCLUDED_ /** @file evutil.h Utility and compatibility functions for Libevent. The <evutil.h> header is deprecated in Libevent 2.0 and later; please use <event2/util.h> instead. */ #include <event2/util.h> #endif /* EVENT1_EVUTIL_H_INCLUDED_ */ cpio.h 0000644 00000004333 15146341150 0005652 0 ustar 00 /* Extended cpio format from POSIX.1. This file is part of the GNU C Library. Copyright (C) 1992-2018 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU cpio. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _CPIO_H #define _CPIO_H 1 /* A cpio archive consists of a sequence of files. Each file has a 76 byte header, a variable length, NUL terminated filename, and variable length file data. A header for a filename "TRAILER!!!" indicates the end of the archive. */ /* All the fields in the header are ISO 646 (approximately ASCII) strings of octal numbers, left padded, not NUL terminated. Field Name Length in Bytes Notes c_magic 6 must be "070707" c_dev 6 c_ino 6 c_mode 6 see below for value c_uid 6 c_gid 6 c_nlink 6 c_rdev 6 only valid for chr and blk special files c_mtime 11 c_namesize 6 count includes terminating NUL in pathname c_filesize 11 must be 0 for FIFOs and directories */ /* Value for the field `c_magic'. */ #define MAGIC "070707" /* Values for c_mode, OR'd together: */ #define C_IRUSR 000400 #define C_IWUSR 000200 #define C_IXUSR 000100 #define C_IRGRP 000040 #define C_IWGRP 000020 #define C_IXGRP 000010 #define C_IROTH 000004 #define C_IWOTH 000002 #define C_IXOTH 000001 #define C_ISUID 004000 #define C_ISGID 002000 #define C_ISVTX 001000 #define C_ISBLK 060000 #define C_ISCHR 020000 #define C_ISDIR 040000 #define C_ISFIFO 010000 #define C_ISSOCK 0140000 #define C_ISLNK 0120000 #define C_ISCTG 0110000 #define C_ISREG 0100000 #endif /* cpio.h */ webp/types.h 0000644 00000003201 15146341150 0007012 0 ustar 00 // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Common types // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_WEBP_TYPES_H_ #define WEBP_WEBP_TYPES_H_ #include <stddef.h> // for size_t #ifndef _MSC_VER #include <inttypes.h> #if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) #define WEBP_INLINE inline #else #define WEBP_INLINE #endif #else typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; typedef unsigned long long int uint64_t; typedef long long int int64_t; #define WEBP_INLINE __forceinline #endif /* _MSC_VER */ #ifndef WEBP_EXTERN // This explicitly marks library functions and allows for changing the // signature for e.g., Windows DLL builds. # if defined(__GNUC__) && __GNUC__ >= 4 # define WEBP_EXTERN extern __attribute__ ((visibility ("default"))) # else # define WEBP_EXTERN extern # endif /* __GNUC__ >= 4 */ #endif /* WEBP_EXTERN */ // Macro to check ABI compatibility (same major revision number) #define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8)) #endif /* WEBP_WEBP_TYPES_H_ */ webp/mux.h 0000644 00000054450 15146341150 0006473 0 ustar 00 // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // RIFF container manipulation and encoding for WebP images. // // Authors: Urvang (urvang@google.com) // Vikas (vikasa@google.com) #ifndef WEBP_WEBP_MUX_H_ #define WEBP_WEBP_MUX_H_ #include "./mux_types.h" #ifdef __cplusplus extern "C" { #endif #define WEBP_MUX_ABI_VERSION 0x0108 // MAJOR(8b) + MINOR(8b) //------------------------------------------------------------------------------ // Mux API // // This API allows manipulation of WebP container images containing features // like color profile, metadata, animation. // // Code Example#1: Create a WebPMux object with image data, color profile and // XMP metadata. /* int copy_data = 0; WebPMux* mux = WebPMuxNew(); // ... (Prepare image data). WebPMuxSetImage(mux, &image, copy_data); // ... (Prepare ICCP color profile data). WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data); // ... (Prepare XMP metadata). WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data); // Get data from mux in WebP RIFF format. WebPMuxAssemble(mux, &output_data); WebPMuxDelete(mux); // ... (Consume output_data; e.g. write output_data.bytes to file). WebPDataClear(&output_data); */ // Code Example#2: Get image and color profile data from a WebP file. /* int copy_data = 0; // ... (Read data from file). WebPMux* mux = WebPMuxCreate(&data, copy_data); WebPMuxGetFrame(mux, 1, &image); // ... (Consume image; e.g. call WebPDecode() to decode the data). WebPMuxGetChunk(mux, "ICCP", &icc_profile); // ... (Consume icc_data). WebPMuxDelete(mux); free(data); */ // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. // typedef enum WebPMuxError WebPMuxError; // typedef enum WebPChunkId WebPChunkId; typedef struct WebPMux WebPMux; // main opaque object. typedef struct WebPMuxFrameInfo WebPMuxFrameInfo; typedef struct WebPMuxAnimParams WebPMuxAnimParams; typedef struct WebPAnimEncoderOptions WebPAnimEncoderOptions; // Error codes typedef enum WebPMuxError { WEBP_MUX_OK = 1, WEBP_MUX_NOT_FOUND = 0, WEBP_MUX_INVALID_ARGUMENT = -1, WEBP_MUX_BAD_DATA = -2, WEBP_MUX_MEMORY_ERROR = -3, WEBP_MUX_NOT_ENOUGH_DATA = -4 } WebPMuxError; // IDs for different types of chunks. typedef enum WebPChunkId { WEBP_CHUNK_VP8X, // VP8X WEBP_CHUNK_ICCP, // ICCP WEBP_CHUNK_ANIM, // ANIM WEBP_CHUNK_ANMF, // ANMF WEBP_CHUNK_DEPRECATED, // (deprecated from FRGM) WEBP_CHUNK_ALPHA, // ALPH WEBP_CHUNK_IMAGE, // VP8/VP8L WEBP_CHUNK_EXIF, // EXIF WEBP_CHUNK_XMP, // XMP WEBP_CHUNK_UNKNOWN, // Other chunks. WEBP_CHUNK_NIL } WebPChunkId; //------------------------------------------------------------------------------ // Returns the version number of the mux library, packed in hexadecimal using // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. WEBP_EXTERN int WebPGetMuxVersion(void); //------------------------------------------------------------------------------ // Life of a Mux object // Internal, version-checked, entry point WEBP_EXTERN WebPMux* WebPNewInternal(int); // Creates an empty mux object. // Returns: // A pointer to the newly created empty mux object. // Or NULL in case of memory error. static WEBP_INLINE WebPMux* WebPMuxNew(void) { return WebPNewInternal(WEBP_MUX_ABI_VERSION); } // Deletes the mux object. // Parameters: // mux - (in/out) object to be deleted WEBP_EXTERN void WebPMuxDelete(WebPMux* mux); //------------------------------------------------------------------------------ // Mux creation. // Internal, version-checked, entry point WEBP_EXTERN WebPMux* WebPMuxCreateInternal(const WebPData*, int, int); // Creates a mux object from raw data given in WebP RIFF format. // Parameters: // bitstream - (in) the bitstream data in WebP RIFF format // copy_data - (in) value 1 indicates given data WILL be copied to the mux // object and value 0 indicates data will NOT be copied. // Returns: // A pointer to the mux object created from given data - on success. // NULL - In case of invalid data or memory error. static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream, int copy_data) { return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION); } //------------------------------------------------------------------------------ // Non-image chunks. // Note: Only non-image related chunks should be managed through chunk APIs. // (Image related chunks are: "ANMF", "VP8 ", "VP8L" and "ALPH"). // To add, get and delete images, use WebPMuxSetImage(), WebPMuxPushFrame(), // WebPMuxGetFrame() and WebPMuxDeleteFrame(). // Adds a chunk with id 'fourcc' and data 'chunk_data' in the mux object. // Any existing chunk(s) with the same id will be removed. // Parameters: // mux - (in/out) object to which the chunk is to be added // fourcc - (in) a character array containing the fourcc of the given chunk; // e.g., "ICCP", "XMP ", "EXIF" etc. // chunk_data - (in) the chunk data to be added // copy_data - (in) value 1 indicates given data WILL be copied to the mux // object and value 0 indicates data will NOT be copied. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL // or if fourcc corresponds to an image chunk. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxSetChunk( WebPMux* mux, const char fourcc[4], const WebPData* chunk_data, int copy_data); // Gets a reference to the data of the chunk with id 'fourcc' in the mux object. // The caller should NOT free the returned data. // Parameters: // mux - (in) object from which the chunk data is to be fetched // fourcc - (in) a character array containing the fourcc of the chunk; // e.g., "ICCP", "XMP ", "EXIF" etc. // chunk_data - (out) returned chunk data // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL // or if fourcc corresponds to an image chunk. // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given id. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxGetChunk( const WebPMux* mux, const char fourcc[4], WebPData* chunk_data); // Deletes the chunk with the given 'fourcc' from the mux object. // Parameters: // mux - (in/out) object from which the chunk is to be deleted // fourcc - (in) a character array containing the fourcc of the chunk; // e.g., "ICCP", "XMP ", "EXIF" etc. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL // or if fourcc corresponds to an image chunk. // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given fourcc. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxDeleteChunk( WebPMux* mux, const char fourcc[4]); //------------------------------------------------------------------------------ // Images. // Encapsulates data about a single frame. struct WebPMuxFrameInfo { WebPData bitstream; // image data: can be a raw VP8/VP8L bitstream // or a single-image WebP file. int x_offset; // x-offset of the frame. int y_offset; // y-offset of the frame. int duration; // duration of the frame (in milliseconds). WebPChunkId id; // frame type: should be one of WEBP_CHUNK_ANMF // or WEBP_CHUNK_IMAGE WebPMuxAnimDispose dispose_method; // Disposal method for the frame. WebPMuxAnimBlend blend_method; // Blend operation for the frame. uint32_t pad[1]; // padding for later use }; // Sets the (non-animated) image in the mux object. // Note: Any existing images (including frames) will be removed. // Parameters: // mux - (in/out) object in which the image is to be set // bitstream - (in) can be a raw VP8/VP8L bitstream or a single-image // WebP file (non-animated) // copy_data - (in) value 1 indicates given data WILL be copied to the mux // object and value 0 indicates data will NOT be copied. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxSetImage( WebPMux* mux, const WebPData* bitstream, int copy_data); // Adds a frame at the end of the mux object. // Notes: (1) frame.id should be WEBP_CHUNK_ANMF // (2) For setting a non-animated image, use WebPMuxSetImage() instead. // (3) Type of frame being pushed must be same as the frames in mux. // (4) As WebP only supports even offsets, any odd offset will be snapped // to an even location using: offset &= ~1 // Parameters: // mux - (in/out) object to which the frame is to be added // frame - (in) frame data. // copy_data - (in) value 1 indicates given data WILL be copied to the mux // object and value 0 indicates data will NOT be copied. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL // or if content of 'frame' is invalid. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxPushFrame( WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data); // Gets the nth frame from the mux object. // The content of 'frame->bitstream' is allocated using malloc(), and NOT // owned by the 'mux' object. It MUST be deallocated by the caller by calling // WebPDataClear(). // nth=0 has a special meaning - last position. // Parameters: // mux - (in) object from which the info is to be fetched // nth - (in) index of the frame in the mux object // frame - (out) data of the returned frame // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL. // WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object. // WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxGetFrame( const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame); // Deletes a frame from the mux object. // nth=0 has a special meaning - last position. // Parameters: // mux - (in/out) object from which a frame is to be deleted // nth - (in) The position from which the frame is to be deleted // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL. // WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object // before deletion. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth); //------------------------------------------------------------------------------ // Animation. // Animation parameters. struct WebPMuxAnimParams { uint32_t bgcolor; // Background color of the canvas stored (in MSB order) as: // Bits 00 to 07: Alpha. // Bits 08 to 15: Red. // Bits 16 to 23: Green. // Bits 24 to 31: Blue. int loop_count; // Number of times to repeat the animation [0 = infinite]. }; // Sets the animation parameters in the mux object. Any existing ANIM chunks // will be removed. // Parameters: // mux - (in/out) object in which ANIM chunk is to be set/added // params - (in) animation parameters. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxSetAnimationParams( WebPMux* mux, const WebPMuxAnimParams* params); // Gets the animation parameters from the mux object. // Parameters: // mux - (in) object from which the animation parameters to be fetched // params - (out) animation parameters extracted from the ANIM chunk // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL. // WEBP_MUX_NOT_FOUND - if ANIM chunk is not present in mux object. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxGetAnimationParams( const WebPMux* mux, WebPMuxAnimParams* params); //------------------------------------------------------------------------------ // Misc Utilities. // Sets the canvas size for the mux object. The width and height can be // specified explicitly or left as zero (0, 0). // * When width and height are specified explicitly, then this frame bound is // enforced during subsequent calls to WebPMuxAssemble() and an error is // reported if any animated frame does not completely fit within the canvas. // * When unspecified (0, 0), the constructed canvas will get the frame bounds // from the bounding-box over all frames after calling WebPMuxAssemble(). // Parameters: // mux - (in) object to which the canvas size is to be set // width - (in) canvas width // height - (in) canvas height // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL; or // width or height are invalid or out of bounds // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxSetCanvasSize(WebPMux* mux, int width, int height); // Gets the canvas size from the mux object. // Note: This method assumes that the VP8X chunk, if present, is up-to-date. // That is, the mux object hasn't been modified since the last call to // WebPMuxAssemble() or WebPMuxCreate(). // Parameters: // mux - (in) object from which the canvas size is to be fetched // width - (out) canvas width // height - (out) canvas height // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux, width or height is NULL. // WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxGetCanvasSize(const WebPMux* mux, int* width, int* height); // Gets the feature flags from the mux object. // Note: This method assumes that the VP8X chunk, if present, is up-to-date. // That is, the mux object hasn't been modified since the last call to // WebPMuxAssemble() or WebPMuxCreate(). // Parameters: // mux - (in) object from which the features are to be fetched // flags - (out) the flags specifying which features are present in the // mux object. This will be an OR of various flag values. // Enum 'WebPFeatureFlags' can be used to test individual flag values. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL. // WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxGetFeatures(const WebPMux* mux, uint32_t* flags); // Gets number of chunks with the given 'id' in the mux object. // Parameters: // mux - (in) object from which the info is to be fetched // id - (in) chunk id specifying the type of chunk // num_elements - (out) number of chunks with the given chunk id // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux, or num_elements is NULL. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxNumChunks(const WebPMux* mux, WebPChunkId id, int* num_elements); // Assembles all chunks in WebP RIFF format and returns in 'assembled_data'. // This function also validates the mux object. // Note: The content of 'assembled_data' will be ignored and overwritten. // Also, the content of 'assembled_data' is allocated using malloc(), and NOT // owned by the 'mux' object. It MUST be deallocated by the caller by calling // WebPDataClear(). It's always safe to call WebPDataClear() upon return, // even in case of error. // Parameters: // mux - (in/out) object whose chunks are to be assembled // assembled_data - (out) assembled WebP data // Returns: // WEBP_MUX_BAD_DATA - if mux object is invalid. // WEBP_MUX_INVALID_ARGUMENT - if mux or assembled_data is NULL. // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success. WEBP_EXTERN WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data); //------------------------------------------------------------------------------ // WebPAnimEncoder API // // This API allows encoding (possibly) animated WebP images. // // Code Example: /* WebPAnimEncoderOptions enc_options; WebPAnimEncoderOptionsInit(&enc_options); // Tune 'enc_options' as needed. WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options); while(<there are more frames>) { WebPConfig config; WebPConfigInit(&config); // Tune 'config' as needed. WebPAnimEncoderAdd(enc, frame, timestamp_ms, &config); } WebPAnimEncoderAdd(enc, NULL, timestamp_ms, NULL); WebPAnimEncoderAssemble(enc, webp_data); WebPAnimEncoderDelete(enc); // Write the 'webp_data' to a file, or re-mux it further. */ typedef struct WebPAnimEncoder WebPAnimEncoder; // Main opaque object. // Forward declarations. Defined in encode.h. struct WebPPicture; struct WebPConfig; // Global options. struct WebPAnimEncoderOptions { WebPMuxAnimParams anim_params; // Animation parameters. int minimize_size; // If true, minimize the output size (slow). Implicitly // disables key-frame insertion. int kmin; int kmax; // Minimum and maximum distance between consecutive key // frames in the output. The library may insert some key // frames as needed to satisfy this criteria. // Note that these conditions should hold: kmax > kmin // and kmin >= kmax / 2 + 1. Also, if kmax <= 0, then // key-frame insertion is disabled; and if kmax == 1, // then all frames will be key-frames (kmin value does // not matter for these special cases). int allow_mixed; // If true, use mixed compression mode; may choose // either lossy and lossless for each frame. int verbose; // If true, print info and warning messages to stderr. uint32_t padding[4]; // Padding for later use. }; // Internal, version-checked, entry point. WEBP_EXTERN int WebPAnimEncoderOptionsInitInternal( WebPAnimEncoderOptions*, int); // Should always be called, to initialize a fresh WebPAnimEncoderOptions // structure before modification. Returns false in case of version mismatch. // WebPAnimEncoderOptionsInit() must have succeeded before using the // 'enc_options' object. static WEBP_INLINE int WebPAnimEncoderOptionsInit( WebPAnimEncoderOptions* enc_options) { return WebPAnimEncoderOptionsInitInternal(enc_options, WEBP_MUX_ABI_VERSION); } // Internal, version-checked, entry point. WEBP_EXTERN WebPAnimEncoder* WebPAnimEncoderNewInternal( int, int, const WebPAnimEncoderOptions*, int); // Creates and initializes a WebPAnimEncoder object. // Parameters: // width/height - (in) canvas width and height of the animation. // enc_options - (in) encoding options; can be passed NULL to pick // reasonable defaults. // Returns: // A pointer to the newly created WebPAnimEncoder object. // Or NULL in case of memory error. static WEBP_INLINE WebPAnimEncoder* WebPAnimEncoderNew( int width, int height, const WebPAnimEncoderOptions* enc_options) { return WebPAnimEncoderNewInternal(width, height, enc_options, WEBP_MUX_ABI_VERSION); } // Optimize the given frame for WebP, encode it and add it to the // WebPAnimEncoder object. // The last call to 'WebPAnimEncoderAdd' should be with frame = NULL, which // indicates that no more frames are to be added. This call is also used to // determine the duration of the last frame. // Parameters: // enc - (in/out) object to which the frame is to be added. // frame - (in/out) frame data in ARGB or YUV(A) format. If it is in YUV(A) // format, it will be converted to ARGB, which incurs a small loss. // timestamp_ms - (in) timestamp of this frame in milliseconds. // Duration of a frame would be calculated as // "timestamp of next frame - timestamp of this frame". // Hence, timestamps should be in non-decreasing order. // config - (in) encoding options; can be passed NULL to pick // reasonable defaults. // Returns: // On error, returns false and frame->error_code is set appropriately. // Otherwise, returns true. WEBP_EXTERN int WebPAnimEncoderAdd( WebPAnimEncoder* enc, struct WebPPicture* frame, int timestamp_ms, const struct WebPConfig* config); // Assemble all frames added so far into a WebP bitstream. // This call should be preceded by a call to 'WebPAnimEncoderAdd' with // frame = NULL; if not, the duration of the last frame will be internally // estimated. // Parameters: // enc - (in/out) object from which the frames are to be assembled. // webp_data - (out) generated WebP bitstream. // Returns: // True on success. WEBP_EXTERN int WebPAnimEncoderAssemble(WebPAnimEncoder* enc, WebPData* webp_data); // Get error string corresponding to the most recent call using 'enc'. The // returned string is owned by 'enc' and is valid only until the next call to // WebPAnimEncoderAdd() or WebPAnimEncoderAssemble() or WebPAnimEncoderDelete(). // Parameters: // enc - (in/out) object from which the error string is to be fetched. // Returns: // NULL if 'enc' is NULL. Otherwise, returns the error string if the last call // to 'enc' had an error, or an empty string if the last call was a success. WEBP_EXTERN const char* WebPAnimEncoderGetError(WebPAnimEncoder* enc); // Deletes the WebPAnimEncoder object. // Parameters: // enc - (in/out) object to be deleted WEBP_EXTERN void WebPAnimEncoderDelete(WebPAnimEncoder* enc); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_MUX_H_ */ webp/decode.h 0000644 00000055156 15146341150 0007111 0 ustar 00 // Copyright 2010 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Main decoding functions for WebP images. // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_WEBP_DECODE_H_ #define WEBP_WEBP_DECODE_H_ #include "./types.h" #ifdef __cplusplus extern "C" { #endif #define WEBP_DECODER_ABI_VERSION 0x0208 // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. // typedef enum VP8StatusCode VP8StatusCode; // typedef enum WEBP_CSP_MODE WEBP_CSP_MODE; typedef struct WebPRGBABuffer WebPRGBABuffer; typedef struct WebPYUVABuffer WebPYUVABuffer; typedef struct WebPDecBuffer WebPDecBuffer; typedef struct WebPIDecoder WebPIDecoder; typedef struct WebPBitstreamFeatures WebPBitstreamFeatures; typedef struct WebPDecoderOptions WebPDecoderOptions; typedef struct WebPDecoderConfig WebPDecoderConfig; // Return the decoder's version number, packed in hexadecimal using 8bits for // each of major/minor/revision. E.g: v2.5.7 is 0x020507. WEBP_EXTERN int WebPGetDecoderVersion(void); // Retrieve basic header information: width, height. // This function will also validate the header, returning true on success, // false otherwise. '*width' and '*height' are only valid on successful return. // Pointers 'width' and 'height' can be passed NULL if deemed irrelevant. WEBP_EXTERN int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height); // Decodes WebP images pointed to by 'data' and returns RGBA samples, along // with the dimensions in *width and *height. The ordering of samples in // memory is R, G, B, A, R, G, B, A... in scan order (endian-independent). // The returned pointer should be deleted calling WebPFree(). // Returns NULL in case of error. WEBP_EXTERN uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size, int* width, int* height); // Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data. WEBP_EXTERN uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size, int* width, int* height); // Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data. WEBP_EXTERN uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size, int* width, int* height); // Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data. // If the bitstream contains transparency, it is ignored. WEBP_EXTERN uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, int* width, int* height); // Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data. WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size, int* width, int* height); // Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer // returned is the Y samples buffer. Upon return, *u and *v will point to // the U and V chroma data. These U and V buffers need NOT be passed to // WebPFree(), unlike the returned Y luma one. The dimension of the U and V // planes are both (*width + 1) / 2 and (*height + 1)/ 2. // Upon return, the Y buffer has a stride returned as '*stride', while U and V // have a common stride returned as '*uv_stride'. // Return NULL in case of error. // (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size, int* width, int* height, uint8_t** u, uint8_t** v, int* stride, int* uv_stride); // Releases memory returned by the WebPDecode*() functions above. WEBP_EXTERN void WebPFree(void* ptr); // These five functions are variants of the above ones, that decode the image // directly into a pre-allocated buffer 'output_buffer'. The maximum storage // available in this buffer is indicated by 'output_buffer_size'. If this // storage is not sufficient (or an error occurred), NULL is returned. // Otherwise, output_buffer is returned, for convenience. // The parameter 'output_stride' specifies the distance (in bytes) // between scanlines. Hence, output_buffer_size is expected to be at least // output_stride x picture-height. WEBP_EXTERN uint8_t* WebPDecodeRGBAInto( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); WEBP_EXTERN uint8_t* WebPDecodeARGBInto( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); WEBP_EXTERN uint8_t* WebPDecodeBGRAInto( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); // RGB and BGR variants. Here too the transparency information, if present, // will be dropped and ignored. WEBP_EXTERN uint8_t* WebPDecodeRGBInto( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); WEBP_EXTERN uint8_t* WebPDecodeBGRInto( const uint8_t* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); // WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly // into pre-allocated luma/chroma plane buffers. This function requires the // strides to be passed: one for the luma plane and one for each of the // chroma ones. The size of each plane buffer is passed as 'luma_size', // 'u_size' and 'v_size' respectively. // Pointer to the luma plane ('*luma') is returned or NULL if an error occurred // during decoding (or because some buffers were found to be too small). WEBP_EXTERN uint8_t* WebPDecodeYUVInto( const uint8_t* data, size_t data_size, uint8_t* luma, size_t luma_size, int luma_stride, uint8_t* u, size_t u_size, int u_stride, uint8_t* v, size_t v_size, int v_stride); //------------------------------------------------------------------------------ // Output colorspaces and buffer // Colorspaces // Note: the naming describes the byte-ordering of packed samples in memory. // For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,... // Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels. // RGBA-4444 and RGB-565 colorspaces are represented by following byte-order: // RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ... // RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ... // In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for // these two modes: // RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ... // RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ... typedef enum WEBP_CSP_MODE { MODE_RGB = 0, MODE_RGBA = 1, MODE_BGR = 2, MODE_BGRA = 3, MODE_ARGB = 4, MODE_RGBA_4444 = 5, MODE_RGB_565 = 6, // RGB-premultiplied transparent modes (alpha value is preserved) MODE_rgbA = 7, MODE_bgrA = 8, MODE_Argb = 9, MODE_rgbA_4444 = 10, // YUV modes must come after RGB ones. MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0 MODE_LAST = 13 } WEBP_CSP_MODE; // Some useful macros: static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) { return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb || mode == MODE_rgbA_4444); } static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) { return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB || mode == MODE_RGBA_4444 || mode == MODE_YUVA || WebPIsPremultipliedMode(mode)); } static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) { return (mode < MODE_YUV); } //------------------------------------------------------------------------------ // WebPDecBuffer: Generic structure for describing the output sample buffer. struct WebPRGBABuffer { // view as RGBA uint8_t* rgba; // pointer to RGBA samples int stride; // stride in bytes from one scanline to the next. size_t size; // total size of the *rgba buffer. }; struct WebPYUVABuffer { // view as YUVA uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples int y_stride; // luma stride int u_stride, v_stride; // chroma strides int a_stride; // alpha stride size_t y_size; // luma plane size size_t u_size, v_size; // chroma planes size size_t a_size; // alpha-plane size }; // Output buffer struct WebPDecBuffer { WEBP_CSP_MODE colorspace; // Colorspace. int width, height; // Dimensions. int is_external_memory; // If non-zero, 'internal_memory' pointer is not // used. If value is '2' or more, the external // memory is considered 'slow' and multiple // read/write will be avoided. union { WebPRGBABuffer RGBA; WebPYUVABuffer YUVA; } u; // Nameless union of buffer parameters. uint32_t pad[4]; // padding for later use uint8_t* private_memory; // Internally allocated memory (only when // is_external_memory is 0). Should not be used // externally, but accessed via the buffer union. }; // Internal, version-checked, entry point WEBP_EXTERN int WebPInitDecBufferInternal(WebPDecBuffer*, int); // Initialize the structure as empty. Must be called before any other use. // Returns false in case of version mismatch static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) { return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION); } // Free any memory associated with the buffer. Must always be called last. // Note: doesn't free the 'buffer' structure itself. WEBP_EXTERN void WebPFreeDecBuffer(WebPDecBuffer* buffer); //------------------------------------------------------------------------------ // Enumeration of the status codes typedef enum VP8StatusCode { VP8_STATUS_OK = 0, VP8_STATUS_OUT_OF_MEMORY, VP8_STATUS_INVALID_PARAM, VP8_STATUS_BITSTREAM_ERROR, VP8_STATUS_UNSUPPORTED_FEATURE, VP8_STATUS_SUSPENDED, VP8_STATUS_USER_ABORT, VP8_STATUS_NOT_ENOUGH_DATA } VP8StatusCode; //------------------------------------------------------------------------------ // Incremental decoding // // This API allows streamlined decoding of partial data. // Picture can be incrementally decoded as data become available thanks to the // WebPIDecoder object. This object can be left in a SUSPENDED state if the // picture is only partially decoded, pending additional input. // Code example: // // WebPInitDecBuffer(&output_buffer); // output_buffer.colorspace = mode; // ... // WebPIDecoder* idec = WebPINewDecoder(&output_buffer); // while (additional_data_is_available) { // // ... (get additional data in some new_data[] buffer) // status = WebPIAppend(idec, new_data, new_data_size); // if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { // break; // an error occurred. // } // // // The above call decodes the current available buffer. // // Part of the image can now be refreshed by calling // // WebPIDecGetRGB()/WebPIDecGetYUVA() etc. // } // WebPIDelete(idec); // Creates a new incremental decoder with the supplied buffer parameter. // This output_buffer can be passed NULL, in which case a default output buffer // is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer' // is kept, which means that the lifespan of 'output_buffer' must be larger than // that of the returned WebPIDecoder object. // The supplied 'output_buffer' content MUST NOT be changed between calls to // WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is // not set to 0. In such a case, it is allowed to modify the pointers, size and // stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain // within valid bounds. // All other fields of WebPDecBuffer MUST remain constant between calls. // Returns NULL if the allocation failed. WEBP_EXTERN WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer); // This function allocates and initializes an incremental-decoder object, which // will output the RGB/A samples specified by 'csp' into a preallocated // buffer 'output_buffer'. The size of this buffer is at least // 'output_buffer_size' and the stride (distance in bytes between two scanlines) // is specified by 'output_stride'. // Additionally, output_buffer can be passed NULL in which case the output // buffer will be allocated automatically when the decoding starts. The // colorspace 'csp' is taken into account for allocating this buffer. All other // parameters are ignored. // Returns NULL if the allocation failed, or if some parameters are invalid. WEBP_EXTERN WebPIDecoder* WebPINewRGB( WEBP_CSP_MODE csp, uint8_t* output_buffer, size_t output_buffer_size, int output_stride); // This function allocates and initializes an incremental-decoder object, which // will output the raw luma/chroma samples into a preallocated planes if // supplied. The luma plane is specified by its pointer 'luma', its size // 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane // is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v // plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer // can be pass NULL in case one is not interested in the transparency plane. // Conversely, 'luma' can be passed NULL if no preallocated planes are supplied. // In this case, the output buffer will be automatically allocated (using // MODE_YUVA) when decoding starts. All parameters are then ignored. // Returns NULL if the allocation failed or if a parameter is invalid. WEBP_EXTERN WebPIDecoder* WebPINewYUVA( uint8_t* luma, size_t luma_size, int luma_stride, uint8_t* u, size_t u_size, int u_stride, uint8_t* v, size_t v_size, int v_stride, uint8_t* a, size_t a_size, int a_stride); // Deprecated version of the above, without the alpha plane. // Kept for backward compatibility. WEBP_EXTERN WebPIDecoder* WebPINewYUV( uint8_t* luma, size_t luma_size, int luma_stride, uint8_t* u, size_t u_size, int u_stride, uint8_t* v, size_t v_size, int v_stride); // Deletes the WebPIDecoder object and associated memory. Must always be called // if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded. WEBP_EXTERN void WebPIDelete(WebPIDecoder* idec); // Copies and decodes the next available data. Returns VP8_STATUS_OK when // the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more // data is expected. Returns error in other cases. WEBP_EXTERN VP8StatusCode WebPIAppend( WebPIDecoder* idec, const uint8_t* data, size_t data_size); // A variant of the above function to be used when data buffer contains // partial data from the beginning. In this case data buffer is not copied // to the internal memory. // Note that the value of the 'data' pointer can change between calls to // WebPIUpdate, for instance when the data buffer is resized to fit larger data. WEBP_EXTERN VP8StatusCode WebPIUpdate( WebPIDecoder* idec, const uint8_t* data, size_t data_size); // Returns the RGB/A image decoded so far. Returns NULL if output params // are not initialized yet. The RGB/A output type corresponds to the colorspace // specified during call to WebPINewDecoder() or WebPINewRGB(). // *last_y is the index of last decoded row in raster scan order. Some pointers // (*last_y, *width etc.) can be NULL if corresponding information is not // needed. The values in these pointers are only valid on successful (non-NULL) // return. WEBP_EXTERN uint8_t* WebPIDecGetRGB( const WebPIDecoder* idec, int* last_y, int* width, int* height, int* stride); // Same as above function to get a YUVA image. Returns pointer to the luma // plane or NULL in case of error. If there is no alpha information // the alpha pointer '*a' will be returned NULL. WEBP_EXTERN uint8_t* WebPIDecGetYUVA( const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v, uint8_t** a, int* width, int* height, int* stride, int* uv_stride, int* a_stride); // Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the // alpha information (if present). Kept for backward compatibility. static WEBP_INLINE uint8_t* WebPIDecGetYUV( const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v, int* width, int* height, int* stride, int* uv_stride) { return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height, stride, uv_stride, NULL); } // Generic call to retrieve information about the displayable area. // If non NULL, the left/right/width/height pointers are filled with the visible // rectangular area so far. // Returns NULL in case the incremental decoder object is in an invalid state. // Otherwise returns the pointer to the internal representation. This structure // is read-only, tied to WebPIDecoder's lifespan and should not be modified. WEBP_EXTERN const WebPDecBuffer* WebPIDecodedArea( const WebPIDecoder* idec, int* left, int* top, int* width, int* height); //------------------------------------------------------------------------------ // Advanced decoding parametrization // // Code sample for using the advanced decoding API /* // A) Init a configuration object WebPDecoderConfig config; CHECK(WebPInitDecoderConfig(&config)); // B) optional: retrieve the bitstream's features. CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK); // C) Adjust 'config', if needed config.no_fancy_upsampling = 1; config.output.colorspace = MODE_BGRA; // etc. // Note that you can also make config.output point to an externally // supplied memory buffer, provided it's big enough to store the decoded // picture. Otherwise, config.output will just be used to allocate memory // and store the decoded picture. // D) Decode! CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK); // E) Decoded image is now in config.output (and config.output.u.RGBA) // F) Reclaim memory allocated in config's object. It's safe to call // this function even if the memory is external and wasn't allocated // by WebPDecode(). WebPFreeDecBuffer(&config.output); */ // Features gathered from the bitstream struct WebPBitstreamFeatures { int width; // Width in pixels, as read from the bitstream. int height; // Height in pixels, as read from the bitstream. int has_alpha; // True if the bitstream contains an alpha channel. int has_animation; // True if the bitstream is an animation. int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless uint32_t pad[5]; // padding for later use }; // Internal, version-checked, entry point WEBP_EXTERN VP8StatusCode WebPGetFeaturesInternal( const uint8_t*, size_t, WebPBitstreamFeatures*, int); // Retrieve features from the bitstream. The *features structure is filled // with information gathered from the bitstream. // Returns VP8_STATUS_OK when the features are successfully retrieved. Returns // VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the // features from headers. Returns error in other cases. static WEBP_INLINE VP8StatusCode WebPGetFeatures( const uint8_t* data, size_t data_size, WebPBitstreamFeatures* features) { return WebPGetFeaturesInternal(data, data_size, features, WEBP_DECODER_ABI_VERSION); } // Decoding options struct WebPDecoderOptions { int bypass_filtering; // if true, skip the in-loop filtering int no_fancy_upsampling; // if true, use faster pointwise upsampler int use_cropping; // if true, cropping is applied _first_ int crop_left, crop_top; // top-left position for cropping. // Will be snapped to even values. int crop_width, crop_height; // dimension of the cropping area int use_scaling; // if true, scaling is applied _afterward_ int scaled_width, scaled_height; // final resolution int use_threads; // if true, use multi-threaded decoding int dithering_strength; // dithering strength (0=Off, 100=full) int flip; // flip output vertically int alpha_dithering_strength; // alpha dithering strength in [0..100] uint32_t pad[5]; // padding for later use }; // Main object storing the configuration for advanced decoding. struct WebPDecoderConfig { WebPBitstreamFeatures input; // Immutable bitstream features (optional) WebPDecBuffer output; // Output buffer (can point to external mem) WebPDecoderOptions options; // Decoding options }; // Internal, version-checked, entry point WEBP_EXTERN int WebPInitDecoderConfigInternal(WebPDecoderConfig*, int); // Initialize the configuration as empty. This function must always be // called first, unless WebPGetFeatures() is to be called. // Returns false in case of mismatched version. static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) { return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION); } // Instantiate a new incremental decoder object with the requested // configuration. The bitstream can be passed using 'data' and 'data_size' // parameter, in which case the features will be parsed and stored into // config->input. Otherwise, 'data' can be NULL and no parsing will occur. // Note that 'config' can be NULL too, in which case a default configuration // is used. If 'config' is not NULL, it must outlive the WebPIDecoder object // as some references to its fields will be used. No internal copy of 'config' // is made. // The return WebPIDecoder object must always be deleted calling WebPIDelete(). // Returns NULL in case of error (and config->status will then reflect // the error condition, if available). WEBP_EXTERN WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size, WebPDecoderConfig* config); // Non-incremental version. This version decodes the full data at once, taking // 'config' into account. Returns decoding status (which should be VP8_STATUS_OK // if the decoding was successful). Note that 'config' cannot be NULL. WEBP_EXTERN VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size, WebPDecoderConfig* config); #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_DECODE_H_ */ webp/mux_types.h 0000644 00000006116 15146341150 0007713 0 ustar 00 // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Data-types common to the mux and demux libraries. // // Author: Urvang (urvang@google.com) #ifndef WEBP_WEBP_MUX_TYPES_H_ #define WEBP_WEBP_MUX_TYPES_H_ #include <stdlib.h> // free() #include <string.h> // memset() #include "./types.h" #ifdef __cplusplus extern "C" { #endif // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. // typedef enum WebPFeatureFlags WebPFeatureFlags; // typedef enum WebPMuxAnimDispose WebPMuxAnimDispose; // typedef enum WebPMuxAnimBlend WebPMuxAnimBlend; typedef struct WebPData WebPData; // VP8X Feature Flags. typedef enum WebPFeatureFlags { ANIMATION_FLAG = 0x00000002, XMP_FLAG = 0x00000004, EXIF_FLAG = 0x00000008, ALPHA_FLAG = 0x00000010, ICCP_FLAG = 0x00000020, ALL_VALID_FLAGS = 0x0000003e } WebPFeatureFlags; // Dispose method (animation only). Indicates how the area used by the current // frame is to be treated before rendering the next frame on the canvas. typedef enum WebPMuxAnimDispose { WEBP_MUX_DISPOSE_NONE, // Do not dispose. WEBP_MUX_DISPOSE_BACKGROUND // Dispose to background color. } WebPMuxAnimDispose; // Blend operation (animation only). Indicates how transparent pixels of the // current frame are blended with those of the previous canvas. typedef enum WebPMuxAnimBlend { WEBP_MUX_BLEND, // Blend. WEBP_MUX_NO_BLEND // Do not blend. } WebPMuxAnimBlend; // Data type used to describe 'raw' data, e.g., chunk data // (ICC profile, metadata) and WebP compressed image data. struct WebPData { const uint8_t* bytes; size_t size; }; // Initializes the contents of the 'webp_data' object with default values. static WEBP_INLINE void WebPDataInit(WebPData* webp_data) { if (webp_data != NULL) { memset(webp_data, 0, sizeof(*webp_data)); } } // Clears the contents of the 'webp_data' object by calling free(). Does not // deallocate the object itself. static WEBP_INLINE void WebPDataClear(WebPData* webp_data) { if (webp_data != NULL) { free((void*)webp_data->bytes); WebPDataInit(webp_data); } } // Allocates necessary storage for 'dst' and copies the contents of 'src'. // Returns true on success. static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) { if (src == NULL || dst == NULL) return 0; WebPDataInit(dst); if (src->bytes != NULL && src->size != 0) { dst->bytes = (uint8_t*)malloc(src->size); if (dst->bytes == NULL) return 0; memcpy((void*)dst->bytes, src->bytes, src->size); dst->size = src->size; } return 1; } #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_MUX_TYPES_H_ */ webp/demux.h 0000644 00000036366 15146341150 0007012 0 ustar 00 // Copyright 2012 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Demux API. // Enables extraction of image and extended format data from WebP files. // Code Example: Demuxing WebP data to extract all the frames, ICC profile // and EXIF/XMP metadata. /* WebPDemuxer* demux = WebPDemux(&webp_data); uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); // ... (Get information about the features present in the WebP file). uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); // ... (Iterate over all frames). WebPIterator iter; if (WebPDemuxGetFrame(demux, 1, &iter)) { do { // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), // ... and get other frame properties like width, height, offsets etc. // ... see 'struct WebPIterator' below for more info). } while (WebPDemuxNextFrame(&iter)); WebPDemuxReleaseIterator(&iter); } // ... (Extract metadata). WebPChunkIterator chunk_iter; if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter); // ... (Consume the ICC profile in 'chunk_iter.chunk'). WebPDemuxReleaseChunkIterator(&chunk_iter); if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter); // ... (Consume the EXIF metadata in 'chunk_iter.chunk'). WebPDemuxReleaseChunkIterator(&chunk_iter); if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter); // ... (Consume the XMP metadata in 'chunk_iter.chunk'). WebPDemuxReleaseChunkIterator(&chunk_iter); WebPDemuxDelete(demux); */ #ifndef WEBP_WEBP_DEMUX_H_ #define WEBP_WEBP_DEMUX_H_ #include "./decode.h" // for WEBP_CSP_MODE #include "./mux_types.h" #ifdef __cplusplus extern "C" { #endif #define WEBP_DEMUX_ABI_VERSION 0x0107 // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. // typedef enum WebPDemuxState WebPDemuxState; // typedef enum WebPFormatFeature WebPFormatFeature; typedef struct WebPDemuxer WebPDemuxer; typedef struct WebPIterator WebPIterator; typedef struct WebPChunkIterator WebPChunkIterator; typedef struct WebPAnimInfo WebPAnimInfo; typedef struct WebPAnimDecoderOptions WebPAnimDecoderOptions; //------------------------------------------------------------------------------ // Returns the version number of the demux library, packed in hexadecimal using // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. WEBP_EXTERN int WebPGetDemuxVersion(void); //------------------------------------------------------------------------------ // Life of a Demux object typedef enum WebPDemuxState { WEBP_DEMUX_PARSE_ERROR = -1, // An error occurred while parsing. WEBP_DEMUX_PARSING_HEADER = 0, // Not enough data to parse full header. WEBP_DEMUX_PARSED_HEADER = 1, // Header parsing complete, // data may be available. WEBP_DEMUX_DONE = 2 // Entire file has been parsed. } WebPDemuxState; // Internal, version-checked, entry point WEBP_EXTERN WebPDemuxer* WebPDemuxInternal( const WebPData*, int, WebPDemuxState*, int); // Parses the full WebP file given by 'data'. For single images the WebP file // header alone or the file header and the chunk header may be absent. // Returns a WebPDemuxer object on successful parse, NULL otherwise. static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) { return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION); } // Parses the possibly incomplete WebP file given by 'data'. // If 'state' is non-NULL it will be set to indicate the status of the demuxer. // Returns NULL in case of error or if there isn't enough data to start parsing; // and a WebPDemuxer object on successful parse. // Note that WebPDemuxer keeps internal pointers to 'data' memory segment. // If this data is volatile, the demuxer object should be deleted (by calling // WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data. // This is usually an inexpensive operation. static WEBP_INLINE WebPDemuxer* WebPDemuxPartial( const WebPData* data, WebPDemuxState* state) { return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION); } // Frees memory associated with 'dmux'. WEBP_EXTERN void WebPDemuxDelete(WebPDemuxer* dmux); //------------------------------------------------------------------------------ // Data/information extraction. typedef enum WebPFormatFeature { WEBP_FF_FORMAT_FLAGS, // bit-wise combination of WebPFeatureFlags // corresponding to the 'VP8X' chunk (if present). WEBP_FF_CANVAS_WIDTH, WEBP_FF_CANVAS_HEIGHT, WEBP_FF_LOOP_COUNT, // only relevant for animated file WEBP_FF_BACKGROUND_COLOR, // idem. WEBP_FF_FRAME_COUNT // Number of frames present in the demux object. // In case of a partial demux, this is the number // of frames seen so far, with the last frame // possibly being partial. } WebPFormatFeature; // Get the 'feature' value from the 'dmux'. // NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial() // returned a state > WEBP_DEMUX_PARSING_HEADER. // If 'feature' is WEBP_FF_FORMAT_FLAGS, the returned value is a bit-wise // combination of WebPFeatureFlags values. // If 'feature' is WEBP_FF_LOOP_COUNT, WEBP_FF_BACKGROUND_COLOR, the returned // value is only meaningful if the bitstream is animated. WEBP_EXTERN uint32_t WebPDemuxGetI( const WebPDemuxer* dmux, WebPFormatFeature feature); //------------------------------------------------------------------------------ // Frame iteration. struct WebPIterator { int frame_num; int num_frames; // equivalent to WEBP_FF_FRAME_COUNT. int x_offset, y_offset; // offset relative to the canvas. int width, height; // dimensions of this frame. int duration; // display duration in milliseconds. WebPMuxAnimDispose dispose_method; // dispose method for the frame. int complete; // true if 'fragment' contains a full frame. partial images // may still be decoded with the WebP incremental decoder. WebPData fragment; // The frame given by 'frame_num'. Note for historical // reasons this is called a fragment. int has_alpha; // True if the frame contains transparency. WebPMuxAnimBlend blend_method; // Blend operation for the frame. uint32_t pad[2]; // padding for later use. void* private_; // for internal use only. }; // Retrieves frame 'frame_number' from 'dmux'. // 'iter->fragment' points to the frame on return from this function. // Setting 'frame_number' equal to 0 will return the last frame of the image. // Returns false if 'dmux' is NULL or frame 'frame_number' is not present. // Call WebPDemuxReleaseIterator() when use of the iterator is complete. // NOTE: 'dmux' must persist for the lifetime of 'iter'. WEBP_EXTERN int WebPDemuxGetFrame( const WebPDemuxer* dmux, int frame_number, WebPIterator* iter); // Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or // previous ('iter->frame_num' - 1) frame. These functions do not loop. // Returns true on success, false otherwise. WEBP_EXTERN int WebPDemuxNextFrame(WebPIterator* iter); WEBP_EXTERN int WebPDemuxPrevFrame(WebPIterator* iter); // Releases any memory associated with 'iter'. // Must be called before any subsequent calls to WebPDemuxGetChunk() on the same // iter. Also, must be called before destroying the associated WebPDemuxer with // WebPDemuxDelete(). WEBP_EXTERN void WebPDemuxReleaseIterator(WebPIterator* iter); //------------------------------------------------------------------------------ // Chunk iteration. struct WebPChunkIterator { // The current and total number of chunks with the fourcc given to // WebPDemuxGetChunk(). int chunk_num; int num_chunks; WebPData chunk; // The payload of the chunk. uint32_t pad[6]; // padding for later use void* private_; }; // Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from // 'dmux'. // 'fourcc' is a character array containing the fourcc of the chunk to return, // e.g., "ICCP", "XMP ", "EXIF", etc. // Setting 'chunk_number' equal to 0 will return the last chunk in a set. // Returns true if the chunk is found, false otherwise. Image related chunk // payloads are accessed through WebPDemuxGetFrame() and related functions. // Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete. // NOTE: 'dmux' must persist for the lifetime of the iterator. WEBP_EXTERN int WebPDemuxGetChunk(const WebPDemuxer* dmux, const char fourcc[4], int chunk_number, WebPChunkIterator* iter); // Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous // ('iter->chunk_num' - 1) chunk. These functions do not loop. // Returns true on success, false otherwise. WEBP_EXTERN int WebPDemuxNextChunk(WebPChunkIterator* iter); WEBP_EXTERN int WebPDemuxPrevChunk(WebPChunkIterator* iter); // Releases any memory associated with 'iter'. // Must be called before destroying the associated WebPDemuxer with // WebPDemuxDelete(). WEBP_EXTERN void WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter); //------------------------------------------------------------------------------ // WebPAnimDecoder API // // This API allows decoding (possibly) animated WebP images. // // Code Example: /* WebPAnimDecoderOptions dec_options; WebPAnimDecoderOptionsInit(&dec_options); // Tune 'dec_options' as needed. WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options); WebPAnimInfo anim_info; WebPAnimDecoderGetInfo(dec, &anim_info); for (uint32_t i = 0; i < anim_info.loop_count; ++i) { while (WebPAnimDecoderHasMoreFrames(dec)) { uint8_t* buf; int timestamp; WebPAnimDecoderGetNext(dec, &buf, ×tamp); // ... (Render 'buf' based on 'timestamp'). // ... (Do NOT free 'buf', as it is owned by 'dec'). } WebPAnimDecoderReset(dec); } const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec); // ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data). WebPAnimDecoderDelete(dec); */ typedef struct WebPAnimDecoder WebPAnimDecoder; // Main opaque object. // Global options. struct WebPAnimDecoderOptions { // Output colorspace. Only the following modes are supported: // MODE_RGBA, MODE_BGRA, MODE_rgbA and MODE_bgrA. WEBP_CSP_MODE color_mode; int use_threads; // If true, use multi-threaded decoding. uint32_t padding[7]; // Padding for later use. }; // Internal, version-checked, entry point. WEBP_EXTERN int WebPAnimDecoderOptionsInitInternal( WebPAnimDecoderOptions*, int); // Should always be called, to initialize a fresh WebPAnimDecoderOptions // structure before modification. Returns false in case of version mismatch. // WebPAnimDecoderOptionsInit() must have succeeded before using the // 'dec_options' object. static WEBP_INLINE int WebPAnimDecoderOptionsInit( WebPAnimDecoderOptions* dec_options) { return WebPAnimDecoderOptionsInitInternal(dec_options, WEBP_DEMUX_ABI_VERSION); } // Internal, version-checked, entry point. WEBP_EXTERN WebPAnimDecoder* WebPAnimDecoderNewInternal( const WebPData*, const WebPAnimDecoderOptions*, int); // Creates and initializes a WebPAnimDecoder object. // Parameters: // webp_data - (in) WebP bitstream. This should remain unchanged during the // lifetime of the output WebPAnimDecoder object. // dec_options - (in) decoding options. Can be passed NULL to choose // reasonable defaults (in particular, color mode MODE_RGBA // will be picked). // Returns: // A pointer to the newly created WebPAnimDecoder object, or NULL in case of // parsing error, invalid option or memory error. static WEBP_INLINE WebPAnimDecoder* WebPAnimDecoderNew( const WebPData* webp_data, const WebPAnimDecoderOptions* dec_options) { return WebPAnimDecoderNewInternal(webp_data, dec_options, WEBP_DEMUX_ABI_VERSION); } // Global information about the animation.. struct WebPAnimInfo { uint32_t canvas_width; uint32_t canvas_height; uint32_t loop_count; uint32_t bgcolor; uint32_t frame_count; uint32_t pad[4]; // padding for later use }; // Get global information about the animation. // Parameters: // dec - (in) decoder instance to get information from. // info - (out) global information fetched from the animation. // Returns: // True on success. WEBP_EXTERN int WebPAnimDecoderGetInfo(const WebPAnimDecoder* dec, WebPAnimInfo* info); // Fetch the next frame from 'dec' based on options supplied to // WebPAnimDecoderNew(). This will be a fully reconstructed canvas of size // 'canvas_width * 4 * canvas_height', and not just the frame sub-rectangle. The // returned buffer 'buf' is valid only until the next call to // WebPAnimDecoderGetNext(), WebPAnimDecoderReset() or WebPAnimDecoderDelete(). // Parameters: // dec - (in/out) decoder instance from which the next frame is to be fetched. // buf - (out) decoded frame. // timestamp - (out) timestamp of the frame in milliseconds. // Returns: // False if any of the arguments are NULL, or if there is a parsing or // decoding error, or if there are no more frames. Otherwise, returns true. WEBP_EXTERN int WebPAnimDecoderGetNext(WebPAnimDecoder* dec, uint8_t** buf, int* timestamp); // Check if there are more frames left to decode. // Parameters: // dec - (in) decoder instance to be checked. // Returns: // True if 'dec' is not NULL and some frames are yet to be decoded. // Otherwise, returns false. WEBP_EXTERN int WebPAnimDecoderHasMoreFrames(const WebPAnimDecoder* dec); // Resets the WebPAnimDecoder object, so that next call to // WebPAnimDecoderGetNext() will restart decoding from 1st frame. This would be // helpful when all frames need to be decoded multiple times (e.g. // info.loop_count times) without destroying and recreating the 'dec' object. // Parameters: // dec - (in/out) decoder instance to be reset WEBP_EXTERN void WebPAnimDecoderReset(WebPAnimDecoder* dec); // Grab the internal demuxer object. // Getting the demuxer object can be useful if one wants to use operations only // available through demuxer; e.g. to get XMP/EXIF/ICC metadata. The returned // demuxer object is owned by 'dec' and is valid only until the next call to // WebPAnimDecoderDelete(). // // Parameters: // dec - (in) decoder instance from which the demuxer object is to be fetched. WEBP_EXTERN const WebPDemuxer* WebPAnimDecoderGetDemuxer( const WebPAnimDecoder* dec); // Deletes the WebPAnimDecoder object. // Parameters: // dec - (in/out) decoder instance to be deleted WEBP_EXTERN void WebPAnimDecoderDelete(WebPAnimDecoder* dec); #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_DEMUX_H_ */ webp/encode.h 0000644 00000065531 15146341150 0007121 0 ustar 00 // Copyright 2011 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // WebP encoder: main interface // // Author: Skal (pascal.massimino@gmail.com) #ifndef WEBP_WEBP_ENCODE_H_ #define WEBP_WEBP_ENCODE_H_ #include "./types.h" #ifdef __cplusplus extern "C" { #endif #define WEBP_ENCODER_ABI_VERSION 0x020e // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. // typedef enum WebPImageHint WebPImageHint; // typedef enum WebPEncCSP WebPEncCSP; // typedef enum WebPPreset WebPPreset; // typedef enum WebPEncodingError WebPEncodingError; typedef struct WebPConfig WebPConfig; typedef struct WebPPicture WebPPicture; // main structure for I/O typedef struct WebPAuxStats WebPAuxStats; typedef struct WebPMemoryWriter WebPMemoryWriter; // Return the encoder's version number, packed in hexadecimal using 8bits for // each of major/minor/revision. E.g: v2.5.7 is 0x020507. WEBP_EXTERN int WebPGetEncoderVersion(void); //------------------------------------------------------------------------------ // One-stop-shop call! No questions asked: // Returns the size of the compressed data (pointed to by *output), or 0 if // an error occurred. The compressed data must be released by the caller // using the call 'WebPFree(*output)'. // These functions compress using the lossy format, and the quality_factor // can go from 0 (smaller output, lower quality) to 100 (best quality, // larger output). WEBP_EXTERN size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output); WEBP_EXTERN size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride, float quality_factor, uint8_t** output); WEBP_EXTERN size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride, float quality_factor, uint8_t** output); WEBP_EXTERN size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride, float quality_factor, uint8_t** output); // These functions are the equivalent of the above, but compressing in a // lossless manner. Files are usually larger than lossy format, but will // not suffer any compression loss. WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height, int stride, uint8_t** output); WEBP_EXTERN size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height, int stride, uint8_t** output); WEBP_EXTERN size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height, int stride, uint8_t** output); WEBP_EXTERN size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height, int stride, uint8_t** output); // Releases memory returned by the WebPEncode*() functions above. WEBP_EXTERN void WebPFree(void* ptr); //------------------------------------------------------------------------------ // Coding parameters // Image characteristics hint for the underlying encoder. typedef enum WebPImageHint { WEBP_HINT_DEFAULT = 0, // default preset. WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc). WEBP_HINT_LAST } WebPImageHint; // Compression parameters. struct WebPConfig { int lossless; // Lossless encoding (0=lossy(default), 1=lossless). float quality; // between 0 and 100. For lossy, 0 gives the smallest // size and 100 the largest. For lossless, this // parameter is the amount of effort put into the // compression: 0 is the fastest but gives larger // files compared to the slowest, but best, 100. int method; // quality/speed trade-off (0=fast, 6=slower-better) WebPImageHint image_hint; // Hint for image type (lossless only for now). int target_size; // if non-zero, set the desired target size in bytes. // Takes precedence over the 'compression' parameter. float target_PSNR; // if non-zero, specifies the minimal distortion to // try to achieve. Takes precedence over target_size. int segments; // maximum number of segments to use, in [1..4] int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum. int filter_strength; // range: [0 = off .. 100 = strongest] int filter_sharpness; // range: [0 = off .. 7 = least sharp] int filter_type; // filtering type: 0 = simple, 1 = strong (only used // if filter_strength > 0 or autofilter > 0) int autofilter; // Auto adjust filter's strength [0 = off, 1 = on] int alpha_compression; // Algorithm for encoding the alpha plane (0 = none, // 1 = compressed with WebP lossless). Default is 1. int alpha_filtering; // Predictive filtering method for alpha plane. // 0: none, 1: fast, 2: best. Default if 1. int alpha_quality; // Between 0 (smallest size) and 100 (lossless). // Default is 100. int pass; // number of entropy-analysis passes (in [1..10]). int show_compressed; // if true, export the compressed picture back. // In-loop filtering is not applied. int preprocessing; // preprocessing filter: // 0=none, 1=segment-smooth, 2=pseudo-random dithering int partitions; // log2(number of token partitions) in [0..3]. Default // is set to 0 for easier progressive decoding. int partition_limit; // quality degradation allowed to fit the 512k limit // on prediction modes coding (0: no degradation, // 100: maximum possible degradation). int emulate_jpeg_size; // If true, compression parameters will be remapped // to better match the expected output size from // JPEG compression. Generally, the output size will // be similar but the degradation will be lower. int thread_level; // If non-zero, try and use multi-threaded encoding. int low_memory; // If set, reduce memory usage (but increase CPU use). int near_lossless; // Near lossless encoding [0 = max loss .. 100 = off // (default)]. int exact; // if non-zero, preserve the exact RGB values under // transparent area. Otherwise, discard this invisible // RGB information for better compression. The default // value is 0. int use_delta_palette; // reserved for future lossless feature int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion uint32_t pad[2]; // padding for later use }; // Enumerate some predefined settings for WebPConfig, depending on the type // of source picture. These presets are used when calling WebPConfigPreset(). typedef enum WebPPreset { WEBP_PRESET_DEFAULT = 0, // default preset. WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details WEBP_PRESET_ICON, // small-sized colorful images WEBP_PRESET_TEXT // text-like } WebPPreset; // Internal, version-checked, entry point WEBP_EXTERN int WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int); // Should always be called, to initialize a fresh WebPConfig structure before // modification. Returns false in case of version mismatch. WebPConfigInit() // must have succeeded before using the 'config' object. // Note that the default values are lossless=0 and quality=75. static WEBP_INLINE int WebPConfigInit(WebPConfig* config) { return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f, WEBP_ENCODER_ABI_VERSION); } // This function will initialize the configuration according to a predefined // set of parameters (referred to by 'preset') and a given quality factor. // This function can be called as a replacement to WebPConfigInit(). Will // return false in case of error. static WEBP_INLINE int WebPConfigPreset(WebPConfig* config, WebPPreset preset, float quality) { return WebPConfigInitInternal(config, preset, quality, WEBP_ENCODER_ABI_VERSION); } // Activate the lossless compression mode with the desired efficiency level // between 0 (fastest, lowest compression) and 9 (slower, best compression). // A good default level is '6', providing a fair tradeoff between compression // speed and final compressed size. // This function will overwrite several fields from config: 'method', 'quality' // and 'lossless'. Returns false in case of parameter error. WEBP_EXTERN int WebPConfigLosslessPreset(WebPConfig* config, int level); // Returns true if 'config' is non-NULL and all configuration parameters are // within their valid ranges. WEBP_EXTERN int WebPValidateConfig(const WebPConfig* config); //------------------------------------------------------------------------------ // Input / Output // Structure for storing auxiliary statistics. struct WebPAuxStats { int coded_size; // final size float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha int block_count[3]; // number of intra4/intra16/skipped macroblocks int header_bytes[2]; // approximate number of bytes spent for header // and mode-partition #0 int residual_bytes[3][4]; // approximate number of bytes spent for // DC/AC/uv coefficients for each (0..3) segments. int segment_size[4]; // number of macroblocks in each segments int segment_quant[4]; // quantizer values for each segments int segment_level[4]; // filtering strength for each segments [0..63] int alpha_data_size; // size of the transparency data int layer_data_size; // size of the enhancement layer data // lossless encoder statistics uint32_t lossless_features; // bit0:predictor bit1:cross-color transform // bit2:subtract-green bit3:color indexing int histogram_bits; // number of precision bits of histogram int transform_bits; // precision bits for transform int cache_bits; // number of bits for color cache lookup int palette_size; // number of color in palette, if used int lossless_size; // final lossless size int lossless_hdr_size; // lossless header (transform, huffman etc) size int lossless_data_size; // lossless image data size uint32_t pad[2]; // padding for later use }; // Signature for output function. Should return true if writing was successful. // data/data_size is the segment of data to write, and 'picture' is for // reference (and so one can make use of picture->custom_ptr). typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size, const WebPPicture* picture); // WebPMemoryWrite: a special WebPWriterFunction that writes to memory using // the following WebPMemoryWriter object (to be set as a custom_ptr). struct WebPMemoryWriter { uint8_t* mem; // final buffer (of size 'max_size', larger than 'size'). size_t size; // final size size_t max_size; // total capacity uint32_t pad[1]; // padding for later use }; // The following must be called first before any use. WEBP_EXTERN void WebPMemoryWriterInit(WebPMemoryWriter* writer); // The following must be called to deallocate writer->mem memory. The 'writer' // object itself is not deallocated. WEBP_EXTERN void WebPMemoryWriterClear(WebPMemoryWriter* writer); // The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon // completion, writer.mem and writer.size will hold the coded data. // writer.mem must be freed by calling WebPMemoryWriterClear. WEBP_EXTERN int WebPMemoryWrite(const uint8_t* data, size_t data_size, const WebPPicture* picture); // Progress hook, called from time to time to report progress. It can return // false to request an abort of the encoding process, or true otherwise if // everything is OK. typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture); // Color spaces. typedef enum WebPEncCSP { // chroma sampling WEBP_YUV420 = 0, // 4:2:0 WEBP_YUV420A = 4, // alpha channel variant WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present } WebPEncCSP; // Encoding error conditions. typedef enum WebPEncodingError { VP8_ENC_OK = 0, VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G VP8_ENC_ERROR_USER_ABORT, // abort request by user VP8_ENC_ERROR_LAST // list terminator. always last. } WebPEncodingError; // maximum width/height allowed (inclusive), in pixels #define WEBP_MAX_DIMENSION 16383 // Main exchange structure (input samples, output bytes, statistics) struct WebPPicture { // INPUT ////////////// // Main flag for encoder selecting between ARGB or YUV input. // It is recommended to use ARGB input (*argb, argb_stride) for lossless // compression, and YUV input (*y, *u, *v, etc.) for lossy compression // since these are the respective native colorspace for these formats. int use_argb; // YUV input (mostly used for input to lossy compression) WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr). int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION) uint8_t *y, *u, *v; // pointers to luma/chroma planes. int y_stride, uv_stride; // luma/chroma strides. uint8_t* a; // pointer to the alpha plane int a_stride; // stride of the alpha plane uint32_t pad1[2]; // padding for later use // ARGB input (mostly used for input to lossless compression) uint32_t* argb; // Pointer to argb (32 bit) plane. int argb_stride; // This is stride in pixels units, not bytes. uint32_t pad2[3]; // padding for later use // OUTPUT /////////////// // Byte-emission hook, to store compressed bytes as they are ready. WebPWriterFunction writer; // can be NULL void* custom_ptr; // can be used by the writer. // map for extra information (only for lossy compression mode) int extra_info_type; // 1: intra type, 2: segment, 3: quant // 4: intra-16 prediction mode, // 5: chroma prediction mode, // 6: bit cost, 7: distortion uint8_t* extra_info; // if not NULL, points to an array of size // ((width + 15) / 16) * ((height + 15) / 16) that // will be filled with a macroblock map, depending // on extra_info_type. // STATS AND REPORTS /////////////////////////// // Pointer to side statistics (updated only if not NULL) WebPAuxStats* stats; // Error code for the latest error encountered during encoding WebPEncodingError error_code; // If not NULL, report progress during encoding. WebPProgressHook progress_hook; void* user_data; // this field is free to be set to any value and // used during callbacks (like progress-report e.g.). uint32_t pad3[3]; // padding for later use // Unused for now uint8_t *pad4, *pad5; uint32_t pad6[8]; // padding for later use // PRIVATE FIELDS //////////////////// void* memory_; // row chunk of memory for yuva planes void* memory_argb_; // and for argb too. void* pad7[2]; // padding for later use }; // Internal, version-checked, entry point WEBP_EXTERN int WebPPictureInitInternal(WebPPicture*, int); // Should always be called, to initialize the structure. Returns false in case // of version mismatch. WebPPictureInit() must have succeeded before using the // 'picture' object. // Note that, by default, use_argb is false and colorspace is WEBP_YUV420. static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) { return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION); } //------------------------------------------------------------------------------ // WebPPicture utils // Convenience allocation / deallocation based on picture->width/height: // Allocate y/u/v buffers as per colorspace/width/height specification. // Note! This function will free the previous buffer if needed. // Returns false in case of memory error. WEBP_EXTERN int WebPPictureAlloc(WebPPicture* picture); // Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*(). // Note that this function does _not_ free the memory used by the 'picture' // object itself. // Besides memory (which is reclaimed) all other fields of 'picture' are // preserved. WEBP_EXTERN void WebPPictureFree(WebPPicture* picture); // Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst // will fully own the copied pixels (this is not a view). The 'dst' picture need // not be initialized as its content is overwritten. // Returns false in case of memory allocation error. WEBP_EXTERN int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst); // Compute the single distortion for packed planes of samples. // 'src' will be compared to 'ref', and the raw distortion stored into // '*distortion'. The refined metric (log(MSE), log(1 - ssim),...' will be // stored in '*result'. // 'x_step' is the horizontal stride (in bytes) between samples. // 'src/ref_stride' is the byte distance between rows. // Returns false in case of error (bad parameter, memory allocation error, ...). WEBP_EXTERN int WebPPlaneDistortion(const uint8_t* src, size_t src_stride, const uint8_t* ref, size_t ref_stride, int width, int height, size_t x_step, int type, // 0 = PSNR, 1 = SSIM, 2 = LSIM float* distortion, float* result); // Compute PSNR, SSIM or LSIM distortion metric between two pictures. Results // are in dB, stored in result[] in the B/G/R/A/All order. The distortion is // always performed using ARGB samples. Hence if the input is YUV(A), the // picture will be internally converted to ARGB (just for the measurement). // Warning: this function is rather CPU-intensive. WEBP_EXTERN int WebPPictureDistortion( const WebPPicture* src, const WebPPicture* ref, int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM float result[5]); // self-crops a picture to the rectangle defined by top/left/width/height. // Returns false in case of memory allocation error, or if the rectangle is // outside of the source picture. // The rectangle for the view is defined by the top-left corner pixel // coordinates (left, top) as well as its width and height. This rectangle // must be fully be comprised inside the 'src' source picture. If the source // picture uses the YUV420 colorspace, the top and left coordinates will be // snapped to even values. WEBP_EXTERN int WebPPictureCrop(WebPPicture* picture, int left, int top, int width, int height); // Extracts a view from 'src' picture into 'dst'. The rectangle for the view // is defined by the top-left corner pixel coordinates (left, top) as well // as its width and height. This rectangle must be fully be comprised inside // the 'src' source picture. If the source picture uses the YUV420 colorspace, // the top and left coordinates will be snapped to even values. // Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed // ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so, // the original dimension will be lost). Picture 'dst' need not be initialized // with WebPPictureInit() if it is different from 'src', since its content will // be overwritten. // Returns false in case of memory allocation error or invalid parameters. WEBP_EXTERN int WebPPictureView(const WebPPicture* src, int left, int top, int width, int height, WebPPicture* dst); // Returns true if the 'picture' is actually a view and therefore does // not own the memory for pixels. WEBP_EXTERN int WebPPictureIsView(const WebPPicture* picture); // Rescale a picture to new dimension width x height. // If either 'width' or 'height' (but not both) is 0 the corresponding // dimension will be calculated preserving the aspect ratio. // No gamma correction is applied. // Returns false in case of error (invalid parameter or insufficient memory). WEBP_EXTERN int WebPPictureRescale(WebPPicture* pic, int width, int height); // Colorspace conversion function to import RGB samples. // Previous buffer will be free'd, if any. // *rgb buffer should have a size of at least height * rgb_stride. // Returns false in case of memory error. WEBP_EXTERN int WebPPictureImportRGB( WebPPicture* picture, const uint8_t* rgb, int rgb_stride); // Same, but for RGBA buffer. WEBP_EXTERN int WebPPictureImportRGBA( WebPPicture* picture, const uint8_t* rgba, int rgba_stride); // Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format // input buffer ignoring the alpha channel. Avoids needing to copy the data // to a temporary 24-bit RGB buffer to import the RGB only. WEBP_EXTERN int WebPPictureImportRGBX( WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride); // Variants of the above, but taking BGR(A|X) input. WEBP_EXTERN int WebPPictureImportBGR( WebPPicture* picture, const uint8_t* bgr, int bgr_stride); WEBP_EXTERN int WebPPictureImportBGRA( WebPPicture* picture, const uint8_t* bgra, int bgra_stride); WEBP_EXTERN int WebPPictureImportBGRX( WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride); // Converts picture->argb data to the YUV420A format. The 'colorspace' // parameter is deprecated and should be equal to WEBP_YUV420. // Upon return, picture->use_argb is set to false. The presence of real // non-opaque transparent values is detected, and 'colorspace' will be // adjusted accordingly. Note that this method is lossy. // Returns false in case of error. WEBP_EXTERN int WebPPictureARGBToYUVA(WebPPicture* picture, WebPEncCSP /*colorspace = WEBP_YUV420*/); // Same as WebPPictureARGBToYUVA(), but the conversion is done using // pseudo-random dithering with a strength 'dithering' between // 0.0 (no dithering) and 1.0 (maximum dithering). This is useful // for photographic picture. WEBP_EXTERN int WebPPictureARGBToYUVADithered( WebPPicture* picture, WebPEncCSP colorspace, float dithering); // Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion. // Downsampling is handled with extra care in case of color clipping. This // method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better // and sharper YUV representation. // Returns false in case of error. WEBP_EXTERN int WebPPictureSharpARGBToYUVA(WebPPicture* picture); // kept for backward compatibility: WEBP_EXTERN int WebPPictureSmartARGBToYUVA(WebPPicture* picture); // Converts picture->yuv to picture->argb and sets picture->use_argb to true. // The input format must be YUV_420 or YUV_420A. The conversion from YUV420 to // ARGB incurs a small loss too. // Note that the use of this colorspace is discouraged if one has access to the // raw ARGB samples, since using YUV420 is comparatively lossy. // Returns false in case of error. WEBP_EXTERN int WebPPictureYUVAToARGB(WebPPicture* picture); // Helper function: given a width x height plane of RGBA or YUV(A) samples // clean-up or smoothen the YUV or RGB samples under fully transparent area, // to help compressibility (no guarantee, though). WEBP_EXTERN void WebPCleanupTransparentArea(WebPPicture* picture); // Scan the picture 'picture' for the presence of non fully opaque alpha values. // Returns true in such case. Otherwise returns false (indicating that the // alpha plane can be ignored altogether e.g.). WEBP_EXTERN int WebPPictureHasTransparency(const WebPPicture* picture); // Remove the transparency information (if present) by blending the color with // the background color 'background_rgb' (specified as 24bit RGB triplet). // After this call, all alpha values are reset to 0xff. WEBP_EXTERN void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb); //------------------------------------------------------------------------------ // Main call // Main encoding call, after config and picture have been initialized. // 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION), // and the 'config' object must be a valid one. // Returns false in case of error, true otherwise. // In case of error, picture->error_code is updated accordingly. // 'picture' can hold the source samples in both YUV(A) or ARGB input, depending // on the value of 'picture->use_argb'. It is highly recommended to use // the former for lossy encoding, and the latter for lossless encoding // (when config.lossless is true). Automatic conversion from one format to // another is provided but they both incur some loss. WEBP_EXTERN int WebPEncode(const WebPConfig* config, WebPPicture* picture); //------------------------------------------------------------------------------ #ifdef __cplusplus } // extern "C" #endif #endif /* WEBP_WEBP_ENCODE_H_ */ threads.h 0000644 00000014777 15146341150 0006367 0 ustar 00 /* ISO C11 Standard: 7.26 - Thread support library <threads.h>. Copyright (C) 2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _THREADS_H #define _THREADS_H 1 #include <features.h> #include <time.h> __BEGIN_DECLS #include <bits/pthreadtypes-arch.h> #include <bits/types/struct_timespec.h> #ifndef __cplusplus # define thread_local _Thread_local #endif #define TSS_DTOR_ITERATIONS 4 typedef unsigned int tss_t; typedef void (*tss_dtor_t) (void*); typedef unsigned long int thrd_t; typedef int (*thrd_start_t) (void*); /* Exit and error codes. */ enum { thrd_success = 0, thrd_busy = 1, thrd_error = 2, thrd_nomem = 3, thrd_timedout = 4 }; /* Mutex types. */ enum { mtx_plain = 0, mtx_recursive = 1, mtx_timed = 2 }; typedef struct { int __data __ONCE_ALIGNMENT; } once_flag; #define ONCE_FLAG_INIT { 0 } typedef union { char __size[__SIZEOF_PTHREAD_MUTEX_T]; long int __align __LOCK_ALIGNMENT; } mtx_t; typedef union { char __size[__SIZEOF_PTHREAD_COND_T]; __extension__ long long int __align __LOCK_ALIGNMENT; } cnd_t; /* Threads functions. */ /* Create a new thread executing the function __FUNC. Arguments for __FUNC are passed through __ARG. If succesful, __THR is set to new thread identifier. */ extern int thrd_create (thrd_t *__thr, thrd_start_t __func, void *__arg); /* Check if __LHS and __RHS point to the same thread. */ extern int thrd_equal (thrd_t __lhs, thrd_t __rhs); /* Return current thread identifier. */ extern thrd_t thrd_current (void); /* Block current thread execution for at least the time pointed by __TIME_POINT. The current thread may resume if receives a signal. In that case, if __REMAINING is not NULL, the remaining time is stored in the object pointed by it. */ extern int thrd_sleep (const struct timespec *__time_point, struct timespec *__remaining); /* Terminate current thread execution, cleaning up any thread local storage and freeing resources. Returns the value specified in __RES. */ extern void thrd_exit (int __res) __attribute__ ((__noreturn__)); /* Detach the thread identified by __THR from the current environment (it does not allow join or wait for it). */ extern int thrd_detach (thrd_t __thr); /* Block current thread until execution of __THR is complete. In case that __RES is not NULL, will store the return value of __THR when exiting. */ extern int thrd_join (thrd_t __thr, int *__res); /* Stop current thread execution and call the scheduler to decide which thread should execute next. The current thread may be selected by the scheduler to keep running. */ extern void thrd_yield (void); #ifdef __USE_EXTERN_INLINES /* Optimizations. */ __extern_inline int thrd_equal (thrd_t __thread1, thrd_t __thread2) { return __thread1 == __thread2; } #endif /* Mutex functions. */ /* Creates a new mutex object with type __TYPE. If successful the new object is pointed by __MUTEX. */ extern int mtx_init (mtx_t *__mutex, int __type); /* Block the current thread until the mutex pointed to by __MUTEX is unlocked. In that case current thread will not be blocked. */ extern int mtx_lock (mtx_t *__mutex); /* Block the current thread until the mutex pointed by __MUTEX is unlocked or time pointed by __TIME_POINT is reached. In case the mutex is unlock, the current thread will not be blocked. */ extern int mtx_timedlock (mtx_t *__restrict __mutex, const struct timespec *__restrict __time_point); /* Try to lock the mutex pointed by __MUTEX without blocking. If the mutex is free the current threads takes control of it, otherwise it returns immediately. */ extern int mtx_trylock (mtx_t *__mutex); /* Unlock the mutex pointed by __MUTEX. It may potentially awake other threads waiting on this mutex. */ extern int mtx_unlock (mtx_t *__mutex); /* Destroy the mutex object pointed by __MUTEX. */ extern void mtx_destroy (mtx_t *__mutex); /* Call function __FUNC exactly once, even if invoked from several threads. All calls must be made with the same __FLAGS object. */ extern void call_once (once_flag *__flag, void (*__func)(void)); /* Condition variable functions. */ /* Initialize new condition variable pointed by __COND. */ extern int cnd_init (cnd_t *__cond); /* Unblock one thread that currently waits on condition variable pointed by __COND. */ extern int cnd_signal (cnd_t *__cond); /* Unblock all threads currently waiting on condition variable pointed by __COND. */ extern int cnd_broadcast (cnd_t *__cond); /* Block current thread on the condition variable pointed by __COND. */ extern int cnd_wait (cnd_t *__cond, mtx_t *__mutex); /* Block current thread on the condition variable until condition variable pointed by __COND is signaled or time pointed by __TIME_POINT is reached. */ extern int cnd_timedwait (cnd_t *__restrict __cond, mtx_t *__restrict __mutex, const struct timespec *__restrict __time_point); /* Destroy condition variable pointed by __cond and free all of its resources. */ extern void cnd_destroy (cnd_t *__COND); /* Thread specific storage functions. */ /* Create new thread-specific storage key and stores it in the object pointed by __TSS_ID. If __DESTRUCTOR is not NULL, the function will be called when the thread terminates. */ extern int tss_create (tss_t *__tss_id, tss_dtor_t __destructor); /* Return the value held in thread-specific storage for the current thread identified by __TSS_ID. */ extern void *tss_get (tss_t __tss_id); /* Sets the value of the thread-specific storage identified by __TSS_ID for the current thread to __VAL. */ extern int tss_set (tss_t __tss_id, void *__val); /* Destroys the thread-specific storage identified by __TSS_ID. The destructor is not called until thrd_exit is called. */ extern void tss_delete (tss_t __tss_id); __END_DECLS #endif /* _THREADS_H */ utmpx.h 0000644 00000010003 15146341150 0006064 0 ustar 00 /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _UTMPX_H #define _UTMPX_H 1 #include <features.h> #include <sys/time.h> /* Required according to Unix98. */ #ifndef __pid_t_defined typedef __pid_t pid_t; # define __pid_t_defined #endif /* Get system dependent values and data structures. */ #include <bits/utmpx.h> #ifdef __USE_GNU /* Compatibility names for the strings of the canonical file names. */ # define UTMPX_FILE _PATH_UTMPX # define UTMPX_FILENAME _PATH_UTMPX # define WTMPX_FILE _PATH_WTMPX # define WTMPX_FILENAME _PATH_WTMPX #endif /* For the getutmp{,x} functions we need the `struct utmp'. */ #ifdef __USE_GNU struct utmp; #endif __BEGIN_DECLS /* Open user accounting database. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void setutxent (void); /* Close user accounting database. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void endutxent (void); /* Get the next entry from the user accounting database. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct utmpx *getutxent (void); /* Get the user accounting database entry corresponding to ID. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct utmpx *getutxid (const struct utmpx *__id); /* Get the user accounting database entry corresponding to LINE. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct utmpx *getutxline (const struct utmpx *__line); /* Write the entry UTMPX into the user accounting database. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct utmpx *pututxline (const struct utmpx *__utmpx); #ifdef __USE_GNU /* Change name of the utmpx file to be examined. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int utmpxname (const char *__file); /* Append entry UTMP to the wtmpx-like file WTMPX_FILE. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern void updwtmpx (const char *__wtmpx_file, const struct utmpx *__utmpx); /* Copy the information in UTMPX to UTMP. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern void getutmp (const struct utmpx *__utmpx, struct utmp *__utmp); /* Copy the information in UTMP to UTMPX. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern void getutmpx (const struct utmp *__utmp, struct utmpx *__utmpx); #endif __END_DECLS #endif /* utmpx.h */ punycode.h 0000644 00000022250 15146341150 0006544 0 ustar 00 /* punycode.h --- Declarations for punycode functions. Copyright (C) 2002-2016 Simon Josefsson This file is part of GNU Libidn. GNU Libidn is free software: you can redistribute it and/or modify it under the terms of either: * the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. or * the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. or both in parallel, as here. GNU Libidn 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. You should have received copies of the GNU General Public License and the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * This file is derived from RFC 3492bis written by Adam M. Costello, * downloaded from http://www.nicemice.net/idn/punycode-spec.gz on * 2015-03-02 with SHA1 a966a8017f6be579d74a50a226accc7607c40133, a * copy of which is stored in the GNU Libidn version controlled * repository under doc/specification/punycode-spec.gz. * * The changes compared to Adam's file include: re-indentation, adding * the license boilerplate and this comment, adding the #ifndef * PUNYCODE_H and IDNAPI blocks, changing the return code of * punycode_encode and punycode_decode from enum to int, simplifying * the definition of punycode_uint by #include'ing idn-int.h and using * uint32_t instead of limit.h-based code, adding Punycode_status and * punycode_strerror, adding 'extern IDNAPI' declarations to function * prototypes, and mentioning variable names in function prototypes. * * Adam's file contains the following: * * punycode-sample.c 2.0.0 (2004-Mar-21-Sun) * http://www.nicemice.net/idn/ * Adam M. Costello * http://www.nicemice.net/amc/ * * This is ANSI C code (C89) implementing Punycode 1.0.x. * * Disclaimer and license: Regarding this entire document or any * portion of it (including the pseudocode and C code), the author * makes no guarantees and is not responsible for any damage resulting * from its use. The author grants irrevocable permission to anyone * to use, modify, and distribute it in any way that does not diminish * the rights of anyone else to use, modify, and distribute it, * provided that redistributed derivative works do not contain * misleading author or version information. Derivative works need * not be licensed under similar terms. */ #ifndef PUNYCODE_H # define PUNYCODE_H # ifndef IDNAPI # if defined LIBIDN_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY # define IDNAPI __attribute__((__visibility__("default"))) # elif defined LIBIDN_BUILDING && defined _MSC_VER && ! defined LIBIDN_STATIC # define IDNAPI __declspec(dllexport) # elif defined _MSC_VER && ! defined LIBIDN_STATIC # define IDNAPI __declspec(dllimport) # else # define IDNAPI # endif # endif #ifdef __cplusplus extern "C" { #endif /************************************************************/ /* Public interface (would normally go in its own .h file): */ #include <stddef.h> /* size_t */ #include <idn-int.h> /* uint32_t */ enum punycode_status { punycode_success = 0, punycode_bad_input = 1, /* Input is invalid. */ punycode_big_output = 2, /* Output would exceed the space provided. */ punycode_overflow = 3 /* Wider integers needed to process input. */ }; typedef enum { PUNYCODE_SUCCESS = punycode_success, PUNYCODE_BAD_INPUT = punycode_bad_input, PUNYCODE_BIG_OUTPUT = punycode_big_output, PUNYCODE_OVERFLOW = punycode_overflow } Punycode_status; extern IDNAPI const char *punycode_strerror (Punycode_status rc); /* punycode_uint needs to be unsigned and needs to be */ /* at least 26 bits wide. The particular type can be */ /* specified by defining PUNYCODE_UINT, otherwise a */ /* suitable type will be chosen automatically. */ typedef uint32_t punycode_uint; extern IDNAPI int punycode_encode (size_t input_length, const punycode_uint input[], const unsigned char case_flags[], size_t * output_length, char output[]); /* punycode_encode() converts a sequence of code points (presumed to be Unicode code points) to Punycode. Input arguments (to be supplied by the caller): input_length The number of code points in the input array and the number of flags in the case_flags array. input An array of code points. They are presumed to be Unicode code points, but that is not strictly necessary. The array contains code points, not code units. UTF-16 uses code units D800 through DFFF to refer to code points 10000..10FFFF. The code points D800..DFFF do not occur in any valid Unicode string. The code points that can occur in Unicode strings (0..D7FF and E000..10FFFF) are also called Unicode scalar values. case_flags A null pointer or an array of boolean values parallel to the input array. Nonzero (true, flagged) suggests that the corresponding Unicode character be forced to uppercase after being decoded (if possible), and zero (false, unflagged) suggests that it be forced to lowercase (if possible). ASCII code points (0..7F) are encoded literally, except that ASCII letters are forced to uppercase or lowercase according to the corresponding case flags. If case_flags is a null pointer then ASCII letters are left as they are, and other code points are treated as unflagged. Output arguments (to be filled in by the function): output An array of ASCII code points. It is *not* null-terminated; it will contain zeros if and only if the input contains zeros. (Of course the caller can leave room for a terminator and add one if needed.) Input/output arguments (to be supplied by the caller and overwritten by the function): output_length The caller passes in the maximum number of ASCII code points that it can receive. On successful return it will contain the number of ASCII code points actually output. Return value: Can be any of the punycode_status values defined above except punycode_bad_input. If not punycode_success, then output_size and output might contain garbage. */ extern IDNAPI int punycode_decode (size_t input_length, const char input[], size_t * output_length, punycode_uint output[], unsigned char case_flags[]); /* punycode_decode() converts Punycode to a sequence of code points (presumed to be Unicode code points). Input arguments (to be supplied by the caller): input_length The number of ASCII code points in the input array. input An array of ASCII code points (0..7F). Output arguments (to be filled in by the function): output An array of code points like the input argument of punycode_encode() (see above). case_flags A null pointer (if the flags are not needed by the caller) or an array of boolean values parallel to the output array. Nonzero (true, flagged) suggests that the corresponding Unicode character be forced to uppercase by the caller (if possible), and zero (false, unflagged) suggests that it be forced to lowercase (if possible). ASCII code points (0..7F) are output already in the proper case, but their flags will be set appropriately so that applying the flags would be harmless. Input/output arguments (to be supplied by the caller and overwritten by the function): output_length The caller passes in the maximum number of code points that it can receive into the output array (which is also the maximum number of flags that it can receive into the case_flags array, if case_flags is not a null pointer). On successful return it will contain the number of code points actually output (which is also the number of flags actually output, if case_flags is not a null pointer). The decoder will never need to output more code points than the number of ASCII code points in the input, because of the way the encoding is defined. The number of code points output cannot exceed the maximum possible value of a punycode_uint, even if the supplied output_length is greater than that. Return value: Can be any of the punycode_status values defined above. If not punycode_success, then output_length, output, and case_flags might contain garbage. */ #ifdef __cplusplus } #endif #endif /* PUNYCODE_H */ e2p/e2p.h 0000644 00000006264 15146341150 0006101 0 ustar 00 /* * e2p.h --- header file for the e2p library * * %Begin-Header% * This file may be redistributed under the terms of the GNU Library * General Public License, version 2. * %End-Header% */ #include <sys/types.h> /* Needed by dirent.h on netbsd */ #include <stdio.h> #include <dirent.h> #include <ext2fs/ext2_fs.h> #define E2P_FEATURE_COMPAT 0 #define E2P_FEATURE_INCOMPAT 1 #define E2P_FEATURE_RO_INCOMPAT 2 #define E2P_FEATURE_TYPE_MASK 0x03 #define E2P_FEATURE_NEGATE_FLAG 0x80 #define E2P_FS_FEATURE 0 #define E2P_JOURNAL_FEATURE 1 /* `options' for print_flags() */ #define PFOPT_LONG 1 /* Must be 1 for compatibility with `int long_format'. */ int fgetflags (const char * name, unsigned long * flags); int fgetversion (const char * name, unsigned long * version); int fsetflags (const char * name, unsigned long flags); int fsetversion (const char * name, unsigned long version); int fgetproject(const char *name, unsigned long *project); int fsetproject(const char *name, unsigned long project); int getflags (int fd, unsigned long * flags); int getversion (int fd, unsigned long * version); int iterate_on_dir (const char * dir_name, int (*func) (const char *, struct dirent *, void *), void * private_arg); void list_super(struct ext2_super_block * s); void list_super2(struct ext2_super_block * s, FILE *f); void print_fs_errors (FILE * f, unsigned short errors); void print_flags (FILE * f, unsigned long flags, unsigned options); void print_fs_state (FILE * f, unsigned short state); int setflags (int fd, unsigned long flags); int setversion (int fd, unsigned long version); void e2p_list_journal_super(FILE *f, char *journal_sb_buf, int exp_block_size, int flags); void e2p_feature_to_string(int compat, unsigned int mask, char *buf, size_t buf_len); const char *e2p_feature2string(int compat, unsigned int mask); const char *e2p_jrnl_feature2string(int compat, unsigned int mask); int e2p_string2feature(char *string, int *compat, unsigned int *mask); int e2p_jrnl_string2feature(char *string, int *compat_type, unsigned int *mask); int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array); int e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array, __u32 *clear_ok_array, int *type_err, unsigned int *mask_err); int e2p_is_null_uuid(void *uu); void e2p_uuid_to_str(void *uu, char *out); const char *e2p_uuid2str(void *uu); const char *e2p_hash2string(int num); int e2p_string2hash(char *string); const char *e2p_mntopt2string(unsigned int mask); int e2p_string2mntopt(char *string, unsigned int *mask); int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok); unsigned long parse_num_blocks(const char *arg, int log_block_size); unsigned long long parse_num_blocks2(const char *arg, int log_block_size); char *e2p_os2string(int os_type); int e2p_string2os(char *str); unsigned int e2p_percent(int percent, unsigned int base); const char *e2p_encmode2string(int num); int e2p_string2encmode(char *string); int e2p_str2encoding(const char *string); const char *e2p_encoding2str(int encoding); int e2p_get_encoding_flags(int encoding); int e2p_str2encoding_flags(int encoding, char *param, __u16 *flags); wordexp.h 0000644 00000004705 15146341150 0006413 0 ustar 00 /* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _WORDEXP_H #define _WORDEXP_H 1 #include <features.h> #define __need_size_t #include <stddef.h> __BEGIN_DECLS /* Bits set in the FLAGS argument to `wordexp'. */ enum { WRDE_DOOFFS = (1 << 0), /* Insert PWORDEXP->we_offs NULLs. */ WRDE_APPEND = (1 << 1), /* Append to results of a previous call. */ WRDE_NOCMD = (1 << 2), /* Don't do command substitution. */ WRDE_REUSE = (1 << 3), /* Reuse storage in PWORDEXP. */ WRDE_SHOWERR = (1 << 4), /* Don't redirect stderr to /dev/null. */ WRDE_UNDEF = (1 << 5), /* Error for expanding undefined variables. */ __WRDE_FLAGS = (WRDE_DOOFFS | WRDE_APPEND | WRDE_NOCMD | WRDE_REUSE | WRDE_SHOWERR | WRDE_UNDEF) }; /* Structure describing a word-expansion run. */ typedef struct { size_t we_wordc; /* Count of words matched. */ char **we_wordv; /* List of expanded words. */ size_t we_offs; /* Slots to reserve in `we_wordv'. */ } wordexp_t; /* Possible nonzero return values from `wordexp'. */ enum { #ifdef __USE_XOPEN WRDE_NOSYS = -1, /* Never used since we support `wordexp'. */ #endif WRDE_NOSPACE = 1, /* Ran out of memory. */ WRDE_BADCHAR, /* A metachar appears in the wrong place. */ WRDE_BADVAL, /* Undefined var reference with WRDE_UNDEF. */ WRDE_CMDSUB, /* Command substitution with WRDE_NOCMD. */ WRDE_SYNTAX /* Shell syntax error. */ }; /* Do word expansion of WORDS into PWORDEXP. */ extern int wordexp (const char *__restrict __words, wordexp_t *__restrict __pwordexp, int __flags); /* Free the storage allocated by a `wordexp' call. */ extern void wordfree (wordexp_t *__wordexp) __THROW; __END_DECLS #endif /* wordexp.h */ criu/criu-plugin.h 0000644 00000010332 15146341150 0010114 0 ustar 00 /* * This file defines types and macros for CRIU plugins. * Copyright (C) 2013-2014 Parallels, Inc * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CRIU_PLUGIN_H__ #define __CRIU_PLUGIN_H__ #include <limits.h> #include <stdbool.h> #define CRIU_PLUGIN_GEN_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) #define CRIU_PLUGIN_VERSION_MAJOR 0 #define CRIU_PLUGIN_VERSION_MINOR 2 #define CRIU_PLUGIN_VERSION_SUBLEVEL 0 #define CRIU_PLUGIN_VERSION_OLD CRIU_PLUGIN_GEN_VERSION(0,1,0) #define CRIU_PLUGIN_VERSION \ CRIU_PLUGIN_GEN_VERSION(CRIU_PLUGIN_VERSION_MAJOR, \ CRIU_PLUGIN_VERSION_MINOR, \ CRIU_PLUGIN_VERSION_SUBLEVEL) /* * Plugin hook points and their arguments in hooks. */ enum { CR_PLUGIN_HOOK__DUMP_UNIX_SK = 0, CR_PLUGIN_HOOK__RESTORE_UNIX_SK = 1, CR_PLUGIN_HOOK__DUMP_EXT_FILE = 2, CR_PLUGIN_HOOK__RESTORE_EXT_FILE = 3, CR_PLUGIN_HOOK__DUMP_EXT_MOUNT = 4, CR_PLUGIN_HOOK__RESTORE_EXT_MOUNT = 5, CR_PLUGIN_HOOK__DUMP_EXT_LINK = 6, CR_PLUGIN_HOOK__MAX }; #define DECLARE_PLUGIN_HOOK_ARGS(__hook, ...) \ typedef int (__hook ##_t)(__VA_ARGS__) DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_UNIX_SK, int fd, int id); DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESTORE_UNIX_SK, int id); DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_EXT_FILE, int fd, int id); DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESTORE_EXT_FILE, int id); DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_EXT_MOUNT, char *mountpoint, int id); DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESTORE_EXT_MOUNT, int id, char *mountpoint, char *old_root, int *is_file); DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_EXT_LINK, int index, int type, char *kind); enum { CR_PLUGIN_STAGE__DUMP, CR_PLUGIN_STAGE__PRE_DUMP, CR_PLUGIN_STAGE__RESTORE, CR_PLUGIN_STAGE_MAX }; /* * Plugin descriptor. */ typedef struct { const char *name; int (*init)(int stage); void (*exit)(int stage, int ret); unsigned int version; unsigned int max_hooks; void *hooks[CR_PLUGIN_HOOK__MAX]; } cr_plugin_desc_t; extern cr_plugin_desc_t CR_PLUGIN_DESC; #define CR_PLUGIN_REGISTER(___name, ___init, ___exit) \ cr_plugin_desc_t CR_PLUGIN_DESC = { \ .name = ___name, \ .init = ___init, \ .exit = ___exit, \ .version = CRIU_PLUGIN_VERSION, \ .max_hooks = CR_PLUGIN_HOOK__MAX, \ }; static inline int cr_plugin_dummy_init(int stage) { return 0; } static inline void cr_plugin_dummy_exit(int stage, int ret) { } #define CR_PLUGIN_REGISTER_DUMMY(___name) \ cr_plugin_desc_t CR_PLUGIN_DESC = { \ .name = ___name, \ .init = cr_plugin_dummy_init, \ .exit = cr_plugin_dummy_exit, \ .version = CRIU_PLUGIN_VERSION, \ .max_hooks = CR_PLUGIN_HOOK__MAX, \ }; #define CR_PLUGIN_REGISTER_HOOK(__hook, __func) \ static void __attribute__((constructor)) cr_plugin_register_hook_##__func (void) \ { \ CR_PLUGIN_DESC.hooks[__hook] = (void *)__func; \ } /* Public API */ extern int criu_get_image_dir(void); /* * Deprecated, will be removed in next version. */ typedef int (cr_plugin_init_t)(void); typedef void (cr_plugin_fini_t)(void); typedef int (cr_plugin_dump_unix_sk_t)(int fd, int id); typedef int (cr_plugin_restore_unix_sk_t)(int id); typedef int (cr_plugin_dump_file_t)(int fd, int id); typedef int (cr_plugin_restore_file_t)(int id); typedef int (cr_plugin_dump_ext_mount_t)(char *mountpoint, int id); typedef int (cr_plugin_restore_ext_mount_t)(int id, char *mountpoint, char *old_root, int *is_file); typedef int (cr_plugin_dump_ext_link_t)(int index, int type, char *kind); #endif /* __CRIU_PLUGIN_H__ */ criu/criu.h 0000644 00000022373 15146341150 0006630 0 ustar 00 /* * (C) Copyright 2013 Parallels, Inc. (www.parallels.com). * * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser General Public License * (LGPL) version 2.1 which accompanies this distribution, and is available at * http://www.gnu.org/licenses/lgpl-2.1.html * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, you can find it here: * www.gnu.org/licenses/lgpl.html */ #ifndef __CRIU_LIB_H__ #define __CRIU_LIB_H__ #include <stdbool.h> #include "version.h" #ifdef __GNUG__ extern "C" { #endif enum criu_service_comm { CRIU_COMM_SK, CRIU_COMM_FD, CRIU_COMM_BIN }; enum criu_cg_mode { CRIU_CG_MODE_IGNORE, CRIU_CG_MODE_NONE, CRIU_CG_MODE_PROPS, CRIU_CG_MODE_SOFT, CRIU_CG_MODE_FULL, CRIU_CG_MODE_STRICT, CRIU_CG_MODE_DEFAULT, }; int criu_set_service_address(const char *path); void criu_set_service_fd(int fd); int criu_set_service_binary(const char *path); /* * Set opts to defaults. _Must_ be called first before using any functions from * the list down below. 0 on success, -1 on fail. */ int criu_init_opts(void); void criu_free_opts(void); /* * For backward compatibility with the mod_lsapi */ void criu_set_service_comm(enum criu_service_comm); void criu_set_pid(int pid); void criu_set_images_dir_fd(int fd); /* must be set for dump/restore */ int criu_set_parent_images(const char *path); void criu_set_work_dir_fd(int fd); void criu_set_leave_running(bool leave_running); void criu_set_ext_unix_sk(bool ext_unix_sk); int criu_add_unix_sk(unsigned int inode); void criu_set_tcp_established(bool tcp_established); void criu_set_tcp_skip_in_flight(bool tcp_skip_in_flight); void criu_set_tcp_close(bool tcp_close); void criu_set_weak_sysctls(bool val); void criu_set_evasive_devices(bool evasive_devices); void criu_set_shell_job(bool shell_job); void criu_set_file_locks(bool file_locks); void criu_set_track_mem(bool track_mem); void criu_set_auto_dedup(bool auto_dedup); void criu_set_force_irmap(bool force_irmap); void criu_set_link_remap(bool link_remap); void criu_set_log_level(int log_level); void criu_set_root_only(bool root_only); int criu_set_log_file(const char *log_file); void criu_set_cpu_cap(unsigned int cap); int criu_set_root(const char *root); void criu_set_manage_cgroups(bool manage); void criu_set_manage_cgroups_mode(enum criu_cg_mode mode); int criu_set_freeze_cgroup(const char *name); int criu_set_lsm_profile(const char *name); void criu_set_timeout(unsigned int timeout); void criu_set_auto_ext_mnt(bool val); void criu_set_ext_sharing(bool val); void criu_set_ext_masters(bool val); int criu_set_exec_cmd(int argc, char *argv[]); int criu_add_ext_mount(const char *key, const char *val); int criu_add_veth_pair(const char *in, const char *out); int criu_add_cg_root(const char *ctrl, const char *path); int criu_add_enable_fs(const char *fs); int criu_add_skip_mnt(const char *mnt); void criu_set_ghost_limit(unsigned int limit); int criu_add_irmap_path(const char *path); int criu_add_inherit_fd(int fd, const char *key); int criu_add_external(const char *key); int criu_set_page_server_address_port(const char *address, int port); /* * The criu_notify_arg_t na argument is an opaque * value that callbacks (cb-s) should pass into * criu_notify_xxx() calls to fetch arbitrary values * from notification. If the value is not available * some non-existing one is reported. */ typedef struct _CriuNotify *criu_notify_arg_t; void criu_set_notify_cb(int (*cb)(char *action, criu_notify_arg_t na)); /* Get pid of root task. 0 if not available */ int criu_notify_pid(criu_notify_arg_t na); /* Here is a table of return values and errno's of functions * from the list down below. * * Return value errno Description * ---------------------------------------------------------------------------- * 0 undefined Success. * * >0 undefined Success(criu_restore() only). * * -BADE rpc err (0 for now) RPC has returned fail. * * -ECONNREFUSED errno Unable to connect to CRIU. * * -ECOMM errno Unable to send/recv msg to/from CRIU. * * -EINVAL undefined CRIU doesn't support this type of request. * You should probably update CRIU. * * -EBADMSG undefined Unexpected response from CRIU. * You should probably update CRIU. */ int criu_check(void); int criu_dump(void); int criu_restore(void); int criu_restore_child(void); /* * Perform dumping but with preliminary iterations. Each * time an iteration ends the ->more callback is called. * The callback's return value is * - positive -- one more iteration starts * - zero -- final dump is performed and call exits * - negative -- dump is aborted, the value is returned * back from criu_dump_iters * * The @pi argument is an opaque value that caller may * use to request pre-dump statistics (not yet implemented). */ typedef void *criu_predump_info; int criu_dump_iters(int (*more)(criu_predump_info pi)); /* * Same as the list above, but lets you have your very own options * structure and lets you set individual options in it. */ typedef struct criu_opts criu_opts; int criu_local_init_opts(criu_opts **opts); void criu_local_free_opts(criu_opts *opts); int criu_local_set_service_address(criu_opts *opts, const char *path); void criu_local_set_service_fd(criu_opts *opts, int fd); void criu_local_set_service_fd(criu_opts *opts, int fd); void criu_local_set_pid(criu_opts *opts, int pid); void criu_local_set_images_dir_fd(criu_opts *opts, int fd); /* must be set for dump/restore */ int criu_local_set_parent_images(criu_opts *opts, const char *path); int criu_local_set_service_binary(criu_opts *opts, const char *path); void criu_local_set_work_dir_fd(criu_opts *opts, int fd); void criu_local_set_leave_running(criu_opts *opts, bool leave_running); void criu_local_set_ext_unix_sk(criu_opts *opts, bool ext_unix_sk); int criu_local_add_unix_sk(criu_opts *opts, unsigned int inode); void criu_local_set_tcp_established(criu_opts *opts, bool tcp_established); void criu_local_set_tcp_skip_in_flight(criu_opts *opts, bool tcp_skip_in_flight); void criu_local_set_tcp_close(criu_opts *opts, bool tcp_close); void criu_local_set_weak_sysctls(criu_opts *opts, bool val); void criu_local_set_evasive_devices(criu_opts *opts, bool evasive_devices); void criu_local_set_shell_job(criu_opts *opts, bool shell_job); void criu_local_set_file_locks(criu_opts *opts, bool file_locks); void criu_local_set_track_mem(criu_opts *opts, bool track_mem); void criu_local_set_auto_dedup(criu_opts *opts, bool auto_dedup); void criu_local_set_force_irmap(criu_opts *opts, bool force_irmap); void criu_local_set_link_remap(criu_opts *opts, bool link_remap); void criu_local_set_log_level(criu_opts *opts, int log_level); void criu_local_set_root_only(criu_opts *opts, bool root_only); int criu_local_set_log_file(criu_opts *opts, const char *log_file); void criu_local_set_cpu_cap(criu_opts *opts, unsigned int cap); int criu_local_set_root(criu_opts *opts, const char *root); void criu_local_set_manage_cgroups(criu_opts *opts, bool manage); void criu_local_set_manage_cgroups_mode(criu_opts *opts, enum criu_cg_mode mode); int criu_local_set_freeze_cgroup(criu_opts *opts, const char *name); int criu_local_set_lsm_profile(criu_opts *opts, const char *name); void criu_local_set_timeout(criu_opts *opts, unsigned int timeout); void criu_local_set_auto_ext_mnt(criu_opts *opts, bool val); void criu_local_set_ext_sharing(criu_opts *opts, bool val); void criu_local_set_ext_masters(criu_opts *opts, bool val); int criu_local_set_exec_cmd(criu_opts *opts, int argc, char *argv[]); int criu_local_add_ext_mount(criu_opts *opts, const char *key, const char *val); int criu_local_add_veth_pair(criu_opts *opts, const char *in, const char *out); int criu_local_add_cg_root(criu_opts *opts, const char *ctrl, const char *path); int criu_local_add_enable_fs(criu_opts *opts, const char *fs); int criu_local_add_skip_mnt(criu_opts *opts, const char *mnt); void criu_local_set_ghost_limit(criu_opts *opts, unsigned int limit); int criu_local_add_irmap_path(criu_opts *opts, const char *path); int criu_local_add_cg_props(criu_opts *opts, const char *stream); int criu_local_add_cg_props_file(criu_opts *opts, const char *path); int criu_local_add_cg_dump_controller(criu_opts *opts, const char *name); int criu_local_add_inherit_fd(criu_opts *opts, int fd, const char *key); int criu_local_add_external(criu_opts *opts, const char *key); int criu_local_set_page_server_address_port(criu_opts *opts, const char *address, int port); void criu_local_set_notify_cb(criu_opts *opts, int (*cb)(char *action, criu_notify_arg_t na)); int criu_local_check(criu_opts *opts); int criu_local_dump(criu_opts *opts); int criu_local_restore(criu_opts *opts); int criu_local_restore_child(criu_opts *opts); int criu_local_dump_iters(criu_opts *opts, int (*more)(criu_predump_info pi)); #ifdef __GNUG__ } #endif #endif /* __CRIU_LIB_H__ */ criu/criu-log.h 0000644 00000003014 15146341150 0007376 0 ustar 00 /* This file defines types and macros for CRIU plugins. Copyright (C) 2013 Parallels, Inc This program 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 2 of the License, or (at your option) any later version. This program 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __CRIU_LOG_H__ #define __CRIU_LOG_H__ #include "log.h" extern int log_init(const char *output); extern void log_fini(void); extern int log_init_by_pid(pid_t pid); extern void log_closedir(void); extern int log_keep_err(void); extern char *log_first_err(void); extern void log_set_fd(int fd); extern int log_get_fd(void); extern void log_set_loglevel(unsigned int loglevel); extern unsigned int log_get_loglevel(void); struct timeval; extern void log_get_logstart(struct timeval *); extern int write_pidfile(int pid); #define DEFAULT_LOG_FILENAME "criu.log" static inline int pr_quelled(unsigned int loglevel) { return log_get_loglevel() < loglevel && loglevel != LOG_MSG; } #endif /* __CR_LOG_LEVELS_H__ */ criu/rpc.proto 0000644 00000012512 15146341150 0007360 0 ustar 00 syntax = "proto2"; message criu_page_server_info { optional string address = 1; optional int32 port = 2; optional int32 pid = 3; optional int32 fd = 4; } message criu_veth_pair { required string if_in = 1; required string if_out = 2; }; message ext_mount_map { required string key = 1; required string val = 2; }; message join_namespace { required string ns = 1; required string ns_file = 2; optional string extra_opt = 3; } message inherit_fd { required string key = 1; required int32 fd = 2; }; message cgroup_root { optional string ctrl = 1; required string path = 2; }; message unix_sk { required uint32 inode = 1; }; enum criu_cg_mode { IGNORE = 0; CG_NONE = 1; PROPS = 2; SOFT = 3; FULL = 4; STRICT = 5; DEFAULT = 6; }; message criu_opts { required int32 images_dir_fd = 1; optional int32 pid = 2; /* if not set on dump, will dump requesting process */ optional bool leave_running = 3; optional bool ext_unix_sk = 4; optional bool tcp_established = 5; optional bool evasive_devices = 6; optional bool shell_job = 7; optional bool file_locks = 8; optional int32 log_level = 9 [default = 2]; optional string log_file = 10; /* No subdirs are allowed. Consider using work-dir */ optional criu_page_server_info ps = 11; optional bool notify_scripts = 12; optional string root = 13; optional string parent_img = 14; optional bool track_mem = 15; optional bool auto_dedup = 16; optional int32 work_dir_fd = 17; optional bool link_remap = 18; repeated criu_veth_pair veths = 19; /* DEPRECATED, use external instead */ optional uint32 cpu_cap = 20 [default = 0xffffffff]; optional bool force_irmap = 21; repeated string exec_cmd = 22; repeated ext_mount_map ext_mnt = 23; /* DEPRECATED, use external instead */ optional bool manage_cgroups = 24; /* backward compatibility */ repeated cgroup_root cg_root = 25; optional bool rst_sibling = 26; /* swrk only */ repeated inherit_fd inherit_fd = 27; /* swrk only */ optional bool auto_ext_mnt = 28; optional bool ext_sharing = 29; optional bool ext_masters = 30; repeated string skip_mnt = 31; repeated string enable_fs = 32; repeated unix_sk unix_sk_ino = 33; /* DEPRECATED, use external instead */ optional criu_cg_mode manage_cgroups_mode = 34; optional uint32 ghost_limit = 35 [default = 0x100000]; repeated string irmap_scan_paths = 36; repeated string external = 37; optional uint32 empty_ns = 38; repeated join_namespace join_ns = 39; optional string cgroup_props = 41; optional string cgroup_props_file = 42; repeated string cgroup_dump_controller = 43; optional string freeze_cgroup = 44; optional uint32 timeout = 45; optional bool tcp_skip_in_flight = 46; optional bool weak_sysctls = 47; optional bool lazy_pages = 48; optional int32 status_fd = 49; optional bool orphan_pts_master = 50; optional string config_file = 51; optional bool tcp_close = 52; optional string lsm_profile = 53; optional string tls_cacert = 54; optional string tls_cacrl = 55; optional string tls_cert = 56; optional string tls_key = 57; optional bool tls = 58; optional bool tls_no_cn_verify = 59; optional bool root_only = 60; /* optional bool check_mounts = 128; */ } message criu_dump_resp { optional bool restored = 1; } message criu_restore_resp { required int32 pid = 1; } message criu_notify { optional string script = 1; optional int32 pid = 2; } enum criu_req_type { EMPTY = 0; DUMP = 1; RESTORE = 2; CHECK = 3; PRE_DUMP = 4; PAGE_SERVER = 5; NOTIFY = 6; CPUINFO_DUMP = 7; CPUINFO_CHECK = 8; FEATURE_CHECK = 9; VERSION = 10; WAIT_PID = 11; PAGE_SERVER_CHLD = 12; } /* * List of features which can queried via * CRIU_REQ_TYPE__FEATURE_CHECK */ message criu_features { optional bool mem_track = 1; optional bool lazy_pages = 2; } /* * Request -- each type corresponds to must-be-there * request arguments of respective type */ message criu_req { required criu_req_type type = 1; optional criu_opts opts = 2; optional bool notify_success = 3; /* * When set service won't close the connection but * will wait for more req-s to appear. Works not * for all request types. */ optional bool keep_open = 4; /* * 'features' can be used to query which features * are supported by the installed criu/kernel * via RPC. */ optional criu_features features = 5; /* 'pid' is used for WAIT_PID */ optional uint32 pid = 6; } /* * Response -- it states whether the request was served * and additional request-specific information */ message criu_resp { required criu_req_type type = 1; required bool success = 2; optional criu_dump_resp dump = 3; optional criu_restore_resp restore = 4; optional criu_notify notify = 5; optional criu_page_server_info ps = 6; optional int32 cr_errno = 7; optional criu_features features = 8; optional string cr_errmsg = 9; optional criu_version version = 10; optional int32 status = 11; } /* Answer for criu_req_type.VERSION requests */ message criu_version { required int32 major_number = 1; required int32 minor_number = 2; optional string gitid = 3; optional int32 sublevel = 4; optional int32 extra = 5; optional string name = 6; } criu/version.h 0000644 00000000341 15146341150 0007342 0 ustar 00 /* Autogenerated, do not edit */ #ifndef __CR_VERSION_H__ #define __CR_VERSION_H__ #define CRIU_VERSION "3.13" #define CRIU_VERSION_MAJOR 3 #define CRIU_VERSION_MINOR 13 #define CRIU_GITID "0" #endif /* __CR_VERSION_H__ */ netatalk/at.h 0000644 00000002004 15146341150 0007120 0 ustar 00 /* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _NETATALK_AT_H #define _NETATALK_AT_H 1 #include <asm/types.h> #include <bits/sockaddr.h> #include <linux/atalk.h> #include <sys/socket.h> #define SOL_ATALK 258 /* sockopt level for atalk */ #endif /* netatalk/at.h */ resolv.h 0000644 00000027571 15146341150 0006243 0 ustar 00 /* * Copyright (c) 1983, 1987, 1989 * The Regents of the University of California. 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. * 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. */ /* * Portions Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* * @(#)resolv.h 8.1 (Berkeley) 6/2/93 * $BINDId: resolv.h,v 8.31 2000/03/30 20:16:50 vixie Exp $ */ #ifndef _RESOLV_H_ #define _RESOLV_H_ #include <sys/cdefs.h> #include <sys/param.h> #include <sys/types.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/nameser.h> #include <bits/types/res_state.h> /* * Global defines and variables for resolver stub. */ #define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */ #define RES_TIMEOUT 5 /* min. seconds between retries */ #define RES_MAXNDOTS 15 /* should reflect bit field size */ #define RES_MAXRETRANS 30 /* only for resolv.conf/RES_OPTIONS */ #define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */ #define RES_DFLRETRY 2 /* Default #/tries. */ #define RES_MAXTIME 65535 /* Infinity, in milliseconds. */ #define nsaddr nsaddr_list[0] /* for backward compatibility */ /* * Revision information. This is the release date in YYYYMMDD format. * It can change every day so the right thing to do with it is use it * in preprocessor commands such as "#if (__RES > 19931104)". Do not * compare for equality; rather, use it to determine whether your resolver * is new enough to contain a certain feature. */ #define __RES 19991006 /* * Resolver configuration file. * Normally not present, but may contain the address of the * inital name server(s) to query and the domain search list. */ #ifndef _PATH_RESCONF #define _PATH_RESCONF "/etc/resolv.conf" #endif struct res_sym { int number; /* Identifying number, like T_MX */ char * name; /* Its symbolic name, like "MX" */ char * humanname; /* Its fun name, like "mail exchanger" */ }; /* * Resolver options (keep these in synch with res_debug.c, please) */ #define RES_INIT 0x00000001 /* address initialized */ #define RES_DEBUG 0x00000002 /* print debug messages */ #define RES_AAONLY \ __glibc_macro_warning ("RES_AAONLY is deprecated") 0x00000004 #define RES_USEVC 0x00000008 /* use virtual circuit */ #define RES_PRIMARY \ __glibc_macro_warning ("RES_PRIMARY is deprecated") 0x00000010 #define RES_IGNTC 0x00000020 /* ignore trucation errors */ #define RES_RECURSE 0x00000040 /* recursion desired */ #define RES_DEFNAMES 0x00000080 /* use default domain name */ #define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */ #define RES_DNSRCH 0x00000200 /* search up local domain tree */ #define RES_INSECURE1 0x00000400 /* type 1 security disabled */ #define RES_INSECURE2 0x00000800 /* type 2 security disabled */ #define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */ #define RES_USE_INET6 \ __glibc_macro_warning ("RES_USE_INET6 is deprecated") 0x00002000 #define RES_ROTATE 0x00004000 /* rotate ns list after each query */ #define RES_NOCHECKNAME \ __glibc_macro_warning ("RES_NOCHECKNAME is deprecated") 0x00008000 #define RES_KEEPTSIG \ __glibc_macro_warning ("RES_KEEPTSIG is deprecated") 0x00010000 #define RES_BLAST \ __glibc_macro_warning ("RES_BLAST is deprecated") 0x00020000 #define RES_USE_EDNS0 0x00100000 /* Use EDNS0. */ #define RES_SNGLKUP 0x00200000 /* one outstanding request at a time */ #define RES_SNGLKUPREOP 0x00400000 /* -"-, but open new socket for each request */ #define RES_USE_DNSSEC 0x00800000 /* use DNSSEC using OK bit in OPT */ #define RES_NOTLDQUERY 0x01000000 /* Do not look up unqualified name as a TLD. */ #define RES_NORELOAD 0x02000000 /* No automatic configuration reload. */ #define RES_NOAAAA 0x08000000 /* Suppress AAAA queries. */ #define RES_STRICTERR 0x10000000 /* Report more DNS errors as errors. */ #define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH) /* * Resolver "pfcode" values. Used by dig. */ #define RES_PRF_STATS 0x00000001 #define RES_PRF_UPDATE 0x00000002 #define RES_PRF_CLASS 0x00000004 #define RES_PRF_CMD 0x00000008 #define RES_PRF_QUES 0x00000010 #define RES_PRF_ANS 0x00000020 #define RES_PRF_AUTH 0x00000040 #define RES_PRF_ADD 0x00000080 #define RES_PRF_HEAD1 0x00000100 #define RES_PRF_HEAD2 0x00000200 #define RES_PRF_TTLID 0x00000400 #define RES_PRF_HEADX 0x00000800 #define RES_PRF_QUERY 0x00001000 #define RES_PRF_REPLY 0x00002000 #define RES_PRF_INIT 0x00004000 /* 0x00008000 */ /* Things involving an internal (static) resolver context. */ __BEGIN_DECLS extern struct __res_state *__res_state(void) __attribute__ ((__const__)); __END_DECLS #define _res (*__res_state()) #define fp_nquery __fp_nquery #define fp_query __fp_query #define hostalias __hostalias #define p_query __p_query #define res_close __res_close #define res_init __res_init #define res_isourserver __res_isourserver #define res_mkquery __res_mkquery #define res_query __res_query #define res_querydomain __res_querydomain #define res_search __res_search #define res_send __res_send __BEGIN_DECLS void fp_nquery (const unsigned char *, int, FILE *) __THROW; void fp_query (const unsigned char *, FILE *) __THROW; const char * hostalias (const char *) __THROW; void p_query (const unsigned char *) __THROW; void res_close (void) __THROW; int res_init (void) __THROW; int res_isourserver (const struct sockaddr_in *) __THROW; int res_mkquery (int, const char *, int, int, const unsigned char *, int, const unsigned char *, unsigned char *, int) __THROW; int res_query (const char *, int, int, unsigned char *, int) __THROW; int res_querydomain (const char *, const char *, int, int, unsigned char *, int) __THROW; int res_search (const char *, int, int, unsigned char *, int) __THROW; int res_send (const unsigned char *, int, unsigned char *, int) __THROW; __END_DECLS #define b64_ntop __b64_ntop #define b64_pton __b64_pton #define dn_comp __dn_comp #define dn_count_labels __dn_count_labels #define dn_expand __dn_expand #define dn_skipname __dn_skipname #define fp_resstat __fp_resstat #define loc_aton __loc_aton #define loc_ntoa __loc_ntoa #define p_cdname __p_cdname #define p_cdnname __p_cdnname #define p_class __p_class #define p_fqname __p_fqname #define p_fqnname __p_fqnname #define p_option __p_option #define p_time __p_time #define p_type __p_type #define p_rcode __p_rcode #define putlong __putlong #define putshort __putshort #define res_dnok __res_dnok #define res_hnok __res_hnok #define res_hostalias __res_hostalias #define res_mailok __res_mailok #define res_nameinquery __res_nameinquery #define res_nclose __res_nclose #define res_ninit __res_ninit #define res_nmkquery __res_nmkquery #define res_nquery __res_nquery #define res_nquerydomain __res_nquerydomain #define res_nsearch __res_nsearch #define res_nsend __res_nsend #define res_ownok __res_ownok #define res_queriesmatch __res_queriesmatch #define res_randomid __res_randomid #define sym_ntop __sym_ntop #define sym_ntos __sym_ntos #define sym_ston __sym_ston __BEGIN_DECLS int res_hnok (const char *) __THROW; int res_ownok (const char *) __THROW; int res_mailok (const char *) __THROW; int res_dnok (const char *) __THROW; int sym_ston (const struct res_sym *, const char *, int *) __THROW; const char * sym_ntos (const struct res_sym *, int, int *) __THROW; const char * sym_ntop (const struct res_sym *, int, int *) __THROW; int b64_ntop (const unsigned char *, size_t, char *, size_t) __THROW; int b64_pton (char const *, unsigned char *, size_t) __THROW; int loc_aton (const char *__ascii, unsigned char *__binary) __THROW; const char * loc_ntoa (const unsigned char *__binary, char *__ascii) __THROW; int dn_skipname (const unsigned char *, const unsigned char *) __THROW; void putlong (uint32_t, unsigned char *) __THROW; void putshort (uint16_t, unsigned char *) __THROW; const char * p_class (int) __THROW; const char * p_time (uint32_t) __THROW; const char * p_type (int) __THROW; const char * p_rcode (int) __THROW; const unsigned char * p_cdnname (const unsigned char *, const unsigned char *, int, FILE *) __THROW; const unsigned char * p_cdname (const unsigned char *, const unsigned char *, FILE *) __THROW; const unsigned char * p_fqnname (const unsigned char *__cp, const unsigned char *__msg, int, char *, int) __THROW; const unsigned char * p_fqname (const unsigned char *, const unsigned char *, FILE *) __THROW; const char * p_option (unsigned long __option) __THROW; int dn_count_labels (const char *) __THROW; int dn_comp (const char *, unsigned char *, int, unsigned char **, unsigned char **) __THROW; int dn_expand (const unsigned char *, const unsigned char *, const unsigned char *, char *, int) __THROW; unsigned int res_randomid (void) __THROW; int res_nameinquery (const char *, int, int, const unsigned char *, const unsigned char *) __THROW; int res_queriesmatch (const unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *) __THROW; /* Things involving a resolver context. */ int res_ninit (res_state) __THROW; void fp_resstat (const res_state, FILE *) __THROW; const char * res_hostalias (const res_state, const char *, char *, size_t) __THROW; int res_nquery (res_state, const char *, int, int, unsigned char *, int) __THROW; int res_nsearch (res_state, const char *, int, int, unsigned char *, int) __THROW; int res_nquerydomain (res_state, const char *, const char *, int, int, unsigned char *, int) __THROW; int res_nmkquery (res_state, int, const char *, int, int, const unsigned char *, int, const unsigned char *, unsigned char *, int) __THROW; int res_nsend (res_state, const unsigned char *, int, unsigned char *, int) __THROW; void res_nclose (res_state) __THROW; __END_DECLS #endif /* !_RESOLV_H_ */ kadm5/kadm_err.h 0000644 00000010371 15146341150 0007504 0 ustar 00 /* * et-h-kadm_err.h: * This file is automatically generated; please do not edit it. */ #include <et/com_err.h> #define KADM5_FAILURE (43787520L) #define KADM5_AUTH_GET (43787521L) #define KADM5_AUTH_ADD (43787522L) #define KADM5_AUTH_MODIFY (43787523L) #define KADM5_AUTH_DELETE (43787524L) #define KADM5_AUTH_INSUFFICIENT (43787525L) #define KADM5_BAD_DB (43787526L) #define KADM5_DUP (43787527L) #define KADM5_RPC_ERROR (43787528L) #define KADM5_NO_SRV (43787529L) #define KADM5_BAD_HIST_KEY (43787530L) #define KADM5_NOT_INIT (43787531L) #define KADM5_UNK_PRINC (43787532L) #define KADM5_UNK_POLICY (43787533L) #define KADM5_BAD_MASK (43787534L) #define KADM5_BAD_CLASS (43787535L) #define KADM5_BAD_LENGTH (43787536L) #define KADM5_BAD_POLICY (43787537L) #define KADM5_BAD_PRINCIPAL (43787538L) #define KADM5_BAD_AUX_ATTR (43787539L) #define KADM5_BAD_HISTORY (43787540L) #define KADM5_BAD_MIN_PASS_LIFE (43787541L) #define KADM5_PASS_Q_TOOSHORT (43787542L) #define KADM5_PASS_Q_CLASS (43787543L) #define KADM5_PASS_Q_DICT (43787544L) #define KADM5_PASS_REUSE (43787545L) #define KADM5_PASS_TOOSOON (43787546L) #define KADM5_POLICY_REF (43787547L) #define KADM5_INIT (43787548L) #define KADM5_BAD_PASSWORD (43787549L) #define KADM5_PROTECT_PRINCIPAL (43787550L) #define KADM5_BAD_SERVER_HANDLE (43787551L) #define KADM5_BAD_STRUCT_VERSION (43787552L) #define KADM5_OLD_STRUCT_VERSION (43787553L) #define KADM5_NEW_STRUCT_VERSION (43787554L) #define KADM5_BAD_API_VERSION (43787555L) #define KADM5_OLD_LIB_API_VERSION (43787556L) #define KADM5_OLD_SERVER_API_VERSION (43787557L) #define KADM5_NEW_LIB_API_VERSION (43787558L) #define KADM5_NEW_SERVER_API_VERSION (43787559L) #define KADM5_SECURE_PRINC_MISSING (43787560L) #define KADM5_NO_RENAME_SALT (43787561L) #define KADM5_BAD_CLIENT_PARAMS (43787562L) #define KADM5_BAD_SERVER_PARAMS (43787563L) #define KADM5_AUTH_LIST (43787564L) #define KADM5_AUTH_CHANGEPW (43787565L) #define KADM5_GSS_ERROR (43787566L) #define KADM5_BAD_TL_TYPE (43787567L) #define KADM5_MISSING_CONF_PARAMS (43787568L) #define KADM5_BAD_SERVER_NAME (43787569L) #define KADM5_AUTH_SETKEY (43787570L) #define KADM5_SETKEY_DUP_ENCTYPES (43787571L) #define KADM5_SETV4KEY_INVAL_ENCTYPE (43787572L) #define KADM5_SETKEY3_ETYPE_MISMATCH (43787573L) #define KADM5_MISSING_KRB5_CONF_PARAMS (43787574L) #define KADM5_XDR_FAILURE (43787575L) #define KADM5_CANT_RESOLVE (43787576L) #define KADM5_PASS_Q_GENERIC (43787577L) #define KADM5_BAD_KEYSALTS (43787578L) #define KADM5_SETKEY_BAD_KVNO (43787579L) #define KADM5_AUTH_EXTRACT (43787580L) #define KADM5_PROTECT_KEYS (43787581L) #define KADM5_AUTH_INITIAL (43787582L) extern const struct error_table et_ovk_error_table; extern void initialize_ovk_error_table(void); /* For compatibility with Heimdal */ extern void initialize_ovk_error_table_r(struct et_list **list); #define ERROR_TABLE_BASE_ovk (43787520L) /* for compatibility with older versions... */ #define init_ovk_err_tbl initialize_ovk_error_table #define ovk_err_base ERROR_TABLE_BASE_ovk kadm5/chpass_util_strings.h 0000644 00000003014 15146341150 0012003 0 ustar 00 /* * et-h-chpass_util_strings.h: * This file is automatically generated; please do not edit it. */ #include <et/com_err.h> #define CHPASS_UTIL_GET_POLICY_INFO (-1492553984L) #define CHPASS_UTIL_GET_PRINC_INFO (-1492553983L) #define CHPASS_UTIL_NEW_PASSWORD_MISMATCH (-1492553982L) #define CHPASS_UTIL_NEW_PASSWORD_PROMPT (-1492553981L) #define CHPASS_UTIL_NEW_PASSWORD_AGAIN_PROMPT (-1492553980L) #define CHPASS_UTIL_NO_PASSWORD_READ (-1492553979L) #define CHPASS_UTIL_NO_POLICY_YET_Q_ERROR (-1492553978L) #define CHPASS_UTIL_PASSWORD_CHANGED (-1492553977L) #define CHPASS_UTIL_PASSWORD_IN_DICTIONARY (-1492553976L) #define CHPASS_UTIL_PASSWORD_NOT_CHANGED (-1492553975L) #define CHPASS_UTIL_PASSWORD_TOO_SHORT (-1492553974L) #define CHPASS_UTIL_TOO_FEW_CLASSES (-1492553973L) #define CHPASS_UTIL_PASSWORD_TOO_SOON (-1492553972L) #define CHPASS_UTIL_PASSWORD_REUSE (-1492553971L) #define CHPASS_UTIL_WHILE_TRYING_TO_CHANGE (-1492553970L) #define CHPASS_UTIL_WHILE_READING_PASSWORD (-1492553969L) extern const struct error_table et_ovku_error_table; extern void initialize_ovku_error_table(void); /* For compatibility with Heimdal */ extern void initialize_ovku_error_table_r(struct et_list **list); #define ERROR_TABLE_BASE_ovku (-1492553984L) /* for compatibility with older versions... */ #define init_ovku_err_tbl initialize_ovku_error_table #define ovku_err_base ERROR_TABLE_BASE_ovku kadm5/admin.h 0000644 00000050137 15146341150 0007014 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* lib/kadm5/admin.h */ /* * Copyright 2001, 2008 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved * * $Header$ */ /* * This API is not considered as stable as the main krb5 API. * * - We may make arbitrary incompatible changes between feature * releases (e.g. from 1.7 to 1.8). * - We will make some effort to avoid making incompatible changes for * bugfix releases, but will make them if necessary. */ #ifndef __KADM5_ADMIN_H__ #define __KADM5_ADMIN_H__ #include <sys/types.h> #include <gssrpc/rpc.h> #include <krb5.h> #include <kdb.h> #include <com_err.h> #include <kadm5/kadm_err.h> #include <kadm5/chpass_util_strings.h> #ifndef KADM5INT_BEGIN_DECLS #if defined(__cplusplus) #define KADM5INT_BEGIN_DECLS extern "C" { #define KADM5INT_END_DECLS } #else #define KADM5INT_BEGIN_DECLS #define KADM5INT_END_DECLS #endif #endif KADM5INT_BEGIN_DECLS #define KADM5_ADMIN_SERVICE "kadmin/admin" #define KADM5_CHANGEPW_SERVICE "kadmin/changepw" #define KADM5_HIST_PRINCIPAL "kadmin/history" #define KADM5_KIPROP_HOST_SERVICE "kiprop" typedef krb5_principal kadm5_princ_t; typedef char *kadm5_policy_t; typedef long kadm5_ret_t; #define KADM5_PW_FIRST_PROMPT \ (error_message(CHPASS_UTIL_NEW_PASSWORD_PROMPT)) #define KADM5_PW_SECOND_PROMPT \ (error_message(CHPASS_UTIL_NEW_PASSWORD_AGAIN_PROMPT)) /* * Successful return code */ #define KADM5_OK 0 /* * Field masks */ /* kadm5_principal_ent_t */ #define KADM5_PRINCIPAL 0x000001 #define KADM5_PRINC_EXPIRE_TIME 0x000002 #define KADM5_PW_EXPIRATION 0x000004 #define KADM5_LAST_PWD_CHANGE 0x000008 #define KADM5_ATTRIBUTES 0x000010 #define KADM5_MAX_LIFE 0x000020 #define KADM5_MOD_TIME 0x000040 #define KADM5_MOD_NAME 0x000080 #define KADM5_KVNO 0x000100 #define KADM5_MKVNO 0x000200 #define KADM5_AUX_ATTRIBUTES 0x000400 #define KADM5_POLICY 0x000800 #define KADM5_POLICY_CLR 0x001000 /* version 2 masks */ #define KADM5_MAX_RLIFE 0x002000 #define KADM5_LAST_SUCCESS 0x004000 #define KADM5_LAST_FAILED 0x008000 #define KADM5_FAIL_AUTH_COUNT 0x010000 #define KADM5_KEY_DATA 0x020000 #define KADM5_TL_DATA 0x040000 #ifdef notyet /* Novell */ #define KADM5_CPW_FUNCTION 0x080000 #define KADM5_RANDKEY_USED 0x100000 #endif #define KADM5_LOAD 0x200000 #define KADM5_KEY_HIST 0x400000 /* all but KEY_DATA, TL_DATA, LOAD */ #define KADM5_PRINCIPAL_NORMAL_MASK 0x41ffff /* kadm5_policy_ent_t */ #define KADM5_PW_MAX_LIFE 0x00004000 #define KADM5_PW_MIN_LIFE 0x00008000 #define KADM5_PW_MIN_LENGTH 0x00010000 #define KADM5_PW_MIN_CLASSES 0x00020000 #define KADM5_PW_HISTORY_NUM 0x00040000 #define KADM5_REF_COUNT 0x00080000 #define KADM5_PW_MAX_FAILURE 0x00100000 #define KADM5_PW_FAILURE_COUNT_INTERVAL 0x00200000 #define KADM5_PW_LOCKOUT_DURATION 0x00400000 #define KADM5_POLICY_ATTRIBUTES 0x00800000 #define KADM5_POLICY_MAX_LIFE 0x01000000 #define KADM5_POLICY_MAX_RLIFE 0x02000000 #define KADM5_POLICY_ALLOWED_KEYSALTS 0x04000000 #define KADM5_POLICY_TL_DATA 0x08000000 /* kadm5_config_params */ #define KADM5_CONFIG_REALM 0x00000001 #define KADM5_CONFIG_DBNAME 0x00000002 #define KADM5_CONFIG_MKEY_NAME 0x00000004 #define KADM5_CONFIG_MAX_LIFE 0x00000008 #define KADM5_CONFIG_MAX_RLIFE 0x00000010 #define KADM5_CONFIG_EXPIRATION 0x00000020 #define KADM5_CONFIG_FLAGS 0x00000040 /*#define KADM5_CONFIG_ADMIN_KEYTAB 0x00000080*/ #define KADM5_CONFIG_STASH_FILE 0x00000100 #define KADM5_CONFIG_ENCTYPE 0x00000200 #define KADM5_CONFIG_ADBNAME 0x00000400 #define KADM5_CONFIG_ADB_LOCKFILE 0x00000800 #define KADM5_CONFIG_KADMIND_LISTEN 0x00001000 #define KADM5_CONFIG_ACL_FILE 0x00002000 #define KADM5_CONFIG_KADMIND_PORT 0x00004000 #define KADM5_CONFIG_ENCTYPES 0x00008000 #define KADM5_CONFIG_ADMIN_SERVER 0x00010000 #define KADM5_CONFIG_DICT_FILE 0x00020000 #define KADM5_CONFIG_MKEY_FROM_KBD 0x00040000 #define KADM5_CONFIG_KPASSWD_PORT 0x00080000 #define KADM5_CONFIG_OLD_AUTH_GSSAPI 0x00100000 #define KADM5_CONFIG_NO_AUTH 0x00200000 #define KADM5_CONFIG_AUTH_NOFALLBACK 0x00400000 #define KADM5_CONFIG_KPASSWD_LISTEN 0x00800000 #define KADM5_CONFIG_IPROP_ENABLED 0x01000000 #define KADM5_CONFIG_ULOG_SIZE 0x02000000 #define KADM5_CONFIG_POLL_TIME 0x04000000 #define KADM5_CONFIG_IPROP_LOGFILE 0x08000000 #define KADM5_CONFIG_IPROP_PORT 0x10000000 #define KADM5_CONFIG_KVNO 0x20000000 #define KADM5_CONFIG_IPROP_RESYNC_TIMEOUT 0x40000000 #define KADM5_CONFIG_IPROP_LISTEN 0x80000000 /* * permission bits */ #define KADM5_PRIV_GET 0x01 #define KADM5_PRIV_ADD 0x02 #define KADM5_PRIV_MODIFY 0x04 #define KADM5_PRIV_DELETE 0x08 /* * API versioning constants */ #define KADM5_MASK_BITS 0xffffff00 #define KADM5_STRUCT_VERSION_MASK 0x12345600 #define KADM5_STRUCT_VERSION_1 (KADM5_STRUCT_VERSION_MASK|0x01) #define KADM5_STRUCT_VERSION KADM5_STRUCT_VERSION_1 #define KADM5_API_VERSION_MASK 0x12345700 #define KADM5_API_VERSION_2 (KADM5_API_VERSION_MASK|0x02) #define KADM5_API_VERSION_3 (KADM5_API_VERSION_MASK|0x03) #define KADM5_API_VERSION_4 (KADM5_API_VERSION_MASK|0x04) typedef struct _kadm5_principal_ent_t { krb5_principal principal; krb5_timestamp princ_expire_time; krb5_timestamp last_pwd_change; krb5_timestamp pw_expiration; krb5_deltat max_life; krb5_principal mod_name; krb5_timestamp mod_date; krb5_flags attributes; krb5_kvno kvno; krb5_kvno mkvno; char *policy; long aux_attributes; /* version 2 fields */ krb5_deltat max_renewable_life; krb5_timestamp last_success; krb5_timestamp last_failed; krb5_kvno fail_auth_count; krb5_int16 n_key_data; krb5_int16 n_tl_data; krb5_tl_data *tl_data; krb5_key_data *key_data; } kadm5_principal_ent_rec, *kadm5_principal_ent_t; typedef struct _kadm5_policy_ent_t { char *policy; long pw_min_life; long pw_max_life; long pw_min_length; long pw_min_classes; long pw_history_num; long policy_refcnt; /* no longer used */ /* version 3 fields */ krb5_kvno pw_max_fail; krb5_deltat pw_failcnt_interval; krb5_deltat pw_lockout_duration; /* version 4 fields */ krb5_flags attributes; krb5_deltat max_life; krb5_deltat max_renewable_life; char *allowed_keysalts; krb5_int16 n_tl_data; krb5_tl_data *tl_data; } kadm5_policy_ent_rec, *kadm5_policy_ent_t; /* * Data structure returned by kadm5_get_config_params() */ typedef struct _kadm5_config_params { long mask; char * realm; int kadmind_port; int kpasswd_port; char * admin_server; #ifdef notyet /* Novell */ /* ABI change? */ char * kpasswd_server; #endif /* Deprecated except for db2 backwards compatibility. Don't add new uses except as fallbacks for parameters that should be specified in the database module section of the config file. */ char * dbname; char * acl_file; char * dict_file; int mkey_from_kbd; char * stash_file; char * mkey_name; krb5_enctype enctype; krb5_deltat max_life; krb5_deltat max_rlife; krb5_timestamp expiration; krb5_flags flags; krb5_key_salt_tuple *keysalts; krb5_int32 num_keysalts; krb5_kvno kvno; bool_t iprop_enabled; uint32_t iprop_ulogsize; krb5_deltat iprop_poll_time; char * iprop_logfile; /* char * iprop_server;*/ int iprop_port; int iprop_resync_timeout; char * kadmind_listen; char * kpasswd_listen; char * iprop_listen; } kadm5_config_params; typedef struct _kadm5_key_data { krb5_kvno kvno; krb5_keyblock key; krb5_keysalt salt; } kadm5_key_data; /* * functions */ krb5_error_code kadm5_get_config_params(krb5_context context, int use_kdc_config, kadm5_config_params *params_in, kadm5_config_params *params_out); krb5_error_code kadm5_free_config_params(krb5_context context, kadm5_config_params *params); krb5_error_code kadm5_get_admin_service_name(krb5_context, char *, char *, size_t); /* * For all initialization functions, the caller must first initialize * a context with kadm5_init_krb5_context which will survive as long * as the resulting handle. The caller should free the context with * krb5_free_context. */ kadm5_ret_t kadm5_init(krb5_context context, char *client_name, char *pass, char *service_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, char **db_args, void **server_handle); kadm5_ret_t kadm5_init_anonymous(krb5_context context, char *client_name, char *service_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, char **db_args, void **server_handle); kadm5_ret_t kadm5_init_with_password(krb5_context context, char *client_name, char *pass, char *service_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, char **db_args, void **server_handle); kadm5_ret_t kadm5_init_with_skey(krb5_context context, char *client_name, char *keytab, char *service_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, char **db_args, void **server_handle); kadm5_ret_t kadm5_init_with_creds(krb5_context context, char *client_name, krb5_ccache cc, char *service_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, char **db_args, void **server_handle); kadm5_ret_t kadm5_lock(void *server_handle); kadm5_ret_t kadm5_unlock(void *server_handle); kadm5_ret_t kadm5_flush(void *server_handle); kadm5_ret_t kadm5_destroy(void *server_handle); kadm5_ret_t kadm5_create_principal(void *server_handle, kadm5_principal_ent_t ent, long mask, char *pass); kadm5_ret_t kadm5_create_principal_3(void *server_handle, kadm5_principal_ent_t ent, long mask, int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, char *pass); kadm5_ret_t kadm5_delete_principal(void *server_handle, krb5_principal principal); kadm5_ret_t kadm5_modify_principal(void *server_handle, kadm5_principal_ent_t ent, long mask); kadm5_ret_t kadm5_rename_principal(void *server_handle, krb5_principal,krb5_principal); kadm5_ret_t kadm5_get_principal(void *server_handle, krb5_principal principal, kadm5_principal_ent_t ent, long mask); kadm5_ret_t kadm5_chpass_principal(void *server_handle, krb5_principal principal, char *pass); kadm5_ret_t kadm5_chpass_principal_3(void *server_handle, krb5_principal principal, krb5_boolean keepold, int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, char *pass); kadm5_ret_t kadm5_randkey_principal(void *server_handle, krb5_principal principal, krb5_keyblock **keyblocks, int *n_keys); kadm5_ret_t kadm5_randkey_principal_3(void *server_handle, krb5_principal principal, krb5_boolean keepold, int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, krb5_keyblock **keyblocks, int *n_keys); kadm5_ret_t kadm5_setkey_principal(void *server_handle, krb5_principal principal, krb5_keyblock *keyblocks, int n_keys); kadm5_ret_t kadm5_setkey_principal_3(void *server_handle, krb5_principal principal, krb5_boolean keepold, int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, krb5_keyblock *keyblocks, int n_keys); kadm5_ret_t kadm5_setkey_principal_4(void *server_handle, krb5_principal principal, krb5_boolean keepold, kadm5_key_data *key_data, int n_key_data); kadm5_ret_t kadm5_decrypt_key(void *server_handle, kadm5_principal_ent_t entry, krb5_int32 ktype, krb5_int32 stype, krb5_int32 kvno, krb5_keyblock *keyblock, krb5_keysalt *keysalt, int *kvnop); kadm5_ret_t kadm5_create_policy(void *server_handle, kadm5_policy_ent_t ent, long mask); kadm5_ret_t kadm5_delete_policy(void *server_handle, kadm5_policy_t policy); kadm5_ret_t kadm5_modify_policy(void *server_handle, kadm5_policy_ent_t ent, long mask); kadm5_ret_t kadm5_get_policy(void *server_handle, kadm5_policy_t policy, kadm5_policy_ent_t ent); kadm5_ret_t kadm5_get_privs(void *server_handle, long *privs); kadm5_ret_t kadm5_chpass_principal_util(void *server_handle, krb5_principal princ, char *new_pw, char **ret_pw, char *msg_ret, unsigned int msg_len); kadm5_ret_t kadm5_free_principal_ent(void *server_handle, kadm5_principal_ent_t ent); kadm5_ret_t kadm5_free_policy_ent(void *server_handle, kadm5_policy_ent_t ent); kadm5_ret_t kadm5_get_principals(void *server_handle, char *exp, char ***princs, int *count); kadm5_ret_t kadm5_get_policies(void *server_handle, char *exp, char ***pols, int *count); kadm5_ret_t kadm5_free_key_data(void *server_handle, krb5_int16 *n_key_data, krb5_key_data *key_data); kadm5_ret_t kadm5_free_name_list(void *server_handle, char **names, int count); krb5_error_code kadm5_init_krb5_context (krb5_context *); krb5_error_code kadm5_init_iprop(void *server_handle, char **db_args); kadm5_ret_t kadm5_get_principal_keys(void *server_handle, krb5_principal principal, krb5_kvno kvno, kadm5_key_data **key_data, int *n_key_data); kadm5_ret_t kadm5_purgekeys(void *server_handle, krb5_principal principal, int keepkvno); kadm5_ret_t kadm5_get_strings(void *server_handle, krb5_principal principal, krb5_string_attr **strings_out, int *count_out); kadm5_ret_t kadm5_set_string(void *server_handle, krb5_principal principal, const char *key, const char *value); kadm5_ret_t kadm5_free_strings(void *server_handle, krb5_string_attr *strings, int count); kadm5_ret_t kadm5_free_kadm5_key_data(krb5_context context, int n_key_data, kadm5_key_data *key_data); KADM5INT_END_DECLS #endif /* __KADM5_ADMIN_H__ */ utmp.h 0000644 00000006226 15146341150 0005710 0 ustar 00 /* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _UTMP_H #define _UTMP_H 1 #include <features.h> #include <sys/types.h> __BEGIN_DECLS /* Get system dependent values and data structures. */ #include <bits/utmp.h> /* Compatibility names for the strings of the canonical file names. */ #define UTMP_FILE _PATH_UTMP #define UTMP_FILENAME _PATH_UTMP #define WTMP_FILE _PATH_WTMP #define WTMP_FILENAME _PATH_WTMP /* Make FD be the controlling terminal, stdin, stdout, and stderr; then close FD. Returns 0 on success, nonzero on error. */ extern int login_tty (int __fd) __THROW; /* Write the given entry into utmp and wtmp. */ extern void login (const struct utmp *__entry) __THROW; /* Write the utmp entry to say the user on UT_LINE has logged out. */ extern int logout (const char *__ut_line) __THROW; /* Append to wtmp an entry for the current time and the given info. */ extern void logwtmp (const char *__ut_line, const char *__ut_name, const char *__ut_host) __THROW; /* Append entry UTMP to the wtmp-like file WTMP_FILE. */ extern void updwtmp (const char *__wtmp_file, const struct utmp *__utmp) __THROW; /* Change name of the utmp file to be examined. */ extern int utmpname (const char *__file) __THROW; /* Read next entry from a utmp-like file. */ extern struct utmp *getutent (void) __THROW; /* Reset the input stream to the beginning of the file. */ extern void setutent (void) __THROW; /* Close the current open file. */ extern void endutent (void) __THROW; /* Search forward from the current point in the utmp file until the next entry with a ut_type matching ID->ut_type. */ extern struct utmp *getutid (const struct utmp *__id) __THROW; /* Search forward from the current point in the utmp file until the next entry with a ut_line matching LINE->ut_line. */ extern struct utmp *getutline (const struct utmp *__line) __THROW; /* Write out entry pointed to by UTMP_PTR into the utmp file. */ extern struct utmp *pututline (const struct utmp *__utmp_ptr) __THROW; #ifdef __USE_MISC /* Reentrant versions of the file for handling utmp files. */ extern int getutent_r (struct utmp *__buffer, struct utmp **__result) __THROW; extern int getutid_r (const struct utmp *__id, struct utmp *__buffer, struct utmp **__result) __THROW; extern int getutline_r (const struct utmp *__line, struct utmp *__buffer, struct utmp **__result) __THROW; #endif /* Use misc. */ __END_DECLS #endif /* utmp.h */ error.h 0000644 00000003767 15146341150 0006063 0 ustar 00 /* Declaration for error-reporting function Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _ERROR_H #define _ERROR_H 1 #include <features.h> __BEGIN_DECLS /* Print a message with `fprintf (stderr, FORMAT, ...)'; if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). If STATUS is nonzero, terminate the program with `exit (STATUS)'. */ extern void error (int __status, int __errnum, const char *__format, ...) __attribute__ ((__format__ (__printf__, 3, 4))); extern void error_at_line (int __status, int __errnum, const char *__fname, unsigned int __lineno, const char *__format, ...) __attribute__ ((__format__ (__printf__, 5, 6))); /* If NULL, error will flush stdout, then print on stderr the program name, a colon and a space. Otherwise, error will call this function without parameters instead. */ extern void (*error_print_progname) (void); /* This variable is incremented each time `error' is called. */ extern unsigned int error_message_count; /* Sometimes we want to have at most one error per line. This variable controls whether this mode is selected or not. */ extern int error_one_per_line; #if defined __extern_always_inline && defined __va_arg_pack # include <bits/error.h> #endif __END_DECLS #endif /* error.h */ krb5/kadm5_hook_plugin.h 0000644 00000014021 15146341150 0011155 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ #ifndef H_KRB5_KADM5_HOOK_PLUGIN #define H_KRB5_KADM5_HOOK_PLUGIN /** * @file krb5/krb5_kadm5_hook_plugin.h * Provide a plugin interface for kadm5 operations. This interface * permits a plugin to intercept principal modification, creation and * change password operations. Operations run at two stages: a * precommit stage that runs before the operation is committed to the * database and a postcommit operation that runs after the database * is updated; see #kadm5_hook_stage for details on semantics. * * This interface is based on a proposed extension to Heimdal by Russ * Allbery; it is likely that Heimdal will adopt an approach based on * stacked kdb modules rather than this interface. For MIT, writing a * plugin to this interface is significantly easier than stacking kdb * modules. Also, the kadm5 interface is significantly more stable * than the kdb interface, so this approach is more desirable than * stacked kdb modules. * * This interface depends on kadm5/admin.h. As such, the interface * does not provide strong guarantees of ABI stability. * * The kadm5_hook interface currently has only one supported major version, * which is 1. Major version 1 has a current minor version number of 2. * * kadm5_hook plugins should: * kadm5_hook_<modulename>_initvt, matching the signature: * * krb5_error_code * kadm5_hook_modname_initvt(krb5_context context, int maj_ver, int min_ver, * krb5_plugin_vtable vtable); * * The initvt function should: * * - Check that the supplied maj_ver number is supported by the module, or * return KRB5_PLUGIN_VER_NOTSUPP if it is not. * * - Cast the vtable pointer as appropriate for maj_ver: * maj_ver == 1: Cast to kadm5_hook_vftable_1 * * - Initialize the methods of the vtable, stopping as appropriate for the * supplied min_ver. Optional methods may be left uninitialized. * * Memory for the vtable is allocated by the caller, not by the module. */ #include <krb5/krb5.h> #include <krb5/plugin.h> #include <kadm5/admin.h> /** * Whether the operation is being run before or after the database * update. */ enum kadm5_hook_stage { /** In this stage, any plugin failure prevents following plugins from * running and aborts the operation.*/ KADM5_HOOK_STAGE_PRECOMMIT, /** In this stage, plugin failures are logged but otherwise ignored.*/ KADM5_HOOK_STAGE_POSTCOMMIT }; /** Opaque module data pointer. */ typedef struct kadm5_hook_modinfo_st kadm5_hook_modinfo; /** * Interface for the v1 virtual table for the kadm5_hook plugin. * All entry points are optional. The name field must be provided. */ typedef struct kadm5_hook_vtable_1_st { /** A text string identifying the plugin for logging messages. */ const char *name; /** Initialize a plugin module. * @param modinfo returns newly allocated module info for future * calls. Cleaned up by the fini() function. */ kadm5_ret_t (*init)(krb5_context, kadm5_hook_modinfo **modinfo); /** Clean up a module and free @a modinfo. */ void (*fini)(krb5_context, kadm5_hook_modinfo *modinfo); /** Indicates that the password is being changed. * @param stage is an integer from #kadm5_hook_stage enumeration * @param keepold is true if existing keys are being kept. * @param newpass is NULL if the key sare being randomized. */ kadm5_ret_t (*chpass)(krb5_context, kadm5_hook_modinfo *modinfo, int stage, krb5_principal, krb5_boolean keepold, int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, const char *newpass); /** Indicate a principal is created. */ kadm5_ret_t (*create)(krb5_context, kadm5_hook_modinfo *, int stage, kadm5_principal_ent_t, long mask, int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, const char *password); /** Modify a principal. */ kadm5_ret_t (*modify)(krb5_context, kadm5_hook_modinfo *, int stage, kadm5_principal_ent_t, long mask); /** Indicate a principal is deleted. */ kadm5_ret_t (*remove)(krb5_context, kadm5_hook_modinfo *modinfo, int stage, krb5_principal); /* End of minor version 1. */ /** Indicate a principal is renamed. */ kadm5_ret_t (*rename)(krb5_context, kadm5_hook_modinfo *modinfo, int stage, krb5_principal, krb5_principal); /* End of minor version 2. */ } kadm5_hook_vftable_1; #endif /*H_KRB5_KADM5_HOOK_PLUGIN*/ krb5/ccselect_plugin.h 0000644 00000010165 15146341150 0010726 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2011 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Declarations for credential cache selection module implementors. * * The ccselect pluggable interface currently has only one supported major * version, which is 1. Major version 1 has a current minor version number of * 1. * * Credential cache selection modules should define a function named * ccselect_<modulename>_initvt, matching the signature: * * krb5_error_code * ccselect_modname_initvt(krb5_context context, int maj_ver, int min_ver, * krb5_plugin_vtable vtable); * * The initvt function should: * * - Check that the supplied maj_ver number is supported by the module, or * return KRB5_PLUGIN_VER_NOTSUPP if it is not. * * - Cast the vtable pointer as appropriate for maj_ver: * maj_ver == 1: Cast to krb5_ccselect_vtable * * - Initialize the methods of the vtable, stopping as appropriate for the * supplied min_ver. Optional methods may be left uninitialized. * * Memory for the vtable is allocated by the caller, not by the module. */ #ifndef KRB5_CCSELECT_PLUGIN_H #define KRB5_CCSELECT_PLUGIN_H #include <krb5/krb5.h> #include <krb5/plugin.h> /* An abstract type for credential cache selection module data. */ typedef struct krb5_ccselect_moddata_st *krb5_ccselect_moddata; #define KRB5_CCSELECT_PRIORITY_AUTHORITATIVE 2 #define KRB5_CCSELECT_PRIORITY_HEURISTIC 1 /*** Method type declarations ***/ /* * Mandatory: Initialize module data and set *priority_out to one of the * KRB5_CCSELECT_PRIORITY constants above. Authoritative modules will be * consulted before heuristic ones. */ typedef krb5_error_code (*krb5_ccselect_init_fn)(krb5_context context, krb5_ccselect_moddata *data_out, int *priority_out); /* * Mandatory: Select a cache based on a server principal. Return 0 on success, * with *cache_out set to the selected cache and *princ_out set to its default * principal. Return KRB5_PLUGIN_NO_HANDLE to defer to other modules. Return * KRB5_CC_NOTFOUND with *princ_out set if the client principal can be * authoritatively determined but no cache exists for it. Return other errors * as appropriate. */ typedef krb5_error_code (*krb5_ccselect_choose_fn)(krb5_context context, krb5_ccselect_moddata data, krb5_principal server, krb5_ccache *cache_out, krb5_principal *princ_out); /* Optional: Release resources used by module data. */ typedef void (*krb5_ccselect_fini_fn)(krb5_context context, krb5_ccselect_moddata data); /*** vtable declarations **/ /* Credential cache selection plugin vtable for major version 1. */ typedef struct krb5_ccselect_vtable_st { const char *name; /* Mandatory: name of module. */ krb5_ccselect_init_fn init; krb5_ccselect_choose_fn choose; krb5_ccselect_fini_fn fini; /* Minor version 1 ends here. */ } *krb5_ccselect_vtable; #endif /* KRB5_CCSELECT_PLUGIN_H */ krb5/plugin.h 0000644 00000004052 15146341150 0007057 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* Generic declarations for dynamic modules implementing krb5 plugin * modules. */ #ifndef KRB5_PLUGIN_H #define KRB5_PLUGIN_H /* krb5_plugin_vtable is an abstract type. Module initvt functions will cast * it to the appropriate interface-specific vtable type. */ typedef struct krb5_plugin_vtable_st *krb5_plugin_vtable; /* * krb5_plugin_initvt_fn is the type of all module initvt functions. Based on * the maj_ver argument, the initvt function should cast vtable to the * appropriate type and then fill it in. If a vtable has been expanded, * min_ver indicates which version of the vtable is being filled in. */ typedef krb5_error_code (*krb5_plugin_initvt_fn)(krb5_context context, int maj_ver, int min_ver, krb5_plugin_vtable vtable); #endif /* KRB5_PLUGIN_H */ krb5/preauth_plugin.h 0000644 00000003356 15146341150 0010615 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2012 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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 COPYRIGHT HOLDERS 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 * COPYRIGHT HOLDER 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. */ /* This header includes the clpreauth and kdcpreauth interface declarations, * for backward compatibility and convenience. */ #ifndef KRB5_PREAUTH_PLUGIN_H #define KRB5_PREAUTH_PLUGIN_H #include <krb5/clpreauth_plugin.h> #include <krb5/kdcpreauth_plugin.h> #endif /* KRB5_PREAUTH_PLUGIN_H */ krb5/krb5.h 0000644 00001256744 15146341150 0006446 0 ustar 00 /* This file is generated, please don't edit it directly. */ #ifndef KRB5_KRB5_H_INCLUDED #define KRB5_KRB5_H_INCLUDED /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* General definitions for Kerberos version 5. */ /* * Copyright 1989, 1990, 1995, 2001, 2003, 2007, 2011 by the Massachusetts * Institute of Technology. All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. * * Export of this software from the United States of America may require * a specific license from the United States Government. It is the * responsibility of any person or organization contemplating export to * obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of FundsXpress. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef KRB5_GENERAL__ #define KRB5_GENERAL__ /** @defgroup KRB5_H krb5 library API * @{ */ /* By default, do not expose deprecated interfaces. */ #ifndef KRB5_DEPRECATED #define KRB5_DEPRECATED 0 #endif #if defined(__MACH__) && defined(__APPLE__) # include <TargetConditionals.h> # if TARGET_RT_MAC_CFM # error "Use KfM 4.0 SDK headers for CFM compilation." # endif #endif #if defined(_MSDOS) || defined(_WIN32) #include <win-mac.h> #endif #ifndef KRB5_CONFIG__ #ifndef KRB5_CALLCONV #define KRB5_CALLCONV #define KRB5_CALLCONV_C #endif /* !KRB5_CALLCONV */ #endif /* !KRB5_CONFIG__ */ #ifndef KRB5_CALLCONV_WRONG #define KRB5_CALLCONV_WRONG #endif #ifndef THREEPARAMOPEN #define THREEPARAMOPEN(x,y,z) open(x,y,z) #endif #if KRB5_PRIVATE #ifndef WRITABLEFOPEN #define WRITABLEFOPEN(x,y) fopen(x,y) #endif #endif #define KRB5_OLD_CRYPTO #include <stdlib.h> #include <limits.h> /* for *_MAX */ #include <stdarg.h> #include <stdint.h> #ifndef KRB5INT_BEGIN_DECLS #if defined(__cplusplus) #define KRB5INT_BEGIN_DECLS extern "C" { #define KRB5INT_END_DECLS } #else #define KRB5INT_BEGIN_DECLS #define KRB5INT_END_DECLS #endif #endif KRB5INT_BEGIN_DECLS #if defined(TARGET_OS_MAC) && TARGET_OS_MAC # pragma pack(push,2) #endif #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 30203 # define KRB5_ATTR_DEPRECATED __attribute__((deprecated)) #elif defined _WIN32 # define KRB5_ATTR_DEPRECATED __declspec(deprecated) #else # define KRB5_ATTR_DEPRECATED #endif /* from profile.h */ struct _profile_t; /* typedef struct _profile_t *profile_t; */ /* * begin wordsize.h */ /* * Word-size related definition. */ typedef uint8_t krb5_octet; typedef int16_t krb5_int16; typedef uint16_t krb5_ui_2; typedef int32_t krb5_int32; typedef uint32_t krb5_ui_4; #define VALID_INT_BITS INT_MAX #define VALID_UINT_BITS UINT_MAX #define KRB5_INT32_MAX 2147483647 /* this strange form is necessary since - is a unary operator, not a sign indicator */ #define KRB5_INT32_MIN (-KRB5_INT32_MAX-1) #define KRB5_INT16_MAX 65535 /* this strange form is necessary since - is a unary operator, not a sign indicator */ #define KRB5_INT16_MIN (-KRB5_INT16_MAX-1) /* * end wordsize.h */ /* * begin "base-defs.h" */ /* * Basic definitions for Kerberos V5 library */ #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif typedef unsigned int krb5_boolean; typedef unsigned int krb5_msgtype; typedef unsigned int krb5_kvno; typedef krb5_int32 krb5_addrtype; typedef krb5_int32 krb5_enctype; typedef krb5_int32 krb5_cksumtype; typedef krb5_int32 krb5_authdatatype; typedef krb5_int32 krb5_keyusage; typedef krb5_int32 krb5_cryptotype; typedef krb5_int32 krb5_preauthtype; /* This may change, later on */ typedef krb5_int32 krb5_flags; /** * Represents a timestamp in seconds since the POSIX epoch. This legacy type * is used frequently in the ABI, but cannot represent timestamps after 2038 as * a positive number. Code which uses this type should cast values of it to * uint32_t so that negative values are treated as timestamps between 2038 and * 2106 on platforms with 64-bit time_t. */ typedef krb5_int32 krb5_timestamp; typedef krb5_int32 krb5_deltat; /** * Used to convey an operation status. The value 0 indicates success; any * other values are com_err codes. Use krb5_get_error_message() to obtain a * string describing the error. */ typedef krb5_int32 krb5_error_code; typedef krb5_error_code krb5_magic; typedef struct _krb5_data { krb5_magic magic; unsigned int length; char *data; } krb5_data; /* Originally introduced for PKINIT; now unused. Do not use this. */ typedef struct _krb5_octet_data { krb5_magic magic; unsigned int length; krb5_octet *data; } krb5_octet_data; /* Originally used to recognize AFS and default salts. No longer used. */ #define SALT_TYPE_AFS_LENGTH UINT_MAX #define SALT_TYPE_NO_LENGTH UINT_MAX typedef void * krb5_pointer; typedef void const * krb5_const_pointer; typedef struct krb5_principal_data { krb5_magic magic; krb5_data realm; krb5_data *data; /**< An array of strings */ krb5_int32 length; krb5_int32 type; } krb5_principal_data; typedef krb5_principal_data * krb5_principal; /* * Per V5 spec on definition of principal types */ #define KRB5_NT_UNKNOWN 0 /**< Name type not known */ #define KRB5_NT_PRINCIPAL 1 /**< Just the name of the principal as in DCE, or for users */ #define KRB5_NT_SRV_INST 2 /**< Service and other unique instance (krbtgt) */ #define KRB5_NT_SRV_HST 3 /**< Service with host name as instance (telnet, rcommands) */ #define KRB5_NT_SRV_XHST 4 /**< Service with host as remaining components */ #define KRB5_NT_UID 5 /**< Unique ID */ #define KRB5_NT_X500_PRINCIPAL 6 /**< PKINIT */ #define KRB5_NT_SMTP_NAME 7 /**< Name in form of SMTP email name */ #define KRB5_NT_ENTERPRISE_PRINCIPAL 10 /**< Windows 2000 UPN */ #define KRB5_NT_WELLKNOWN 11 /**< Well-known (special) principal */ #define KRB5_WELLKNOWN_NAMESTR "WELLKNOWN" /**< First component of NT_WELLKNOWN principals */ #define KRB5_NT_MS_PRINCIPAL -128 /**< Windows 2000 UPN and SID */ #define KRB5_NT_MS_PRINCIPAL_AND_ID -129 /**< NT 4 style name */ #define KRB5_NT_ENT_PRINCIPAL_AND_ID -130 /**< NT 4 style name and SID */ /** Constant version of krb5_principal_data */ typedef const krb5_principal_data *krb5_const_principal; #define krb5_princ_realm(context, princ) (&(princ)->realm) #define krb5_princ_set_realm(context, princ,value) ((princ)->realm = *(value)) #define krb5_princ_set_realm_length(context, princ,value) (princ)->realm.length = (value) #define krb5_princ_set_realm_data(context, princ,value) (princ)->realm.data = (value) #define krb5_princ_size(context, princ) (princ)->length #define krb5_princ_type(context, princ) (princ)->type #define krb5_princ_name(context, princ) (princ)->data #define krb5_princ_component(context, princ,i) \ (((i) < krb5_princ_size(context, princ)) \ ? (princ)->data + (i) \ : NULL) /** Constant for realm referrals. */ #define KRB5_REFERRAL_REALM "" /* * Referral-specific functions. */ /** * Check for a match with KRB5_REFERRAL_REALM. * * @param [in] r Realm to check * * @return @c TRUE if @a r is zero-length, @c FALSE otherwise */ krb5_boolean KRB5_CALLCONV krb5_is_referral_realm(const krb5_data *r); /** * Return an anonymous realm data. * * This function returns constant storage that must not be freed. * * @sa #KRB5_ANONYMOUS_REALMSTR */ const krb5_data *KRB5_CALLCONV krb5_anonymous_realm(void); /** * Build an anonymous principal. * * This function returns constant storage that must not be freed. * * @sa #KRB5_ANONYMOUS_PRINCSTR */ krb5_const_principal KRB5_CALLCONV krb5_anonymous_principal(void); #define KRB5_ANONYMOUS_REALMSTR "WELLKNOWN:ANONYMOUS" /**< Anonymous realm */ #define KRB5_ANONYMOUS_PRINCSTR "ANONYMOUS" /**< Anonymous principal name */ /* * end "base-defs.h" */ /* * begin "hostaddr.h" */ /** Structure for address */ typedef struct _krb5_address { krb5_magic magic; krb5_addrtype addrtype; unsigned int length; krb5_octet *contents; } krb5_address; /* per Kerberos v5 protocol spec */ #define ADDRTYPE_INET 0x0002 #define ADDRTYPE_CHAOS 0x0005 #define ADDRTYPE_XNS 0x0006 #define ADDRTYPE_ISO 0x0007 #define ADDRTYPE_DDP 0x0010 #define ADDRTYPE_NETBIOS 0x0014 #define ADDRTYPE_INET6 0x0018 /* not yet in the spec... */ #define ADDRTYPE_ADDRPORT 0x0100 #define ADDRTYPE_IPPORT 0x0101 /* macros to determine if a type is a local type */ #define ADDRTYPE_IS_LOCAL(addrtype) (addrtype & 0x8000) /* * end "hostaddr.h" */ struct _krb5_context; typedef struct _krb5_context * krb5_context; struct _krb5_auth_context; typedef struct _krb5_auth_context * krb5_auth_context; struct _krb5_cryptosystem_entry; /* * begin "encryption.h" */ /** Exposed contents of a key. */ typedef struct _krb5_keyblock { krb5_magic magic; krb5_enctype enctype; unsigned int length; krb5_octet *contents; } krb5_keyblock; struct krb5_key_st; /** * Opaque identifier for a key. * * Use with the krb5_k APIs for better performance for repeated operations with * the same key and usage. Key identifiers must not be used simultaneously * within multiple threads, as they may contain mutable internal state and are * not mutex-protected. */ typedef struct krb5_key_st *krb5_key; #ifdef KRB5_OLD_CRYPTO typedef struct _krb5_encrypt_block { krb5_magic magic; krb5_enctype crypto_entry; /* to call krb5_encrypt_size, you need this. it was a pointer, but it doesn't have to be. gross. */ krb5_keyblock *key; } krb5_encrypt_block; #endif typedef struct _krb5_checksum { krb5_magic magic; krb5_cksumtype checksum_type; /* checksum type */ unsigned int length; krb5_octet *contents; } krb5_checksum; typedef struct _krb5_enc_data { krb5_magic magic; krb5_enctype enctype; krb5_kvno kvno; krb5_data ciphertext; } krb5_enc_data; /** * Structure to describe a region of text to be encrypted or decrypted. * * The @a flags member describes the type of the iov. * The @a data member points to the memory that will be manipulated. * All iov APIs take a pointer to the first element of an array of krb5_crypto_iov's * along with the size of that array. Buffer contents are manipulated in-place; * data is overwritten. Callers must allocate the right number of krb5_crypto_iov * structures before calling into an iov API. */ typedef struct _krb5_crypto_iov { krb5_cryptotype flags; /**< @ref KRB5_CRYPTO_TYPE type of the iov */ krb5_data data; } krb5_crypto_iov; /* per Kerberos v5 protocol spec */ #define ENCTYPE_NULL 0x0000 #define ENCTYPE_DES_CBC_CRC 0x0001 /**< @deprecated no longer supported */ #define ENCTYPE_DES_CBC_MD4 0x0002 /**< @deprecated no longer supported */ #define ENCTYPE_DES_CBC_MD5 0x0003 /**< @deprecated no longer supported */ #define ENCTYPE_DES_CBC_RAW 0x0004 /**< @deprecated no longer supported */ #define ENCTYPE_DES3_CBC_SHA 0x0005 /**< @deprecated no longer supported */ #define ENCTYPE_DES3_CBC_RAW 0x0006 /**< @deprecated no longer supported */ #define ENCTYPE_DES_HMAC_SHA1 0x0008 /**< @deprecated no longer supported */ /* PKINIT */ #define ENCTYPE_DSA_SHA1_CMS 0x0009 /**< DSA with SHA1, CMS signature */ #define ENCTYPE_MD5_RSA_CMS 0x000a /**< MD5 with RSA, CMS signature */ #define ENCTYPE_SHA1_RSA_CMS 0x000b /**< SHA1 with RSA, CMS signature */ #define ENCTYPE_RC2_CBC_ENV 0x000c /**< RC2 cbc mode, CMS enveloped data */ #define ENCTYPE_RSA_ENV 0x000d /**< RSA encryption, CMS enveloped data */ #define ENCTYPE_RSA_ES_OAEP_ENV 0x000e /**< RSA w/OEAP encryption, CMS enveloped data */ #define ENCTYPE_DES3_CBC_ENV 0x000f /**< @deprecated no longer supported */ #define ENCTYPE_DES3_CBC_SHA1 0x0010 /**< @deprecated removed */ #define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011 /**< RFC 3962 */ #define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012 /**< RFC 3962 */ #define ENCTYPE_AES128_CTS_HMAC_SHA256_128 0x0013 /**< RFC 8009 */ #define ENCTYPE_AES256_CTS_HMAC_SHA384_192 0x0014 /**< RFC 8009 */ #define ENCTYPE_ARCFOUR_HMAC 0x0017 /**< RFC 4757 */ #define ENCTYPE_ARCFOUR_HMAC_EXP 0x0018 /**< RFC 4757 */ #define ENCTYPE_CAMELLIA128_CTS_CMAC 0x0019 /**< RFC 6803 */ #define ENCTYPE_CAMELLIA256_CTS_CMAC 0x001a /**< RFC 6803 */ #define ENCTYPE_UNKNOWN 0x01ff /* * Historically we used the value 9 for unkeyed SHA-1. RFC 3961 assigns this * value to rsa-md5-des3, which fortunately is unused. For ABI compatibility * we allow either 9 or 14 for SHA-1. */ #define CKSUMTYPE_CRC32 0x0001 #define CKSUMTYPE_RSA_MD4 0x0002 #define CKSUMTYPE_RSA_MD4_DES 0x0003 #define CKSUMTYPE_DESCBC 0x0004 /* des-mac-k */ /* rsa-md4-des-k */ #define CKSUMTYPE_RSA_MD5 0x0007 #define CKSUMTYPE_RSA_MD5_DES 0x0008 #define CKSUMTYPE_NIST_SHA 0x0009 #define CKSUMTYPE_HMAC_SHA1_DES3 0x000c /* @deprecated removed */ #define CKSUMTYPE_SHA1 0x000d /**< RFC 3962 */ #define CKSUMTYPE_HMAC_SHA1_96_AES128 0x000f /**< RFC 3962. Used with ENCTYPE_AES128_CTS_HMAC_SHA1_96 */ #define CKSUMTYPE_HMAC_SHA1_96_AES256 0x0010 /**< RFC 3962. Used with ENCTYPE_AES256_CTS_HMAC_SHA1_96 */ #define CKSUMTYPE_HMAC_SHA256_128_AES128 0x0013 /**< RFC 8009 */ #define CKSUMTYPE_HMAC_SHA384_192_AES256 0x0014 /**< RFC 8009 */ #define CKSUMTYPE_CMAC_CAMELLIA128 0x0011 /**< RFC 6803 */ #define CKSUMTYPE_CMAC_CAMELLIA256 0x0012 /**< RFC 6803 */ #define CKSUMTYPE_MD5_HMAC_ARCFOUR -137 /* Microsoft netlogon */ #define CKSUMTYPE_HMAC_MD5_ARCFOUR -138 /**< RFC 4757 */ /* * The following are entropy source designations. Whenever * krb5_C_random_add_entropy is called, one of these source ids is passed in. * This allows the library to better estimate bits of entropy in the sample and * to keep track of what sources of entropy have contributed enough entropy. * Sources marked internal MUST NOT be used by applications outside the * Kerberos library */ enum { KRB5_C_RANDSOURCE_OLDAPI = 0, /*calls to krb5_C_RANDOM_SEED (INTERNAL)*/ KRB5_C_RANDSOURCE_OSRAND = 1, /* /dev/random or equivalent (internal)*/ KRB5_C_RANDSOURCE_TRUSTEDPARTY = 2, /* From KDC or other trusted party*/ /* * This source should be used carefully; data in this category * should be from a third party trusted to give random bits * For example keys issued by the KDC in the application server. */ KRB5_C_RANDSOURCE_TIMING = 3, /* Timing of operations*/ KRB5_C_RANDSOURCE_EXTERNAL_PROTOCOL = 4, /*Protocol data possibly from attacker*/ KRB5_C_RANDSOURCE_MAX = 5 /*Do not use; maximum source ID*/ }; #ifndef krb5_roundup /* round x up to nearest multiple of y */ #define krb5_roundup(x, y) ((((x) + (y) - 1)/(y))*(y)) #endif /* roundup */ /* macro function definitions to help clean up code */ #if 1 #define krb5_x(ptr,args) ((ptr)?((*(ptr)) args):(abort(),1)) #define krb5_xc(ptr,args) ((ptr)?((*(ptr)) args):(abort(),(char*)0)) #else #define krb5_x(ptr,args) ((*(ptr)) args) #define krb5_xc(ptr,args) ((*(ptr)) args) #endif /** * Encrypt data using a key (operates on keyblock). * * @param [in] context Library context * @param [in] key Encryption key * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in,out] cipher_state Cipher state; specify NULL if not needed * @param [in] input Data to be encrypted * @param [out] output Encrypted data * * This function encrypts the data block @a input and stores the output into @a * output. The actual encryption key will be derived from @a key and @a usage * if key derivation is specified for the encryption type. If non-null, @a * cipher_state specifies the beginning state for the encryption operation, and * is updated with the state to be passed as input to the next operation. * * @note The caller must initialize @a output and allocate at least enough * space for the result (using krb5_c_encrypt_length() to determine the amount * of space needed). @a output->length will be set to the actual length of the * ciphertext. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_encrypt(krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_data *input, krb5_enc_data *output); /** * Decrypt data using a key (operates on keyblock). * * @param [in] context Library context * @param [in] key Encryption key * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in,out] cipher_state Cipher state; specify NULL if not needed * @param [in] input Encrypted data * @param [out] output Decrypted data * * This function decrypts the data block @a input and stores the output into @a * output. The actual decryption key will be derived from @a key and @a usage * if key derivation is specified for the encryption type. If non-null, @a * cipher_state specifies the beginning state for the decryption operation, and * is updated with the state to be passed as input to the next operation. * * @note The caller must initialize @a output and allocate at least enough * space for the result. The usual practice is to allocate an output buffer as * long as the ciphertext, and let krb5_c_decrypt() trim @a output->length. * For some enctypes, the resulting @a output->length may include padding * bytes. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_decrypt(krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_enc_data *input, krb5_data *output); /** * Compute encrypted data length. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [in] inputlen Length of the data to be encrypted * @param [out] length Length of the encrypted data * * This function computes the length of the ciphertext produced by encrypting * @a inputlen bytes including padding, confounder, and checksum. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_encrypt_length(krb5_context context, krb5_enctype enctype, size_t inputlen, size_t *length); /** * Return cipher block size. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [out] blocksize Block size for @a enctype * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_block_size(krb5_context context, krb5_enctype enctype, size_t *blocksize); /** * Return length of the specified key in bytes. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [out] keybytes Number of bytes required to make a key * @param [out] keylength Length of final key * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_keylengths(krb5_context context, krb5_enctype enctype, size_t *keybytes, size_t *keylength); /** * Initialize a new cipher state. * * @param [in] context Library context * @param [in] key Key * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [out] new_state New cipher state * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_init_state(krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, krb5_data *new_state); /** * Free a cipher state previously allocated by krb5_c_init_state(). * * @param [in] context Library context * @param [in] key Key * @param [in] state Cipher state to be freed * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_free_state(krb5_context context, const krb5_keyblock *key, krb5_data *state); /** * Generate enctype-specific pseudo-random bytes. * * @param [in] context Library context * @param [in] keyblock Key * @param [in] input Input data * @param [out] output Output data * * This function selects a pseudo-random function based on @a keyblock and * computes its value over @a input, placing the result into @a output. * The caller must preinitialize @a output and allocate space for the * result, using krb5_c_prf_length() to determine the required length. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_prf(krb5_context context, const krb5_keyblock *keyblock, krb5_data *input, krb5_data *output); /** * Get the output length of pseudo-random functions for an encryption type. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [out] len Length of PRF output * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_prf_length(krb5_context context, krb5_enctype enctype, size_t *len); /** * Generate pseudo-random bytes using RFC 6113 PRF+. * * @param [in] context Library context * @param [in] k KDC contribution key * @param [in] input Input data * @param [out] output Pseudo-random output buffer * * This function fills @a output with PRF+(k, input) as defined in RFC 6113 * section 5.1. The caller must preinitialize @a output and allocate the * desired amount of space. The length of the pseudo-random output will match * the length of @a output. * * @note RFC 4402 defines a different PRF+ operation. This function does not * implement that operation. * * @return 0 on success, @c E2BIG if output->length is too large for PRF+ to * generate, @c ENOMEM on allocation failure, or an error code from * krb5_c_prf() */ krb5_error_code KRB5_CALLCONV krb5_c_prfplus(krb5_context context, const krb5_keyblock *k, const krb5_data *input, krb5_data *output); /** * Derive a key using some input data (via RFC 6113 PRF+). * * @param [in] context Library context * @param [in] k KDC contribution key * @param [in] input Input string * @param [in] enctype Output key enctype (or @c ENCTYPE_NULL) * @param [out] out Derived keyblock * * This function uses PRF+ as defined in RFC 6113 to derive a key from another * key and an input string. If @a enctype is @c ENCTYPE_NULL, the output key * will have the same enctype as the input key. */ krb5_error_code KRB5_CALLCONV krb5_c_derive_prfplus(krb5_context context, const krb5_keyblock *k, const krb5_data *input, krb5_enctype enctype, krb5_keyblock **out); /** * Compute the KRB-FX-CF2 combination of two keys and pepper strings. * * @param [in] context Library context * @param [in] k1 KDC contribution key * @param [in] pepper1 String "PKINIT" * @param [in] k2 Reply key * @param [in] pepper2 String "KeyExchange" * @param [out] out Output key * * This function computes the KRB-FX-CF2 function over its inputs and places * the results in a newly allocated keyblock. This function is simple in that * it assumes that @a pepper1 and @a pepper2 are C strings with no internal * nulls and that the enctype of the result will be the same as that of @a k1. * @a k1 and @a k2 may be of different enctypes. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_fx_cf2_simple(krb5_context context, const krb5_keyblock *k1, const char *pepper1, const krb5_keyblock *k2, const char *pepper2, krb5_keyblock **out); /** * Generate an enctype-specific random encryption key. * * @param [in] context Library context * @param [in] enctype Encryption type of the generated key * @param [out] k5_random_key An allocated and initialized keyblock * * Use krb5_free_keyblock_contents() to free @a k5_random_key when * no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_make_random_key(krb5_context context, krb5_enctype enctype, krb5_keyblock *k5_random_key); /** * Generate an enctype-specific key from random data. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [in] random_data Random input data * @param [out] k5_random_key Resulting key * * This function takes random input data @a random_data and produces a valid * key @a k5_random_key for a given @a enctype. * * @note It is assumed that @a k5_random_key has already been initialized and * @a k5_random_key->contents has been allocated with the correct length. * * @sa krb5_c_keylengths() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_random_to_key(krb5_context context, krb5_enctype enctype, krb5_data *random_data, krb5_keyblock *k5_random_key); /** * Add entropy to the pseudo-random number generator. * * @param [in] context Library context * @param [in] randsource Entropy source (see KRB5_RANDSOURCE types) * @param [in] data Data * * Contribute entropy to the PRNG used by krb5 crypto operations. This may or * may not affect the output of the next crypto operation requiring random * data. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_random_add_entropy(krb5_context context, unsigned int randsource, const krb5_data *data); /** * Generate pseudo-random bytes. * * @param [in] context Library context * @param [out] data Random data * * Fills in @a data with bytes from the PRNG used by krb5 crypto operations. * The caller must preinitialize @a data and allocate the desired amount of * space. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_random_make_octets(krb5_context context, krb5_data *data); /** * Collect entropy from the OS if possible. * * @param [in] context Library context * @param [in] strong Strongest available source of entropy * @param [out] success 1 if OS provides entropy, 0 otherwise * * If @a strong is non-zero, this function attempts to use the strongest * available source of entropy. Setting this flag may cause the function to * block on some operating systems. Good uses include seeding the PRNG for * kadmind and realm setup. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_random_os_entropy(krb5_context context, int strong, int *success); /** @deprecated Replaced by krb5_c_* API family. */ krb5_error_code KRB5_CALLCONV krb5_c_random_seed(krb5_context context, krb5_data *data); /** * Convert a string (such a password) to a key. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [in] string String to be converted * @param [in] salt Salt value * @param [out] key Generated key * * This function converts @a string to a @a key of encryption type @a enctype, * using the specified @a salt. The newly created @a key must be released by * calling krb5_free_keyblock_contents() when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_string_to_key(krb5_context context, krb5_enctype enctype, const krb5_data *string, const krb5_data *salt, krb5_keyblock *key); /** * Convert a string (such as a password) to a key with additional parameters. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [in] string String to be converted * @param [in] salt Salt value * @param [in] params Parameters * @param [out] key Generated key * * This function is similar to krb5_c_string_to_key(), but also takes * parameters which may affect the algorithm in an enctype-dependent way. The * newly created @a key must be released by calling * krb5_free_keyblock_contents() when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_string_to_key_with_params(krb5_context context, krb5_enctype enctype, const krb5_data *string, const krb5_data *salt, const krb5_data *params, krb5_keyblock *key); /** * Compare two encryption types. * * @param [in] context Library context * @param [in] e1 First encryption type * @param [in] e2 Second encryption type * @param [out] similar @c TRUE if types are similar, @c FALSE if not * * This function determines whether two encryption types use the same kind of * keys. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_enctype_compare(krb5_context context, krb5_enctype e1, krb5_enctype e2, krb5_boolean *similar); /** * Compute a checksum (operates on keyblock). * * @param [in] context Library context * @param [in] cksumtype Checksum type (0 for mandatory type) * @param [in] key Encryption key for a keyed checksum * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in] input Input data * @param [out] cksum Generated checksum * * This function computes a checksum of type @a cksumtype over @a input, using * @a key if the checksum type is a keyed checksum. If @a cksumtype is 0 and * @a key is non-null, the checksum type will be the mandatory-to-implement * checksum type for the key's encryption type. The actual checksum key will * be derived from @a key and @a usage if key derivation is specified for the * checksum type. The newly created @a cksum must be released by calling * krb5_free_checksum_contents() when it is no longer needed. * * @note This function is similar to krb5_k_make_checksum(), but operates * on keyblock @a key. * * @sa krb5_c_verify_checksum() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_make_checksum(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *input, krb5_checksum *cksum); /** * Verify a checksum (operates on keyblock). * * @param [in] context Library context * @param [in] key Encryption key for a keyed checksum * @param [in] usage @a key usage * @param [in] data Data to be used to compute a new checksum * using @a key to compare @a cksum against * @param [in] cksum Checksum to be verified * @param [out] valid Non-zero for success, zero for failure * * This function verifies that @a cksum is a valid checksum for @a data. If * the checksum type of @a cksum is a keyed checksum, @a key is used to verify * the checksum. If the checksum type in @a cksum is 0 and @a key is not NULL, * the mandatory checksum type for @a key will be used. The actual checksum * key will be derived from @a key and @a usage if key derivation is specified * for the checksum type. * * @note This function is similar to krb5_k_verify_checksum(), but operates * on keyblock @a key. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_verify_checksum(krb5_context context, const krb5_keyblock *key, krb5_keyusage usage, const krb5_data *data, const krb5_checksum *cksum, krb5_boolean *valid); /** * Return the length of checksums for a checksum type. * * @param [in] context Library context * @param [in] cksumtype Checksum type * @param [out] length Checksum length * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_checksum_length(krb5_context context, krb5_cksumtype cksumtype, size_t *length); /** * Return a list of keyed checksum types usable with an encryption type. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [out] count Count of allowable checksum types * @param [out] cksumtypes Array of allowable checksum types * * Use krb5_free_cksumtypes() to free @a cksumtypes when it is no longer * needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_keyed_checksum_types(krb5_context context, krb5_enctype enctype, unsigned int *count, krb5_cksumtype **cksumtypes); /** @defgroup KRB5_KEYUSAGE KRB5_KEYUSAGE * @{ */ #define KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS 1 #define KRB5_KEYUSAGE_KDC_REP_TICKET 2 #define KRB5_KEYUSAGE_AS_REP_ENCPART 3 #define KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY 4 #define KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY 5 #define KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM 6 #define KRB5_KEYUSAGE_TGS_REQ_AUTH 7 #define KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY 8 #define KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY 9 #define KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM 10 #define KRB5_KEYUSAGE_AP_REQ_AUTH 11 #define KRB5_KEYUSAGE_AP_REP_ENCPART 12 #define KRB5_KEYUSAGE_KRB_PRIV_ENCPART 13 #define KRB5_KEYUSAGE_KRB_CRED_ENCPART 14 #define KRB5_KEYUSAGE_KRB_SAFE_CKSUM 15 #define KRB5_KEYUSAGE_APP_DATA_ENCRYPT 16 #define KRB5_KEYUSAGE_APP_DATA_CKSUM 17 #define KRB5_KEYUSAGE_KRB_ERROR_CKSUM 18 #define KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM 19 #define KRB5_KEYUSAGE_AD_MTE 20 #define KRB5_KEYUSAGE_AD_ITE 21 /* XXX need to register these */ #define KRB5_KEYUSAGE_GSS_TOK_MIC 22 #define KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG 23 #define KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV 24 /* Defined in Integrating SAM Mechanisms with Kerberos draft */ #define KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM 25 /** Note conflict with @ref KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST */ #define KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID 26 /** Note conflict with @ref KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY */ #define KRB5_KEYUSAGE_PA_SAM_RESPONSE 27 /* Defined in [MS-SFU] */ /** Note conflict with @ref KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID */ #define KRB5_KEYUSAGE_PA_S4U_X509_USER_REQUEST 26 /** Note conflict with @ref KRB5_KEYUSAGE_PA_SAM_RESPONSE */ #define KRB5_KEYUSAGE_PA_S4U_X509_USER_REPLY 27 /* unused */ #define KRB5_KEYUSAGE_PA_REFERRAL 26 #define KRB5_KEYUSAGE_AD_SIGNEDPATH -21 #define KRB5_KEYUSAGE_IAKERB_FINISHED 42 #define KRB5_KEYUSAGE_PA_PKINIT_KX 44 #define KRB5_KEYUSAGE_PA_OTP_REQUEST 45 /**< See RFC 6560 section 4.2 */ /* define in draft-ietf-krb-wg-preauth-framework*/ #define KRB5_KEYUSAGE_FAST_REQ_CHKSUM 50 #define KRB5_KEYUSAGE_FAST_ENC 51 #define KRB5_KEYUSAGE_FAST_REP 52 #define KRB5_KEYUSAGE_FAST_FINISHED 53 #define KRB5_KEYUSAGE_ENC_CHALLENGE_CLIENT 54 #define KRB5_KEYUSAGE_ENC_CHALLENGE_KDC 55 #define KRB5_KEYUSAGE_AS_REQ 56 #define KRB5_KEYUSAGE_CAMMAC 64 #define KRB5_KEYUSAGE_SPAKE 65 /* Key usage values 512-1023 are reserved for uses internal to a Kerberos * implementation. */ #define KRB5_KEYUSAGE_PA_FX_COOKIE 513 /**< Used for encrypted FAST cookies */ #define KRB5_KEYUSAGE_PA_AS_FRESHNESS 514 /**< Used for freshness tokens */ /** @} */ /* end of KRB5_KEYUSAGE group */ /** * Verify that a specified encryption type is a valid Kerberos encryption type. * * @param [in] ktype Encryption type * * @return @c TRUE if @a ktype is valid, @c FALSE if not */ krb5_boolean KRB5_CALLCONV krb5_c_valid_enctype(krb5_enctype ktype); /** * Verify that specified checksum type is a valid Kerberos checksum type. * * @param [in] ctype Checksum type * * @return @c TRUE if @a ctype is valid, @c FALSE if not */ krb5_boolean KRB5_CALLCONV krb5_c_valid_cksumtype(krb5_cksumtype ctype); /** * Test whether a checksum type is collision-proof. * * @param [in] ctype Checksum type * * @return @c TRUE if @a ctype is collision-proof, @c FALSE if it is not * collision-proof or not a valid checksum type. */ krb5_boolean KRB5_CALLCONV krb5_c_is_coll_proof_cksum(krb5_cksumtype ctype); /** * Test whether a checksum type is keyed. * * @param [in] ctype Checksum type * * @return @c TRUE if @a ctype is a keyed checksum type, @c FALSE otherwise. */ krb5_boolean KRB5_CALLCONV krb5_c_is_keyed_cksum(krb5_cksumtype ctype); /* AEAD APIs */ /** @defgroup KRB5_CRYPTO_TYPE KRB5_CRYPTO_TYPE * @{ */ #define KRB5_CRYPTO_TYPE_EMPTY 0 /**< [in] ignored */ #define KRB5_CRYPTO_TYPE_HEADER 1 /**< [out] header */ #define KRB5_CRYPTO_TYPE_DATA 2 /**< [in, out] plaintext */ #define KRB5_CRYPTO_TYPE_SIGN_ONLY 3 /**< [in] associated data */ #define KRB5_CRYPTO_TYPE_PADDING 4 /**< [out] padding */ #define KRB5_CRYPTO_TYPE_TRAILER 5 /**< [out] checksum for encrypt */ #define KRB5_CRYPTO_TYPE_CHECKSUM 6 /**< [out] checksum for MIC */ #define KRB5_CRYPTO_TYPE_STREAM 7 /**< [in] entire message without decomposing the structure into header, data and trailer buffers */ /** @} */ /* end of KRB5_CRYPTO_TYPE group */ /** * Fill in a checksum element in IOV array (operates on keyblock) * * @param [in] context Library context * @param [in] cksumtype Checksum type (0 for mandatory type) * @param [in] key Encryption key for a keyed checksum * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in,out] data IOV array * @param [in] num_data Size of @a data * * Create a checksum in the #KRB5_CRYPTO_TYPE_CHECKSUM element over * #KRB5_CRYPTO_TYPE_DATA and #KRB5_CRYPTO_TYPE_SIGN_ONLY chunks in @a data. * Only the #KRB5_CRYPTO_TYPE_CHECKSUM region is modified. * * @note This function is similar to krb5_k_make_checksum_iov(), but operates * on keyblock @a key. * * @sa krb5_c_verify_checksum_iov() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock *key, krb5_keyusage usage, krb5_crypto_iov *data, size_t num_data); /** * Validate a checksum element in IOV array (operates on keyblock). * * @param [in] context Library context * @param [in] cksumtype Checksum type (0 for mandatory type) * @param [in] key Encryption key for a keyed checksum * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in] data IOV array * @param [in] num_data Size of @a data * @param [out] valid Non-zero for success, zero for failure * * Confirm that the checksum in the #KRB5_CRYPTO_TYPE_CHECKSUM element is a * valid checksum of the #KRB5_CRYPTO_TYPE_DATA and #KRB5_CRYPTO_TYPE_SIGN_ONLY * regions in the iov. * * @note This function is similar to krb5_k_verify_checksum_iov(), but operates * on keyblock @a key. * * @sa krb5_c_make_checksum_iov() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_verify_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, const krb5_keyblock *key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_boolean *valid); /** * Encrypt data in place supporting AEAD (operates on keyblock). * * @param [in] context Library context * @param [in] keyblock Encryption key * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in] cipher_state Cipher state; specify NULL if not needed * @param [in,out] data IOV array. Modified in-place. * @param [in] num_data Size of @a data * * This function encrypts the data block @a data and stores the output in-place. * The actual encryption key will be derived from @a keyblock and @a usage * if key derivation is specified for the encryption type. If non-null, @a * cipher_state specifies the beginning state for the encryption operation, and * is updated with the state to be passed as input to the next operation. * The caller must allocate the right number of krb5_crypto_iov * structures before calling into this API. * * @note On return from a krb5_c_encrypt_iov() call, the @a data->length in the * iov structure are adjusted to reflect actual lengths of the ciphertext used. * For example, if the padding length is too large, the length will be reduced. * Lengths are never increased. * * @note This function is similar to krb5_k_encrypt_iov(), but operates * on keyblock @a keyblock. * * @sa krb5_c_decrypt_iov() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_encrypt_iov(krb5_context context, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data); /** * Decrypt data in place supporting AEAD (operates on keyblock). * * @param [in] context Library context * @param [in] keyblock Encryption key * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in] cipher_state Cipher state; specify NULL if not needed * @param [in,out] data IOV array. Modified in-place. * @param [in] num_data Size of @a data * * This function decrypts the data block @a data and stores the output in-place. * The actual decryption key will be derived from @a keyblock and @a usage * if key derivation is specified for the encryption type. If non-null, @a * cipher_state specifies the beginning state for the decryption operation, and * is updated with the state to be passed as input to the next operation. * The caller must allocate the right number of krb5_crypto_iov * structures before calling into this API. * * @note On return from a krb5_c_decrypt_iov() call, the @a data->length in the * iov structure are adjusted to reflect actual lengths of the ciphertext used. * For example, if the padding length is too large, the length will be reduced. * Lengths are never increased. * * @note This function is similar to krb5_k_decrypt_iov(), but operates * on keyblock @a keyblock. * * @sa krb5_c_decrypt_iov() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_decrypt_iov(krb5_context context, const krb5_keyblock *keyblock, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data); /** * Return a length of a message field specific to the encryption type. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [in] type Type field (See @ref KRB5_CRYPTO_TYPE types) * @param [out] size Length of the @a type specific to @a enctype * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_crypto_length(krb5_context context, krb5_enctype enctype, krb5_cryptotype type, unsigned int *size); /** * Fill in lengths for header, trailer and padding in a IOV array. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [in,out] data IOV array * @param [in] num_data Size of @a data * * Padding is set to the actual padding required based on the provided * @a data buffers. Typically this API is used after setting up the data * buffers and #KRB5_CRYPTO_TYPE_SIGN_ONLY buffers, but before actually * allocating header, trailer and padding. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_c_crypto_length_iov(krb5_context context, krb5_enctype enctype, krb5_crypto_iov *data, size_t num_data); /** * Return a number of padding octets. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [in] data_length Length of the plaintext to pad * @param [out] size Number of padding octets * * This function returns the number of the padding octets required to pad * @a data_length octets of plaintext. * * @retval 0 Success; otherwise - KRB5_BAD_ENCTYPE */ krb5_error_code KRB5_CALLCONV krb5_c_padding_length(krb5_context context, krb5_enctype enctype, size_t data_length, unsigned int *size); /** * Create a krb5_key from the enctype and key data in a keyblock. * * @param [in] context Library context * @param [in] key_data Keyblock * @param [out] out Opaque key * * The reference count on a key @a out is set to 1. * Use krb5_k_free_key() to free @a out when it is no longer needed. * * @retval 0 Success; otherwise - KRB5_BAD_ENCTYPE */ krb5_error_code KRB5_CALLCONV krb5_k_create_key(krb5_context context, const krb5_keyblock *key_data, krb5_key *out); /** Increment the reference count on a key. */ void KRB5_CALLCONV krb5_k_reference_key(krb5_context context, krb5_key key); /** Decrement the reference count on a key and free it if it hits zero. */ void KRB5_CALLCONV krb5_k_free_key(krb5_context context, krb5_key key); /** Retrieve a copy of the keyblock from a krb5_key structure. */ krb5_error_code KRB5_CALLCONV krb5_k_key_keyblock(krb5_context context, krb5_key key, krb5_keyblock **key_data); /** Retrieve the enctype of a krb5_key structure. */ krb5_enctype KRB5_CALLCONV krb5_k_key_enctype(krb5_context context, krb5_key key); /** * Encrypt data using a key (operates on opaque key). * * @param [in] context Library context * @param [in] key Encryption key * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in,out] cipher_state Cipher state; specify NULL if not needed * @param [in] input Data to be encrypted * @param [out] output Encrypted data * * This function encrypts the data block @a input and stores the output into @a * output. The actual encryption key will be derived from @a key and @a usage * if key derivation is specified for the encryption type. If non-null, @a * cipher_state specifies the beginning state for the encryption operation, and * is updated with the state to be passed as input to the next operation. * * @note The caller must initialize @a output and allocate at least enough * space for the result (using krb5_c_encrypt_length() to determine the amount * of space needed). @a output->length will be set to the actual length of the * ciphertext. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_k_encrypt(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_data *input, krb5_enc_data *output); /** * Encrypt data in place supporting AEAD (operates on opaque key). * * @param [in] context Library context * @param [in] key Encryption key * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in] cipher_state Cipher state; specify NULL if not needed * @param [in,out] data IOV array. Modified in-place. * @param [in] num_data Size of @a data * * This function encrypts the data block @a data and stores the output in-place. * The actual encryption key will be derived from @a key and @a usage * if key derivation is specified for the encryption type. If non-null, @a * cipher_state specifies the beginning state for the encryption operation, and * is updated with the state to be passed as input to the next operation. * The caller must allocate the right number of krb5_crypto_iov * structures before calling into this API. * * @note On return from a krb5_c_encrypt_iov() call, the @a data->length in the * iov structure are adjusted to reflect actual lengths of the ciphertext used. * For example, if the padding length is too large, the length will be reduced. * Lengths are never increased. * * @note This function is similar to krb5_c_encrypt_iov(), but operates * on opaque key @a key. * * @sa krb5_k_decrypt_iov() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_k_encrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data); /** * Decrypt data using a key (operates on opaque key). * * @param [in] context Library context * @param [in] key Encryption key * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in,out] cipher_state Cipher state; specify NULL if not needed * @param [in] input Encrypted data * @param [out] output Decrypted data * * This function decrypts the data block @a input and stores the output into @a * output. The actual decryption key will be derived from @a key and @a usage * if key derivation is specified for the encryption type. If non-null, @a * cipher_state specifies the beginning state for the decryption operation, and * is updated with the state to be passed as input to the next operation. * * @note The caller must initialize @a output and allocate at least enough * space for the result. The usual practice is to allocate an output buffer as * long as the ciphertext, and let krb5_c_decrypt() trim @a output->length. * For some enctypes, the resulting @a output->length may include padding * bytes. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_k_decrypt(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, const krb5_enc_data *input, krb5_data *output); /** * Decrypt data in place supporting AEAD (operates on opaque key). * * @param [in] context Library context * @param [in] key Encryption key * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in] cipher_state Cipher state; specify NULL if not needed * @param [in,out] data IOV array. Modified in-place. * @param [in] num_data Size of @a data * * This function decrypts the data block @a data and stores the output in-place. * The actual decryption key will be derived from @a key and @a usage * if key derivation is specified for the encryption type. If non-null, @a * cipher_state specifies the beginning state for the decryption operation, and * is updated with the state to be passed as input to the next operation. * The caller must allocate the right number of krb5_crypto_iov * structures before calling into this API. * * @note On return from a krb5_c_decrypt_iov() call, the @a data->length in the * iov structure are adjusted to reflect actual lengths of the ciphertext used. * For example, if the padding length is too large, the length will be reduced. * Lengths are never increased. * * @note This function is similar to krb5_c_decrypt_iov(), but operates * on opaque key @a key. * * @sa krb5_k_encrypt_iov() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_k_decrypt_iov(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *cipher_state, krb5_crypto_iov *data, size_t num_data); /** * Compute a checksum (operates on opaque key). * * @param [in] context Library context * @param [in] cksumtype Checksum type (0 for mandatory type) * @param [in] key Encryption key for a keyed checksum * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in] input Input data * @param [out] cksum Generated checksum * * This function computes a checksum of type @a cksumtype over @a input, using * @a key if the checksum type is a keyed checksum. If @a cksumtype is 0 and * @a key is non-null, the checksum type will be the mandatory-to-implement * checksum type for the key's encryption type. The actual checksum key will * be derived from @a key and @a usage if key derivation is specified for the * checksum type. The newly created @a cksum must be released by calling * krb5_free_checksum_contents() when it is no longer needed. * * @note This function is similar to krb5_c_make_checksum(), but operates * on opaque @a key. * * @sa krb5_c_verify_checksum() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_k_make_checksum(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, const krb5_data *input, krb5_checksum *cksum); /** * Fill in a checksum element in IOV array (operates on opaque key) * * @param [in] context Library context * @param [in] cksumtype Checksum type (0 for mandatory type) * @param [in] key Encryption key for a keyed checksum * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in,out] data IOV array * @param [in] num_data Size of @a data * * Create a checksum in the #KRB5_CRYPTO_TYPE_CHECKSUM element over * #KRB5_CRYPTO_TYPE_DATA and #KRB5_CRYPTO_TYPE_SIGN_ONLY chunks in @a data. * Only the #KRB5_CRYPTO_TYPE_CHECKSUM region is modified. * * @note This function is similar to krb5_c_make_checksum_iov(), but operates * on opaque @a key. * * @sa krb5_k_verify_checksum_iov() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_k_make_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, krb5_crypto_iov *data, size_t num_data); /** * Verify a checksum (operates on opaque key). * * @param [in] context Library context * @param [in] key Encryption key for a keyed checksum * @param [in] usage @a key usage * @param [in] data Data to be used to compute a new checksum * using @a key to compare @a cksum against * @param [in] cksum Checksum to be verified * @param [out] valid Non-zero for success, zero for failure * * This function verifies that @a cksum is a valid checksum for @a data. If * the checksum type of @a cksum is a keyed checksum, @a key is used to verify * the checksum. If the checksum type in @a cksum is 0 and @a key is not NULL, * the mandatory checksum type for @a key will be used. The actual checksum * key will be derived from @a key and @a usage if key derivation is specified * for the checksum type. * * @note This function is similar to krb5_c_verify_checksum(), but operates * on opaque @a key. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_k_verify_checksum(krb5_context context, krb5_key key, krb5_keyusage usage, const krb5_data *data, const krb5_checksum *cksum, krb5_boolean *valid); /** * Validate a checksum element in IOV array (operates on opaque key). * * @param [in] context Library context * @param [in] cksumtype Checksum type (0 for mandatory type) * @param [in] key Encryption key for a keyed checksum * @param [in] usage Key usage (see @ref KRB5_KEYUSAGE types) * @param [in] data IOV array * @param [in] num_data Size of @a data * @param [out] valid Non-zero for success, zero for failure * * Confirm that the checksum in the #KRB5_CRYPTO_TYPE_CHECKSUM element is a * valid checksum of the #KRB5_CRYPTO_TYPE_DATA and #KRB5_CRYPTO_TYPE_SIGN_ONLY * regions in the iov. * * @note This function is similar to krb5_c_verify_checksum_iov(), but operates * on opaque @a key. * * @sa krb5_k_make_checksum_iov() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_k_verify_checksum_iov(krb5_context context, krb5_cksumtype cksumtype, krb5_key key, krb5_keyusage usage, const krb5_crypto_iov *data, size_t num_data, krb5_boolean *valid); /** * Generate enctype-specific pseudo-random bytes (operates on opaque key). * * @param [in] context Library context * @param [in] key Key * @param [in] input Input data * @param [out] output Output data * * This function selects a pseudo-random function based on @a key and * computes its value over @a input, placing the result into @a output. * The caller must preinitialize @a output and allocate space for the * result. * * @note This function is similar to krb5_c_prf(), but operates * on opaque @a key. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_k_prf(krb5_context context, krb5_key key, krb5_data *input, krb5_data *output); #ifdef KRB5_OLD_CRYPTO /* * old cryptosystem routine prototypes. These are now layered * on top of the functions above. */ /** @deprecated Replaced by krb5_c_* API family.*/ krb5_error_code KRB5_CALLCONV krb5_encrypt(krb5_context context, krb5_const_pointer inptr, krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock, krb5_pointer ivec); /** @deprecated Replaced by krb5_c_* API family. */ krb5_error_code KRB5_CALLCONV krb5_decrypt(krb5_context context, krb5_const_pointer inptr, krb5_pointer outptr, size_t size, krb5_encrypt_block *eblock, krb5_pointer ivec); /** @deprecated Replaced by krb5_c_* API family. */ krb5_error_code KRB5_CALLCONV krb5_process_key(krb5_context context, krb5_encrypt_block *eblock, const krb5_keyblock * key); /** @deprecated Replaced by krb5_c_* API family. */ krb5_error_code KRB5_CALLCONV krb5_finish_key(krb5_context context, krb5_encrypt_block * eblock); /** @deprecated See krb5_c_string_to_key() */ krb5_error_code KRB5_CALLCONV krb5_string_to_key(krb5_context context, const krb5_encrypt_block *eblock, krb5_keyblock * keyblock, const krb5_data *data, const krb5_data *salt); /** @deprecated Replaced by krb5_c_* API family. */ krb5_error_code KRB5_CALLCONV krb5_init_random_key(krb5_context context, const krb5_encrypt_block *eblock, const krb5_keyblock *keyblock, krb5_pointer *ptr); /** @deprecated Replaced by krb5_c_* API family. */ krb5_error_code KRB5_CALLCONV krb5_finish_random_key(krb5_context context, const krb5_encrypt_block *eblock, krb5_pointer *ptr); /** @deprecated Replaced by krb5_c_* API family. */ krb5_error_code KRB5_CALLCONV krb5_random_key(krb5_context context, const krb5_encrypt_block *eblock, krb5_pointer ptr, krb5_keyblock **keyblock); /** @deprecated Replaced by krb5_c_* API family. */ krb5_enctype KRB5_CALLCONV krb5_eblock_enctype(krb5_context context, const krb5_encrypt_block *eblock); /** @deprecated Replaced by krb5_c_* API family. */ krb5_error_code KRB5_CALLCONV krb5_use_enctype(krb5_context context, krb5_encrypt_block *eblock, krb5_enctype enctype); /** @deprecated Replaced by krb5_c_* API family. */ size_t KRB5_CALLCONV krb5_encrypt_size(size_t length, krb5_enctype crypto); /** @deprecated See krb5_c_checksum_length() */ size_t KRB5_CALLCONV krb5_checksum_size(krb5_context context, krb5_cksumtype ctype); /** @deprecated See krb5_c_make_checksum() */ krb5_error_code KRB5_CALLCONV krb5_calculate_checksum(krb5_context context, krb5_cksumtype ctype, krb5_const_pointer in, size_t in_length, krb5_const_pointer seed, size_t seed_length, krb5_checksum * outcksum); /** @deprecated See krb5_c_verify_checksum() */ krb5_error_code KRB5_CALLCONV krb5_verify_checksum(krb5_context context, krb5_cksumtype ctype, const krb5_checksum * cksum, krb5_const_pointer in, size_t in_length, krb5_const_pointer seed, size_t seed_length); #endif /* KRB5_OLD_CRYPTO */ /* * end "encryption.h" */ /* * begin "fieldbits.h" */ /* kdc_options for kdc_request */ /* options is 32 bits; each host is responsible to put the 4 bytes representing these bits into net order before transmission */ /* #define KDC_OPT_RESERVED 0x80000000 */ #define KDC_OPT_FORWARDABLE 0x40000000 #define KDC_OPT_FORWARDED 0x20000000 #define KDC_OPT_PROXIABLE 0x10000000 #define KDC_OPT_PROXY 0x08000000 #define KDC_OPT_ALLOW_POSTDATE 0x04000000 #define KDC_OPT_POSTDATED 0x02000000 /* #define KDC_OPT_UNUSED 0x01000000 */ #define KDC_OPT_RENEWABLE 0x00800000 /* #define KDC_OPT_UNUSED 0x00400000 */ /* #define KDC_OPT_RESERVED 0x00200000 */ /* #define KDC_OPT_RESERVED 0x00100000 */ /* #define KDC_OPT_RESERVED 0x00080000 */ /* #define KDC_OPT_RESERVED 0x00040000 */ #define KDC_OPT_CNAME_IN_ADDL_TKT 0x00020000 #define KDC_OPT_CANONICALIZE 0x00010000 #define KDC_OPT_REQUEST_ANONYMOUS 0x00008000 /* #define KDC_OPT_RESERVED 0x00004000 */ /* #define KDC_OPT_RESERVED 0x00002000 */ /* #define KDC_OPT_RESERVED 0x00001000 */ /* #define KDC_OPT_RESERVED 0x00000800 */ /* #define KDC_OPT_RESERVED 0x00000400 */ /* #define KDC_OPT_RESERVED 0x00000200 */ /* #define KDC_OPT_RESERVED 0x00000100 */ /* #define KDC_OPT_RESERVED 0x00000080 */ /* #define KDC_OPT_RESERVED 0x00000040 */ #define KDC_OPT_DISABLE_TRANSITED_CHECK 0x00000020 #define KDC_OPT_RENEWABLE_OK 0x00000010 #define KDC_OPT_ENC_TKT_IN_SKEY 0x00000008 /* #define KDC_OPT_UNUSED 0x00000004 */ #define KDC_OPT_RENEW 0x00000002 #define KDC_OPT_VALIDATE 0x00000001 /* * Mask of ticket flags in the TGT which should be converted into KDC * options when using the TGT to get derivative tickets. * * New mask = KDC_OPT_FORWARDABLE | KDC_OPT_PROXIABLE | * KDC_OPT_ALLOW_POSTDATE | KDC_OPT_RENEWABLE */ #define KDC_TKT_COMMON_MASK 0x54800000 /* definitions for ap_options fields */ /** @defgroup AP_OPTS AP_OPTS * * ap_options are 32 bits; each host is responsible to put the 4 bytes * representing these bits into net order before transmission * @{ */ #define AP_OPTS_RESERVED 0x80000000 #define AP_OPTS_USE_SESSION_KEY 0x40000000 /**< Use session key */ #define AP_OPTS_MUTUAL_REQUIRED 0x20000000 /**< Perform a mutual authentication exchange */ #define AP_OPTS_ETYPE_NEGOTIATION 0x00000002 #define AP_OPTS_USE_SUBKEY 0x00000001 /**< Generate a subsession key from the current session key obtained from the credentials */ /* #define AP_OPTS_RESERVED 0x10000000 */ /* #define AP_OPTS_RESERVED 0x08000000 */ /* #define AP_OPTS_RESERVED 0x04000000 */ /* #define AP_OPTS_RESERVED 0x02000000 */ /* #define AP_OPTS_RESERVED 0x01000000 */ /* #define AP_OPTS_RESERVED 0x00800000 */ /* #define AP_OPTS_RESERVED 0x00400000 */ /* #define AP_OPTS_RESERVED 0x00200000 */ /* #define AP_OPTS_RESERVED 0x00100000 */ /* #define AP_OPTS_RESERVED 0x00080000 */ /* #define AP_OPTS_RESERVED 0x00040000 */ /* #define AP_OPTS_RESERVED 0x00020000 */ /* #define AP_OPTS_RESERVED 0x00010000 */ /* #define AP_OPTS_RESERVED 0x00008000 */ /* #define AP_OPTS_RESERVED 0x00004000 */ /* #define AP_OPTS_RESERVED 0x00002000 */ /* #define AP_OPTS_RESERVED 0x00001000 */ /* #define AP_OPTS_RESERVED 0x00000800 */ /* #define AP_OPTS_RESERVED 0x00000400 */ /* #define AP_OPTS_RESERVED 0x00000200 */ /* #define AP_OPTS_RESERVED 0x00000100 */ /* #define AP_OPTS_RESERVED 0x00000080 */ /* #define AP_OPTS_RESERVED 0x00000040 */ /* #define AP_OPTS_RESERVED 0x00000020 */ /* #define AP_OPTS_RESERVED 0x00000010 */ /* #define AP_OPTS_RESERVED 0x00000008 */ /* #define AP_OPTS_RESERVED 0x00000004 */ #define AP_OPTS_WIRE_MASK 0xfffffff0 /** @} */ /* end of AP_OPTS group */ /* definitions for ad_type fields. */ #define AD_TYPE_RESERVED 0x8000 #define AD_TYPE_EXTERNAL 0x4000 #define AD_TYPE_REGISTERED 0x2000 #define AD_TYPE_FIELD_TYPE_MASK 0x1fff /* Ticket flags */ /* flags are 32 bits; each host is responsible to put the 4 bytes representing these bits into net order before transmission */ /* #define TKT_FLG_RESERVED 0x80000000 */ #define TKT_FLG_FORWARDABLE 0x40000000 #define TKT_FLG_FORWARDED 0x20000000 #define TKT_FLG_PROXIABLE 0x10000000 #define TKT_FLG_PROXY 0x08000000 #define TKT_FLG_MAY_POSTDATE 0x04000000 #define TKT_FLG_POSTDATED 0x02000000 #define TKT_FLG_INVALID 0x01000000 #define TKT_FLG_RENEWABLE 0x00800000 #define TKT_FLG_INITIAL 0x00400000 #define TKT_FLG_PRE_AUTH 0x00200000 #define TKT_FLG_HW_AUTH 0x00100000 #define TKT_FLG_TRANSIT_POLICY_CHECKED 0x00080000 #define TKT_FLG_OK_AS_DELEGATE 0x00040000 #define TKT_FLG_ENC_PA_REP 0x00010000 #define TKT_FLG_ANONYMOUS 0x00008000 /* #define TKT_FLG_RESERVED 0x00004000 */ /* #define TKT_FLG_RESERVED 0x00002000 */ /* #define TKT_FLG_RESERVED 0x00001000 */ /* #define TKT_FLG_RESERVED 0x00000800 */ /* #define TKT_FLG_RESERVED 0x00000400 */ /* #define TKT_FLG_RESERVED 0x00000200 */ /* #define TKT_FLG_RESERVED 0x00000100 */ /* #define TKT_FLG_RESERVED 0x00000080 */ /* #define TKT_FLG_RESERVED 0x00000040 */ /* #define TKT_FLG_RESERVED 0x00000020 */ /* #define TKT_FLG_RESERVED 0x00000010 */ /* #define TKT_FLG_RESERVED 0x00000008 */ /* #define TKT_FLG_RESERVED 0x00000004 */ /* #define TKT_FLG_RESERVED 0x00000002 */ /* #define TKT_FLG_RESERVED 0x00000001 */ /* definitions for lr_type fields. */ #define LR_TYPE_THIS_SERVER_ONLY 0x8000 #define LR_TYPE_INTERPRETATION_MASK 0x7fff /* definitions for msec direction bit for KRB_SAFE, KRB_PRIV */ #define MSEC_DIRBIT 0x8000 #define MSEC_VAL_MASK 0x7fff /* * end "fieldbits.h" */ /* * begin "proto.h" */ /** Protocol version number */ #define KRB5_PVNO 5 /* Message types */ #define KRB5_AS_REQ ((krb5_msgtype)10) /**< Initial authentication request */ #define KRB5_AS_REP ((krb5_msgtype)11) /**< Response to AS request */ #define KRB5_TGS_REQ ((krb5_msgtype)12) /**< Ticket granting server request */ #define KRB5_TGS_REP ((krb5_msgtype)13) /**< Response to TGS request */ #define KRB5_AP_REQ ((krb5_msgtype)14) /**< Auth req to application server */ #define KRB5_AP_REP ((krb5_msgtype)15) /**< Response to mutual AP request */ #define KRB5_SAFE ((krb5_msgtype)20) /**< Safe application message */ #define KRB5_PRIV ((krb5_msgtype)21) /**< Private application message */ #define KRB5_CRED ((krb5_msgtype)22) /**< Cred forwarding message */ #define KRB5_ERROR ((krb5_msgtype)30) /**< Error response */ /* LastReq types */ #define KRB5_LRQ_NONE 0 #define KRB5_LRQ_ALL_LAST_TGT 1 #define KRB5_LRQ_ONE_LAST_TGT (-1) #define KRB5_LRQ_ALL_LAST_INITIAL 2 #define KRB5_LRQ_ONE_LAST_INITIAL (-2) #define KRB5_LRQ_ALL_LAST_TGT_ISSUED 3 #define KRB5_LRQ_ONE_LAST_TGT_ISSUED (-3) #define KRB5_LRQ_ALL_LAST_RENEWAL 4 #define KRB5_LRQ_ONE_LAST_RENEWAL (-4) #define KRB5_LRQ_ALL_LAST_REQ 5 #define KRB5_LRQ_ONE_LAST_REQ (-5) #define KRB5_LRQ_ALL_PW_EXPTIME 6 #define KRB5_LRQ_ONE_PW_EXPTIME (-6) #define KRB5_LRQ_ALL_ACCT_EXPTIME 7 #define KRB5_LRQ_ONE_ACCT_EXPTIME (-7) /* PADATA types */ #define KRB5_PADATA_NONE 0 #define KRB5_PADATA_AP_REQ 1 #define KRB5_PADATA_TGS_REQ KRB5_PADATA_AP_REQ #define KRB5_PADATA_ENC_TIMESTAMP 2 /**< RFC 4120 */ #define KRB5_PADATA_PW_SALT 3 /**< RFC 4120 */ #if 0 /* Not used */ #define KRB5_PADATA_ENC_ENCKEY 4 /* Key encrypted within itself */ #endif #define KRB5_PADATA_ENC_UNIX_TIME 5 /**< timestamp encrypted in key. RFC 4120 */ #define KRB5_PADATA_ENC_SANDIA_SECURID 6 /**< SecurId passcode. RFC 4120 */ #define KRB5_PADATA_SESAME 7 /**< Sesame project. RFC 4120 */ #define KRB5_PADATA_OSF_DCE 8 /**< OSF DCE. RFC 4120 */ #define KRB5_CYBERSAFE_SECUREID 9 /**< Cybersafe. RFC 4120 */ #define KRB5_PADATA_AFS3_SALT 10 /**< Cygnus. RFC 4120, 3961 */ #define KRB5_PADATA_ETYPE_INFO 11 /**< Etype info for preauth. RFC 4120 */ #define KRB5_PADATA_SAM_CHALLENGE 12 /**< SAM/OTP */ #define KRB5_PADATA_SAM_RESPONSE 13 /**< SAM/OTP */ #define KRB5_PADATA_PK_AS_REQ_OLD 14 /**< PKINIT */ #define KRB5_PADATA_PK_AS_REP_OLD 15 /**< PKINIT */ #define KRB5_PADATA_PK_AS_REQ 16 /**< PKINIT. RFC 4556 */ #define KRB5_PADATA_PK_AS_REP 17 /**< PKINIT. RFC 4556 */ #define KRB5_PADATA_ETYPE_INFO2 19 /**< RFC 4120 */ #define KRB5_PADATA_USE_SPECIFIED_KVNO 20 /**< RFC 4120 */ #define KRB5_PADATA_SVR_REFERRAL_INFO 20 /**< Windows 2000 referrals. RFC 6820 */ #define KRB5_PADATA_SAM_REDIRECT 21 /**< SAM/OTP. RFC 4120 */ #define KRB5_PADATA_GET_FROM_TYPED_DATA 22 /**< Embedded in typed data. RFC 4120 */ #define KRB5_PADATA_REFERRAL 25 /**< draft referral system */ #define KRB5_PADATA_SAM_CHALLENGE_2 30 /**< draft challenge system, updated */ #define KRB5_PADATA_SAM_RESPONSE_2 31 /**< draft challenge system, updated */ /* MS-KILE */ #define KRB5_PADATA_PAC_REQUEST 128 /**< include Windows PAC */ #define KRB5_PADATA_FOR_USER 129 /**< username protocol transition request */ #define KRB5_PADATA_S4U_X509_USER 130 /**< certificate protocol transition request */ #define KRB5_PADATA_AS_CHECKSUM 132 /**< AS checksum */ #define KRB5_PADATA_FX_COOKIE 133 /**< RFC 6113 */ #define KRB5_PADATA_FX_FAST 136 /**< RFC 6113 */ #define KRB5_PADATA_FX_ERROR 137 /**< RFC 6113 */ #define KRB5_PADATA_ENCRYPTED_CHALLENGE 138 /**< RFC 6113 */ #define KRB5_PADATA_OTP_CHALLENGE 141 /**< RFC 6560 section 4.1 */ #define KRB5_PADATA_OTP_REQUEST 142 /**< RFC 6560 section 4.2 */ #define KRB5_PADATA_OTP_PIN_CHANGE 144 /**< RFC 6560 section 4.3 */ #define KRB5_PADATA_PKINIT_KX 147 /**< RFC 6112 */ #define KRB5_ENCPADATA_REQ_ENC_PA_REP 149 /**< RFC 6806 */ #define KRB5_PADATA_AS_FRESHNESS 150 /**< RFC 8070 */ #define KRB5_PADATA_SPAKE 151 #define KRB5_PADATA_PAC_OPTIONS 167 /**< MS-KILE and MS-SFU */ #define KRB5_SAM_USE_SAD_AS_KEY 0x80000000 #define KRB5_SAM_SEND_ENCRYPTED_SAD 0x40000000 #define KRB5_SAM_MUST_PK_ENCRYPT_SAD 0x20000000 /**< currently must be zero */ /** Transited encoding types */ #define KRB5_DOMAIN_X500_COMPRESS 1 /** alternate authentication types */ #define KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE 64 /* authorization data types. See RFC 4120 section 5.2.6 */ /** @defgroup KRB5_AUTHDATA KRB5_AUTHDATA * @{ */ #define KRB5_AUTHDATA_IF_RELEVANT 1 #define KRB5_AUTHDATA_KDC_ISSUED 4 #define KRB5_AUTHDATA_AND_OR 5 #define KRB5_AUTHDATA_MANDATORY_FOR_KDC 8 #define KRB5_AUTHDATA_INITIAL_VERIFIED_CAS 9 #define KRB5_AUTHDATA_OSF_DCE 64 #define KRB5_AUTHDATA_SESAME 65 #define KRB5_AUTHDATA_CAMMAC 96 #define KRB5_AUTHDATA_WIN2K_PAC 128 #define KRB5_AUTHDATA_ETYPE_NEGOTIATION 129 /**< RFC 4537 */ #define KRB5_AUTHDATA_SIGNTICKET 512 /**< @deprecated use PAC */ #define KRB5_AUTHDATA_FX_ARMOR 71 #define KRB5_AUTHDATA_AUTH_INDICATOR 97 #define KRB5_AUTHDATA_AP_OPTIONS 143 /** @} */ /* end of KRB5_AUTHDATA group */ /* password change constants */ #define KRB5_KPASSWD_SUCCESS 0 /**< Success */ #define KRB5_KPASSWD_MALFORMED 1 /**< Malformed request */ #define KRB5_KPASSWD_HARDERROR 2 /**< Server error */ #define KRB5_KPASSWD_AUTHERROR 3 /**< Authentication error */ #define KRB5_KPASSWD_SOFTERROR 4 /**< Password change rejected */ /* These are Microsoft's extensions in RFC 3244, and it looks like they'll become standardized, possibly with other additions. */ #define KRB5_KPASSWD_ACCESSDENIED 5 /**< Not authorized */ #define KRB5_KPASSWD_BAD_VERSION 6 /**< Unknown RPC version */ /** The presented credentials were not obtained using a password directly */ #define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 /* * end "proto.h" */ /* Time set */ /** Ticket start time, end time, and renewal duration. */ typedef struct _krb5_ticket_times { krb5_timestamp authtime; /**< Time at which KDC issued the initial ticket that corresponds to this ticket */ /* XXX ? should ktime in KDC_REP == authtime in ticket? otherwise client can't get this */ krb5_timestamp starttime; /**< optional in ticket, if not present, use @a authtime */ krb5_timestamp endtime; /**< Ticket expiration time */ krb5_timestamp renew_till; /**< Latest time at which renewal of ticket can be valid */ } krb5_ticket_times; /** Structure for auth data */ typedef struct _krb5_authdata { krb5_magic magic; krb5_authdatatype ad_type; /**< ADTYPE */ unsigned int length; /**< Length of data */ krb5_octet *contents; /**< Data */ } krb5_authdata; /** Structure for transited encoding */ typedef struct _krb5_transited { krb5_magic magic; krb5_octet tr_type; /**< Transited encoding type */ krb5_data tr_contents; /**< Contents */ } krb5_transited; /** Encrypted part of ticket. */ typedef struct _krb5_enc_tkt_part { krb5_magic magic; /* to-be-encrypted portion */ krb5_flags flags; /**< flags */ krb5_keyblock *session; /**< session key: includes enctype */ krb5_principal client; /**< client name/realm */ krb5_transited transited; /**< list of transited realms */ krb5_ticket_times times; /**< auth, start, end, renew_till */ krb5_address **caddrs; /**< array of ptrs to addresses */ krb5_authdata **authorization_data; /**< auth data */ } krb5_enc_tkt_part; /** * Ticket structure. * * The C representation of the ticket message, with a pointer to the * C representation of the encrypted part. */ typedef struct _krb5_ticket { krb5_magic magic; /* cleartext portion */ krb5_principal server; /**< server name/realm */ krb5_enc_data enc_part; /**< encryption type, kvno, encrypted encoding */ krb5_enc_tkt_part *enc_part2; /**< ptr to decrypted version, if available */ } krb5_ticket; /* the unencrypted version */ /** * Ticket authenticator. * * The C representation of an unencrypted authenticator. */ typedef struct _krb5_authenticator { krb5_magic magic; krb5_principal client; /**< client name/realm */ krb5_checksum *checksum; /**< checksum, includes type, optional */ krb5_int32 cusec; /**< client usec portion */ krb5_timestamp ctime; /**< client sec portion */ krb5_keyblock *subkey; /**< true session key, optional */ krb5_ui_4 seq_number; /**< sequence #, optional */ krb5_authdata **authorization_data; /**< authoriazation data */ } krb5_authenticator; /** Ticket authentication data. */ typedef struct _krb5_tkt_authent { krb5_magic magic; krb5_ticket *ticket; krb5_authenticator *authenticator; krb5_flags ap_options; } krb5_tkt_authent; /** Credentials structure including ticket, session key, and lifetime info. */ typedef struct _krb5_creds { krb5_magic magic; krb5_principal client; /**< client's principal identifier */ krb5_principal server; /**< server's principal identifier */ krb5_keyblock keyblock; /**< session encryption key info */ krb5_ticket_times times; /**< lifetime info */ krb5_boolean is_skey; /**< true if ticket is encrypted in another ticket's skey */ krb5_flags ticket_flags; /**< flags in ticket */ krb5_address **addresses; /**< addrs in ticket */ krb5_data ticket; /**< ticket string itself */ krb5_data second_ticket; /**< second ticket, if related to ticket (via DUPLICATE-SKEY or ENC-TKT-IN-SKEY) */ krb5_authdata **authdata; /**< authorization data */ } krb5_creds; /** Last request entry */ typedef struct _krb5_last_req_entry { krb5_magic magic; krb5_int32 lr_type; /**< LR type */ krb5_timestamp value; /**< Timestamp */ } krb5_last_req_entry; /** Pre-authentication data */ typedef struct _krb5_pa_data { krb5_magic magic; krb5_preauthtype pa_type; /**< Preauthentication data type */ unsigned int length; /**< Length of data */ krb5_octet *contents; /**< Data */ } krb5_pa_data; /* Don't use this; use krb5_pa_data instead. */ typedef struct _krb5_typed_data { krb5_magic magic; krb5_int32 type; unsigned int length; krb5_octet *data; } krb5_typed_data; /** C representation of KDC-REQ protocol message, including KDC-REQ-BODY */ typedef struct _krb5_kdc_req { krb5_magic magic; krb5_msgtype msg_type; /**< KRB5_AS_REQ or KRB5_TGS_REQ */ krb5_pa_data **padata; /**< Preauthentication data */ /* real body */ krb5_flags kdc_options; /**< Requested options */ krb5_principal client; /**< Client principal and realm */ krb5_principal server; /**< Server principal and realm */ krb5_timestamp from; /**< Requested start time */ krb5_timestamp till; /**< Requested end time */ krb5_timestamp rtime; /**< Requested renewable end time */ krb5_int32 nonce; /**< Nonce to match request and response */ int nktypes; /**< Number of enctypes */ krb5_enctype *ktype; /**< Requested enctypes */ krb5_address **addresses; /**< Requested addresses (optional) */ krb5_enc_data authorization_data; /**< Encrypted authz data (optional) */ krb5_authdata **unenc_authdata; /**< Unencrypted authz data */ krb5_ticket **second_ticket; /**< Second ticket array (optional) */ } krb5_kdc_req; /** * C representation of @c EncKDCRepPart protocol message. * * This is the cleartext message that is encrypted and inserted in @c KDC-REP. */ typedef struct _krb5_enc_kdc_rep_part { krb5_magic magic; /* encrypted part: */ krb5_msgtype msg_type; /**< krb5 message type */ krb5_keyblock *session; /**< Session key */ krb5_last_req_entry **last_req; /**< Array of pointers to entries */ krb5_int32 nonce; /**< Nonce from request */ krb5_timestamp key_exp; /**< Expiration date */ krb5_flags flags; /**< Ticket flags */ krb5_ticket_times times; /**< Lifetime info */ krb5_principal server; /**< Server's principal identifier */ krb5_address **caddrs; /**< Array of ptrs to addrs, optional */ krb5_pa_data **enc_padata; /**< Encrypted preauthentication data */ } krb5_enc_kdc_rep_part; /** Representation of the @c KDC-REP protocol message. */ typedef struct _krb5_kdc_rep { krb5_magic magic; /* cleartext part: */ krb5_msgtype msg_type; /**< KRB5_AS_REP or KRB5_KDC_REP */ krb5_pa_data **padata; /**< Preauthentication data from KDC */ krb5_principal client; /**< Client principal and realm */ krb5_ticket *ticket; /**< Ticket */ krb5_enc_data enc_part; /**< Encrypted part of reply */ krb5_enc_kdc_rep_part *enc_part2; /**< Unencrypted version, if available */ } krb5_kdc_rep; /** Error message structure */ typedef struct _krb5_error { krb5_magic magic; /* some of these may be meaningless in certain contexts */ krb5_timestamp ctime; /**< Client sec portion; optional */ krb5_int32 cusec; /**< Client usec portion; optional */ krb5_int32 susec; /**< Server usec portion */ krb5_timestamp stime; /**< Server sec portion */ krb5_ui_4 error; /**< Error code (protocol error #'s) */ krb5_principal client; /**< Client principal and realm */ krb5_principal server; /**< Server principal and realm */ krb5_data text; /**< Descriptive text */ krb5_data e_data; /**< Additional error-describing data */ } krb5_error; /** Authentication header. */ typedef struct _krb5_ap_req { krb5_magic magic; krb5_flags ap_options; /**< Requested options */ krb5_ticket *ticket; /**< Ticket */ krb5_enc_data authenticator; /**< Encrypted authenticator */ } krb5_ap_req; /** * C representaton of AP-REP message. * * The server's response to a client's request for mutual authentication. */ typedef struct _krb5_ap_rep { krb5_magic magic; krb5_enc_data enc_part; /**< Ciphertext of ApRepEncPart */ } krb5_ap_rep; /** Cleartext that is encrypted and put into @c _krb5_ap_rep. */ typedef struct _krb5_ap_rep_enc_part { krb5_magic magic; krb5_timestamp ctime; /**< Client time, seconds portion */ krb5_int32 cusec; /**< Client time, microseconds portion */ krb5_keyblock *subkey; /**< Subkey (optional) */ krb5_ui_4 seq_number; /**< Sequence number */ } krb5_ap_rep_enc_part; /* Unused */ typedef struct _krb5_response { krb5_magic magic; krb5_octet message_type; krb5_data response; krb5_int32 expected_nonce; krb5_timestamp request_time; } krb5_response; /** Credentials information inserted into @c EncKrbCredPart. */ typedef struct _krb5_cred_info { krb5_magic magic; krb5_keyblock *session; /**< Session key used to encrypt ticket */ krb5_principal client; /**< Client principal and realm */ krb5_principal server; /**< Server principal and realm */ krb5_flags flags; /**< Ticket flags */ krb5_ticket_times times; /**< Auth, start, end, renew_till */ krb5_address **caddrs; /**< Array of pointers to addrs (optional) */ } krb5_cred_info; /** Cleartext credentials information. */ typedef struct _krb5_cred_enc_part { krb5_magic magic; krb5_int32 nonce; /**< Nonce (optional) */ krb5_timestamp timestamp; /**< Generation time, seconds portion */ krb5_int32 usec; /**< Generation time, microseconds portion */ krb5_address *s_address; /**< Sender address (optional) */ krb5_address *r_address; /**< Recipient address (optional) */ krb5_cred_info **ticket_info; } krb5_cred_enc_part; /** Credentials data structure.*/ typedef struct _krb5_cred { krb5_magic magic; krb5_ticket **tickets; /**< Tickets */ krb5_enc_data enc_part; /**< Encrypted part */ krb5_cred_enc_part *enc_part2; /**< Unencrypted version, if available */ } krb5_cred; /* Unused, but here for API compatibility. */ typedef struct _passwd_phrase_element { krb5_magic magic; krb5_data *passwd; krb5_data *phrase; } passwd_phrase_element; /* Unused, but here for API compatibility. */ typedef struct _krb5_pwd_data { krb5_magic magic; int sequence_count; passwd_phrase_element **element; } krb5_pwd_data; /* Unused, but here for API compatibility. */ typedef struct _krb5_pa_svr_referral_data { /** Referred name, only realm is required */ krb5_principal principal; } krb5_pa_svr_referral_data; /* Unused, but here for API compatibility. */ typedef struct _krb5_pa_server_referral_data { krb5_data *referred_realm; krb5_principal true_principal_name; krb5_principal requested_principal_name; krb5_timestamp referral_valid_until; krb5_checksum rep_cksum; } krb5_pa_server_referral_data; typedef struct _krb5_pa_pac_req { /** TRUE if a PAC should be included in TGS-REP */ krb5_boolean include_pac; } krb5_pa_pac_req; /* * begin "safepriv.h" */ /** @defgroup KRB5_AUTH_CONTEXT KRB5_AUTH_CONTEXT * @{ */ /** Prevent replays with timestamps and replay cache. */ #define KRB5_AUTH_CONTEXT_DO_TIME 0x00000001 /** Save timestamps for application. */ #define KRB5_AUTH_CONTEXT_RET_TIME 0x00000002 /** Prevent replays with sequence numbers. */ #define KRB5_AUTH_CONTEXT_DO_SEQUENCE 0x00000004 /** Save sequence numbers for application. */ #define KRB5_AUTH_CONTEXT_RET_SEQUENCE 0x00000008 #define KRB5_AUTH_CONTEXT_PERMIT_ALL 0x00000010 #define KRB5_AUTH_CONTEXT_USE_SUBKEY 0x00000020 /** @} */ /* end of KRB5_AUTH_CONTEXT group */ /** * Replay data. * * Sequence number and timestamp information output by krb5_rd_priv() and * krb5_rd_safe(). */ typedef struct krb5_replay_data { krb5_timestamp timestamp; /**< Timestamp, seconds portion */ krb5_int32 usec; /**< Timestamp, microseconds portion */ krb5_ui_4 seq; /**< Sequence number */ } krb5_replay_data; /* Flags for krb5_auth_con_genaddrs(). */ /** Generate the local network address. */ #define KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR 0x00000001 /** Generate the remote network address. */ #define KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR 0x00000002 /** Generate the local network address and the local port. */ #define KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR 0x00000004 /** Generate the remote network address and the remote port. */ #define KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR 0x00000008 /** Type of function used as a callback to generate checksum data for mk_req */ typedef krb5_error_code (KRB5_CALLCONV * krb5_mk_req_checksum_func)(krb5_context, krb5_auth_context, void *, krb5_data **); /* * end "safepriv.h" */ /* * begin "ccache.h" */ /** Cursor for sequential lookup */ typedef krb5_pointer krb5_cc_cursor; struct _krb5_ccache; typedef struct _krb5_ccache *krb5_ccache; struct _krb5_cc_ops; typedef struct _krb5_cc_ops krb5_cc_ops; struct _krb5_cccol_cursor; /** Cursor for iterating over all ccaches */ typedef struct _krb5_cccol_cursor *krb5_cccol_cursor; /* Flags for krb5_cc_retrieve_cred. */ /** The requested lifetime must be at least as great as the time specified. */ #define KRB5_TC_MATCH_TIMES 0x00000001 /** The is_skey field must match exactly. */ #define KRB5_TC_MATCH_IS_SKEY 0x00000002 /** All the flags set in the match credentials must be set. */ #define KRB5_TC_MATCH_FLAGS 0x00000004 /** All the time fields must match exactly. */ #define KRB5_TC_MATCH_TIMES_EXACT 0x00000008 /** All the flags must match exactly. */ #define KRB5_TC_MATCH_FLAGS_EXACT 0x00000010 /** The authorization data must match. */ #define KRB5_TC_MATCH_AUTHDATA 0x00000020 /** Only the name portion of the principal name must match. */ #define KRB5_TC_MATCH_SRV_NAMEONLY 0x00000040 /** The second ticket must match. */ #define KRB5_TC_MATCH_2ND_TKT 0x00000080 /** The encryption key type must match. */ #define KRB5_TC_MATCH_KTYPE 0x00000100 /** The supported key types must match. */ #define KRB5_TC_SUPPORTED_KTYPES 0x00000200 /* Flags for krb5_cc_set_flags and similar. */ /** Open and close the file for each cache operation. */ #define KRB5_TC_OPENCLOSE 0x00000001 /**< @deprecated has no effect */ #define KRB5_TC_NOTICKET 0x00000002 /** * Retrieve the name, but not type of a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * * @warning Returns the name of the credential cache. The result is an alias * into @a cache and should not be freed or modified by the caller. This name * does not include the cache type, so should not be used as input to * krb5_cc_resolve(). * * @return * On success - the name of the credential cache. */ const char * KRB5_CALLCONV krb5_cc_get_name(krb5_context context, krb5_ccache cache); /** * Retrieve the full name of a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [out] fullname_out Full name of cache * * Use krb5_free_string() to free @a fullname_out when it is no longer needed. * * @version New in 1.10 */ krb5_error_code KRB5_CALLCONV krb5_cc_get_full_name(krb5_context context, krb5_ccache cache, char **fullname_out); #if KRB5_DEPRECATED krb5_error_code KRB5_CALLCONV krb5_cc_gen_new(krb5_context context, krb5_ccache *cache); #endif /* KRB5_DEPRECATED */ /** * Initialize a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [in] principal Default principal name * * Destroy any existing contents of @a cache and initialize it for the default * principal @a principal. * * @retval * 0 Success * @return * System errors; Permission errors; Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_initialize(krb5_context context, krb5_ccache cache, krb5_principal principal); /** * Destroy a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * * This function destroys any existing contents of @a cache and closes the * handle to it. * * @retval * 0 Success * @return * Permission errors */ krb5_error_code KRB5_CALLCONV krb5_cc_destroy(krb5_context context, krb5_ccache cache); /** * Close a credential cache handle. * * @param [in] context Library context * @param [in] cache Credential cache handle * * This function closes a credential cache handle @a cache without affecting * the contents of the cache. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_close(krb5_context context, krb5_ccache cache); /** * Store credentials in a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [in] creds Credentials to be stored in cache * * This function stores @a creds into @a cache. If @a creds->server and the * server in the decoded ticket @a creds->ticket differ, the credentials will * be stored under both server principal names. * * @retval * 0 Success * @return Permission errors; storage failure errors; Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_store_cred(krb5_context context, krb5_ccache cache, krb5_creds *creds); /** * Retrieve a specified credentials from a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [in] flags Flags bit mask * @param [in] mcreds Credentials to match * @param [out] creds Credentials matching the requested value * * This function searches a credential cache for credentials matching @a mcreds * and returns it if found. * * Valid values for @a flags are: * * @li #KRB5_TC_MATCH_TIMES The requested lifetime must be at least as * great as in @a mcreds . * @li #KRB5_TC_MATCH_IS_SKEY The @a is_skey field much match exactly. * @li #KRB5_TC_MATCH_FLAGS Flags set in @a mcreds must be set. * @li #KRB5_TC_MATCH_TIMES_EXACT The requested lifetime must match exactly. * @li #KRB5_TC_MATCH_FLAGS_EXACT Flags must match exactly. * @li #KRB5_TC_MATCH_AUTHDATA The authorization data must match. * @li #KRB5_TC_MATCH_SRV_NAMEONLY Only the name portion of the principal * name must match, not the realm. * @li #KRB5_TC_MATCH_2ND_TKT The second tickets must match. * @li #KRB5_TC_MATCH_KTYPE The encryption key types must match. * @li #KRB5_TC_SUPPORTED_KTYPES Check all matching entries that have any * supported encryption type and return the * one with the encryption type listed earliest. * * Use krb5_free_cred_contents() to free @a creds when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_retrieve_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *mcreds, krb5_creds *creds); /** * Get the default principal of a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [out] principal Primary principal * * Returns the default client principal of a credential cache as set by * krb5_cc_initialize(). * * Use krb5_free_principal() to free @a principal when it is no longer needed. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_get_principal(krb5_context context, krb5_ccache cache, krb5_principal *principal); /** * Prepare to sequentially read every credential in a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [out] cursor Cursor * * krb5_cc_end_seq_get() must be called to complete the retrieve operation. * * @note If the cache represented by @a cache is modified between the time of * the call to this function and the time of the final krb5_cc_end_seq_get(), * these changes may not be reflected in the results of krb5_cc_next_cred() * calls. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_start_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor); /** * Retrieve the next entry from the credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [in] cursor Cursor * @param [out] creds Next credential cache entry * * This function fills in @a creds with the next entry in @a cache and advances * @a cursor. * * Use krb5_free_cred_contents() to free @a creds when it is no longer needed. * * @sa krb5_cc_start_seq_get(), krb5_end_seq_get() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor, krb5_creds *creds); /** * Finish a series of sequential processing credential cache entries. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [in] cursor Cursor * * This function finishes processing credential cache entries and invalidates * @a cursor. * * @sa krb5_cc_start_seq_get(), krb5_cc_next_cred() * * @retval 0 (always) */ krb5_error_code KRB5_CALLCONV krb5_cc_end_seq_get(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor); /** * Remove credentials from a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [in] flags Bitwise-ORed search flags * @param [in] creds Credentials to be matched * * @warning This function is not implemented for some cache types. * * This function accepts the same flag values as krb5_cc_retrieve_cred(). * * @retval KRB5_CC_NOSUPP Not implemented for this cache type * @return No matches found; Data cannot be deleted; Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags, krb5_creds *creds); /** * Set options flags on a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [in] flags Flag bit mask * * This function resets @a cache flags to @a flags. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_set_flags(krb5_context context, krb5_ccache cache, krb5_flags flags); /** * Retrieve flags from a credential cache structure. * * @param [in] context Library context * @param [in] cache Credential cache handle * @param [out] flags Flag bit mask * * @warning For memory credential cache always returns a flag mask of 0. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_get_flags(krb5_context context, krb5_ccache cache, krb5_flags *flags); /** * Retrieve the type of a credential cache. * * @param [in] context Library context * @param [in] cache Credential cache handle * * @return The type of a credential cache as an alias that must not be modified * or freed by the caller. */ const char * KRB5_CALLCONV krb5_cc_get_type(krb5_context context, krb5_ccache cache); /** * Move a credential cache. * * @param [in] context Library context * @param [in] src The credential cache to move the content from * @param [in] dst The credential cache to move the content to * * This function reinitializes @a dst and populates it with the credentials and * default principal of @a src; then, if successful, destroys @a src. * * @retval * 0 Success; @a src is closed. * @return * Kerberos error codes; @a src is still allocated. */ krb5_error_code KRB5_CALLCONV krb5_cc_move(krb5_context context, krb5_ccache src, krb5_ccache dst); /** * Prepare to iterate over the collection of known credential caches. * * @param [in] context Library context * @param [out] cursor Cursor * * Get a new cache iteration @a cursor that will iterate over all known * credential caches independent of type. * * Use krb5_cccol_cursor_free() to release @a cursor when it is no longer * needed. * * @sa krb5_cccol_cursor_next() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cccol_cursor_new(krb5_context context, krb5_cccol_cursor *cursor); /** * Get the next credential cache in the collection. * * @param [in] context Library context * @param [in] cursor Cursor * @param [out] ccache Credential cache handle * * @note When all caches are iterated over and the end of the list is reached, * @a ccache is set to NULL. * * Use krb5_cc_close() to close @a ccache when it is no longer needed. * * @sa krb5_cccol_cursor_new(), krb5_cccol_cursor_free() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cccol_cursor_next(krb5_context context, krb5_cccol_cursor cursor, krb5_ccache *ccache); /** * Free a credential cache collection cursor. * * @param [in] context Library context * @param [in] cursor Cursor * * @sa krb5_cccol_cursor_new(), krb5_cccol_cursor_next() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cccol_cursor_free(krb5_context context, krb5_cccol_cursor *cursor); /** * Check if the credential cache collection contains any credentials. * * @param [in] context Library context * * @version New in 1.11 * * @retval 0 Credentials are available in the collection * @retval KRB5_CC_NOTFOUND The collection contains no credentials */ krb5_error_code KRB5_CALLCONV krb5_cccol_have_content(krb5_context context); /** * Create a new credential cache of the specified type with a unique name. * * @param [in] context Library context * @param [in] type Credential cache type name * @param [in] hint Unused * @param [out] id Credential cache handle * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_new_unique(krb5_context context, const char *type, const char *hint, krb5_ccache *id); /* * end "ccache.h" */ /* * begin "rcache.h" */ struct krb5_rc_st; typedef struct krb5_rc_st *krb5_rcache; /* * end "rcache.h" */ /* * begin "keytab.h" */ /* XXX */ #define MAX_KEYTAB_NAME_LEN 1100 /**< Long enough for MAXPATHLEN + some extra */ typedef krb5_pointer krb5_kt_cursor; /** A key table entry. */ typedef struct krb5_keytab_entry_st { krb5_magic magic; krb5_principal principal; /**< Principal of this key */ krb5_timestamp timestamp; /**< Time entry written to keytable */ krb5_kvno vno; /**< Key version number */ krb5_keyblock key; /**< The secret key */ } krb5_keytab_entry; struct _krb5_kt; typedef struct _krb5_kt *krb5_keytab; /** * Return the type of a key table. * * @param [in] context Library context * @param [in] keytab Key table handle * * @return The type of a key table as an alias that must not be modified or * freed by the caller. */ const char * KRB5_CALLCONV krb5_kt_get_type(krb5_context context, krb5_keytab keytab); /** * Get a key table name. * * @param [in] context Library context * @param [in] keytab Key table handle * @param [out] name Key table name * @param [in] namelen Maximum length to fill in name * * Fill @a name with the name of @a keytab including the type and delimiter. * * @sa MAX_KEYTAB_NAME_LEN * * @retval * 0 Success * @retval * KRB5_KT_NAME_TOOLONG Key table name does not fit in @a namelen bytes * * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_kt_get_name(krb5_context context, krb5_keytab keytab, char *name, unsigned int namelen); /** * Close a key table handle. * * @param [in] context Library context * @param [in] keytab Key table handle * * @retval 0 */ krb5_error_code KRB5_CALLCONV krb5_kt_close(krb5_context context, krb5_keytab keytab); /** * Get an entry from a key table. * * @param [in] context Library context * @param [in] keytab Key table handle * @param [in] principal Principal name * @param [in] vno Key version number (0 for highest available) * @param [in] enctype Encryption type (0 zero for any enctype) * @param [out] entry Returned entry from key table * * Retrieve an entry from a key table which matches the @a keytab, @a * principal, @a vno, and @a enctype. If @a vno is zero, retrieve the * highest-numbered kvno matching the other fields. If @a enctype is 0, match * any enctype. * * Use krb5_free_keytab_entry_contents() to free @a entry when it is no longer * needed. * * @note If @a vno is zero, the function retrieves the highest-numbered-kvno * entry that matches the specified principal. * * @retval * 0 Success * @retval * Kerberos error codes on failure */ krb5_error_code KRB5_CALLCONV krb5_kt_get_entry(krb5_context context, krb5_keytab keytab, krb5_const_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keytab_entry *entry); /** * Start a sequential retrieval of key table entries. * * @param [in] context Library context * @param [in] keytab Key table handle * @param [out] cursor Cursor * * Prepare to read sequentially every key in the specified key table. Use * krb5_kt_end_seq_get() to release the cursor when it is no longer needed. * * @sa krb5_kt_next_entry(), krb5_kt_end_seq_get() * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_kt_start_seq_get(krb5_context context, krb5_keytab keytab, krb5_kt_cursor *cursor); /** * Retrieve the next entry from the key table. * * @param [in] context Library context * @param [in] keytab Key table handle * @param [out] entry Returned key table entry * @param [in] cursor Key table cursor * * Return the next sequential entry in @a keytab and advance @a cursor. * Callers must release the returned entry with krb5_kt_free_entry(). * * @sa krb5_kt_start_seq_get(), krb5_kt_end_seq_get() * * @retval * 0 Success * @retval * KRB5_KT_END - if the last entry was reached * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_kt_next_entry(krb5_context context, krb5_keytab keytab, krb5_keytab_entry *entry, krb5_kt_cursor *cursor); /** * Release a keytab cursor. * * @param [in] context Library context * @param [in] keytab Key table handle * @param [out] cursor Cursor * * This function should be called to release the cursor created by * krb5_kt_start_seq_get(). * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_kt_end_seq_get(krb5_context context, krb5_keytab keytab, krb5_kt_cursor *cursor); /** * Check if a keytab exists and contains entries. * * @param [in] context Library context * @param [in] keytab Key table handle * * @version New in 1.11 * * @retval 0 Keytab exists and contains entries * @retval KRB5_KT_NOTFOUND Keytab does not contain entries */ krb5_error_code KRB5_CALLCONV krb5_kt_have_content(krb5_context context, krb5_keytab keytab); /* * end "keytab.h" */ /* * begin "func-proto.h" */ #define KRB5_INIT_CONTEXT_SECURE 0x1 /**< Use secure context configuration */ #define KRB5_INIT_CONTEXT_KDC 0x2 /**< Use KDC configuration if available */ /** * Create a krb5 library context. * * @param [out] context Library context * * The @a context must be released by calling krb5_free_context() when * it is no longer needed. * * @warning Any program or module that needs the Kerberos code to not trust the * environment must use krb5_init_secure_context(), or clean out the * environment. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_context(krb5_context *context); /** * Create a krb5 library context using only configuration files. * * @param [out] context Library context * * Create a context structure, using only system configuration files. All * information passed through the environment variables is ignored. * * The @a context must be released by calling krb5_free_context() when * it is no longer needed. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_secure_context(krb5_context *context); /** * Create a krb5 library context using a specified profile. * * @param [in] profile Profile object (NULL to create default profile) * @param [in] flags Context initialization flags * @param [out] context Library context * * Create a context structure, optionally using a specified profile and * initialization flags. If @a profile is NULL, the default profile will be * created from config files. If @a profile is non-null, a copy of it will be * made for the new context; the caller should still clean up its copy. Valid * flag values are: * * @li #KRB5_INIT_CONTEXT_SECURE Ignore environment variables * @li #KRB5_INIT_CONTEXT_KDC Use KDC configuration if creating profile */ krb5_error_code KRB5_CALLCONV krb5_init_context_profile(struct _profile_t *profile, krb5_flags flags, krb5_context *context); /** * Free a krb5 library context. * * @param [in] context Library context * * This function frees a @a context that was created by krb5_init_context() * or krb5_init_secure_context(). */ void KRB5_CALLCONV krb5_free_context(krb5_context context); /** * Copy a krb5_context structure. * * @param [in] ctx Library context * @param [out] nctx_out New context structure * * The newly created context must be released by calling krb5_free_context() * when it is no longer needed. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_context(krb5_context ctx, krb5_context *nctx_out); /** * Set default TGS encryption types in a krb5_context structure. * * @param [in] context Library context * @param [in] etypes Encryption type(s) to set * * This function sets the default enctype list for TGS requests * made using @a context to @a etypes. * * @note This overrides the default list (from config file or built-in). * * @retval * 0 Success * @retval * KRB5_PROG_ETYPE_NOSUPP Program lacks support for encryption type * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_set_default_tgs_enctypes(krb5_context context, const krb5_enctype *etypes); /** * Return a list of encryption types permitted for session keys. * * @param [in] context Library context * @param [out] ktypes Zero-terminated list of encryption types * * This function returns the list of encryption types permitted for session * keys within @a context, as determined by configuration or by a previous call * to krb5_set_default_tgs_enctypes(). * * Use krb5_free_enctypes() to free @a ktypes when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_permitted_enctypes(krb5_context context, krb5_enctype **ktypes); /** * Test whether the Kerberos library was built with multithread support. * * @retval * TRUE if the library is threadsafe; FALSE otherwise */ krb5_boolean KRB5_CALLCONV krb5_is_thread_safe(void); /* libkrb.spec */ /** * Decrypt a ticket using the specified key table. * * @param [in] context Library context * @param [in] kt Key table * @param [in] ticket Ticket to be decrypted * * This function takes a @a ticket as input and decrypts it using * key data from @a kt. The result is placed into @a ticket->enc_part2. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_server_decrypt_ticket_keytab(krb5_context context, const krb5_keytab kt, krb5_ticket *ticket); /** * Free an array of credential structures. * * @param [in] context Library context * @param [in] tgts Null-terminated array of credentials to free * * @note The last entry in the array @a tgts must be a NULL pointer. */ void KRB5_CALLCONV krb5_free_tgt_creds(krb5_context context, krb5_creds **tgts); /** @defgroup KRB5_GC KRB5_GC * @{ */ #define KRB5_GC_USER_USER 1 /**< Want user-user ticket */ #define KRB5_GC_CACHED 2 /**< Want cached ticket only */ #define KRB5_GC_CANONICALIZE 4 /**< Set canonicalize KDC option */ #define KRB5_GC_NO_STORE 8 /**< Do not store in credential cache */ #define KRB5_GC_FORWARDABLE 16 /**< Acquire forwardable tickets */ #define KRB5_GC_NO_TRANSIT_CHECK 32 /**< Disable transited check */ #define KRB5_GC_CONSTRAINED_DELEGATION 64 /**< Constrained delegation */ /** @} */ /* end of KRB5_GC group */ /** * Get an additional ticket. * * @param [in] context Library context * @param [in] options Options * @param [in] ccache Credential cache handle * @param [in] in_creds Input credentials * @param [out] out_creds Output updated credentials * * Use @a ccache or a TGS exchange to get a service ticket matching @a * in_creds. * * Valid values for @a options are: * @li #KRB5_GC_CACHED Search only credential cache for the ticket * @li #KRB5_GC_USER_USER Return a user to user authentication ticket * * @a in_creds must be non-null. @a in_creds->client and @a in_creds->server * must be filled in to specify the client and the server respectively. If any * authorization data needs to be requested for the service ticket (such as * restrictions on how the ticket can be used), specify it in @a * in_creds->authdata; otherwise set @a in_creds->authdata to NULL. The * session key type is specified in @a in_creds->keyblock.enctype, if it is * nonzero. * * The expiration date is specified in @a in_creds->times.endtime. * The KDC may return tickets with an earlier expiration date. * If @a in_creds->times.endtime is set to 0, the latest possible * expiration date will be requested. * * Any returned ticket and intermediate ticket-granting tickets are stored * in @a ccache. * * Use krb5_free_creds() to free @a out_creds when it is no longer needed. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_credentials(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds **out_creds); /** * Serialize a @c krb5_creds object. * * @param [in] context Library context * @param [in] creds The credentials object to serialize * @param [out] data_out The serialized credentials * * Serialize @a creds in the format used by the FILE ccache format (vesion 4) * and KCM ccache protocol. * * Use krb5_free_data() to free @a data_out when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds, krb5_data **data_out); /** * Deserialize a @c krb5_creds object. * * @param [in] context Library context * @param [in] data The serialized credentials * @param [out] creds_out The resulting creds object * * Deserialize @a data to credentials in the format used by the FILE ccache * format (vesion 4) and KCM ccache protocol. * * Use krb5_free_creds() to free @a creds_out when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_unmarshal_credentials(krb5_context context, const krb5_data *data, krb5_creds **creds_out); /** @deprecated Replaced by krb5_get_validated_creds. */ krb5_error_code KRB5_CALLCONV krb5_get_credentials_validate(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds **out_creds); /** @deprecated Replaced by krb5_get_renewed_creds. */ krb5_error_code KRB5_CALLCONV krb5_get_credentials_renew(krb5_context context, krb5_flags options, krb5_ccache ccache, krb5_creds *in_creds, krb5_creds **out_creds); /** * Create a @c KRB_AP_REQ message. * * @param [in] context Library context * @param [in,out] auth_context Pre-existing or newly created auth context * @param [in] ap_req_options @ref AP_OPTS options * @param [in] service Service name, or NULL to use @c "host" * @param [in] hostname Host name, or NULL to use local hostname * @param [in] in_data Application data to be checksummed in the * authenticator, or NULL * @param [in] ccache Credential cache used to obtain credentials * for the desired service. * @param [out] outbuf @c AP-REQ message * * This function is similar to krb5_mk_req_extended() except that it uses a * given @a hostname, @a service, and @a ccache to construct a service * principal name and obtain credentials. * * Use krb5_free_data_contents() to free @a outbuf when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_mk_req(krb5_context context, krb5_auth_context *auth_context, krb5_flags ap_req_options, const char *service, const char *hostname, krb5_data *in_data, krb5_ccache ccache, krb5_data *outbuf); /** * Create a @c KRB_AP_REQ message using supplied credentials. * * @param [in] context Library context * @param [in,out] auth_context Pre-existing or newly created auth context * @param [in] ap_req_options @ref AP_OPTS options * @param [in] in_data Application data to be checksummed in the * authenticator, or NULL * @param [in] in_creds Credentials for the service with valid ticket * and key * @param [out] outbuf @c AP-REQ message * * Valid @a ap_req_options are: * @li #AP_OPTS_USE_SESSION_KEY - Use the session key when creating the * request used for user to user * authentication. * @li #AP_OPTS_MUTUAL_REQUIRED - Request a mutual authentication packet from * the receiver. * @li #AP_OPTS_USE_SUBKEY - Generate a subsession key from the current * session key obtained from the credentials. * * This function creates a KRB_AP_REQ message using supplied credentials @a * in_creds. @a auth_context may point to an existing auth context or to NULL, * in which case a new one will be created. If @a in_data is non-null, a * checksum of it will be included in the authenticator contained in the * KRB_AP_REQ message. Use krb5_free_data_contents() to free @a outbuf when it * is no longer needed. * * On successful return, the authenticator is stored in @a auth_context with * the @a client and @a checksum fields nulled out. (This is to prevent * pointer-sharing problems; the caller should not need these fields anyway, * since the caller supplied them.) * * @sa krb5_mk_req() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_mk_req_extended(krb5_context context, krb5_auth_context *auth_context, krb5_flags ap_req_options, krb5_data *in_data, krb5_creds *in_creds, krb5_data *outbuf); /** * Format and encrypt a @c KRB_AP_REP message. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] outbuf @c AP-REP message * * This function fills in @a outbuf with an AP-REP message using information * from @a auth_context. * * If the flags in @a auth_context indicate that a sequence number should be * used (either #KRB5_AUTH_CONTEXT_DO_SEQUENCE or * #KRB5_AUTH_CONTEXT_RET_SEQUENCE) and the local sequence number in @a * auth_context is 0, a new number will be generated with * krb5_generate_seq_number(). * * Use krb5_free_data_contents() to free @a outbuf when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_mk_rep(krb5_context context, krb5_auth_context auth_context, krb5_data *outbuf); /** * Format and encrypt a @c KRB_AP_REP message for DCE RPC. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] outbuf @c AP-REP message * * Use krb5_free_data_contents() to free @a outbuf when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_mk_rep_dce(krb5_context context, krb5_auth_context auth_context, krb5_data *outbuf); /** * Parse and decrypt a @c KRB_AP_REP message. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] inbuf AP-REP message * @param [out] repl Decrypted reply message * * This function parses, decrypts and verifies a message from @a inbuf and * fills in @a repl with a pointer to allocated memory containing the fields * from the encrypted response. * * Use krb5_free_ap_rep_enc_part() to free @a repl when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_rd_rep(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_ap_rep_enc_part **repl); /** * Parse and decrypt a @c KRB_AP_REP message for DCE RPC. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] inbuf AP-REP message * @param [out] nonce Sequence number from the decrypted reply * * This function parses, decrypts and verifies a message from @a inbuf and * fills in @a nonce with a decrypted reply sequence number. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_rd_rep_dce(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_ui_4 *nonce); /** * Format and encode a @c KRB_ERROR message. * * @param [in] context Library context * @param [in] dec_err Error structure to be encoded * @param [out] enc_err Encoded error structure * * This function creates a @c KRB_ERROR message in @a enc_err. Use * krb5_free_data_contents() to free @a enc_err when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_mk_error(krb5_context context, const krb5_error *dec_err, krb5_data *enc_err); /** * Decode a @c KRB-ERROR message. * * @param [in] context Library context * @param [in] enc_errbuf Encoded error message * @param [out] dec_error Decoded error message * * This function processes @c KRB-ERROR message @a enc_errbuf and returns * an allocated structure @a dec_error containing the error message. * Use krb5_free_error() to free @a dec_error when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_rd_error(krb5_context context, const krb5_data *enc_errbuf, krb5_error **dec_error); /** * Process @c KRB-SAFE message. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] inbuf @c KRB-SAFE message to be parsed * @param [out] userdata_out Data parsed from @c KRB-SAFE message * @param [out] rdata_out Replay data. Specify NULL if not needed * * This function parses a @c KRB-SAFE message, verifies its integrity, and * stores its data into @a userdata_out. * * @note The @a rdata_out argument is required if the * #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set * in @a auth_context. * * If @a auth_context has a remote address set, the address will be used to * verify the sender address in the KRB-SAFE message. If @a auth_context has a * local address set, it will be used to verify the receiver address in the * KRB-SAFE message if the message contains one. * * If the #KRB5_AUTH_CONTEXT_DO_SEQUENCE flag is set in @a auth_context, the * sequence number of the KRB-SAFE message is checked against the remote * sequence number field of @a auth_context. Otherwise, the sequence number is * not used. * * If the #KRB5_AUTH_CONTEXT_DO_TIME flag is set in @a auth_context, then the * timestamp in the message is verified to be within the permitted clock skew * of the current time, and the message is checked against an in-memory replay * cache to detect reflections or replays. * * Use krb5_free_data_contents() to free @a userdata_out when it is no longer * needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_rd_safe(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_data *userdata_out, krb5_replay_data *rdata_out); /** * Process a @c KRB-PRIV message. * * @param [in] context Library context * @param [in] auth_context Authentication structure * @param [in] inbuf @c KRB-PRIV message to be parsed * @param [out] userdata_out Data parsed from @c KRB-PRIV message * @param [out] rdata_out Replay data. Specify NULL if not needed * * This function parses a @c KRB-PRIV message, verifies its integrity, and * stores its unencrypted data into @a userdata_out. * * @note The @a rdata_out argument is required if the * #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set * in @a auth_context. * * If @a auth_context has a remote address set, the address will be used to * verify the sender address in the KRB-PRIV message. If @a auth_context has a * local address set, it will be used to verify the receiver address in the * KRB-PRIV message if the message contains one. * * If the #KRB5_AUTH_CONTEXT_DO_SEQUENCE flag is set in @a auth_context, the * sequence number of the KRB-PRIV message is checked against the remote * sequence number field of @a auth_context. Otherwise, the sequence number is * not used. * * If the #KRB5_AUTH_CONTEXT_DO_TIME flag is set in @a auth_context, then the * timestamp in the message is verified to be within the permitted clock skew * of the current time, and the message is checked against an in-memory replay * cache to detect reflections or replays. * * Use krb5_free_data_contents() to free @a userdata_out when it is no longer * needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_rd_priv(krb5_context context, krb5_auth_context auth_context, const krb5_data *inbuf, krb5_data *userdata_out, krb5_replay_data *rdata_out); /** * Convert a string principal name to a krb5_principal structure. * * @param [in] context Library context * @param [in] name String representation of a principal name * @param [out] principal_out New principal * * Convert a string representation of a principal name to a krb5_principal * structure. * * A string representation of a Kerberos name consists of one or more principal * name components, separated by slashes, optionally followed by the \@ * character and a realm name. If the realm name is not specified, the local * realm is used. * * To use the slash and \@ symbols as part of a component (quoted) instead of * using them as a component separator or as a realm prefix), put a backslash * (\) character in front of the symbol. Similarly, newline, tab, backspace, * and NULL characters can be included in a component by using @c n, @c t, @c b * or @c 0, respectively. * * @note The realm in a Kerberos @a name cannot contain slash, colon, * or NULL characters. * * Use krb5_free_principal() to free @a principal_out when it is no longer * needed. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_parse_name(krb5_context context, const char *name, krb5_principal *principal_out); #define KRB5_PRINCIPAL_PARSE_NO_REALM 0x1 /**< Error if realm is present */ #define KRB5_PRINCIPAL_PARSE_REQUIRE_REALM 0x2 /**< Error if realm is not present */ #define KRB5_PRINCIPAL_PARSE_ENTERPRISE 0x4 /**< Create single-component enterprise principle */ #define KRB5_PRINCIPAL_PARSE_IGNORE_REALM 0x8 /**< Ignore realm if present */ /** * Convert a string principal name to a krb5_principal with flags. * * @param [in] context Library context * @param [in] name String representation of a principal name * @param [in] flags Flag * @param [out] principal_out New principal * * Similar to krb5_parse_name(), this function converts a single-string * representation of a principal name to a krb5_principal structure. * * The following flags are valid: * @li #KRB5_PRINCIPAL_PARSE_NO_REALM - no realm must be present in @a name * @li #KRB5_PRINCIPAL_PARSE_REQUIRE_REALM - realm must be present in @a name * @li #KRB5_PRINCIPAL_PARSE_ENTERPRISE - create single-component enterprise * principal * @li #KRB5_PRINCIPAL_PARSE_IGNORE_REALM - ignore realm if present in @a name * * If @c KRB5_PRINCIPAL_PARSE_NO_REALM or @c KRB5_PRINCIPAL_PARSE_IGNORE_REALM * is specified in @a flags, the realm of the new principal will be empty. * Otherwise, the default realm for @a context will be used if @a name does not * specify a realm. * * Use krb5_free_principal() to free @a principal_out when it is no longer * needed. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_parse_name_flags(krb5_context context, const char *name, int flags, krb5_principal *principal_out); /** * Convert a krb5_principal structure to a string representation. * * @param [in] context Library context * @param [in] principal Principal * @param [out] name String representation of principal name * * The resulting string representation uses the format and quoting conventions * described for krb5_parse_name(). * * Use krb5_free_unparsed_name() to free @a name when it is no longer needed. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_unparse_name(krb5_context context, krb5_const_principal principal, char **name); /** * Convert krb5_principal structure to string and length. * * @param [in] context Library context * @param [in] principal Principal * @param [in,out] name String representation of principal name * @param [in,out] size Size of unparsed name * * This function is similar to krb5_unparse_name(), but allows the use of an * existing buffer for the result. If size is not NULL, then @a name must * point to either NULL or an existing buffer of at least the size pointed to * by @a size. The buffer will be allocated or resized if necessary, with the * new pointer stored into @a name. Whether or not the buffer is resized, the * necessary space for the result, including null terminator, will be stored * into @a size. * * If size is NULL, this function behaves exactly as krb5_unparse_name(). * * @retval * 0 Success * @return * Kerberos error codes. On failure @a name is set to NULL */ krb5_error_code KRB5_CALLCONV krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, char **name, unsigned int *size); #define KRB5_PRINCIPAL_UNPARSE_SHORT 0x1 /**< Omit realm if it is the local realm */ #define KRB5_PRINCIPAL_UNPARSE_NO_REALM 0x2 /**< Omit realm always */ #define KRB5_PRINCIPAL_UNPARSE_DISPLAY 0x4 /**< Don't escape special characters */ /** * Convert krb5_principal structure to a string with flags. * * @param [in] context Library context * @param [in] principal Principal * @param [in] flags Flags * @param [out] name String representation of principal name * * Similar to krb5_unparse_name(), this function converts a krb5_principal * structure to a string representation. * * The following flags are valid: * @li #KRB5_PRINCIPAL_UNPARSE_SHORT - omit realm if it is the local realm * @li #KRB5_PRINCIPAL_UNPARSE_NO_REALM - omit realm * @li #KRB5_PRINCIPAL_UNPARSE_DISPLAY - do not quote special characters * * Use krb5_free_unparsed_name() to free @a name when it is no longer needed. * * @retval * 0 Success * @return * Kerberos error codes. On failure @a name is set to NULL */ krb5_error_code KRB5_CALLCONV krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal, int flags, char **name); /** * Convert krb5_principal structure to string format with flags. * * @param [in] context Library context * @param [in] principal Principal * @param [in] flags Flags * @param [out] name Single string format of principal name * @param [out] size Size of unparsed name buffer * * @sa krb5_unparse_name() krb5_unparse_name_flags() krb5_unparse_name_ext() * * @retval * 0 Success * @return * Kerberos error codes. On failure @a name is set to NULL */ krb5_error_code KRB5_CALLCONV krb5_unparse_name_flags_ext(krb5_context context, krb5_const_principal principal, int flags, char **name, unsigned int *size); /** * Set the realm field of a principal * * @param [in] context Library context * @param [in] principal Principal name * @param [in] realm Realm name * * Set the realm name part of @a principal to @a realm, overwriting the * previous realm. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_set_principal_realm(krb5_context context, krb5_principal principal, const char *realm); /** * Search a list of addresses for a specified address. * * @param [in] context Library context * @param [in] addr Address to search for * @param [in] addrlist Address list to be searched (or NULL) * * @note If @a addrlist contains only a NetBIOS addresses, it will be treated * as a null list. * * @return * TRUE if @a addr is listed in @a addrlist, or @c addrlist is NULL; FALSE * otherwise */ krb5_boolean KRB5_CALLCONV_WRONG krb5_address_search(krb5_context context, const krb5_address *addr, krb5_address *const *addrlist); /** * Compare two Kerberos addresses. * * @param [in] context Library context * @param [in] addr1 First address to be compared * @param [in] addr2 Second address to be compared * * @return * TRUE if the addresses are the same, FALSE otherwise */ krb5_boolean KRB5_CALLCONV krb5_address_compare(krb5_context context, const krb5_address *addr1, const krb5_address *addr2); /** * Return an ordering of the specified addresses. * * @param [in] context Library context * @param [in] addr1 First address * @param [in] addr2 Second address * * @retval * 0 The two addresses are the same * @retval * \< 0 First address is less than second * @retval * \> 0 First address is greater than second */ int KRB5_CALLCONV krb5_address_order(krb5_context context, const krb5_address *addr1, const krb5_address *addr2); /** * Compare the realms of two principals. * * @param [in] context Library context * @param [in] princ1 First principal * @param [in] princ2 Second principal * * @retval * TRUE if the realm names are the same; FALSE otherwise */ krb5_boolean KRB5_CALLCONV krb5_realm_compare(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2); /** * Compare two principals. * * @param [in] context Library context * @param [in] princ1 First principal * @param [in] princ2 Second principal * * @retval * TRUE if the principals are the same; FALSE otherwise */ krb5_boolean KRB5_CALLCONV krb5_principal_compare(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2); /** * Compare two principals ignoring realm components. * * @param [in] context Library context * @param [in] princ1 First principal * @param [in] princ2 Second principal * * Similar to krb5_principal_compare(), but do not compare the realm * components of the principals. * * @retval * TRUE if the principals are the same; FALSE otherwise */ krb5_boolean KRB5_CALLCONV krb5_principal_compare_any_realm(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2); #define KRB5_PRINCIPAL_COMPARE_IGNORE_REALM 1 /**< ignore realm component */ #define KRB5_PRINCIPAL_COMPARE_ENTERPRISE 2 /**< UPNs as real principals */ #define KRB5_PRINCIPAL_COMPARE_CASEFOLD 4 /**< case-insensitive */ #define KRB5_PRINCIPAL_COMPARE_UTF8 8 /**< treat principals as UTF-8 */ /** * Compare two principals with additional flags. * * @param [in] context Library context * @param [in] princ1 First principal * @param [in] princ2 Second principal * @param [in] flags Flags * * Valid flags are: * @li #KRB5_PRINCIPAL_COMPARE_IGNORE_REALM - ignore realm component * @li #KRB5_PRINCIPAL_COMPARE_ENTERPRISE - UPNs as real principals * @li #KRB5_PRINCIPAL_COMPARE_CASEFOLD case-insensitive * @li #KRB5_PRINCIPAL_COMPARE_UTF8 - treat principals as UTF-8 * * @sa krb5_principal_compare() * * @retval * TRUE if the principal names are the same; FALSE otherwise */ krb5_boolean KRB5_CALLCONV krb5_principal_compare_flags(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2, int flags); /** * Initialize an empty @c krb5_keyblock. * * @param [in] context Library context * @param [in] enctype Encryption type * @param [in] length Length of keyblock (or 0) * @param [out] out New keyblock structure * * Initialize a new keyblock and allocate storage for the contents of the key. * It is legal to pass in a length of 0, in which case contents are left * unallocated. Use krb5_free_keyblock() to free @a out when it is no longer * needed. * * @note If @a length is set to 0, contents are left unallocated. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_keyblock(krb5_context context, krb5_enctype enctype, size_t length, krb5_keyblock **out); /** * Copy a keyblock. * * @param [in] context Library context * @param [in] from Keyblock to be copied * @param [out] to Copy of keyblock @a from * * This function creates a new keyblock with the same contents as @a from. Use * krb5_free_keyblock() to free @a to when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_keyblock(krb5_context context, const krb5_keyblock *from, krb5_keyblock **to); /** * Copy the contents of a keyblock. * * @param [in] context Library context * @param [in] from Key to be copied * @param [out] to Output key * * This function copies the contents of @a from to @a to. Use * krb5_free_keyblock_contents() to free @a to when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_keyblock_contents(krb5_context context, const krb5_keyblock *from, krb5_keyblock *to); /** * Copy a krb5_creds structure. * * @param [in] context Library context * @param [in] incred Credentials structure to be copied * @param [out] outcred Copy of @a incred * * This function creates a new credential with the contents of @a incred. Use * krb5_free_creds() to free @a outcred when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_creds(krb5_context context, const krb5_creds *incred, krb5_creds **outcred); /** * Copy a krb5_data object. * * @param [in] context Library context * @param [in] indata Data object to be copied * @param [out] outdata Copy of @a indata * * This function creates a new krb5_data object with the contents of @a indata. * Use krb5_free_data() to free @a outdata when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_data(krb5_context context, const krb5_data *indata, krb5_data **outdata); /** * Copy a principal. * * @param [in] context Library context * @param [in] inprinc Principal to be copied * @param [out] outprinc Copy of @a inprinc * * This function creates a new principal structure with the contents of @a * inprinc. Use krb5_free_principal() to free @a outprinc when it is no longer * needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_principal *outprinc); /** * Copy an array of addresses. * * @param [in] context Library context * @param [in] inaddr Array of addresses to be copied * @param [out] outaddr Copy of array of addresses * * This function creates a new address array containing a copy of @a inaddr. * Use krb5_free_addresses() to free @a outaddr when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_addresses(krb5_context context, krb5_address *const *inaddr, krb5_address ***outaddr); /** * Copy a krb5_ticket structure. * * @param [in] context Library context * @param [in] from Ticket to be copied * @param [out] pto Copy of ticket * * This function creates a new krb5_ticket structure containing the contents of * @a from. Use krb5_free_ticket() to free @a pto when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_ticket(krb5_context context, const krb5_ticket *from, krb5_ticket **pto); /** * Copy an authorization data list. * * @param [in] context Library context * @param [in] in_authdat List of @a krb5_authdata structures * @param [out] out New array of @a krb5_authdata structures * * This function creates a new authorization data list containing a copy of @a * in_authdat, which must be null-terminated. Use krb5_free_authdata() to free * @a out when it is no longer needed. * * @note The last array entry in @a in_authdat must be a NULL pointer. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_authdata(krb5_context context, krb5_authdata *const *in_authdat, krb5_authdata ***out); /** * Find authorization data elements. * * @param [in] context Library context * @param [in] ticket_authdata Authorization data list from ticket * @param [in] ap_req_authdata Authorization data list from AP request * @param [in] ad_type Authorization data type to find * @param [out] results List of matching entries * * This function searches @a ticket_authdata and @a ap_req_authdata for * elements of type @a ad_type. Either input list may be NULL, in which case * it will not be searched; otherwise, the input lists must be terminated by * NULL entries. This function will search inside AD-IF-RELEVANT containers if * found in either list. Use krb5_free_authdata() to free @a results when it * is no longer needed. * * @version New in 1.10 */ krb5_error_code KRB5_CALLCONV krb5_find_authdata(krb5_context context, krb5_authdata *const *ticket_authdata, krb5_authdata *const *ap_req_authdata, krb5_authdatatype ad_type, krb5_authdata ***results); /** * Merge two authorization data lists into a new list. * * @param [in] context Library context * @param [in] inauthdat1 First list of @a krb5_authdata structures * @param [in] inauthdat2 Second list of @a krb5_authdata structures * @param [out] outauthdat Merged list of @a krb5_authdata structures * * Merge two authdata arrays, such as the array from a ticket * and authenticator. * Use krb5_free_authdata() to free @a outauthdat when it is no longer needed. * * @note The last array entry in @a inauthdat1 and @a inauthdat2 * must be a NULL pointer. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_merge_authdata(krb5_context context, krb5_authdata *const *inauthdat1, krb5_authdata * const *inauthdat2, krb5_authdata ***outauthdat); /** * Copy a krb5_authenticator structure. * * @param [in] context Library context * @param [in] authfrom krb5_authenticator structure to be copied * @param [out] authto Copy of krb5_authenticator structure * * This function creates a new krb5_authenticator structure with the content of * @a authfrom. Use krb5_free_authenticator() to free @a authto when it is no * longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_authenticator(krb5_context context, const krb5_authenticator *authfrom, krb5_authenticator **authto); /** * Copy a krb5_checksum structure. * * @param [in] context Library context * @param [in] ckfrom Checksum to be copied * @param [out] ckto Copy of krb5_checksum structure * * This function creates a new krb5_checksum structure with the contents of @a * ckfrom. Use krb5_free_checksum() to free @a ckto when it is no longer * needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_copy_checksum(krb5_context context, const krb5_checksum *ckfrom, krb5_checksum **ckto); /** * Generate a replay cache object for server use and open it. * * @param [in] context Library context * @param [in] piece Unused (replay cache identifier) * @param [out] rcptr Handle to an open rcache * * This function creates a handle to the default replay cache. Use * krb5_rc_close() to close @a rcptr when it is no longer needed. * * @version Prior to release 1.18, this function creates a handle to a * different replay cache for each unique value of @a piece. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_server_rcache(krb5_context context, const krb5_data *piece, krb5_rcache *rcptr); /** * Build a principal name using length-counted strings. * * @param [in] context Library context * @param [out] princ Principal name * @param [in] rlen Realm name length * @param [in] realm Realm name * @param [in] ... List of unsigned int/char * components, followed by 0 * * This function creates a principal from a length-counted string and a * variable-length list of length-counted components. The list of components * ends with the first 0 length argument (so it is not possible to specify an * empty component with this function). Call krb5_free_principal() to free * allocated memory for principal when it is no longer needed. * * @code * Example of how to build principal WELLKNOWN/ANONYMOUS@R * krb5_build_principal_ext(context, &principal, strlen("R"), "R", * (unsigned int)strlen(KRB5_WELLKNOWN_NAMESTR), * KRB5_WELLKNOWN_NAMESTR, * (unsigned int)strlen(KRB5_ANONYMOUS_PRINCSTR), * KRB5_ANONYMOUS_PRINCSTR, 0); * @endcode * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV_C krb5_build_principal_ext(krb5_context context, krb5_principal * princ, unsigned int rlen, const char * realm, ...); /** * Build a principal name using null-terminated strings. * * @param [in] context Library context * @param [out] princ Principal name * @param [in] rlen Realm name length * @param [in] realm Realm name * @param [in] ... List of char * components, ending with NULL * * Call krb5_free_principal() to free @a princ when it is no longer needed. * * @note krb5_build_principal() and krb5_build_principal_alloc_va() perform the * same task. krb5_build_principal() takes variadic arguments. * krb5_build_principal_alloc_va() takes a pre-computed @a varargs pointer. * * @code * Example of how to build principal H/S@R * krb5_build_principal(context, &principal, * strlen("R"), "R", "H", "S", (char*)NULL); * @endcode * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV_C krb5_build_principal(krb5_context context, krb5_principal * princ, unsigned int rlen, const char * realm, ...) #if __GNUC__ >= 4 __attribute__ ((sentinel)) #endif ; #if KRB5_DEPRECATED /** @deprecated Replaced by krb5_build_principal_alloc_va(). */ KRB5_ATTR_DEPRECATED krb5_error_code KRB5_CALLCONV krb5_build_principal_va(krb5_context context, krb5_principal princ, unsigned int rlen, const char *realm, va_list ap); #endif /** * Build a principal name, using a precomputed variable argument list * * @param [in] context Library context * @param [out] princ Principal structure * @param [in] rlen Realm name length * @param [in] realm Realm name * @param [in] ap List of char * components, ending with NULL * * Similar to krb5_build_principal(), this function builds a principal name, * but its name components are specified as a va_list. * * Use krb5_free_principal() to deallocate @a princ when it is no longer * needed. * * @code * Function usage example: * va_list ap; * va_start(ap, realm); * krb5_build_principal_alloc_va(context, princ, rlen, realm, ap); * va_end(ap); * @endcode * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_build_principal_alloc_va(krb5_context context, krb5_principal *princ, unsigned int rlen, const char *realm, va_list ap); /** * Convert a Kerberos V4 principal to a Kerberos V5 principal. * * @param [in] context Library context * @param [in] name V4 name * @param [in] instance V4 instance * @param [in] realm Realm * @param [out] princ V5 principal * * This function builds a @a princ from V4 specification based on given input * @a name.instance\@realm. * * Use krb5_free_principal() to free @a princ when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_425_conv_principal(krb5_context context, const char *name, const char *instance, const char *realm, krb5_principal *princ); /** * Convert a Kerberos V5 principal to a Kerberos V4 principal. * * @param [in] context Library context * @param [in] princ V5 Principal * @param [out] name V4 principal's name to be filled in * @param [out] inst V4 principal's instance name to be filled in * @param [out] realm Principal's realm name to be filled in * * This function separates a V5 principal @a princ into @a name, @a instance, * and @a realm. * * @retval * 0 Success * @retval * KRB5_INVALID_PRINCIPAL Invalid principal name * @retval * KRB5_CONFIG_CANTOPEN Can't open or find Kerberos configuration file * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_524_conv_principal(krb5_context context, krb5_const_principal princ, char *name, char *inst, char *realm); /** *@deprecated */ struct credentials; /** * Convert a Kerberos V5 credentials to a Kerberos V4 credentials * * @note Not implemented * * @retval KRB524_KRB4_DISABLED (always) */ int KRB5_CALLCONV krb5_524_convert_creds(krb5_context context, krb5_creds *v5creds, struct credentials *v4creds); #if KRB5_DEPRECATED #define krb524_convert_creds_kdc krb5_524_convert_creds #define krb524_init_ets(x) (0) #endif /* libkt.spec */ /** * Get a handle for a key table. * * @param [in] context Library context * @param [in] name Name of the key table * @param [out] ktid Key table handle * * Resolve the key table name @a name and set @a ktid to a handle identifying * the key table. Use krb5_kt_close() to free @a ktid when it is no longer * needed. * * @a name must be of the form @c type:residual, where @a type must be a type * known to the library and @a residual portion should be specific to the * particular keytab type. If no @a type is given, the default is @c FILE. * * If @a name is of type @c FILE, the keytab file is not opened by this call. * * @code * Example: krb5_kt_resolve(context, "FILE:/tmp/filename", &ktid); * @endcode * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_kt_resolve(krb5_context context, const char *name, krb5_keytab *ktid); /** * Duplicate keytab handle. * * @param [in] context Library context * @param [in] in Key table handle to be duplicated * @param [out] out Key table handle * * Create a new handle referring to the same key table as @a in. The new * handle and @a in can be closed independently. * * @version New in 1.12 */ krb5_error_code KRB5_CALLCONV krb5_kt_dup(krb5_context context, krb5_keytab in, krb5_keytab *out); /** * Get the default key table name. * * @param [in] context Library context * @param [out] name Default key table name * @param [in] name_size Space available in @a name * * Fill @a name with the name of the default key table for @a context. * * @sa MAX_KEYTAB_NAME_LEN * * @retval * 0 Success * @retval * KRB5_CONFIG_NOTENUFSPACE Buffer is too short * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_kt_default_name(krb5_context context, char *name, int name_size); /** * Resolve the default key table. * * @param [in] context Library context * @param [out] id Key table handle * * Set @a id to a handle to the default key table. The key table is not * opened. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_kt_default(krb5_context context, krb5_keytab *id); /** * Resolve the default client key table. * * @param [in] context Library context * @param [out] keytab_out Key table handle * * Fill @a keytab_out with a handle to the default client key table. * * @version New in 1.11 * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_kt_client_default(krb5_context context, krb5_keytab *keytab_out); /** * Free the contents of a key table entry. * * @param [in] context Library context * @param [in] entry Key table entry whose contents are to be freed * * @note The pointer is not freed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_free_keytab_entry_contents(krb5_context context, krb5_keytab_entry *entry); /** @deprecated Use krb5_free_keytab_entry_contents instead. */ krb5_error_code KRB5_CALLCONV krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *entry); /* remove and add are functions, so that they can return NOWRITE if not a writable keytab */ /** * Remove an entry from a key table. * * @param [in] context Library context * @param [in] id Key table handle * @param [in] entry Entry to remove from key table * * @retval * 0 Success * @retval * KRB5_KT_NOWRITE Key table is not writable * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_kt_remove_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry); /** * Add a new entry to a key table. * * @param [in] context Library context * @param [in] id Key table handle * @param [in] entry Entry to be added * * @retval * 0 Success * @retval * ENOMEM Insufficient memory * @retval * KRB5_KT_NOWRITE Key table is not writeable * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_kt_add_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry); /** * Convert a principal name into the default salt for that principal. * * @param [in] context Library context * @param [in] pr Principal name * @param [out] ret Default salt for @a pr to be filled in * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV_WRONG krb5_principal2salt(krb5_context context, krb5_const_principal pr, krb5_data *ret); /* librc.spec--see rcache.h */ /* libcc.spec */ /** * Resolve a credential cache name. * * @param [in] context Library context * @param [in] name Credential cache name to be resolved * @param [out] cache Credential cache handle * * Fills in @a cache with a @a cache handle that corresponds to the name in @a * name. @a name should be of the form @c type:residual, and @a type must be a * type known to the library. If the @a name does not contain a colon, * interpret it as a file name. * * @code * Example: krb5_cc_resolve(context, "MEMORY:C_", &cache); * @endcode * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_resolve(krb5_context context, const char *name, krb5_ccache *cache); /** * Duplicate ccache handle. * * @param [in] context Library context * @param [in] in Credential cache handle to be duplicated * @param [out] out Credential cache handle * * Create a new handle referring to the same cache as @a in. * The new handle and @a in can be closed independently. */ krb5_error_code KRB5_CALLCONV krb5_cc_dup(krb5_context context, krb5_ccache in, krb5_ccache *out); /** * Return the name of the default credential cache. * * @param [in] context Library context * * Return a pointer to the default credential cache name for @a context, as * determined by a prior call to krb5_cc_set_default_name(), by the KRB5CCNAME * environment variable, by the default_ccache_name profile variable, or by the * operating system or build-time default value. The returned value must not * be modified or freed by the caller. The returned value becomes invalid when * @a context is destroyed krb5_free_context() or if a subsequent call to * krb5_cc_set_default_name() is made on @a context. * * The default credential cache name is cached in @a context between calls to * this function, so if the value of KRB5CCNAME changes in the process * environment after the first call to this function on, that change will not * be reflected in later calls with the same context. The caller can invoke * krb5_cc_set_default_name() with a NULL value of @a name to clear the cached * value and force the default name to be recomputed. * * @return * Name of default credential cache for the current user. */ const char *KRB5_CALLCONV krb5_cc_default_name(krb5_context context); /** * Set the default credential cache name. * * @param [in] context Library context * @param [in] name Default credential cache name or NULL * * Set the default credential cache name to @a name for future operations using * @a context. If @a name is NULL, clear any previous application-set default * name and forget any cached value of the default name for @a context. * * Calls to this function invalidate the result of any previous calls to * krb5_cc_default_name() using @a context. * * @retval * 0 Success * @retval * KV5M_CONTEXT Bad magic number for @c _krb5_context structure * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_set_default_name(krb5_context context, const char *name); /** * Resolve the default credential cache name. * * @param [in] context Library context * @param [out] ccache Pointer to credential cache name * * Create a handle to the default credential cache as given by * krb5_cc_default_name(). * * @retval * 0 Success * @retval * KV5M_CONTEXT Bad magic number for @c _krb5_context structure * @retval * KRB5_FCC_INTERNAL The name of the default credential cache cannot be * obtained * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_default(krb5_context context, krb5_ccache *ccache); /** * Copy a credential cache. * * @param [in] context Library context * @param [in] incc Credential cache to be copied * @param [out] outcc Copy of credential cache to be filled in * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_copy_creds(krb5_context context, krb5_ccache incc, krb5_ccache outcc); /** * Get a configuration value from a credential cache. * * @param [in] context Library context * @param [in] id Credential cache handle * @param [in] principal Configuration for this principal; * if NULL, global for the whole cache * @param [in] key Name of config variable * @param [out] data Data to be fetched * * Use krb5_free_data_contents() to free @a data when it is no longer needed. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_get_config(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char *key, krb5_data *data); /** * Store a configuration value in a credential cache. * * @param [in] context Library context * @param [in] id Credential cache handle * @param [in] principal Configuration for a specific principal; * if NULL, global for the whole cache * @param [in] key Name of config variable * @param [in] data Data to store, or NULL to remove * * @note Existing configuration under the same key is over-written. * * @warning Before version 1.10 @a data was assumed to be always non-null. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_set_config(krb5_context context, krb5_ccache id, krb5_const_principal principal, const char *key, krb5_data *data); /** * Test whether a principal is a configuration principal. * * @param [in] context Library context * @param [in] principal Principal to check * * @return * @c TRUE if the principal is a configuration principal (generated part of * krb5_cc_set_config()); @c FALSE otherwise. */ krb5_boolean KRB5_CALLCONV krb5_is_config_principal(krb5_context context, krb5_const_principal principal); /** * Make a credential cache the primary cache for its collection. * * @param [in] context Library context * @param [in] cache Credential cache handle * * If the type of @a cache supports it, set @a cache to be the primary * credential cache for the collection it belongs to. * * @retval * 0 Success, or the type of @a cache doesn't support switching * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cc_switch(krb5_context context, krb5_ccache cache); /** * Determine whether a credential cache type supports switching. * * @param [in] context Library context * @param [in] type Credential cache type * * @version New in 1.10 * * @retval TRUE if @a type supports switching * @retval FALSE if it does not or is not a valid credential cache type. */ krb5_boolean KRB5_CALLCONV krb5_cc_support_switch(krb5_context context, const char *type); /** * Find a credential cache with a specified client principal. * * @param [in] context Library context * @param [in] client Client principal * @param [out] cache_out Credential cache handle * * Find a cache within the collection whose default principal is @a client. * Use @a krb5_cc_close to close @a ccache when it is no longer needed. * * @retval 0 Success * @retval KRB5_CC_NOTFOUND * * @sa krb5_cccol_cursor_new * * @version New in 1.10 */ krb5_error_code KRB5_CALLCONV krb5_cc_cache_match(krb5_context context, krb5_principal client, krb5_ccache *cache_out); /** * Select a credential cache to use with a server principal. * * @param [in] context Library context * @param [in] server Server principal * @param [out] cache_out Credential cache handle * @param [out] princ_out Client principal * * Select a cache within the collection containing credentials most appropriate * for use with @a server, according to configured rules and heuristics. * * Use krb5_cc_close() to release @a cache_out when it is no longer needed. * Use krb5_free_principal() to release @a princ_out when it is no longer * needed. Note that @a princ_out is set in some error conditions. * * @return * If an appropriate cache is found, 0 is returned, @a cache_out is set to the * selected cache, and @a princ_out is set to the default principal of that * cache. * * If the appropriate client principal can be authoritatively determined but * the cache collection contains no credentials for that principal, then * KRB5_CC_NOTFOUND is returned, @a cache_out is set to NULL, and @a princ_out * is set to the appropriate client principal. * * If no configured mechanism can determine the appropriate cache or principal, * KRB5_CC_NOTFOUND is returned and @a cache_out and @a princ_out are set to * NULL. * * Any other error code indicates a fatal error in the processing of a cache * selection mechanism. * * @version New in 1.10 */ krb5_error_code KRB5_CALLCONV krb5_cc_select(krb5_context context, krb5_principal server, krb5_ccache *cache_out, krb5_principal *princ_out); /* krb5_free.c */ /** * Free the storage assigned to a principal. * * @param [in] context Library context * @param [in] val Principal to be freed */ void KRB5_CALLCONV krb5_free_principal(krb5_context context, krb5_principal val); /** * Free a krb5_authenticator structure. * * @param [in] context Library context * @param [in] val Authenticator structure to be freed * * This function frees the contents of @a val and the structure itself. */ void KRB5_CALLCONV krb5_free_authenticator(krb5_context context, krb5_authenticator *val); /** * Free the data stored in array of addresses. * * @param [in] context Library context * @param [in] val Array of addresses to be freed * * This function frees the contents of @a val and the array itself. * * @note The last entry in the array must be a NULL pointer. */ void KRB5_CALLCONV krb5_free_addresses(krb5_context context, krb5_address **val); /** * Free the storage assigned to array of authentication data. * * @param [in] context Library context * @param [in] val Array of authentication data to be freed * * This function frees the contents of @a val and the array itself. * * @note The last entry in the array must be a NULL pointer. */ void KRB5_CALLCONV krb5_free_authdata(krb5_context context, krb5_authdata **val); /** * Free a ticket. * * @param [in] context Library context * @param [in] val Ticket to be freed * * This function frees the contents of @a val and the structure itself. */ void KRB5_CALLCONV krb5_free_ticket(krb5_context context, krb5_ticket *val); /** * Free an error allocated by krb5_read_error() or krb5_sendauth(). * * @param [in] context Library context * @param [in] val Error data structure to be freed * * This function frees the contents of @a val and the structure itself. */ void KRB5_CALLCONV krb5_free_error(krb5_context context, krb5_error *val); /** * Free a krb5_creds structure. * * @param [in] context Library context * @param [in] val Credential structure to be freed. * * This function frees the contents of @a val and the structure itself. */ void KRB5_CALLCONV krb5_free_creds(krb5_context context, krb5_creds *val); /** * Free the contents of a krb5_creds structure. * * @param [in] context Library context * @param [in] val Credential structure to free contents of * * This function frees the contents of @a val, but not the structure itself. */ void KRB5_CALLCONV krb5_free_cred_contents(krb5_context context, krb5_creds *val); /** * Free a krb5_checksum structure. * * @param [in] context Library context * @param [in] val Checksum structure to be freed * * This function frees the contents of @a val and the structure itself. */ void KRB5_CALLCONV krb5_free_checksum(krb5_context context, krb5_checksum *val); /** * Free the contents of a krb5_checksum structure. * * @param [in] context Library context * @param [in] val Checksum structure to free contents of * * This function frees the contents of @a val, but not the structure itself. */ void KRB5_CALLCONV krb5_free_checksum_contents(krb5_context context, krb5_checksum *val); /** * Free a krb5_keyblock structure. * * @param [in] context Library context * @param [in] val Keyblock to be freed * * This function frees the contents of @a val and the structure itself. */ void KRB5_CALLCONV krb5_free_keyblock(krb5_context context, krb5_keyblock *val); /** * Free the contents of a krb5_keyblock structure. * * @param [in] context Library context * @param [in] key Keyblock to be freed * * This function frees the contents of @a key, but not the structure itself. */ void KRB5_CALLCONV krb5_free_keyblock_contents(krb5_context context, krb5_keyblock *key); /** * Free a krb5_ap_rep_enc_part structure. * * @param [in] context Library context * @param [in] val AP-REP enc part to be freed * * This function frees the contents of @a val and the structure itself. */ void KRB5_CALLCONV krb5_free_ap_rep_enc_part(krb5_context context, krb5_ap_rep_enc_part *val); /** * Free a krb5_data structure. * * @param [in] context Library context * @param [in] val Data structure to be freed * * This function frees the contents of @a val and the structure itself. */ void KRB5_CALLCONV krb5_free_data(krb5_context context, krb5_data *val); /* Free a krb5_octet_data structure (should be unused). */ void KRB5_CALLCONV krb5_free_octet_data(krb5_context context, krb5_octet_data *val); /** * Free the contents of a krb5_data structure and zero the data field. * * @param [in] context Library context * @param [in] val Data structure to free contents of * * This function frees the contents of @a val, but not the structure itself. */ void KRB5_CALLCONV krb5_free_data_contents(krb5_context context, krb5_data *val); /** * Free a string representation of a principal. * * @param [in] context Library context * @param [in] val Name string to be freed */ void KRB5_CALLCONV krb5_free_unparsed_name(krb5_context context, char *val); /** * Free a string allocated by a krb5 function. * * @param [in] context Library context * @param [in] val String to be freed * * @version New in 1.10 */ void KRB5_CALLCONV krb5_free_string(krb5_context context, char *val); /** * Free an array of encryption types. * * @param [in] context Library context * @param [in] val Array of enctypes to be freed * * @version New in 1.12 */ void KRB5_CALLCONV krb5_free_enctypes(krb5_context context, krb5_enctype *val); /** * Free an array of checksum types. * * @param [in] context Library context * @param [in] val Array of checksum types to be freed */ void KRB5_CALLCONV krb5_free_cksumtypes(krb5_context context, krb5_cksumtype *val); /* From krb5/os, but needed by the outside world */ /** * Retrieve the system time of day, in sec and ms, since the epoch. * * @param [in] context Library context * @param [out] seconds System timeofday, seconds portion * @param [out] microseconds System timeofday, microseconds portion * * This function retrieves the system time of day with the context * specific time offset adjustment. * * @sa krb5_crypto_us_timeofday() * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_us_timeofday(krb5_context context, krb5_timestamp *seconds, krb5_int32 *microseconds); /** * Retrieve the current time with context specific time offset adjustment. * * @param [in] context Library context * @param [out] timeret Timestamp to fill in * * This function retrieves the system time of day with the context specific * time offset adjustment. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_timeofday(krb5_context context, krb5_timestamp *timeret); /** * Check if a timestamp is within the allowed clock skew of the current time. * * @param [in] context Library context * @param [in] date Timestamp to check * * This function checks if @a date is close enough to the current time * according to the configured allowable clock skew. * * @version New in 1.10 * * @retval 0 Success * @retval KRB5KRB_AP_ERR_SKEW @a date is not within allowable clock skew */ krb5_error_code KRB5_CALLCONV krb5_check_clockskew(krb5_context context, krb5_timestamp date); /** * Return all interface addresses for this host. * * @param [in] context Library context * @param [out] addr Array of krb5_address pointers, ending with * NULL * * Use krb5_free_addresses() to free @a addr when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_os_localaddr(krb5_context context, krb5_address ***addr); /** * Retrieve the default realm. * * @param [in] context Library context * @param [out] lrealm Default realm name * * Retrieves the default realm to be used if no user-specified realm is * available. * * Use krb5_free_default_realm() to free @a lrealm when it is no longer needed. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_default_realm(krb5_context context, char **lrealm); /** * Override the default realm for the specified context. * * @param [in] context Library context * @param [in] lrealm Realm name for the default realm * * If @a lrealm is NULL, clear the default realm setting. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_set_default_realm(krb5_context context, const char *lrealm); /** * Free a default realm string returned by krb5_get_default_realm(). * * @param [in] context Library context * @param [in] lrealm Realm to be freed */ void KRB5_CALLCONV krb5_free_default_realm(krb5_context context, char *lrealm); /** * Canonicalize a hostname, possibly using name service. * * @param [in] context Library context * @param [in] host Input hostname * @param [out] canonhost_out Canonicalized hostname * * This function canonicalizes orig_hostname, possibly using name service * lookups if configuration permits. Use krb5_free_string() to free @a * canonhost_out when it is no longer needed. * * @version New in 1.15 */ krb5_error_code KRB5_CALLCONV krb5_expand_hostname(krb5_context context, const char *host, char **canonhost_out); /** * Generate a full principal name from a service name. * * @param [in] context Library context * @param [in] hostname Host name, or NULL to use local host * @param [in] sname Service name, or NULL to use @c "host" * @param [in] type Principal type * @param [out] ret_princ Generated principal * * This function converts a @a hostname and @a sname into @a krb5_principal * structure @a ret_princ. The returned principal will be of the form @a * sname\/hostname\@REALM where REALM is determined by krb5_get_host_realm(). * In some cases this may be the referral (empty) realm. * * The @a type can be one of the following: * * @li #KRB5_NT_SRV_HST canonicalizes the host name before looking up the * realm and generating the principal. * * @li #KRB5_NT_UNKNOWN accepts the hostname as given, and does not * canonicalize it. * * Use krb5_free_principal to free @a ret_princ when it is no longer needed. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_sname_to_principal(krb5_context context, const char *hostname, const char *sname, krb5_int32 type, krb5_principal *ret_princ); /** * Test whether a principal matches a matching principal. * * @param [in] context Library context * @param [in] matching Matching principal * @param [in] princ Principal to test * * @note A matching principal is a host-based principal with an empty realm * and/or second data component (hostname). Profile configuration may cause * the hostname to be ignored even if it is present. A principal matches a * matching principal if the former has the same non-empty (and non-ignored) * components of the latter. * * If @a matching is NULL, return TRUE. If @a matching is not a matching * principal, return the value of krb5_principal_compare(context, matching, * princ). * * @return * TRUE if @a princ matches @a matching, FALSE otherwise. */ krb5_boolean KRB5_CALLCONV krb5_sname_match(krb5_context context, krb5_const_principal matching, krb5_const_principal princ); /** * Change a password for an existing Kerberos account. * * @param [in] context Library context * @param [in] creds Credentials for kadmin/changepw service * @param [in] newpw New password * @param [out] result_code Numeric error code from server * @param [out] result_code_string String equivalent to @a result_code * @param [out] result_string Change password response from the KDC * * Change the password for the existing principal identified by @a creds. * * The possible values of the output @a result_code are: * * @li #KRB5_KPASSWD_SUCCESS (0) - success * @li #KRB5_KPASSWD_MALFORMED (1) - Malformed request error * @li #KRB5_KPASSWD_HARDERROR (2) - Server error * @li #KRB5_KPASSWD_AUTHERROR (3) - Authentication error * @li #KRB5_KPASSWD_SOFTERROR (4) - Password change rejected * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_change_password(krb5_context context, krb5_creds *creds, const char *newpw, int *result_code, krb5_data *result_code_string, krb5_data *result_string); /** * Set a password for a principal using specified credentials. * * @param [in] context Library context * @param [in] creds Credentials for kadmin/changepw service * @param [in] newpw New password * @param [in] change_password_for Change the password for this principal * @param [out] result_code Numeric error code from server * @param [out] result_code_string String equivalent to @a result_code * @param [out] result_string Data returned from the remote system * * This function uses the credentials @a creds to set the password @a newpw for * the principal @a change_password_for. It implements the set password * operation of RFC 3244, for interoperability with Microsoft Windows * implementations. * * @note If @a change_password_for is NULL, the change is performed on the * current principal. If @a change_password_for is non-null, the change is * performed on the principal name passed in @a change_password_for. * * The error code and strings are returned in @a result_code, * @a result_code_string and @a result_string. * * @sa krb5_set_password_using_ccache() * * @retval * 0 Success and result_code is set to #KRB5_KPASSWD_SUCCESS. * @return * Kerberos error codes. */ krb5_error_code KRB5_CALLCONV krb5_set_password(krb5_context context, krb5_creds *creds, const char *newpw, krb5_principal change_password_for, int *result_code, krb5_data *result_code_string, krb5_data *result_string); /** * Set a password for a principal using cached credentials. * * @param [in] context Library context * @param [in] ccache Credential cache * @param [in] newpw New password * @param [in] change_password_for Change the password for this principal * @param [out] result_code Numeric error code from server * @param [out] result_code_string String equivalent to @a result_code * @param [out] result_string Data returned from the remote system * * This function uses the cached credentials from @a ccache to set the password * @a newpw for the principal @a change_password_for. It implements RFC 3244 * set password operation (interoperable with MS Windows implementations) using * the credential cache. * * The error code and strings are returned in @a result_code, * @a result_code_string and @a result_string. * * @note If @a change_password_for is set to NULL, the change is performed on * the default principal in @a ccache. If @a change_password_for is non null, * the change is performed on the specified principal. * * @sa krb5_set_password() * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_set_password_using_ccache(krb5_context context, krb5_ccache ccache, const char *newpw, krb5_principal change_password_for, int *result_code, krb5_data *result_code_string, krb5_data *result_string); /** * Get a result message for changing or setting a password. * * @param [in] context Library context * @param [in] server_string Data returned from the remote system * @param [out] message_out A message displayable to the user * * This function processes the @a server_string returned in the @a * result_string parameter of krb5_change_password(), krb5_set_password(), and * related functions, and returns a displayable string. If @a server_string * contains Active Directory structured policy information, it will be * converted into human-readable text. * * Use krb5_free_string() to free @a message_out when it is no longer needed. * * @retval * 0 Success * @return * Kerberos error codes * * @version New in 1.11 */ krb5_error_code KRB5_CALLCONV krb5_chpw_message(krb5_context context, const krb5_data *server_string, char **message_out); /** * Retrieve configuration profile from the context. * * @param [in] context Library context * @param [out] profile Pointer to data read from a configuration file * * This function creates a new @a profile object that reflects profile * in the supplied @a context. * * The @a profile object may be freed with profile_release() function. * See profile.h and profile API for more details. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_profile(krb5_context context, struct _profile_t ** profile); #if KRB5_DEPRECATED /** @deprecated Replaced by krb5_get_init_creds_password().*/ KRB5_ATTR_DEPRECATED krb5_error_code KRB5_CALLCONV krb5_get_in_tkt_with_password(krb5_context context, krb5_flags options, krb5_address *const *addrs, krb5_enctype *ktypes, krb5_preauthtype *pre_auth_types, const char *password, krb5_ccache ccache, krb5_creds *creds, krb5_kdc_rep **ret_as_reply); /** @deprecated Replaced by krb5_get_init_creds(). */ KRB5_ATTR_DEPRECATED krb5_error_code KRB5_CALLCONV krb5_get_in_tkt_with_skey(krb5_context context, krb5_flags options, krb5_address *const *addrs, krb5_enctype *ktypes, krb5_preauthtype *pre_auth_types, const krb5_keyblock *key, krb5_ccache ccache, krb5_creds *creds, krb5_kdc_rep **ret_as_reply); /** @deprecated Replaced by krb5_get_init_creds_keytab(). */ KRB5_ATTR_DEPRECATED krb5_error_code KRB5_CALLCONV krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options, krb5_address *const *addrs, krb5_enctype *ktypes, krb5_preauthtype *pre_auth_types, krb5_keytab arg_keytab, krb5_ccache ccache, krb5_creds *creds, krb5_kdc_rep **ret_as_reply); #endif /* KRB5_DEPRECATED */ /** * Parse and decrypt a @c KRB_AP_REQ message. * * @param [in] context Library context * @param [in,out] auth_context Pre-existing or newly created auth context * @param [in] inbuf AP-REQ message to be parsed * @param [in] server Matching principal for server, or NULL to * allow any principal in keytab * @param [in] keytab Key table, or NULL to use the default * @param [out] ap_req_options If non-null, the AP-REQ flags on output * @param [out] ticket If non-null, ticket from the AP-REQ message * * This function parses, decrypts and verifies a AP-REQ message from @a inbuf * and stores the authenticator in @a auth_context. * * If a keyblock was specified in @a auth_context using * krb5_auth_con_setuseruserkey(), that key is used to decrypt the ticket in * AP-REQ message and @a keytab is ignored. In this case, @a server should be * specified as a complete principal name to allow for proper transited-path * checking and replay cache selection. * * Otherwise, the decryption key is obtained from @a keytab, or from the * default keytab if it is NULL. In this case, @a server may be a complete * principal name, a matching principal (see krb5_sname_match()), or NULL to * match any principal name. The keys tried against the encrypted part of the * ticket are determined as follows: * * - If @a server is a complete principal name, then its entry in @a keytab is * tried. * - Otherwise, if @a keytab is iterable, then all entries in @a keytab which * match @a server are tried. * - Otherwise, the server principal in the ticket must match @a server, and * its entry in @a keytab is tried. * * The client specified in the decrypted authenticator must match the client * specified in the decrypted ticket. * * If the @a remote_addr field of @a auth_context is set, the request must come * from that address. * * If a replay cache handle is provided in the @a auth_context, the * authenticator and ticket are verified against it. If no conflict is found, * the new authenticator is then stored in the replay cache of @a auth_context. * * Various other checks are performed on the decoded data, including * cross-realm policy, clockskew, and ticket validation times. * * On success the authenticator, subkey, and remote sequence number of the * request are stored in @a auth_context. If the #AP_OPTS_MUTUAL_REQUIRED * bit is set, the local sequence number is XORed with the remote sequence * number in the request. * * Use krb5_free_ticket() to free @a ticket when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_rd_req(krb5_context context, krb5_auth_context *auth_context, const krb5_data *inbuf, krb5_const_principal server, krb5_keytab keytab, krb5_flags *ap_req_options, krb5_ticket **ticket); /** * Retrieve a service key from a key table. * * @param [in] context Library context * @param [in] keyprocarg Name of a key table (NULL to use default name) * @param [in] principal Service principal * @param [in] vno Key version number (0 for highest available) * @param [in] enctype Encryption type (0 for any type) * @param [out] key Service key from key table * * Open and search the specified key table for the entry identified by @a * principal, @a enctype, and @a vno. If no key is found, return an error code. * * The default key table is used, unless @a keyprocarg is non-null. * @a keyprocarg designates a specific key table. * * Use krb5_free_keyblock() to free @a key when it is no longer needed. * * @retval * 0 Success * @return Kerberos error code if not found or @a keyprocarg is invalid. */ krb5_error_code KRB5_CALLCONV krb5_kt_read_service_key(krb5_context context, krb5_pointer keyprocarg, krb5_principal principal, krb5_kvno vno, krb5_enctype enctype, krb5_keyblock **key); /** * Format a @c KRB-SAFE message. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] userdata User data in the message * @param [out] der_out Formatted @c KRB-SAFE buffer * @param [out] rdata_out Replay data. Specify NULL if not needed * * This function creates an integrity protected @c KRB-SAFE message * using data supplied by the application. * * Fields in @a auth_context specify the checksum type, the keyblock that * can be used to seed the checksum, full addresses (host and port) for * the sender and receiver, and @ref KRB5_AUTH_CONTEXT flags. * * The local address in @a auth_context must be set, and is used to form the * sender address used in the KRB-SAFE message. The remote address is * optional; if specified, it will be used to form the receiver address used in * the message. * * @note The @a rdata_out argument is required if the * #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set * in @a auth_context. * * If the #KRB5_AUTH_CONTEXT_DO_TIME flag is set in @a auth_context, a * timestamp is included in the KRB-SAFE message, and an entry for the message * is entered in an in-memory replay cache to detect if the message is * reflected by an attacker. If #KRB5_AUTH_CONTEXT_DO_TIME is not set, no * replay cache is used. If #KRB5_AUTH_CONTEXT_RET_TIME is set in @a * auth_context, a timestamp is included in the KRB-SAFE message and is stored * in @a rdata_out. * * If either #KRB5_AUTH_CONTEXT_DO_SEQUENCE or #KRB5_AUTH_CONTEXT_RET_SEQUENCE * is set, the @a auth_context local sequence number is included in the * KRB-SAFE message and then incremented. If #KRB5_AUTH_CONTEXT_RET_SEQUENCE * is set, the sequence number used is stored in @a rdata_out. * * Use krb5_free_data_contents() to free @a der_out when it is no longer * needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_mk_safe(krb5_context context, krb5_auth_context auth_context, const krb5_data *userdata, krb5_data *der_out, krb5_replay_data *rdata_out); /** * Format a @c KRB-PRIV message. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] userdata User data for @c KRB-PRIV message * @param [out] der_out Formatted @c KRB-PRIV message * @param [out] rdata_out Replay data (NULL if not needed) * * This function is similar to krb5_mk_safe(), but the message is encrypted and * integrity-protected, not just integrity-protected. * * The local address in @a auth_context must be set, and is used to form the * sender address used in the KRB-PRIV message. The remote address is * optional; if specified, it will be used to form the receiver address used in * the message. * * @note The @a rdata_out argument is required if the * #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set * in @a auth_context. * * If the #KRB5_AUTH_CONTEXT_DO_TIME flag is set in @a auth_context, a * timestamp is included in the KRB-PRIV message, and an entry for the message * is entered in an in-memory replay cache to detect if the message is * reflected by an attacker. If #KRB5_AUTH_CONTEXT_DO_TIME is not set, no * replay cache is used. If #KRB5_AUTH_CONTEXT_RET_TIME is set in @a * auth_context, a timestamp is included in the KRB-PRIV message and is stored * in @a rdata_out. * * If either #KRB5_AUTH_CONTEXT_DO_SEQUENCE or #KRB5_AUTH_CONTEXT_RET_SEQUENCE * is set, the @a auth_context local sequence number is included in the * KRB-PRIV message and then incremented. If #KRB5_AUTH_CONTEXT_RET_SEQUENCE * is set, the sequence number used is stored in @a rdata_out. * * Use krb5_free_data_contents() to free @a der_out when it is no longer * needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_mk_priv(krb5_context context, krb5_auth_context auth_context, const krb5_data *userdata, krb5_data *der_out, krb5_replay_data *rdata_out); /** * Client function for @c sendauth protocol. * * @param [in] context Library context * @param [in,out] auth_context Pre-existing or newly created auth context * @param [in] fd File descriptor that describes network socket * @param [in] appl_version Application protocol version to be matched * with the receiver's application version * @param [in] client Client principal * @param [in] server Server principal * @param [in] ap_req_options @ref AP_OPTS options * @param [in] in_data Data to be sent to the server * @param [in] in_creds Input credentials, or NULL to use @a ccache * @param [in] ccache Credential cache * @param [out] error If non-null, contains KRB_ERROR message * returned from server * @param [out] rep_result If non-null and @a ap_req_options is * #AP_OPTS_MUTUAL_REQUIRED, contains the result * of mutual authentication exchange * @param [out] out_creds If non-null, the retrieved credentials * * This function performs the client side of a sendauth/recvauth exchange by * sending and receiving messages over @a fd. * * Credentials may be specified in three ways: * * @li If @a in_creds is NULL, credentials are obtained with * krb5_get_credentials() using the principals @a client and @a server. @a * server must be non-null; @a client may NULL to use the default principal of * @a ccache. * * @li If @a in_creds is non-null, but does not contain a ticket, credentials * for the exchange are obtained with krb5_get_credentials() using @a in_creds. * In this case, the values of @a client and @a server are unused. * * @li If @a in_creds is a complete credentials structure, it used directly. * In this case, the values of @a client, @a server, and @a ccache are unused. * * If the server is using a different application protocol than that specified * in @a appl_version, an error will be returned. * * Use krb5_free_creds() to free @a out_creds, krb5_free_ap_rep_enc_part() to * free @a rep_result, and krb5_free_error() to free @a error when they are no * longer needed. * * @sa krb5_recvauth() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_sendauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointer fd, char *appl_version, krb5_principal client, krb5_principal server, krb5_flags ap_req_options, krb5_data *in_data, krb5_creds *in_creds, krb5_ccache ccache, krb5_error **error, krb5_ap_rep_enc_part **rep_result, krb5_creds **out_creds); /** * Server function for @a sendauth protocol. * * @param [in] context Library context * @param [in,out] auth_context Pre-existing or newly created auth context * @param [in] fd File descriptor * @param [in] appl_version Application protocol version to be matched * against the client's application version * @param [in] server Server principal (NULL for any in @a keytab) * @param [in] flags Additional specifications * @param [in] keytab Key table containing service keys * @param [out] ticket Ticket (NULL if not needed) * * This function performs the server side of a sendauth/recvauth exchange by * sending and receiving messages over @a fd. * * Use krb5_free_ticket() to free @a ticket when it is no longer needed. * * @sa krb5_sendauth() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_recvauth(krb5_context context, krb5_auth_context *auth_context, krb5_pointer fd, char *appl_version, krb5_principal server, krb5_int32 flags, krb5_keytab keytab, krb5_ticket **ticket); /** * Server function for @a sendauth protocol with version parameter. * * @param [in] context Library context * @param [in,out] auth_context Pre-existing or newly created auth context * @param [in] fd File descriptor * @param [in] server Server principal (NULL for any in @a keytab) * @param [in] flags Additional specifications * @param [in] keytab Decryption key * @param [out] ticket Ticket (NULL if not needed) * @param [out] version sendauth protocol version (NULL if not needed) * * This function is similar to krb5_recvauth() with the additional output * information place into @a version. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_recvauth_version(krb5_context context, krb5_auth_context *auth_context, krb5_pointer fd, krb5_principal server, krb5_int32 flags, krb5_keytab keytab, krb5_ticket **ticket, krb5_data *version); /** * Format a @c KRB-CRED message for an array of credentials. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] creds Null-terminated array of credentials * @param [out] der_out Encoded credentials * @param [out] rdata_out Replay cache information (NULL if not needed) * * This function takes an array of credentials @a creds and formats * a @c KRB-CRED message @a der_out to pass to krb5_rd_cred(). * * The local and remote addresses in @a auth_context are optional; if either is * specified, they are used to form the sender and receiver addresses in the * KRB-CRED message. * * @note The @a rdata_out argument is required if the * #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set * in @a auth_context. * * If the #KRB5_AUTH_CONTEXT_DO_TIME flag is set in @a auth_context, an entry * for the message is entered in an in-memory replay cache to detect if the * message is reflected by an attacker. If #KRB5_AUTH_CONTEXT_DO_TIME is not * set, no replay cache is used. If #KRB5_AUTH_CONTEXT_RET_TIME is set in @a * auth_context, the timestamp used for the KRB-CRED message is stored in @a * rdata_out. * * If either #KRB5_AUTH_CONTEXT_DO_SEQUENCE or #KRB5_AUTH_CONTEXT_RET_SEQUENCE * is set, the @a auth_context local sequence number is included in the * KRB-CRED message and then incremented. If #KRB5_AUTH_CONTEXT_RET_SEQUENCE * is set, the sequence number used is stored in @a rdata_out. * * Use krb5_free_data_contents() to free @a der_out when it is no longer * needed. * * The message will be encrypted using the send subkey of @a auth_context if it * is present, or the session key otherwise. If neither key is present, the * credentials will not be encrypted, and the message should only be sent over * a secure channel. No replay cache entry is used in this case. * * @retval * 0 Success * @retval * ENOMEM Insufficient memory * @retval * KRB5_RC_REQUIRED Message replay detection requires @a rcache parameter * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_mk_ncred(krb5_context context, krb5_auth_context auth_context, krb5_creds **creds, krb5_data **der_out, krb5_replay_data *rdata_out); /** * Format a @c KRB-CRED message for a single set of credentials. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] creds Pointer to credentials * @param [out] der_out Encoded credentials * @param [out] rdata_out Replay cache data (NULL if not needed) * * This is a convenience function that calls krb5_mk_ncred() with a single set * of credentials. * * @retval * 0 Success * @retval * ENOMEM Insufficient memory * @retval * KRB5_RC_REQUIRED Message replay detection requires @a rcache parameter * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_mk_1cred(krb5_context context, krb5_auth_context auth_context, krb5_creds *creds, krb5_data **der_out, krb5_replay_data *rdata_out); /** * Read and validate a @c KRB-CRED message. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] creddata @c KRB-CRED message * @param [out] creds_out Null-terminated array of forwarded credentials * @param [out] rdata_out Replay data (NULL if not needed) * * @note The @a rdata_out argument is required if the * #KRB5_AUTH_CONTEXT_RET_TIME or #KRB5_AUTH_CONTEXT_RET_SEQUENCE flag is set * in @a auth_context.` * * @a creddata will be decrypted using the receiving subkey if it is present in * @a auth_context, or the session key if the receiving subkey is not present * or fails to decrypt the message. * * Use krb5_free_tgt_creds() to free @a creds_out when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_rd_cred(krb5_context context, krb5_auth_context auth_context, krb5_data *creddata, krb5_creds ***creds_out, krb5_replay_data *rdata_out); /** * Get a forwarded TGT and format a @c KRB-CRED message. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] rhost Remote host * @param [in] client Client principal of TGT * @param [in] server Principal of server to receive TGT * @param [in] cc Credential cache handle (NULL to use default) * @param [in] forwardable Whether TGT should be forwardable * @param [out] outbuf KRB-CRED message * * Get a TGT for use at the remote host @a rhost and format it into a KRB-CRED * message. If @a rhost is NULL and @a server is of type #KRB5_NT_SRV_HST, * the second component of @a server will be used. * * @retval * 0 Success * @retval * ENOMEM Insufficient memory * @retval * KRB5_PRINC_NOMATCH Requested principal and ticket do not match * @retval * KRB5_NO_TKT_SUPPLIED Request did not supply a ticket * @retval * KRB5_CC_BADNAME Credential cache name or principal name malformed * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_fwd_tgt_creds(krb5_context context, krb5_auth_context auth_context, const char *rhost, krb5_principal client, krb5_principal server, krb5_ccache cc, int forwardable, krb5_data *outbuf); /** * Create and initialize an authentication context. * * @param [in] context Library context * @param [out] auth_context Authentication context * * This function creates an authentication context to hold configuration and * state relevant to krb5 functions for authenticating principals and * protecting messages once authentication has occurred. * * By default, flags for the context are set to enable the use of the replay * cache (#KRB5_AUTH_CONTEXT_DO_TIME), but not sequence numbers. Use * krb5_auth_con_setflags() to change the flags. * * The allocated @a auth_context must be freed with krb5_auth_con_free() when * it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_init(krb5_context context, krb5_auth_context *auth_context); /** * Free a krb5_auth_context structure. * * @param [in] context Library context * @param [in] auth_context Authentication context to be freed * * This function frees an auth context allocated by krb5_auth_con_init(). * * @retval 0 (always) */ krb5_error_code KRB5_CALLCONV krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context); /** * Set a flags field in a krb5_auth_context structure. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] flags Flags bit mask * * Valid values for @a flags are: * @li #KRB5_AUTH_CONTEXT_DO_TIME Use timestamps * @li #KRB5_AUTH_CONTEXT_RET_TIME Save timestamps * @li #KRB5_AUTH_CONTEXT_DO_SEQUENCE Use sequence numbers * @li #KRB5_AUTH_CONTEXT_RET_SEQUENCE Save sequence numbers * * @retval 0 (always) */ krb5_error_code KRB5_CALLCONV krb5_auth_con_setflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 flags); /** * Retrieve flags from a krb5_auth_context structure. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] flags Flags bit mask * * Valid values for @a flags are: * @li #KRB5_AUTH_CONTEXT_DO_TIME Use timestamps * @li #KRB5_AUTH_CONTEXT_RET_TIME Save timestamps * @li #KRB5_AUTH_CONTEXT_DO_SEQUENCE Use sequence numbers * @li #KRB5_AUTH_CONTEXT_RET_SEQUENCE Save sequence numbers * * @retval 0 (always) */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getflags(krb5_context context, krb5_auth_context auth_context, krb5_int32 *flags); /** * Set a checksum callback in an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] func Checksum callback * @param [in] data Callback argument * * Set a callback to obtain checksum data in krb5_mk_req(). The callback will * be invoked after the subkey and local sequence number are stored in @a * auth_context. * * @retval 0 (always) */ krb5_error_code KRB5_CALLCONV krb5_auth_con_set_checksum_func( krb5_context context, krb5_auth_context auth_context, krb5_mk_req_checksum_func func, void *data); /** * Get the checksum callback from an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] func Checksum callback * @param [out] data Callback argument * * @retval 0 (always) */ krb5_error_code KRB5_CALLCONV krb5_auth_con_get_checksum_func( krb5_context context, krb5_auth_context auth_context, krb5_mk_req_checksum_func *func, void **data); /** * Set the local and remote addresses in an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] local_addr Local address * @param [in] remote_addr Remote address * * This function releases the storage assigned to the contents of the local and * remote addresses of @a auth_context and then sets them to @a local_addr and * @a remote_addr respectively. * * @sa krb5_auth_con_genaddrs() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV_WRONG krb5_auth_con_setaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address *local_addr, krb5_address *remote_addr); /** * Retrieve address fields from an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] local_addr Local address (NULL if not needed) * @param [out] remote_addr Remote address (NULL if not needed) * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address **local_addr, krb5_address **remote_addr); /** * Set local and remote port fields in an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] local_port Local port * @param [in] remote_port Remote port * * This function releases the storage assigned to the contents of the local and * remote ports of @a auth_context and then sets them to @a local_port and @a * remote_port respectively. * * @sa krb5_auth_con_genaddrs() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_setports(krb5_context context, krb5_auth_context auth_context, krb5_address *local_port, krb5_address *remote_port); /** * Set the session key in an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] keyblock User key * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock *keyblock); /** * Retrieve the session key from an auth context as a keyblock. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] keyblock Session key * * This function creates a keyblock containing the session key from @a * auth_context. Use krb5_free_keyblock() to free @a keyblock when it is no * longer needed * * @retval 0 Success. Otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock); /** * Retrieve the session key from an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] key Session key * * This function sets @a key to the session key from @a auth_context. Use * krb5_k_free_key() to release @a key when it is no longer needed. * * @retval 0 (always) */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getkey_k(krb5_context context, krb5_auth_context auth_context, krb5_key *key); /** * Retrieve the send subkey from an auth context as a keyblock. * * @param [in] ctx Library context * @param [in] ac Authentication context * @param [out] keyblock Send subkey * * This function creates a keyblock containing the send subkey from @a * auth_context. Use krb5_free_keyblock() to free @a keyblock when it is no * longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock); /** * Retrieve the send subkey from an auth context. * * @param [in] ctx Library context * @param [in] ac Authentication context * @param [out] key Send subkey * * This function sets @a key to the send subkey from @a auth_context. Use * krb5_k_free_key() to release @a key when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getsendsubkey_k(krb5_context ctx, krb5_auth_context ac, krb5_key *key); /** * Retrieve the receiving subkey from an auth context as a keyblock. * * @param [in] ctx Library context * @param [in] ac Authentication context * @param [out] keyblock Receiving subkey * * This function creates a keyblock containing the receiving subkey from @a * auth_context. Use krb5_free_keyblock() to free @a keyblock when it is no * longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock **keyblock); /** * Retrieve the receiving subkey from an auth context as a keyblock. * * @param [in] ctx Library context * @param [in] ac Authentication context * @param [out] key Receiving subkey * * This function sets @a key to the receiving subkey from @a auth_context. Use * krb5_k_free_key() to release @a key when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getrecvsubkey_k(krb5_context ctx, krb5_auth_context ac, krb5_key *key); /** * Set the send subkey in an auth context with a keyblock. * * @param [in] ctx Library context * @param [in] ac Authentication context * @param [in] keyblock Send subkey * * This function sets the send subkey in @a ac to a copy of @a keyblock. * * @retval 0 Success. Otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_setsendsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock); /** * Set the send subkey in an auth context. * * @param [in] ctx Library context * @param [in] ac Authentication context * @param [out] key Send subkey * * This function sets the send subkey in @a ac to @a key, incrementing its * reference count. * * @version New in 1.9 * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_setsendsubkey_k(krb5_context ctx, krb5_auth_context ac, krb5_key key); /** * Set the receiving subkey in an auth context with a keyblock. * * @param [in] ctx Library context * @param [in] ac Authentication context * @param [in] keyblock Receiving subkey * * This function sets the receiving subkey in @a ac to a copy of @a keyblock. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_setrecvsubkey(krb5_context ctx, krb5_auth_context ac, krb5_keyblock *keyblock); /** * Set the receiving subkey in an auth context. * * @param [in] ctx Library context * @param [in] ac Authentication context * @param [in] key Receiving subkey * * This function sets the receiving subkey in @a ac to @a key, incrementing its * reference count. * * @version New in 1.9 * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_setrecvsubkey_k(krb5_context ctx, krb5_auth_context ac, krb5_key key); #if KRB5_DEPRECATED /** @deprecated Replaced by krb5_auth_con_getsendsubkey(). */ KRB5_ATTR_DEPRECATED krb5_error_code KRB5_CALLCONV krb5_auth_con_getlocalsubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock); /** @deprecated Replaced by krb5_auth_con_getrecvsubkey(). */ KRB5_ATTR_DEPRECATED krb5_error_code KRB5_CALLCONV krb5_auth_con_getremotesubkey(krb5_context context, krb5_auth_context auth_context, krb5_keyblock **keyblock); #endif /** * Retrieve the local sequence number from an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] seqnumber Local sequence number * * Retrieve the local sequence number from @a auth_context and return it in @a * seqnumber. The #KRB5_AUTH_CONTEXT_DO_SEQUENCE flag must be set in @a * auth_context for this function to be useful. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getlocalseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber); /** * Retrieve the remote sequence number from an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] seqnumber Remote sequence number * * Retrieve the remote sequence number from @a auth_context and return it in @a * seqnumber. The #KRB5_AUTH_CONTEXT_DO_SEQUENCE flag must be set in @a * auth_context for this function to be useful. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getremoteseqnumber(krb5_context context, krb5_auth_context auth_context, krb5_int32 *seqnumber); /** * Cause an auth context to use cipher state. * * @param [in] context Library context * @param [in] auth_context Authentication context * * Prepare @a auth_context to use cipher state when krb5_mk_priv() or * krb5_rd_priv() encrypt or decrypt data. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context); /** * Set the replay cache in an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] rcache Replay cache haddle * * This function sets the replay cache in @a auth_context to @a rcache. @a * rcache will be closed when @a auth_context is freed, so the caller should * relinquish that responsibility. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_setrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache rcache); /** * Retrieve the replay cache from an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] rcache Replay cache handle * * This function fetches the replay cache from @a auth_context. The caller * should not close @a rcache. * * @retval 0 (always) */ krb5_error_code KRB5_CALLCONV_WRONG krb5_auth_con_getrcache(krb5_context context, krb5_auth_context auth_context, krb5_rcache *rcache); /** * Retrieve the authenticator from an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [out] authenticator Authenticator * * Use krb5_free_authenticator() to free @a authenticator when it is no longer * needed. * * @retval 0 Success. Otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_getauthenticator(krb5_context context, krb5_auth_context auth_context, krb5_authenticator **authenticator); /** * Set checksum type in an an auth context. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] cksumtype Checksum type * * This function sets the checksum type in @a auth_context to be used by * krb5_mk_req() for the authenticator checksum. * * @retval 0 Success. Otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_set_req_cksumtype(krb5_context context, krb5_auth_context auth_context, krb5_cksumtype cksumtype); #define KRB5_REALM_BRANCH_CHAR '.' /* * end "func-proto.h" */ /* * begin stuff from libos.h */ /** * @brief Read a password from keyboard input. * * @param [in] context Library context * @param [in] prompt First user prompt when reading password * @param [in] prompt2 Second user prompt (NULL to prompt only once) * @param [out] return_pwd Returned password * @param [in,out] size_return On input, maximum size of password; on output, * size of password read * * This function reads a password from keyboard input and stores it in @a * return_pwd. @a size_return should be set by the caller to the amount of * storage space available in @a return_pwd; on successful return, it will be * set to the length of the password read. * * @a prompt is printed to the terminal, followed by ": ", and then a password * is read from the keyboard. * * If @a prompt2 is NULL, the password is read only once. Otherwise, @a * prompt2 is printed to the terminal and a second password is read. If the * two passwords entered are not identical, KRB5_LIBOS_BADPWDMATCH is returned. * * Echoing is turned off when the password is read. * * @retval * 0 Success * @return * Error in reading or verifying the password * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_read_password(krb5_context context, const char *prompt, const char *prompt2, char *return_pwd, unsigned int *size_return); /** * Convert a principal name to a local name. * * @param [in] context Library context * @param [in] aname Principal name * @param [in] lnsize_in Space available in @a lname * @param [out] lname Local name buffer to be filled in * * If @a aname does not correspond to any local account, KRB5_LNAME_NOTRANS is * returned. If @a lnsize_in is too small for the local name, * KRB5_CONFIG_NOTENUFSPACE is returned. * * Local names, rather than principal names, can be used by programs that * translate to an environment-specific name (for example, a user account * name). * * @retval * 0 Success * @retval * System errors * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_aname_to_localname(krb5_context context, krb5_const_principal aname, int lnsize_in, char *lname); /** * Get the Kerberos realm names for a host. * * @param [in] context Library context * @param [in] host Host name (or NULL) * @param [out] realmsp Null-terminated list of realm names * * Fill in @a realmsp with a pointer to a null-terminated list of realm names. * If there are no known realms for the host, a list containing the referral * (empty) realm is returned. * * If @a host is NULL, the local host's realms are determined. * * Use krb5_free_host_realm() to release @a realmsp when it is no longer * needed. * * @retval * 0 Success * @retval * ENOMEM Insufficient memory * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_host_realm(krb5_context context, const char *host, char ***realmsp); /** * * @param [in] context Library context * @param [in] hdata Host name (or NULL) * @param [out] realmsp Null-terminated list of realm names * * Fill in @a realmsp with a pointer to a null-terminated list of realm names * obtained through heuristics or insecure resolution methods which have lower * priority than KDC referrals. * * If @a host is NULL, the local host's realms are determined. * * Use krb5_free_host_realm() to release @a realmsp when it is no longer * needed. */ krb5_error_code KRB5_CALLCONV krb5_get_fallback_host_realm(krb5_context context, krb5_data *hdata, char ***realmsp); /** * Free the memory allocated by krb5_get_host_realm(). * * @param [in] context Library context * @param [in] realmlist List of realm names to be released * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_free_host_realm(krb5_context context, char *const *realmlist); /** * Determine if a principal is authorized to log in as a local user. * * @param [in] context Library context * @param [in] principal Principal name * @param [in] luser Local username * * Determine whether @a principal is authorized to log in as a local user @a * luser. * * @retval * TRUE Principal is authorized to log in as user; FALSE otherwise. */ krb5_boolean KRB5_CALLCONV krb5_kuserok(krb5_context context, krb5_principal principal, const char *luser); /** * Generate auth context addresses from a connected socket. * * @param [in] context Library context * @param [in] auth_context Authentication context * @param [in] infd Connected socket descriptor * @param [in] flags Flags * * This function sets the local and/or remote addresses in @a auth_context * based on the local and remote endpoints of the socket @a infd. The * following flags determine the operations performed: * * @li #KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR Generate local address. * @li #KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR Generate remote address. * @li #KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR Generate local address and port. * @li #KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR Generate remote address and port. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_auth_con_genaddrs(krb5_context context, krb5_auth_context auth_context, int infd, int flags); /** * Set time offset field in a krb5_context structure. * * @param [in] context Library context * @param [in] seconds Real time, seconds portion * @param [in] microseconds Real time, microseconds portion * * This function sets the time offset in @a context to the difference between * the system time and the real time as determined by @a seconds and @a * microseconds. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds); /** * Return the time offsets from the os context. * * @param [in] context Library context * @param [out] seconds Time offset, seconds portion * @param [out] microseconds Time offset, microseconds portion * * This function returns the time offsets in @a context. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_time_offsets(krb5_context context, krb5_timestamp *seconds, krb5_int32 *microseconds); /* str_conv.c */ /** * Convert a string to an encryption type. * * @param [in] string String to convert to an encryption type * @param [out] enctypep Encryption type * * @retval 0 Success; otherwise - EINVAL */ krb5_error_code KRB5_CALLCONV krb5_string_to_enctype(char *string, krb5_enctype *enctypep); /** * Convert a string to a salt type. * * @param [in] string String to convert to an encryption type * @param [out] salttypep Salt type to be filled in * * @retval 0 Success; otherwise - EINVAL */ krb5_error_code KRB5_CALLCONV krb5_string_to_salttype(char *string, krb5_int32 *salttypep); /** * Convert a string to a checksum type. * * @param [in] string String to be converted * @param [out] cksumtypep Checksum type to be filled in * * @retval 0 Success; otherwise - EINVAL */ krb5_error_code KRB5_CALLCONV krb5_string_to_cksumtype(char *string, krb5_cksumtype *cksumtypep); /** * Convert a string to a timestamp. * * @param [in] string String to be converted * @param [out] timestampp Pointer to timestamp * * @retval 0 Success; otherwise - EINVAL */ krb5_error_code KRB5_CALLCONV krb5_string_to_timestamp(char *string, krb5_timestamp *timestampp); /** * Convert a string to a delta time value. * * @param [in] string String to be converted * @param [out] deltatp Delta time to be filled in * * @retval 0 Success; otherwise - KRB5_DELTAT_BADFORMAT */ krb5_error_code KRB5_CALLCONV krb5_string_to_deltat(char *string, krb5_deltat *deltatp); /** * Convert an encryption type to a string. * * @param [in] enctype Encryption type * @param [out] buffer Buffer to hold encryption type string * @param [in] buflen Storage available in @a buffer * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_enctype_to_string(krb5_enctype enctype, char *buffer, size_t buflen); /** * Convert an encryption type to a name or alias. * * @param [in] enctype Encryption type * @param [in] shortest Flag * @param [out] buffer Buffer to hold encryption type string * @param [in] buflen Storage available in @a buffer * * If @a shortest is FALSE, this function returns the enctype's canonical name * (like "aes128-cts-hmac-sha1-96"). If @a shortest is TRUE, it return the * enctype's shortest alias (like "aes128-cts"). * * @version New in 1.9 * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_enctype_to_name(krb5_enctype enctype, krb5_boolean shortest, char *buffer, size_t buflen); /** * Convert a salt type to a string. * * @param [in] salttype Salttype to convert * @param [out] buffer Buffer to receive the converted string * @param [in] buflen Storage available in @a buffer * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_salttype_to_string(krb5_int32 salttype, char *buffer, size_t buflen); /** * Convert a checksum type to a string. * * @param [in] cksumtype Checksum type * @param [out] buffer Buffer to hold converted checksum type * @param [in] buflen Storage available in @a buffer * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_cksumtype_to_string(krb5_cksumtype cksumtype, char *buffer, size_t buflen); /** * Convert a timestamp to a string. * * @param [in] timestamp Timestamp to convert * @param [out] buffer Buffer to hold converted timestamp * @param [in] buflen Storage available in @a buffer * * The string is returned in the locale's appropriate date and time * representation. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_timestamp_to_string(krb5_timestamp timestamp, char *buffer, size_t buflen); /** * Convert a timestamp to a string, with optional output padding * * @param [in] timestamp Timestamp to convert * @param [out] buffer Buffer to hold the converted timestamp * @param [in] buflen Length of buffer * @param [in] pad Optional value to pad @a buffer if converted * timestamp does not fill it * * If @a pad is not NULL, @a buffer is padded out to @a buflen - 1 characters * with the value of *@a pad. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_timestamp_to_sfstring(krb5_timestamp timestamp, char *buffer, size_t buflen, char *pad); /** * Convert a relative time value to a string. * * @param [in] deltat Relative time value to convert * @param [out] buffer Buffer to hold time string * @param [in] buflen Storage available in @a buffer * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_deltat_to_string(krb5_deltat deltat, char *buffer, size_t buflen); /* The name of the Kerberos ticket granting service... and its size */ #define KRB5_TGS_NAME "krbtgt" #define KRB5_TGS_NAME_SIZE 6 /* flags for recvauth */ #define KRB5_RECVAUTH_SKIP_VERSION 0x0001 #define KRB5_RECVAUTH_BADAUTHVERS 0x0002 /* initial ticket api functions */ /** Text for prompt used in prompter callback function. */ typedef struct _krb5_prompt { char *prompt; /**< The prompt to show to the user */ int hidden; /**< Boolean; informative prompt or hidden (e.g. PIN) */ krb5_data *reply; /**< Must be allocated before call to prompt routine */ } krb5_prompt; /** Pointer to a prompter callback function. */ typedef krb5_error_code (KRB5_CALLCONV *krb5_prompter_fct)(krb5_context context, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]); /** * Prompt user for password. * * @param [in] context Library context * @param data Unused (callback argument) * @param [in] name Name to output during prompt * @param [in] banner Banner to output during prompt * @param [in] num_prompts Number of prompts in @a prompts * @param [in] prompts Array of prompts and replies * * This function is intended to be used as a prompter callback for * krb5_get_init_creds_password() or krb5_init_creds_init(). * * Writes @a name and @a banner to stdout, each followed by a newline, then * writes each prompt field in the @a prompts array, followed by ": ", and sets * the reply field of the entry to a line of input read from stdin. If the * hidden flag is set for a prompt, then terminal echoing is turned off when * input is read. * * @retval * 0 Success * @return * Kerberos error codes * */ krb5_error_code KRB5_CALLCONV krb5_prompter_posix(krb5_context context, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]); /** * Long-term password responder question * * This question is asked when the long-term password is needed. It has no * challenge and the response is simply the password string. * * @version New in 1.11 */ #define KRB5_RESPONDER_QUESTION_PASSWORD "password" /** * OTP responder question * * The OTP responder question is asked when the KDC indicates that an OTP * value is required in order to complete the authentication. The JSON format * of the challenge is: * * @n { * @n "service": <string (optional)>, * @n "tokenInfo": [ * @n { * @n "flags": <number>, * @n "vendor": <string (optional)>, * @n "challenge": <string (optional)>, * @n "length": <number (optional)>, * @n "format": <number (optional)>, * @n "tokenID": <string (optional)>, * @n "algID": <string (optional)>, * @n }, * @n ... * @n ] * @n } * * The answer to the question MUST be JSON formatted: * * @n { * @n "tokeninfo": <number>, * @n "value": <string (optional)>, * @n "pin": <string (optional)>, * @n } * * For more detail, please see RFC 6560. * * @version New in 1.11 */ #define KRB5_RESPONDER_QUESTION_OTP "otp" /** * These format constants identify the format of the token value. */ #define KRB5_RESPONDER_OTP_FORMAT_DECIMAL 0 #define KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL 1 #define KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC 2 /** * This flag indicates that the token value MUST be collected. */ #define KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN 0x0001 /** * This flag indicates that the PIN value MUST be collected. */ #define KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN 0x0002 /** * This flag indicates that the token is now in re-synchronization mode with * the server. The user is expected to reply with the next code displayed on * the token. */ #define KRB5_RESPONDER_OTP_FLAGS_NEXTOTP 0x0004 /** * This flag indicates that the PIN MUST be returned as a separate item. This * flag only takes effect if KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN is set. If * this flag is not set, the responder may either concatenate PIN + token value * and store it as "value" in the answer or it may return them separately. If * they are returned separately, they will be concatenated internally. */ #define KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN 0x0008 /** * PKINIT responder question * * The PKINIT responder question is asked when the client needs a password * that's being used to protect key information, and is formatted as a JSON * object. A specific identity's flags value, if not zero, is the bitwise-OR * of one or more of the KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_* flags defined * below, and possibly other flags to be added later. Any resemblance to * similarly-named CKF_* values in the PKCS#11 API should not be depended on. * * @n { * @n identity <string> : flags <number>, * @n ... * @n } * * The answer to the question MUST be JSON formatted: * * @n { * @n identity <string> : password <string>, * @n ... * @n } * * @version New in 1.12 */ #define KRB5_RESPONDER_QUESTION_PKINIT "pkinit" /** * This flag indicates that an incorrect PIN was supplied at least once since * the last time the correct PIN was supplied. */ #define KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_COUNT_LOW (1 << 0) /** * This flag indicates that supplying an incorrect PIN will cause the token to * lock itself. */ #define KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_FINAL_TRY (1 << 1) /** * This flag indicates that the user PIN is locked, and you can't log in to the * token with it. */ #define KRB5_RESPONDER_PKINIT_FLAGS_TOKEN_USER_PIN_LOCKED (1 << 2) /** * A container for a set of preauthentication questions and answers * * A responder context is supplied by the krb5 authentication system to a @ref * krb5_responder_fn callback. It contains a list of questions and can receive * answers. Questions contained in a responder context can be listed using * krb5_responder_list_questions(), retrieved using * krb5_responder_get_challenge(), or answered using * krb5_responder_set_answer(). The form of a question's challenge and * answer depend on the question name. * * @version New in 1.11 */ typedef struct krb5_responder_context_st *krb5_responder_context; /** * List the question names contained in the responder context. * * @param [in] ctx Library context * @param [in] rctx Responder context * * Return a pointer to a null-terminated list of question names which are * present in @a rctx. The pointer is an alias, valid only as long as the * lifetime of @a rctx, and should not be modified or freed by the caller. A * question's challenge can be retrieved using krb5_responder_get_challenge() * and answered using krb5_responder_set_answer(). * * @version New in 1.11 */ const char * const * KRB5_CALLCONV krb5_responder_list_questions(krb5_context ctx, krb5_responder_context rctx); /** * Retrieve the challenge data for a given question in the responder context. * * @param [in] ctx Library context * @param [in] rctx Responder context * @param [in] question Question name * * Return a pointer to a C string containing the challenge for @a question * within @a rctx, or NULL if the question is not present in @a rctx. The * structure of the question depends on the question name, but will always be * printable UTF-8 text. The returned pointer is an alias, valid only as long * as the lifetime of @a rctx, and should not be modified or freed by the * caller. * * @version New in 1.11 */ const char * KRB5_CALLCONV krb5_responder_get_challenge(krb5_context ctx, krb5_responder_context rctx, const char *question); /** * Answer a named question in the responder context. * * @param [in] ctx Library context * @param [in] rctx Responder context * @param [in] question Question name * @param [in] answer The string to set (MUST be printable UTF-8) * * This function supplies an answer to @a question within @a rctx. The * appropriate form of the answer depends on the question name. * * @retval EINVAL @a question is not present within @a rctx * * @version New in 1.11 */ krb5_error_code KRB5_CALLCONV krb5_responder_set_answer(krb5_context ctx, krb5_responder_context rctx, const char *question, const char *answer); /** * Responder function for an initial credential exchange. * * @param [in] ctx Library context * @param [in] data Callback data * @param [in] rctx Responder context * * A responder function is like a prompter function, but is used for handling * questions and answers as potentially complex data types. Client * preauthentication modules will insert a set of named "questions" into * the responder context. Each question may optionally contain a challenge. * This challenge is printable UTF-8, but may be an encoded value. The * precise encoding and contents of the challenge are specific to the question * asked. When the responder is called, it should answer all the questions it * understands. Like the challenge, the answer MUST be printable UTF-8, but * may contain structured/encoded data formatted to the expected answer format * of the question. * * If a required question is unanswered, the prompter may be called. */ typedef krb5_error_code (KRB5_CALLCONV *krb5_responder_fn)(krb5_context ctx, void *data, krb5_responder_context rctx); typedef struct _krb5_responder_otp_tokeninfo { krb5_flags flags; krb5_int32 format; /* -1 when not specified. */ krb5_int32 length; /* -1 when not specified. */ char *vendor; char *challenge; char *token_id; char *alg_id; } krb5_responder_otp_tokeninfo; typedef struct _krb5_responder_otp_challenge { char *service; krb5_responder_otp_tokeninfo **tokeninfo; } krb5_responder_otp_challenge; /** * Decode the KRB5_RESPONDER_QUESTION_OTP to a C struct. * * A convenience function which parses the KRB5_RESPONDER_QUESTION_OTP * question challenge data, making it available in native C. The main feature * of this function is the ability to interact with OTP tokens without parsing * the JSON. * * The returned value must be passed to krb5_responder_otp_challenge_free() to * be freed. * * @param [in] ctx Library context * @param [in] rctx Responder context * @param [out] chl Challenge structure * * @version New in 1.11 */ krb5_error_code KRB5_CALLCONV krb5_responder_otp_get_challenge(krb5_context ctx, krb5_responder_context rctx, krb5_responder_otp_challenge **chl); /** * Answer the KRB5_RESPONDER_QUESTION_OTP question. * * @param [in] ctx Library context * @param [in] rctx Responder context * @param [in] ti The index of the tokeninfo selected * @param [in] value The value to set, or NULL for none * @param [in] pin The pin to set, or NULL for none * * @version New in 1.11 */ krb5_error_code KRB5_CALLCONV krb5_responder_otp_set_answer(krb5_context ctx, krb5_responder_context rctx, size_t ti, const char *value, const char *pin); /** * Free the value returned by krb5_responder_otp_get_challenge(). * * @param [in] ctx Library context * @param [in] rctx Responder context * @param [in] chl The challenge to free * * @version New in 1.11 */ void KRB5_CALLCONV krb5_responder_otp_challenge_free(krb5_context ctx, krb5_responder_context rctx, krb5_responder_otp_challenge *chl); typedef struct _krb5_responder_pkinit_identity { char *identity; krb5_int32 token_flags; /* 0 when not specified or not applicable. */ } krb5_responder_pkinit_identity; typedef struct _krb5_responder_pkinit_challenge { krb5_responder_pkinit_identity **identities; } krb5_responder_pkinit_challenge; /** * Decode the KRB5_RESPONDER_QUESTION_PKINIT to a C struct. * * A convenience function which parses the KRB5_RESPONDER_QUESTION_PKINIT * question challenge data, making it available in native C. The main feature * of this function is the ability to read the challenge without parsing * the JSON. * * The returned value must be passed to krb5_responder_pkinit_challenge_free() * to be freed. * * @param [in] ctx Library context * @param [in] rctx Responder context * @param [out] chl_out Challenge structure * * @version New in 1.12 */ krb5_error_code KRB5_CALLCONV krb5_responder_pkinit_get_challenge(krb5_context ctx, krb5_responder_context rctx, krb5_responder_pkinit_challenge **chl_out); /** * Answer the KRB5_RESPONDER_QUESTION_PKINIT question for one identity. * * @param [in] ctx Library context * @param [in] rctx Responder context * @param [in] identity The identity for which a PIN is being supplied * @param [in] pin The provided PIN, or NULL for none * * @version New in 1.12 */ krb5_error_code KRB5_CALLCONV krb5_responder_pkinit_set_answer(krb5_context ctx, krb5_responder_context rctx, const char *identity, const char *pin); /** * Free the value returned by krb5_responder_pkinit_get_challenge(). * * @param [in] ctx Library context * @param [in] rctx Responder context * @param [in] chl The challenge to free * * @version New in 1.12 */ void KRB5_CALLCONV krb5_responder_pkinit_challenge_free(krb5_context ctx, krb5_responder_context rctx, krb5_responder_pkinit_challenge *chl); /** Store options for @c _krb5_get_init_creds */ typedef struct _krb5_get_init_creds_opt { krb5_flags flags; krb5_deltat tkt_life; krb5_deltat renew_life; int forwardable; int proxiable; krb5_enctype *etype_list; int etype_list_length; krb5_address **address_list; krb5_preauthtype *preauth_list; int preauth_list_length; krb5_data *salt; } krb5_get_init_creds_opt; #define KRB5_GET_INIT_CREDS_OPT_TKT_LIFE 0x0001 #define KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE 0x0002 #define KRB5_GET_INIT_CREDS_OPT_FORWARDABLE 0x0004 #define KRB5_GET_INIT_CREDS_OPT_PROXIABLE 0x0008 #define KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST 0x0010 #define KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST 0x0020 #define KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST 0x0040 #define KRB5_GET_INIT_CREDS_OPT_SALT 0x0080 #define KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT 0x0100 #define KRB5_GET_INIT_CREDS_OPT_CANONICALIZE 0x0200 #define KRB5_GET_INIT_CREDS_OPT_ANONYMOUS 0x0400 /** * Allocate a new initial credential options structure. * * @param [in] context Library context * @param [out] opt New options structure * * This function is the preferred way to create an options structure for * getting initial credentials, and is required to make use of certain options. * Use krb5_get_init_creds_opt_free() to free @a opt when it is no longer * needed. * * @retval 0 - Success; Kerberos errors otherwise. */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_alloc(krb5_context context, krb5_get_init_creds_opt **opt); /** * Free initial credential options. * * @param [in] context Library context * @param [in] opt Options structure to free * * @sa krb5_get_init_creds_opt_alloc() */ void KRB5_CALLCONV krb5_get_init_creds_opt_free(krb5_context context, krb5_get_init_creds_opt *opt); /** @deprecated Use krb5_get_init_creds_opt_alloc() instead. */ void KRB5_CALLCONV krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt); /** * Set the ticket lifetime in initial credential options. * * @param [in] opt Options structure * @param [in] tkt_life Ticket lifetime */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_tkt_life(krb5_get_init_creds_opt *opt, krb5_deltat tkt_life); /** * Set the ticket renewal lifetime in initial credential options. * * @param [in] opt Pointer to @a options field * @param [in] renew_life Ticket renewal lifetime */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_renew_life(krb5_get_init_creds_opt *opt, krb5_deltat renew_life); /** * Set or unset the forwardable flag in initial credential options. * * @param [in] opt Options structure * @param [in] forwardable Whether credentials should be forwardable */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_forwardable(krb5_get_init_creds_opt *opt, int forwardable); /** * Set or unset the proxiable flag in initial credential options. * * @param [in] opt Options structure * @param [in] proxiable Whether credentials should be proxiable */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_proxiable(krb5_get_init_creds_opt *opt, int proxiable); /** * Set or unset the canonicalize flag in initial credential options. * * @param [in] opt Options structure * @param [in] canonicalize Whether to canonicalize client principal */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_canonicalize(krb5_get_init_creds_opt *opt, int canonicalize); /** * Set or unset the anonymous flag in initial credential options. * * @param [in] opt Options structure * @param [in] anonymous Whether to make an anonymous request * * This function may be used to request anonymous credentials from the KDC by * setting @a anonymous to non-zero. Note that anonymous credentials are only * a request; clients must verify that credentials are anonymous if that is a * requirement. */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_anonymous(krb5_get_init_creds_opt *opt, int anonymous); /** * Set allowable encryption types in initial credential options. * * @param [in] opt Options structure * @param [in] etype_list Array of encryption types * @param [in] etype_list_length Length of @a etype_list */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_etype_list(krb5_get_init_creds_opt *opt, krb5_enctype *etype_list, int etype_list_length); /** * Set address restrictions in initial credential options. * * @param [in] opt Options structure * @param [in] addresses Null-terminated array of addresses */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_address_list(krb5_get_init_creds_opt *opt, krb5_address **addresses); /** * Set preauthentication types in initial credential options. * * @param [in] opt Options structure * @param [in] preauth_list Array of preauthentication types * @param [in] preauth_list_length Length of @a preauth_list * * This function can be used to perform optimistic preauthentication when * getting initial credentials, in combination with * krb5_get_init_creds_opt_set_salt() and krb5_get_init_creds_opt_set_pa(). */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt, krb5_preauthtype *preauth_list, int preauth_list_length); /** * Set salt for optimistic preauthentication in initial credential options. * * @param [in] opt Options structure * @param [in] salt Salt data * * When getting initial credentials with a password, a salt string it used to * convert the password to a key. Normally this salt is obtained from the * first KDC reply, but when performing optimistic preauthentication, the * client may need to supply the salt string with this function. */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt, krb5_data *salt); /** * Set or unset change-password-prompt flag in initial credential options. * * @param [in] opt Options structure * @param [in] prompt Whether to prompt to change password * * This flag is on by default. It controls whether * krb5_get_init_creds_password() will react to an expired-password error by * prompting for a new password and attempting to change the old one. */ void KRB5_CALLCONV krb5_get_init_creds_opt_set_change_password_prompt(krb5_get_init_creds_opt *opt, int prompt); /** Generic preauth option attribute/value pairs */ typedef struct _krb5_gic_opt_pa_data { char *attr; char *value; } krb5_gic_opt_pa_data; /** * Supply options for preauthentication in initial credential options. * * @param [in] context Library context * @param [in] opt Options structure * @param [in] attr Preauthentication option name * @param [in] value Preauthentication option value * * This function allows the caller to supply options for preauthentication. * The values of @a attr and @a value are supplied to each preauthentication * module available within @a context. */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_pa(krb5_context context, krb5_get_init_creds_opt *opt, const char *attr, const char *value); /** * Set location of FAST armor ccache in initial credential options. * * @param [in] context Library context * @param [in] opt Options * @param [in] fast_ccache_name Credential cache name * * Sets the location of a credential cache containing an armor ticket to * protect an initial credential exchange using the FAST protocol extension. * * In version 1.7, setting an armor ccache requires that FAST be used for the * exchange. In version 1.8 or later, setting the armor ccache causes FAST to * be used if the KDC supports it; krb5_get_init_creds_opt_set_fast_flags() * must be used to require that FAST be used. */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_fast_ccache_name(krb5_context context, krb5_get_init_creds_opt *opt, const char *fast_ccache_name); /** * Set FAST armor cache in initial credential options. * * @param [in] context Library context * @param [in] opt Options * @param [in] ccache Credential cache handle * * This function is similar to krb5_get_init_creds_opt_set_fast_ccache_name(), * but uses a credential cache handle instead of a name. * * @version New in 1.9 */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_fast_ccache(krb5_context context, krb5_get_init_creds_opt *opt, krb5_ccache ccache); /** * Set an input credential cache in initial credential options. * * @param [in] context Library context * @param [in] opt Options * @param [in] ccache Credential cache handle * * If an input credential cache is set, then the krb5_get_init_creds family of * APIs will read settings from it. Setting an input ccache is desirable when * the application wishes to perform authentication in the same way (using the * same preauthentication mechanisms, and making the same non-security- * sensitive choices) as the previous authentication attempt, which stored * information in the passed-in ccache. * * @version New in 1.11 */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_in_ccache(krb5_context context, krb5_get_init_creds_opt *opt, krb5_ccache ccache); /** * Set an output credential cache in initial credential options. * * @param [in] context Library context * @param [in] opt Options * @param [in] ccache Credential cache handle * * If an output credential cache is set, then the krb5_get_init_creds family of * APIs will write credentials to it. Setting an output ccache is desirable * both because it simplifies calling code and because it permits the * krb5_get_init_creds APIs to write out configuration information about the * realm to the ccache. */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_out_ccache(krb5_context context, krb5_get_init_creds_opt *opt, krb5_ccache ccache); /** * @brief Ask the KDC to include or not include a PAC in the ticket * * @param [in] context Library context * @param [in] opt Options structure * @param [in] req_pac Whether to request a PAC or not * * If this option is set, the AS request will include a PAC-REQUEST pa-data * item explicitly asking the KDC to either include or not include a privilege * attribute certificate in the ticket authorization data. By default, no * request is made; typically the KDC will default to including a PAC if it * supports them. * * @version New in 1.15 */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_pac_request(krb5_context context, krb5_get_init_creds_opt *opt, krb5_boolean req_pac); /** * Set FAST flags in initial credential options. * * @param [in] context Library context * @param [in] opt Options * @param [in] flags FAST flags * * The following flag values are valid: * @li #KRB5_FAST_REQUIRED - Require FAST to be used * * @retval * 0 - Success; Kerberos errors otherwise. */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_fast_flags(krb5_context context, krb5_get_init_creds_opt *opt, krb5_flags flags); /** * Retrieve FAST flags from initial credential options. * * @param [in] context Library context * @param [in] opt Options * @param [out] out_flags FAST flags * * @retval * 0 - Success; Kerberos errors otherwise. */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_get_fast_flags(krb5_context context, krb5_get_init_creds_opt *opt, krb5_flags *out_flags); /* Fast flags*/ #define KRB5_FAST_REQUIRED 0x0001 /**< Require KDC to support FAST*/ typedef void (KRB5_CALLCONV *krb5_expire_callback_func)(krb5_context context, void *data, krb5_timestamp password_expiration, krb5_timestamp account_expiration, krb5_boolean is_last_req); /** * Set an expiration callback in initial credential options. * * @param [in] context Library context * @param [in] opt Options structure * @param [in] cb Callback function * @param [in] data Callback argument * * Set a callback to receive password and account expiration times. * * @a cb will be invoked if and only if credentials are successfully acquired. * The callback will receive the @a context from the calling function and the * @a data argument supplied with this API. The remaining arguments should be * interpreted as follows: * * If @a is_last_req is true, then the KDC reply contained last-req entries * which unambiguously indicated the password expiration, account expiration, * or both. (If either value was not present, the corresponding argument will * be 0.) Furthermore, a non-zero @a password_expiration should be taken as a * suggestion from the KDC that a warning be displayed. * * If @a is_last_req is false, then @a account_expiration will be 0 and @a * password_expiration will contain the expiration time of either the password * or account, or 0 if no expiration time was indicated in the KDC reply. The * callback should independently decide whether to display a password * expiration warning. * * Note that @a cb may be invoked even if credentials are being acquired for * the kadmin/changepw service in order to change the password. It is the * caller's responsibility to avoid displaying a password expiry warning in * this case. * * @warning Setting an expire callback with this API will cause * krb5_get_init_creds_password() not to send password expiry warnings to the * prompter, as it ordinarily may. * * @version New in 1.9 */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_expire_callback(krb5_context context, krb5_get_init_creds_opt *opt, krb5_expire_callback_func cb, void *data); /** * Set the responder function in initial credential options. * * @param [in] context Library context * @param [in] opt Options structure * @param [in] responder Responder function * @param [in] data Responder data argument * * @version New in 1.11 */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_set_responder(krb5_context context, krb5_get_init_creds_opt *opt, krb5_responder_fn responder, void *data); /** * Get initial credentials using a password. * * @param [in] context Library context * @param [out] creds New credentials * @param [in] client Client principal * @param [in] password Password (or NULL) * @param [in] prompter Prompter function * @param [in] data Prompter callback data * @param [in] start_time Time when ticket becomes valid (0 for now) * @param [in] in_tkt_service Service name of initial credentials (or NULL) * @param [in] k5_gic_options Initial credential options * * This function requests KDC for an initial credentials for @a client using @a * password. If @a password is NULL, a password will be prompted for using @a * prompter if necessary. If @a in_tkt_service is specified, it is parsed as a * principal name (with the realm ignored) and used as the service principal * for the request; otherwise the ticket-granting service is used. * * @sa krb5_verify_init_creds() * * @retval * 0 Success * @retval * EINVAL Invalid argument * @retval * KRB5_KDC_UNREACH Cannot contact any KDC for requested realm * @retval * KRB5_PREAUTH_FAILED Generic Pre-athentication failure * @retval * KRB5_LIBOS_PWDINTR Password read interrupted * @retval * KRB5_REALM_CANT_RESOLVE Cannot resolve network address for KDC in requested realm * @retval * KRB5KDC_ERR_KEY_EXP Password has expired * @retval * KRB5_LIBOS_BADPWDMATCH Password mismatch * @retval * KRB5_CHPW_PWDNULL New password cannot be zero length * @retval * KRB5_CHPW_FAIL Password change failed * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_password(krb5_context context, krb5_creds *creds, krb5_principal client, const char *password, krb5_prompter_fct prompter, void *data, krb5_deltat start_time, const char *in_tkt_service, krb5_get_init_creds_opt *k5_gic_options); /** * Retrieve enctype, salt and s2kparams from KDC * * @param [in] context Library context * @param [in] principal Principal whose information is requested * @param [in] opt Initial credential options * @param [out] enctype_out The enctype chosen by KDC * @param [out] salt_out Salt returned from KDC * @param [out] s2kparams_out String-to-key parameters returned from KDC * * Send an initial ticket request for @a principal and extract the encryption * type, salt type, and string-to-key parameters from the KDC response. If the * KDC provides no etype-info, set @a enctype_out to @c ENCTYPE_NULL and set @a * salt_out and @a s2kparams_out to empty. If the KDC etype-info provides no * salt, compute the default salt and place it in @a salt_out. If the KDC * etype-info provides no string-to-key parameters, set @a s2kparams_out to * empty. * * @a opt may be used to specify options which affect the initial request, such * as request encryption types or a FAST armor cache (see * krb5_get_init_creds_opt_set_etype_list() and * krb5_get_init_creds_opt_set_fast_ccache_name()). * * Use krb5_free_data_contents() to free @a salt_out and @a s2kparams_out when * they are no longer needed. * * @version New in 1.17 * * @retval 0 Success * @return A Kerberos error code */ krb5_error_code KRB5_CALLCONV krb5_get_etype_info(krb5_context context, krb5_principal principal, krb5_get_init_creds_opt *opt, krb5_enctype *enctype_out, krb5_data *salt_out, krb5_data *s2kparams_out); struct _krb5_init_creds_context; typedef struct _krb5_init_creds_context *krb5_init_creds_context; #define KRB5_INIT_CREDS_STEP_FLAG_CONTINUE 0x1 /**< More responses needed */ /** * Free an initial credentials context. * * @param [in] context Library context * @param [in] ctx Initial credentials context * * @a context must be the same as the one passed to krb5_init_creds_init() for * this initial credentials context. */ void KRB5_CALLCONV krb5_init_creds_free(krb5_context context, krb5_init_creds_context ctx); /** * Acquire credentials using an initial credentials context. * * @param [in] context Library context * @param [in] ctx Initial credentials context * * This function synchronously obtains credentials using a context created by * krb5_init_creds_init(). On successful return, the credentials can be * retrieved with krb5_init_creds_get_creds(). * * @a context must be the same as the one passed to krb5_init_creds_init() for * this initial credentials context. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_creds_get(krb5_context context, krb5_init_creds_context ctx); /** * Retrieve acquired credentials from an initial credentials context. * * @param [in] context Library context * @param [in] ctx Initial credentials context * @param [out] creds Acquired credentials * * This function copies the acquired initial credentials from @a ctx into @a * creds, after the successful completion of krb5_init_creds_get() or * krb5_init_creds_step(). Use krb5_free_cred_contents() to free @a creds when * it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_creds_get_creds(krb5_context context, krb5_init_creds_context ctx, krb5_creds *creds); /** * Get the last error from KDC from an initial credentials context. * * @param [in] context Library context * @param [in] ctx Initial credentials context * @param [out] error Error from KDC, or NULL if none was received * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_creds_get_error(krb5_context context, krb5_init_creds_context ctx, krb5_error **error); /** * Create a context for acquiring initial credentials. * * @param [in] context Library context * @param [in] client Client principal to get initial creds for * @param [in] prompter Prompter callback * @param [in] data Prompter callback argument * @param [in] start_time Time when credentials become valid (0 for now) * @param [in] options Options structure (NULL for default) * @param [out] ctx New initial credentials context * * This function creates a new context for acquiring initial credentials. Use * krb5_init_creds_free() to free @a ctx when it is no longer needed. * * Any subsequent calls to krb5_init_creds_step(), krb5_init_creds_get(), or * krb5_init_creds_free() for this initial credentials context must use the * same @a context argument as the one passed to this function. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_creds_init(krb5_context context, krb5_principal client, krb5_prompter_fct prompter, void *data, krb5_deltat start_time, krb5_get_init_creds_opt *options, krb5_init_creds_context *ctx); /** * Specify a keytab to use for acquiring initial credentials. * * @param [in] context Library context * @param [in] ctx Initial credentials context * @param [in] keytab Key table handle * * This function supplies a keytab containing the client key for an initial * credentials request. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_creds_set_keytab(krb5_context context, krb5_init_creds_context ctx, krb5_keytab keytab); /** * Get the next KDC request for acquiring initial credentials. * * @param [in] context Library context * @param [in] ctx Initial credentials context * @param [in] in KDC response (empty on the first call) * @param [out] out Next KDC request * @param [out] realm Realm for next KDC request * @param [out] flags Output flags * * This function constructs the next KDC request in an initial credential * exchange, allowing the caller to control the transport of KDC requests and * replies. On the first call, @a in should be set to an empty buffer; on * subsequent calls, it should be set to the KDC's reply to the previous * request. * * If more requests are needed, @a flags will be set to * #KRB5_INIT_CREDS_STEP_FLAG_CONTINUE and the next request will be placed in * @a out. If no more requests are needed, @a flags will not contain * #KRB5_INIT_CREDS_STEP_FLAG_CONTINUE and @a out will be empty. * * If this function returns @c KRB5KRB_ERR_RESPONSE_TOO_BIG, the caller should * transmit the next request using TCP rather than UDP. If this function * returns any other error, the initial credential exchange has failed. * * @a context must be the same as the one passed to krb5_init_creds_init() for * this initial credentials context. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_creds_step(krb5_context context, krb5_init_creds_context ctx, krb5_data *in, krb5_data *out, krb5_data *realm, unsigned int *flags); /** * Set a password for acquiring initial credentials. * * @param [in] context Library context * @param [in] ctx Initial credentials context * @param [in] password Password * * This function supplies a password to be used to construct the client key for * an initial credentials request. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_creds_set_password(krb5_context context, krb5_init_creds_context ctx, const char *password); /** * Specify a service principal for acquiring initial credentials. * * @param [in] context Library context * @param [in] ctx Initial credentials context * @param [in] service Service principal string * * This function supplies a service principal string to acquire initial * credentials for instead of the default krbtgt service. @a service is parsed * as a principal name; any realm part is ignored. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_creds_set_service(krb5_context context, krb5_init_creds_context ctx, const char *service); /** * Retrieve ticket times from an initial credentials context. * * @param [in] context Library context * @param [in] ctx Initial credentials context * @param [out] times Ticket times for acquired credentials * * The initial credentials context must have completed obtaining credentials * via either krb5_init_creds_get() or krb5_init_creds_step(). * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_init_creds_get_times(krb5_context context, krb5_init_creds_context ctx, krb5_ticket_times *times); struct _krb5_tkt_creds_context; typedef struct _krb5_tkt_creds_context *krb5_tkt_creds_context; /** * Create a context to get credentials from a KDC's Ticket Granting Service. * * @param[in] context Library context * @param[in] ccache Credential cache handle * @param[in] creds Input credentials * @param[in] options @ref KRB5_GC options for this request. * @param[out] ctx New TGS request context * * This function prepares to obtain credentials matching @a creds, either by * retrieving them from @a ccache or by making requests to ticket-granting * services beginning with a ticket-granting ticket for the client principal's * realm. * * The resulting TGS acquisition context can be used asynchronously with * krb5_tkt_creds_step() or synchronously with krb5_tkt_creds_get(). See also * krb5_get_credentials() for synchronous use. * * Use krb5_tkt_creds_free() to free @a ctx when it is no longer needed. * * @version New in 1.9 * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_tkt_creds_init(krb5_context context, krb5_ccache ccache, krb5_creds *creds, krb5_flags options, krb5_tkt_creds_context *ctx); /** * Synchronously obtain credentials using a TGS request context. * * @param[in] context Library context * @param[in] ctx TGS request context * * This function synchronously obtains credentials using a context created by * krb5_tkt_creds_init(). On successful return, the credentials can be * retrieved with krb5_tkt_creds_get_creds(). * * @version New in 1.9 * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_tkt_creds_get(krb5_context context, krb5_tkt_creds_context ctx); /** * Retrieve acquired credentials from a TGS request context. * * @param[in] context Library context * @param[in] ctx TGS request context * @param[out] creds Acquired credentials * * This function copies the acquired initial credentials from @a ctx into @a * creds, after the successful completion of krb5_tkt_creds_get() or * krb5_tkt_creds_step(). Use krb5_free_cred_contents() to free @a creds when * it is no longer needed. * * @version New in 1.9 * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_tkt_creds_get_creds(krb5_context context, krb5_tkt_creds_context ctx, krb5_creds *creds); /** * Free a TGS request context. * * @param[in] context Library context * @param[in] ctx TGS request context * * @version New in 1.9 */ void KRB5_CALLCONV krb5_tkt_creds_free(krb5_context context, krb5_tkt_creds_context ctx); #define KRB5_TKT_CREDS_STEP_FLAG_CONTINUE 0x1 /**< More responses needed */ /** * Get the next KDC request in a TGS exchange. * * @param[in] context Library context * @param[in] ctx TGS request context * @param[in] in KDC response (empty on the first call) * @param[out] out Next KDC request * @param[out] realm Realm for next KDC request * @param[out] flags Output flags * * This function constructs the next KDC request for a TGS exchange, allowing * the caller to control the transport of KDC requests and replies. On the * first call, @a in should be set to an empty buffer; on subsequent calls, it * should be set to the KDC's reply to the previous request. * * If more requests are needed, @a flags will be set to * #KRB5_TKT_CREDS_STEP_FLAG_CONTINUE and the next request will be placed in @a * out. If no more requests are needed, @a flags will not contain * #KRB5_TKT_CREDS_STEP_FLAG_CONTINUE and @a out will be empty. * * If this function returns @c KRB5KRB_ERR_RESPONSE_TOO_BIG, the caller should * transmit the next request using TCP rather than UDP. If this function * returns any other error, the TGS exchange has failed. * * @version New in 1.9 * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_tkt_creds_step(krb5_context context, krb5_tkt_creds_context ctx, krb5_data *in, krb5_data *out, krb5_data *realm, unsigned int *flags); /** * Retrieve ticket times from a TGS request context. * * @param[in] context Library context * @param[in] ctx TGS request context * @param[out] times Ticket times for acquired credentials * * The TGS request context must have completed obtaining credentials via either * krb5_tkt_creds_get() or krb5_tkt_creds_step(). * * @version New in 1.9 * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_tkt_creds_get_times(krb5_context context, krb5_tkt_creds_context ctx, krb5_ticket_times *times); /** * Get initial credentials using a key table. * * @param [in] context Library context * @param [out] creds New credentials * @param [in] client Client principal * @param [in] arg_keytab Key table handle * @param [in] start_time Time when ticket becomes valid (0 for now) * @param [in] in_tkt_service Service name of initial credentials (or NULL) * @param [in] k5_gic_options Initial credential options * * This function requests KDC for an initial credentials for @a client using a * client key stored in @a arg_keytab. If @a in_tkt_service is specified, it * is parsed as a principal name (with the realm ignored) and used as the * service principal for the request; otherwise the ticket-granting service is * used. * * @sa krb5_verify_init_creds() * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_keytab(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_keytab arg_keytab, krb5_deltat start_time, const char *in_tkt_service, krb5_get_init_creds_opt *k5_gic_options); typedef struct _krb5_verify_init_creds_opt { krb5_flags flags; int ap_req_nofail; /**< boolean */ } krb5_verify_init_creds_opt; #define KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL 0x0001 /** * Initialize a credential verification options structure. * * @param [in] k5_vic_options Verification options structure */ void KRB5_CALLCONV krb5_verify_init_creds_opt_init(krb5_verify_init_creds_opt *k5_vic_options); /** * Set whether credential verification is required. * * @param [in] k5_vic_options Verification options structure * @param [in] ap_req_nofail Whether to require successful verification * * This function determines how krb5_verify_init_creds() behaves if no keytab * information is available. If @a ap_req_nofail is @c FALSE, verification * will be skipped in this case and krb5_verify_init_creds() will return * successfully. If @a ap_req_nofail is @c TRUE, krb5_verify_init_creds() will * not return successfully unless verification can be performed. * * If this function is not used, the behavior of krb5_verify_init_creds() is * determined through configuration. */ void KRB5_CALLCONV krb5_verify_init_creds_opt_set_ap_req_nofail(krb5_verify_init_creds_opt * k5_vic_options, int ap_req_nofail); /** * Verify initial credentials against a keytab. * * @param [in] context Library context * @param [in] creds Initial credentials to be verified * @param [in] server Server principal (or NULL) * @param [in] keytab Key table (NULL to use default keytab) * @param [in] ccache Credential cache for fetched creds (or NULL) * @param [in] options Verification options (NULL for default options) * * This function attempts to verify that @a creds were obtained from a KDC with * knowledge of a key in @a keytab, or the default keytab if @a keytab is NULL. * If @a server is provided, the highest-kvno key entry for that principal name * is used to verify the credentials; otherwise, all unique "host" service * principals in the keytab are tried. * * If the specified keytab does not exist, or is empty, or cannot be read, or * does not contain an entry for @a server, then credential verification may be * skipped unless configuration demands that it succeed. The caller can * control this behavior by providing a verification options structure; see * krb5_verify_init_creds_opt_init() and * krb5_verify_init_creds_opt_set_ap_req_nofail(). * * If @a ccache is NULL, any additional credentials fetched during the * verification process will be destroyed. If @a ccache points to NULL, a * memory ccache will be created for the additional credentials and returned in * @a ccache. If @a ccache points to a valid credential cache handle, the * additional credentials will be stored in that cache. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_verify_init_creds(krb5_context context, krb5_creds *creds, krb5_principal server, krb5_keytab keytab, krb5_ccache *ccache, krb5_verify_init_creds_opt *options); /** * Get validated credentials from the KDC. * * @param [in] context Library context * @param [out] creds Validated credentials * @param [in] client Client principal name * @param [in] ccache Credential cache * @param [in] in_tkt_service Server principal string (or NULL) * * This function gets a validated credential using a postdated credential from * @a ccache. If @a in_tkt_service is specified, it is parsed (with the realm * part ignored) and used as the server principal of the credential; * otherwise, the ticket-granting service is used. * * If successful, the validated credential is placed in @a creds. * * @sa krb5_get_renewed_creds() * * @retval * 0 Success * @retval * KRB5_NO_2ND_TKT Request missing second ticket * @retval * KRB5_NO_TKT_SUPPLIED Request did not supply a ticket * @retval * KRB5_PRINC_NOMATCH Requested principal and ticket do not match * @retval * KRB5_KDCREP_MODIFIED KDC reply did not match expectations * @retval * KRB5_KDCREP_SKEW Clock skew too great in KDC reply * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_validated_creds(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_ccache ccache, const char *in_tkt_service); /** * Get renewed credential from KDC using an existing credential. * * @param [in] context Library context * @param [out] creds Renewed credentials * @param [in] client Client principal name * @param [in] ccache Credential cache * @param [in] in_tkt_service Server principal string (or NULL) * * This function gets a renewed credential using an existing one from @a * ccache. If @a in_tkt_service is specified, it is parsed (with the realm * part ignored) and used as the server principal of the credential; otherwise, * the ticket-granting service is used. * * If successful, the renewed credential is placed in @a creds. * * @retval * 0 Success * @return * Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_get_renewed_creds(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_ccache ccache, const char *in_tkt_service); /** * Decode an ASN.1-formatted ticket. * * @param [in] code ASN.1-formatted ticket * @param [out] rep Decoded ticket information * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_decode_ticket(const krb5_data *code, krb5_ticket **rep); /** * Retrieve a string value from the appdefaults section of krb5.conf. * * @param [in] context Library context * @param [in] appname Application name * @param [in] realm Realm name * @param [in] option Option to be checked * @param [in] default_value Default value to return if no match is found * @param [out] ret_value String value of @a option * * This function gets the application defaults for @a option based on the given * @a appname and/or @a realm. * * @sa krb5_appdefault_boolean() */ void KRB5_CALLCONV krb5_appdefault_string(krb5_context context, const char *appname, const krb5_data *realm, const char *option, const char *default_value, char ** ret_value); /** * Retrieve a boolean value from the appdefaults section of krb5.conf. * * @param [in] context Library context * @param [in] appname Application name * @param [in] realm Realm name * @param [in] option Option to be checked * @param [in] default_value Default value to return if no match is found * @param [out] ret_value Boolean value of @a option * * This function gets the application defaults for @a option based on the given * @a appname and/or @a realm. * * @sa krb5_appdefault_string() */ void KRB5_CALLCONV krb5_appdefault_boolean(krb5_context context, const char *appname, const krb5_data *realm, const char *option, int default_value, int *ret_value); /* * Prompter enhancements */ /** Prompt for password */ #define KRB5_PROMPT_TYPE_PASSWORD 0x1 /** Prompt for new password (during password change) */ #define KRB5_PROMPT_TYPE_NEW_PASSWORD 0x2 /** Prompt for new password again */ #define KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN 0x3 /** Prompt for preauthentication data (such as an OTP value) */ #define KRB5_PROMPT_TYPE_PREAUTH 0x4 typedef krb5_int32 krb5_prompt_type; /** * Get prompt types array from a context. * * @param [in] context Library context * * @return * Pointer to an array of prompt types corresponding to the prompter's @a * prompts arguments. Each type has one of the following values: * @li #KRB5_PROMPT_TYPE_PASSWORD * @li #KRB5_PROMPT_TYPE_NEW_PASSWORD * @li #KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN * @li #KRB5_PROMPT_TYPE_PREAUTH */ krb5_prompt_type* KRB5_CALLCONV krb5_get_prompt_types(krb5_context context); /* Error reporting */ /** * Set an extended error message for an error code. * * @param [in] ctx Library context * @param [in] code Error code * @param [in] fmt Error string for the error code * @param [in] ... printf(3) style parameters */ void KRB5_CALLCONV_C krb5_set_error_message(krb5_context ctx, krb5_error_code code, const char *fmt, ...) #if !defined(__cplusplus) && (__GNUC__ > 2) __attribute__((__format__(__printf__, 3, 4))) #endif ; /** * Set an extended error message for an error code using a va_list. * * @param [in] ctx Library context * @param [in] code Error code * @param [in] fmt Error string for the error code * @param [in] args List of vprintf(3) style arguments */ void KRB5_CALLCONV krb5_vset_error_message(krb5_context ctx, krb5_error_code code, const char *fmt, va_list args) #if !defined(__cplusplus) && (__GNUC__ > 2) __attribute__((__format__(__printf__, 3, 0))) #endif ; /** * Add a prefix to the message for an error code. * * @param [in] ctx Library context * @param [in] code Error code * @param [in] fmt Format string for error message prefix * @param [in] ... printf(3) style parameters * * Format a message and prepend it to the current message for @a code. The * prefix will be separated from the old message with a colon and space. */ void KRB5_CALLCONV_C krb5_prepend_error_message(krb5_context ctx, krb5_error_code code, const char *fmt, ...) #if !defined(__cplusplus) && (__GNUC__ > 2) __attribute__((__format__(__printf__, 3, 4))) #endif ; /** * Add a prefix to the message for an error code using a va_list. * * @param [in] ctx Library context * @param [in] code Error code * @param [in] fmt Format string for error message prefix * @param [in] args List of vprintf(3) style arguments * * This function is similar to krb5_prepend_error_message(), but uses a * va_list instead of variadic arguments. */ void KRB5_CALLCONV krb5_vprepend_error_message(krb5_context ctx, krb5_error_code code, const char *fmt, va_list args) #if !defined(__cplusplus) && (__GNUC__ > 2) __attribute__((__format__(__printf__, 3, 0))) #endif ; /** * Add a prefix to a different error code's message. * * @param [in] ctx Library context * @param [in] old_code Previous error code * @param [in] code Error code * @param [in] fmt Format string for error message prefix * @param [in] ... printf(3) style parameters * * Format a message and prepend it to the message for @a old_code. The prefix * will be separated from the old message with a colon and space. Set the * resulting message as the extended error message for @a code. */ void KRB5_CALLCONV_C krb5_wrap_error_message(krb5_context ctx, krb5_error_code old_code, krb5_error_code code, const char *fmt, ...) #if !defined(__cplusplus) && (__GNUC__ > 2) __attribute__((__format__(__printf__, 4, 5))) #endif ; /** * Add a prefix to a different error code's message using a va_list. * * @param [in] ctx Library context * @param [in] old_code Previous error code * @param [in] code Error code * @param [in] fmt Format string for error message prefix * @param [in] args List of vprintf(3) style arguments * * This function is similar to krb5_wrap_error_message(), but uses a * va_list instead of variadic arguments. */ void KRB5_CALLCONV krb5_vwrap_error_message(krb5_context ctx, krb5_error_code old_code, krb5_error_code code, const char *fmt, va_list args) #if !defined(__cplusplus) && (__GNUC__ > 2) __attribute__((__format__(__printf__, 4, 0))) #endif ; /** * Copy the most recent extended error message from one context to another. * * @param [in] dest_ctx Library context to copy message to * @param [in] src_ctx Library context with current message */ void KRB5_CALLCONV krb5_copy_error_message(krb5_context dest_ctx, krb5_context src_ctx); /** * Get the (possibly extended) error message for a code. * * @param [in] ctx Library context * @param [in] code Error code * * The behavior of krb5_get_error_message() is only defined the first time it * is called after a failed call to a krb5 function using the same context, and * only when the error code passed in is the same as that returned by the krb5 * function. * * This function never returns NULL, so its result may be used unconditionally * as a C string. * * The string returned by this function must be freed using * krb5_free_error_message() * * @note Future versions may return the same string for the second * and following calls. */ const char * KRB5_CALLCONV krb5_get_error_message(krb5_context ctx, krb5_error_code code); /** * Free an error message generated by krb5_get_error_message(). * * @param [in] ctx Library context * @param [in] msg Pointer to error message */ void KRB5_CALLCONV krb5_free_error_message(krb5_context ctx, const char *msg); /** * Clear the extended error message in a context. * * @param [in] ctx Library context * * This function unsets the extended error message in a context, to ensure that * it is not mistakenly applied to another occurrence of the same error code. */ void KRB5_CALLCONV krb5_clear_error_message(krb5_context ctx); /** * Unwrap authorization data. * * @param [in] context Library context * @param [in] type @ref KRB5_AUTHDATA type of @a container * @param [in] container Authorization data to be decoded * @param [out] authdata List of decoded authorization data * * @sa krb5_encode_authdata_container() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_decode_authdata_container(krb5_context context, krb5_authdatatype type, const krb5_authdata *container, krb5_authdata ***authdata); /** * Wrap authorization data in a container. * * @param [in] context Library context * @param [in] type @ref KRB5_AUTHDATA type of @a container * @param [in] authdata List of authorization data to be encoded * @param [out] container List of encoded authorization data * * The result is returned in @a container as a single-element list. * * @sa krb5_decode_authdata_container() * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_encode_authdata_container(krb5_context context, krb5_authdatatype type, krb5_authdata * const*authdata, krb5_authdata ***container); /* * AD-KDCIssued */ /** * Encode and sign AD-KDCIssued authorization data. * * @param [in] context Library context * @param [in] key Session key * @param [in] issuer The name of the issuing principal * @param [in] authdata List of authorization data to be signed * @param [out] ad_kdcissued List containing AD-KDCIssued authdata * * This function wraps a list of authorization data entries @a authdata in an * AD-KDCIssued container (see RFC 4120 section 5.2.6.2) signed with @a key. * The result is returned in @a ad_kdcissued as a single-element list. */ krb5_error_code KRB5_CALLCONV krb5_make_authdata_kdc_issued(krb5_context context, const krb5_keyblock *key, krb5_const_principal issuer, krb5_authdata *const *authdata, krb5_authdata ***ad_kdcissued); /** * Unwrap and verify AD-KDCIssued authorization data. * * @param [in] context Library context * @param [in] key Session key * @param [in] ad_kdcissued AD-KDCIssued authorization data to be unwrapped * @param [out] issuer Name of issuing principal (or NULL) * @param [out] authdata Unwrapped list of authorization data * * This function unwraps an AD-KDCIssued authdatum (see RFC 4120 section * 5.2.6.2) and verifies its signature against @a key. The issuer field of the * authdatum element is returned in @a issuer, and the unwrapped list of * authdata is returned in @a authdata. */ krb5_error_code KRB5_CALLCONV krb5_verify_authdata_kdc_issued(krb5_context context, const krb5_keyblock *key, const krb5_authdata *ad_kdcissued, krb5_principal *issuer, krb5_authdata ***authdata); /* * Windows PAC */ /* Microsoft defined types of data */ #define KRB5_PAC_LOGON_INFO 1 /**< Logon information */ #define KRB5_PAC_CREDENTIALS_INFO 2 /**< Credentials information */ #define KRB5_PAC_SERVER_CHECKSUM 6 /**< Server checksum */ #define KRB5_PAC_PRIVSVR_CHECKSUM 7 /**< KDC checksum */ #define KRB5_PAC_CLIENT_INFO 10 /**< Client name and ticket info */ #define KRB5_PAC_DELEGATION_INFO 11 /**< Constrained delegation info */ #define KRB5_PAC_UPN_DNS_INFO 12 /**< User principal name and DNS info */ #define KRB5_PAC_CLIENT_CLAIMS 13 /**< Client claims information */ #define KRB5_PAC_DEVICE_INFO 14 /**< Device information */ #define KRB5_PAC_DEVICE_CLAIMS 15 /**< Device claims information */ #define KRB5_PAC_TICKET_CHECKSUM 16 /**< Ticket checksum */ #define KRB5_PAC_ATTRIBUTES_INFO 17 /**< PAC attributes */ #define KRB5_PAC_REQUESTOR 18 /**< PAC requestor SID */ #define KRB5_PAC_FULL_CHECKSUM 19 /**< KDC full checksum */ struct krb5_pac_data; /** PAC data structure to convey authorization information */ typedef struct krb5_pac_data *krb5_pac; /** * Add a buffer to a PAC handle. * * @param [in] context Library context * @param [in] pac PAC handle * @param [in] type Buffer type * @param [in] data contents * * This function adds a buffer of type @a type and contents @a data to @a pac * if there isn't already a buffer of this type present. * * The valid values of @a type is one of the following: * @li #KRB5_PAC_LOGON_INFO - Logon information * @li #KRB5_PAC_CREDENTIALS_INFO - Credentials information * @li #KRB5_PAC_SERVER_CHECKSUM - Server checksum * @li #KRB5_PAC_PRIVSVR_CHECKSUM - KDC checksum * @li #KRB5_PAC_CLIENT_INFO - Client name and ticket information * @li #KRB5_PAC_DELEGATION_INFO - Constrained delegation information * @li #KRB5_PAC_UPN_DNS_INFO - User principal name and DNS information * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_pac_add_buffer(krb5_context context, krb5_pac pac, krb5_ui_4 type, const krb5_data *data); /** * Free a PAC handle. * * @param [in] context Library context * @param [in] pac PAC to be freed * * This function frees the contents of @a pac and the structure itself. */ void KRB5_CALLCONV krb5_pac_free(krb5_context context, krb5_pac pac); /** * Retrieve a buffer value from a PAC. * * @param [in] context Library context * @param [in] pac PAC handle * @param [in] type Type of buffer to retrieve * @param [out] data Buffer value * * Use krb5_free_data_contents() to free @a data when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_pac_get_buffer(krb5_context context, krb5_pac pac, krb5_ui_4 type, krb5_data *data); /** * Return an array of buffer types in a PAC handle. * * @param [in] context Library context * @param [in] pac PAC handle * @param [out] len Number of entries in @a types * @param [out] types Array of buffer types * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_pac_get_types(krb5_context context, krb5_pac pac, size_t *len, krb5_ui_4 **types); /** * Create an empty Privilege Attribute Certificate (PAC) handle. * * @param [in] context Library context * @param [out] pac New PAC handle * * Use krb5_pac_free() to free @a pac when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_pac_init(krb5_context context, krb5_pac *pac); /** * Unparse an encoded PAC into a new handle. * * @param [in] context Library context * @param [in] ptr PAC buffer * @param [in] len Length of @a ptr * @param [out] pac PAC handle * * Use krb5_pac_free() to free @a pac when it is no longer needed. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_pac_parse(krb5_context context, const void *ptr, size_t len, krb5_pac *pac); /** * Verify a PAC. * * @param [in] context Library context * @param [in] pac PAC handle * @param [in] authtime Expected timestamp * @param [in] principal Expected principal name (or NULL) * @param [in] server Key to validate server checksum (or NULL) * @param [in] privsvr Key to validate KDC checksum (or NULL) * * This function validates @a pac against the supplied @a server, @a privsvr, * @a principal and @a authtime. If @a principal is NULL, the principal and * authtime are not verified. If @a server or @a privsvr is NULL, the * corresponding checksum is not verified. * * If successful, @a pac is marked as verified. * * @note A checksum mismatch can occur if the PAC was copied from a cross-realm * TGT by an ignorant KDC; also macOS Server Open Directory (as of 10.6) * generates PACs with no server checksum at all. One should consider not * failing the whole authentication because of this reason, but, instead, * treating the ticket as if it did not contain a PAC or marking the PAC * information as non-verified. * * @retval 0 Success; otherwise - Kerberos error codes */ krb5_error_code KRB5_CALLCONV krb5_pac_verify(krb5_context context, const krb5_pac pac, krb5_timestamp authtime, krb5_const_principal principal, const krb5_keyblock *server, const krb5_keyblock *privsvr); /** * Verify a PAC, possibly from a specified realm. * * @param [in] context Library context * @param [in] pac PAC handle * @param [in] authtime Expected timestamp * @param [in] principal Expected principal name (or NULL) * @param [in] server Key to validate server checksum (or NULL) * @param [in] privsvr Key to validate KDC checksum (or NULL) * @param [in] with_realm If true, expect the realm of @a principal * * This function is similar to krb5_pac_verify(), but adds a parameter * @a with_realm. If @a with_realm is true, the PAC_CLIENT_INFO field is * expected to include the realm of @a principal as well as the name. This * flag is necessary to verify PACs in cross-realm S4U2Self referral TGTs. * * @version New in 1.17 */ krb5_error_code KRB5_CALLCONV krb5_pac_verify_ext(krb5_context context, const krb5_pac pac, krb5_timestamp authtime, krb5_const_principal principal, const krb5_keyblock *server, const krb5_keyblock *privsvr, krb5_boolean with_realm); /** * Verify a PAC, possibly including ticket signature * * @param [in] context Library context * @param [in] enc_tkt Ticket enc-part, possibly containing a PAC * @param [in] server_princ Canonicalized name of ticket server * @param [in] server Key to validate server checksum (or NULL) * @param [in] privsvr Key to validate KDC checksum (or NULL) * @param [out] pac_out Verified PAC (NULL if no PAC included) * * If a PAC is present in @a enc_tkt, verify its signatures. If @a privsvr is * not NULL and @a server_princ is not a krbtgt or kadmin/changepw service, * require a ticket signature over @a enc_tkt in addition to the KDC signature. * Place the verified PAC in @a pac_out. If an invalid PAC signature is found, * return an error matching the Windows KDC protocol code for that condition as * closely as possible. * * If no PAC is present in @a enc_tkt, set @a pac_out to NULL and return * successfully. * * @note This function does not validate the PAC_CLIENT_INFO buffer. If a * specific value is expected, the caller can make a separate call to * krb5_pac_verify_ext() with a principal but no keys. * * @retval 0 Success; otherwise - Kerberos error codes * * @version New in 1.20 */ krb5_error_code KRB5_CALLCONV krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt, krb5_const_principal server_princ, const krb5_keyblock *server, const krb5_keyblock *privsvr, krb5_pac *pac_out); /** @deprecated Use krb5_kdc_sign_ticket() instead. */ krb5_error_code KRB5_CALLCONV krb5_pac_sign(krb5_context context, krb5_pac pac, krb5_timestamp authtime, krb5_const_principal principal, const krb5_keyblock *server_key, const krb5_keyblock *privsvr_key, krb5_data *data); /** @deprecated Use krb5_kdc_sign_ticket() instead. */ krb5_error_code KRB5_CALLCONV krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime, krb5_const_principal principal, const krb5_keyblock *server_key, const krb5_keyblock *privsvr_key, krb5_boolean with_realm, krb5_data *data); /** * Compatibility function used by IPA if the 1.20 KDB diver API is not * available. It generates PAC signatures, including the extended KDC one when * relevant. * * It is similar to krb5_kdc_sign_ticket(), except it will not generate the * PAC ticket signature, and therefore does not expect encrypted ticket part as * parameter. * * @param [in] context Library context * @param [in] pac PAC handle * @param [in] authtime Expected timestamp * @param [in] client_princ Client principal name (or NULL) * @param [in] server_princ Server principal name * @param [in] server_key Key for server checksum * @param [in] privsvr_key Key for KDC checksum * @param [in] with_realm If true, include the realm of @a client_princ * @param [out] data Signed PAC encoding * * This function signs @a pac using the keys @a server_key and @a privsvr_key * and returns the signed encoding in @a data. @a pac is modified to include * the server and KDC checksum buffers. Use krb5_free_data_contents() to free * @a data when it is no longer needed. * * If @a with_realm is true, the PAC_CLIENT_INFO field of the signed PAC will * include the realm of @a client_princ as well as the name. This flag is * necessary to generate PACs for cross-realm S4U2Self referrals. */ krb5_error_code KRB5_CALLCONV krb5_pac_full_sign_compat(krb5_context context, krb5_pac pac, krb5_timestamp authtime, krb5_const_principal client_princ, krb5_const_principal server_princ, const krb5_keyblock *server_key, const krb5_keyblock *privsvr_key, krb5_boolean with_realm, krb5_data *data); /** * Sign a PAC, possibly including a ticket signature * * @param [in] context Library context * @param [in] enc_tkt The ticket for the signature * @param [in] pac PAC handle * @param [in] server_princ Canonical ticket server name * @param [in] client_princ PAC_CLIENT_INFO principal (or NULL) * @param [in] server Key for server checksum * @param [in] privsvr Key for KDC and ticket checksum * @param [in] with_realm If true, include the realm of @a principal * * Sign @a pac using the keys @a server and @a privsvr. Include a ticket * signature over @a enc_tkt if @a server_princ is not a TGS or kadmin/changepw * principal name. Add the signed PAC's encoding to the authorization data of * @a enc_tkt in the first slot, wrapped in an AD-IF-RELEVANT container. If @a * client_princ is non-null, add a PAC_CLIENT_INFO buffer, including the realm * if @a with_realm is true. * * @retval 0 on success, otherwise - Kerberos error codes * * @version New in 1.20 */ krb5_error_code KRB5_CALLCONV krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt, const krb5_pac pac, krb5_const_principal server_princ, krb5_const_principal client_princ, const krb5_keyblock *server, const krb5_keyblock *privsvr, krb5_boolean with_realm); /** * Read client information from a PAC. * * @param [in] context Library context * @param [in] pac PAC handle * @param [out] authtime_out Authentication timestamp (NULL if not needed) * @param [out] princname_out Client account name * * Read the PAC_CLIENT_INFO buffer in @a pac. Place the client account name as * a string in @a princname_out. If @a authtime_out is not NULL, place the * initial authentication timestamp in @a authtime_out. * * @retval 0 on success, ENOENT if no PAC_CLIENT_INFO buffer is present in @a * pac, ERANGE if the buffer contains invalid lengths. * * @version New in 1.18 */ krb5_error_code KRB5_CALLCONV krb5_pac_get_client_info(krb5_context context, const krb5_pac pac, krb5_timestamp *authtime_out, char **princname_out); /** * Allow the application to override the profile's allow_weak_crypto setting. * * @param [in] context Library context * @param [in] enable Boolean flag * * This function allows an application to override the allow_weak_crypto * setting. It is primarily for use by aklog. * * @retval 0 (always) */ krb5_error_code KRB5_CALLCONV krb5_allow_weak_crypto(krb5_context context, krb5_boolean enable); /** * A wrapper for passing information to a @c krb5_trace_callback. * * Currently, it only contains the formatted message as determined * the the format string and arguments of the tracing macro, but it * may be extended to contain more fields in the future. */ typedef struct _krb5_trace_info { const char *message; } krb5_trace_info; typedef void (KRB5_CALLCONV *krb5_trace_callback)(krb5_context context, const krb5_trace_info *info, void *cb_data); /** * Specify a callback function for trace events. * * @param [in] context Library context * @param [in] fn Callback function * @param [in] cb_data Callback data * * Specify a callback for trace events occurring in krb5 operations performed * within @a context. @a fn will be invoked with @a context as the first * argument, @a cb_data as the last argument, and a pointer to a * krb5_trace_info as the second argument. If the trace callback is reset via * this function or @a context is destroyed, @a fn will be invoked with a NULL * second argument so it can clean up @a cb_data. Supply a NULL value for @a * fn to disable trace callbacks within @a context. * * @note This function overrides the information passed through the * @a KRB5_TRACE environment variable. * * @version New in 1.9 * * @return Returns KRB5_TRACE_NOSUPP if tracing is not supported in the library * (unless @a fn is NULL). */ krb5_error_code KRB5_CALLCONV krb5_set_trace_callback(krb5_context context, krb5_trace_callback fn, void *cb_data); /** * Specify a file name for directing trace events. * * @param [in] context Library context * @param [in] filename File name * * Open @a filename for appending (creating it, if necessary) and set up a * callback to write trace events to it. * * @note This function overrides the information passed through the * @a KRB5_TRACE environment variable. * * @version New in 1.9 * * @retval KRB5_TRACE_NOSUPP Tracing is not supported in the library. */ krb5_error_code KRB5_CALLCONV krb5_set_trace_filename(krb5_context context, const char *filename); /** * Hook function for inspecting or modifying messages sent to KDCs. * * @param [in] context Library context * @param [in] data Callback data * @param [in] realm The realm the message will be sent to * @param [in] message The original message to be sent to the KDC * @param [out] new_message_out Optional replacement message to be sent * @param [out] reply_out Optional synthetic reply * * If the hook function returns an error code, the KDC communication will be * aborted and the error code will be returned to the library operation which * initiated the communication. * * If the hook function sets @a reply_out, @a message will not be sent to the * KDC, and the given reply will used instead. * * If the hook function sets @a new_message_out, the given message will be sent * to the KDC in place of @a message. * * If the hook function returns successfully without setting either output, * @a message will be sent to the KDC normally. * * The hook function should use krb5_copy_data() to construct the value for * @a new_message_out or @a reply_out, to ensure that it can be freed correctly * by the library. * * @version New in 1.15 * * @retval 0 Success * @return A Kerberos error code */ typedef krb5_error_code (KRB5_CALLCONV *krb5_pre_send_fn)(krb5_context context, void *data, const krb5_data *realm, const krb5_data *message, krb5_data **new_message_out, krb5_data **new_reply_out); /** * Hook function for inspecting or overriding KDC replies. * * @param [in] context Library context * @param [in] data Callback data * @param [in] code Status of KDC communication * @param [in] realm The realm the reply was received from * @param [in] message The message sent to the realm's KDC * @param [in] reply The reply received from the KDC * @param [out] new_reply_out Optional replacement reply * * If @a code is zero, @a reply contains the reply received from the KDC. The * hook function may return an error code to simulate an error, may synthesize * a different reply by setting @a new_reply_out, or may simply return * successfully to do nothing. * * If @a code is non-zero, KDC communication failed and @a reply should be * ignored. The hook function may return @a code or a different error code, or * may synthesize a reply by setting @a new_reply_out and return successfully. * * The hook function should use krb5_copy_data() to construct the value for * @a new_reply_out, to ensure that it can be freed correctly by the library. * * @version New in 1.15 * * @retval 0 Success * @return A Kerberos error code */ typedef krb5_error_code (KRB5_CALLCONV *krb5_post_recv_fn)(krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply_out); /** * Set a KDC pre-send hook function. * * @param [in] context Library context * @param [in] send_hook Hook function (or NULL to disable the hook) * @param [in] data Callback data to be passed to @a send_hook * * @a send_hook will be called before messages are sent to KDCs by library * functions such as krb5_get_credentials(). The hook function may inspect, * override, or synthesize its own reply to the message. * * @version New in 1.15 */ void KRB5_CALLCONV krb5_set_kdc_send_hook(krb5_context context, krb5_pre_send_fn send_hook, void *data); /** * Set a KDC post-receive hook function. * * @param [in] context The library context. * @param [in] recv_hook Hook function (or NULL to disable the hook) * @param [in] data Callback data to be passed to @a recv_hook * * @a recv_hook will be called after a reply is received from a KDC during a * call to a library function such as krb5_get_credentials(). The hook * function may inspect or override the reply. This hook will not be executed * if the pre-send hook returns a synthetic reply. * * @version New in 1.15 */ void KRB5_CALLCONV krb5_set_kdc_recv_hook(krb5_context context, krb5_post_recv_fn recv_hook, void *data); #if defined(TARGET_OS_MAC) && TARGET_OS_MAC # pragma pack(pop) #endif KRB5INT_END_DECLS /* Don't use this! We're going to phase it out. It's just here to keep applications from breaking right away. */ #define krb5_const const #undef KRB5_ATTR_DEPRECATED /** @} */ /* end of KRB5_H group */ #endif /* KRB5_GENERAL__ */ /* * et-h-krb5_err.h: * This file is automatically generated; please do not edit it. */ #include <et/com_err.h> #define KRB5KDC_ERR_NONE (-1765328384L) #define KRB5KDC_ERR_NAME_EXP (-1765328383L) #define KRB5KDC_ERR_SERVICE_EXP (-1765328382L) #define KRB5KDC_ERR_BAD_PVNO (-1765328381L) #define KRB5KDC_ERR_C_OLD_MAST_KVNO (-1765328380L) #define KRB5KDC_ERR_S_OLD_MAST_KVNO (-1765328379L) #define KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN (-1765328378L) #define KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN (-1765328377L) #define KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE (-1765328376L) #define KRB5KDC_ERR_NULL_KEY (-1765328375L) #define KRB5KDC_ERR_CANNOT_POSTDATE (-1765328374L) #define KRB5KDC_ERR_NEVER_VALID (-1765328373L) #define KRB5KDC_ERR_POLICY (-1765328372L) #define KRB5KDC_ERR_BADOPTION (-1765328371L) #define KRB5KDC_ERR_ETYPE_NOSUPP (-1765328370L) #define KRB5KDC_ERR_SUMTYPE_NOSUPP (-1765328369L) #define KRB5KDC_ERR_PADATA_TYPE_NOSUPP (-1765328368L) #define KRB5KDC_ERR_TRTYPE_NOSUPP (-1765328367L) #define KRB5KDC_ERR_CLIENT_REVOKED (-1765328366L) #define KRB5KDC_ERR_SERVICE_REVOKED (-1765328365L) #define KRB5KDC_ERR_TGT_REVOKED (-1765328364L) #define KRB5KDC_ERR_CLIENT_NOTYET (-1765328363L) #define KRB5KDC_ERR_SERVICE_NOTYET (-1765328362L) #define KRB5KDC_ERR_KEY_EXP (-1765328361L) #define KRB5KDC_ERR_PREAUTH_FAILED (-1765328360L) #define KRB5KDC_ERR_PREAUTH_REQUIRED (-1765328359L) #define KRB5KDC_ERR_SERVER_NOMATCH (-1765328358L) #define KRB5KDC_ERR_MUST_USE_USER2USER (-1765328357L) #define KRB5KDC_ERR_PATH_NOT_ACCEPTED (-1765328356L) #define KRB5KDC_ERR_SVC_UNAVAILABLE (-1765328355L) #define KRB5PLACEHOLD_30 (-1765328354L) #define KRB5KRB_AP_ERR_BAD_INTEGRITY (-1765328353L) #define KRB5KRB_AP_ERR_TKT_EXPIRED (-1765328352L) #define KRB5KRB_AP_ERR_TKT_NYV (-1765328351L) #define KRB5KRB_AP_ERR_REPEAT (-1765328350L) #define KRB5KRB_AP_ERR_NOT_US (-1765328349L) #define KRB5KRB_AP_ERR_BADMATCH (-1765328348L) #define KRB5KRB_AP_ERR_SKEW (-1765328347L) #define KRB5KRB_AP_ERR_BADADDR (-1765328346L) #define KRB5KRB_AP_ERR_BADVERSION (-1765328345L) #define KRB5KRB_AP_ERR_MSG_TYPE (-1765328344L) #define KRB5KRB_AP_ERR_MODIFIED (-1765328343L) #define KRB5KRB_AP_ERR_BADORDER (-1765328342L) #define KRB5KRB_AP_ERR_ILL_CR_TKT (-1765328341L) #define KRB5KRB_AP_ERR_BADKEYVER (-1765328340L) #define KRB5KRB_AP_ERR_NOKEY (-1765328339L) #define KRB5KRB_AP_ERR_MUT_FAIL (-1765328338L) #define KRB5KRB_AP_ERR_BADDIRECTION (-1765328337L) #define KRB5KRB_AP_ERR_METHOD (-1765328336L) #define KRB5KRB_AP_ERR_BADSEQ (-1765328335L) #define KRB5KRB_AP_ERR_INAPP_CKSUM (-1765328334L) #define KRB5KRB_AP_PATH_NOT_ACCEPTED (-1765328333L) #define KRB5KRB_ERR_RESPONSE_TOO_BIG (-1765328332L) #define KRB5PLACEHOLD_53 (-1765328331L) #define KRB5PLACEHOLD_54 (-1765328330L) #define KRB5PLACEHOLD_55 (-1765328329L) #define KRB5PLACEHOLD_56 (-1765328328L) #define KRB5PLACEHOLD_57 (-1765328327L) #define KRB5PLACEHOLD_58 (-1765328326L) #define KRB5PLACEHOLD_59 (-1765328325L) #define KRB5KRB_ERR_GENERIC (-1765328324L) #define KRB5KRB_ERR_FIELD_TOOLONG (-1765328323L) #define KRB5KDC_ERR_CLIENT_NOT_TRUSTED (-1765328322L) #define KRB5KDC_ERR_KDC_NOT_TRUSTED (-1765328321L) #define KRB5KDC_ERR_INVALID_SIG (-1765328320L) #define KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED (-1765328319L) #define KRB5KDC_ERR_CERTIFICATE_MISMATCH (-1765328318L) #define KRB5KRB_AP_ERR_NO_TGT (-1765328317L) #define KRB5KDC_ERR_WRONG_REALM (-1765328316L) #define KRB5KRB_AP_ERR_USER_TO_USER_REQUIRED (-1765328315L) #define KRB5KDC_ERR_CANT_VERIFY_CERTIFICATE (-1765328314L) #define KRB5KDC_ERR_INVALID_CERTIFICATE (-1765328313L) #define KRB5KDC_ERR_REVOKED_CERTIFICATE (-1765328312L) #define KRB5KDC_ERR_REVOCATION_STATUS_UNKNOWN (-1765328311L) #define KRB5KDC_ERR_REVOCATION_STATUS_UNAVAILABLE (-1765328310L) #define KRB5KDC_ERR_CLIENT_NAME_MISMATCH (-1765328309L) #define KRB5KDC_ERR_KDC_NAME_MISMATCH (-1765328308L) #define KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE (-1765328307L) #define KRB5KDC_ERR_DIGEST_IN_CERT_NOT_ACCEPTED (-1765328306L) #define KRB5KDC_ERR_PA_CHECKSUM_MUST_BE_INCLUDED (-1765328305L) #define KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED (-1765328304L) #define KRB5KDC_ERR_PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED (-1765328303L) #define KRB5PLACEHOLD_82 (-1765328302L) #define KRB5PLACEHOLD_83 (-1765328301L) #define KRB5PLACEHOLD_84 (-1765328300L) #define KRB5KRB_AP_ERR_IAKERB_KDC_NOT_FOUND (-1765328299L) #define KRB5KRB_AP_ERR_IAKERB_KDC_NO_RESPONSE (-1765328298L) #define KRB5PLACEHOLD_87 (-1765328297L) #define KRB5PLACEHOLD_88 (-1765328296L) #define KRB5PLACEHOLD_89 (-1765328295L) #define KRB5KDC_ERR_PREAUTH_EXPIRED (-1765328294L) #define KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED (-1765328293L) #define KRB5PLACEHOLD_92 (-1765328292L) #define KRB5KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTION (-1765328291L) #define KRB5PLACEHOLD_94 (-1765328290L) #define KRB5PLACEHOLD_95 (-1765328289L) #define KRB5PLACEHOLD_96 (-1765328288L) #define KRB5PLACEHOLD_97 (-1765328287L) #define KRB5PLACEHOLD_98 (-1765328286L) #define KRB5PLACEHOLD_99 (-1765328285L) #define KRB5KDC_ERR_NO_ACCEPTABLE_KDF (-1765328284L) #define KRB5PLACEHOLD_101 (-1765328283L) #define KRB5PLACEHOLD_102 (-1765328282L) #define KRB5PLACEHOLD_103 (-1765328281L) #define KRB5PLACEHOLD_104 (-1765328280L) #define KRB5PLACEHOLD_105 (-1765328279L) #define KRB5PLACEHOLD_106 (-1765328278L) #define KRB5PLACEHOLD_107 (-1765328277L) #define KRB5PLACEHOLD_108 (-1765328276L) #define KRB5PLACEHOLD_109 (-1765328275L) #define KRB5PLACEHOLD_110 (-1765328274L) #define KRB5PLACEHOLD_111 (-1765328273L) #define KRB5PLACEHOLD_112 (-1765328272L) #define KRB5PLACEHOLD_113 (-1765328271L) #define KRB5PLACEHOLD_114 (-1765328270L) #define KRB5PLACEHOLD_115 (-1765328269L) #define KRB5PLACEHOLD_116 (-1765328268L) #define KRB5PLACEHOLD_117 (-1765328267L) #define KRB5PLACEHOLD_118 (-1765328266L) #define KRB5PLACEHOLD_119 (-1765328265L) #define KRB5PLACEHOLD_120 (-1765328264L) #define KRB5PLACEHOLD_121 (-1765328263L) #define KRB5PLACEHOLD_122 (-1765328262L) #define KRB5PLACEHOLD_123 (-1765328261L) #define KRB5PLACEHOLD_124 (-1765328260L) #define KRB5PLACEHOLD_125 (-1765328259L) #define KRB5PLACEHOLD_126 (-1765328258L) #define KRB5PLACEHOLD_127 (-1765328257L) #define KRB5_ERR_RCSID (-1765328256L) #define KRB5_LIBOS_BADLOCKFLAG (-1765328255L) #define KRB5_LIBOS_CANTREADPWD (-1765328254L) #define KRB5_LIBOS_BADPWDMATCH (-1765328253L) #define KRB5_LIBOS_PWDINTR (-1765328252L) #define KRB5_PARSE_ILLCHAR (-1765328251L) #define KRB5_PARSE_MALFORMED (-1765328250L) #define KRB5_CONFIG_CANTOPEN (-1765328249L) #define KRB5_CONFIG_BADFORMAT (-1765328248L) #define KRB5_CONFIG_NOTENUFSPACE (-1765328247L) #define KRB5_BADMSGTYPE (-1765328246L) #define KRB5_CC_BADNAME (-1765328245L) #define KRB5_CC_UNKNOWN_TYPE (-1765328244L) #define KRB5_CC_NOTFOUND (-1765328243L) #define KRB5_CC_END (-1765328242L) #define KRB5_NO_TKT_SUPPLIED (-1765328241L) #define KRB5KRB_AP_WRONG_PRINC (-1765328240L) #define KRB5KRB_AP_ERR_TKT_INVALID (-1765328239L) #define KRB5_PRINC_NOMATCH (-1765328238L) #define KRB5_KDCREP_MODIFIED (-1765328237L) #define KRB5_KDCREP_SKEW (-1765328236L) #define KRB5_IN_TKT_REALM_MISMATCH (-1765328235L) #define KRB5_PROG_ETYPE_NOSUPP (-1765328234L) #define KRB5_PROG_KEYTYPE_NOSUPP (-1765328233L) #define KRB5_WRONG_ETYPE (-1765328232L) #define KRB5_PROG_SUMTYPE_NOSUPP (-1765328231L) #define KRB5_REALM_UNKNOWN (-1765328230L) #define KRB5_SERVICE_UNKNOWN (-1765328229L) #define KRB5_KDC_UNREACH (-1765328228L) #define KRB5_NO_LOCALNAME (-1765328227L) #define KRB5_MUTUAL_FAILED (-1765328226L) #define KRB5_RC_TYPE_EXISTS (-1765328225L) #define KRB5_RC_MALLOC (-1765328224L) #define KRB5_RC_TYPE_NOTFOUND (-1765328223L) #define KRB5_RC_UNKNOWN (-1765328222L) #define KRB5_RC_REPLAY (-1765328221L) #define KRB5_RC_IO (-1765328220L) #define KRB5_RC_NOIO (-1765328219L) #define KRB5_RC_PARSE (-1765328218L) #define KRB5_RC_IO_EOF (-1765328217L) #define KRB5_RC_IO_MALLOC (-1765328216L) #define KRB5_RC_IO_PERM (-1765328215L) #define KRB5_RC_IO_IO (-1765328214L) #define KRB5_RC_IO_UNKNOWN (-1765328213L) #define KRB5_RC_IO_SPACE (-1765328212L) #define KRB5_TRANS_CANTOPEN (-1765328211L) #define KRB5_TRANS_BADFORMAT (-1765328210L) #define KRB5_LNAME_CANTOPEN (-1765328209L) #define KRB5_LNAME_NOTRANS (-1765328208L) #define KRB5_LNAME_BADFORMAT (-1765328207L) #define KRB5_CRYPTO_INTERNAL (-1765328206L) #define KRB5_KT_BADNAME (-1765328205L) #define KRB5_KT_UNKNOWN_TYPE (-1765328204L) #define KRB5_KT_NOTFOUND (-1765328203L) #define KRB5_KT_END (-1765328202L) #define KRB5_KT_NOWRITE (-1765328201L) #define KRB5_KT_IOERR (-1765328200L) #define KRB5_NO_TKT_IN_RLM (-1765328199L) #define KRB5DES_BAD_KEYPAR (-1765328198L) #define KRB5DES_WEAK_KEY (-1765328197L) #define KRB5_BAD_ENCTYPE (-1765328196L) #define KRB5_BAD_KEYSIZE (-1765328195L) #define KRB5_BAD_MSIZE (-1765328194L) #define KRB5_CC_TYPE_EXISTS (-1765328193L) #define KRB5_KT_TYPE_EXISTS (-1765328192L) #define KRB5_CC_IO (-1765328191L) #define KRB5_FCC_PERM (-1765328190L) #define KRB5_FCC_NOFILE (-1765328189L) #define KRB5_FCC_INTERNAL (-1765328188L) #define KRB5_CC_WRITE (-1765328187L) #define KRB5_CC_NOMEM (-1765328186L) #define KRB5_CC_FORMAT (-1765328185L) #define KRB5_CC_NOT_KTYPE (-1765328184L) #define KRB5_INVALID_FLAGS (-1765328183L) #define KRB5_NO_2ND_TKT (-1765328182L) #define KRB5_NOCREDS_SUPPLIED (-1765328181L) #define KRB5_SENDAUTH_BADAUTHVERS (-1765328180L) #define KRB5_SENDAUTH_BADAPPLVERS (-1765328179L) #define KRB5_SENDAUTH_BADRESPONSE (-1765328178L) #define KRB5_SENDAUTH_REJECTED (-1765328177L) #define KRB5_PREAUTH_BAD_TYPE (-1765328176L) #define KRB5_PREAUTH_NO_KEY (-1765328175L) #define KRB5_PREAUTH_FAILED (-1765328174L) #define KRB5_RCACHE_BADVNO (-1765328173L) #define KRB5_CCACHE_BADVNO (-1765328172L) #define KRB5_KEYTAB_BADVNO (-1765328171L) #define KRB5_PROG_ATYPE_NOSUPP (-1765328170L) #define KRB5_RC_REQUIRED (-1765328169L) #define KRB5_ERR_BAD_HOSTNAME (-1765328168L) #define KRB5_ERR_HOST_REALM_UNKNOWN (-1765328167L) #define KRB5_SNAME_UNSUPP_NAMETYPE (-1765328166L) #define KRB5KRB_AP_ERR_V4_REPLY (-1765328165L) #define KRB5_REALM_CANT_RESOLVE (-1765328164L) #define KRB5_TKT_NOT_FORWARDABLE (-1765328163L) #define KRB5_FWD_BAD_PRINCIPAL (-1765328162L) #define KRB5_GET_IN_TKT_LOOP (-1765328161L) #define KRB5_CONFIG_NODEFREALM (-1765328160L) #define KRB5_SAM_UNSUPPORTED (-1765328159L) #define KRB5_SAM_INVALID_ETYPE (-1765328158L) #define KRB5_SAM_NO_CHECKSUM (-1765328157L) #define KRB5_SAM_BAD_CHECKSUM (-1765328156L) #define KRB5_KT_NAME_TOOLONG (-1765328155L) #define KRB5_KT_KVNONOTFOUND (-1765328154L) #define KRB5_APPL_EXPIRED (-1765328153L) #define KRB5_LIB_EXPIRED (-1765328152L) #define KRB5_CHPW_PWDNULL (-1765328151L) #define KRB5_CHPW_FAIL (-1765328150L) #define KRB5_KT_FORMAT (-1765328149L) #define KRB5_NOPERM_ETYPE (-1765328148L) #define KRB5_CONFIG_ETYPE_NOSUPP (-1765328147L) #define KRB5_OBSOLETE_FN (-1765328146L) #define KRB5_EAI_FAIL (-1765328145L) #define KRB5_EAI_NODATA (-1765328144L) #define KRB5_EAI_NONAME (-1765328143L) #define KRB5_EAI_SERVICE (-1765328142L) #define KRB5_ERR_NUMERIC_REALM (-1765328141L) #define KRB5_ERR_BAD_S2K_PARAMS (-1765328140L) #define KRB5_ERR_NO_SERVICE (-1765328139L) #define KRB5_CC_READONLY (-1765328138L) #define KRB5_CC_NOSUPP (-1765328137L) #define KRB5_DELTAT_BADFORMAT (-1765328136L) #define KRB5_PLUGIN_NO_HANDLE (-1765328135L) #define KRB5_PLUGIN_OP_NOTSUPP (-1765328134L) #define KRB5_ERR_INVALID_UTF8 (-1765328133L) #define KRB5_ERR_FAST_REQUIRED (-1765328132L) #define KRB5_LOCAL_ADDR_REQUIRED (-1765328131L) #define KRB5_REMOTE_ADDR_REQUIRED (-1765328130L) #define KRB5_TRACE_NOSUPP (-1765328129L) extern const struct error_table et_krb5_error_table; extern void initialize_krb5_error_table(void); /* For compatibility with Heimdal */ extern void initialize_krb5_error_table_r(struct et_list **list); #define ERROR_TABLE_BASE_krb5 (-1765328384L) /* for compatibility with older versions... */ #define init_krb5_err_tbl initialize_krb5_error_table #define krb5_err_base ERROR_TABLE_BASE_krb5 /* * et-h-k5e1_err.h: * This file is automatically generated; please do not edit it. */ #include <et/com_err.h> #define KRB5_PLUGIN_VER_NOTSUPP (-1750600192L) #define KRB5_PLUGIN_BAD_MODULE_SPEC (-1750600191L) #define KRB5_PLUGIN_NAME_NOTFOUND (-1750600190L) #define KRB5KDC_ERR_DISCARD (-1750600189L) #define KRB5_DCC_CANNOT_CREATE (-1750600188L) #define KRB5_KCC_INVALID_ANCHOR (-1750600187L) #define KRB5_KCC_UNKNOWN_VERSION (-1750600186L) #define KRB5_KCC_INVALID_UID (-1750600185L) #define KRB5_KCM_MALFORMED_REPLY (-1750600184L) #define KRB5_KCM_RPC_ERROR (-1750600183L) #define KRB5_KCM_REPLY_TOO_BIG (-1750600182L) #define KRB5_KCM_NO_SERVER (-1750600181L) #define KRB5_CERTAUTH_HWAUTH (-1750600180L) extern const struct error_table et_k5e1_error_table; extern void initialize_k5e1_error_table(void); /* For compatibility with Heimdal */ extern void initialize_k5e1_error_table_r(struct et_list **list); #define ERROR_TABLE_BASE_k5e1 (-1750600192L) /* for compatibility with older versions... */ #define init_k5e1_err_tbl initialize_k5e1_error_table #define k5e1_err_base ERROR_TABLE_BASE_k5e1 /* * et-h-kdb5_err.h: * This file is automatically generated; please do not edit it. */ #include <et/com_err.h> #define KRB5_KDB_RCSID (-1780008448L) #define KRB5_KDB_INUSE (-1780008447L) #define KRB5_KDB_UK_SERROR (-1780008446L) #define KRB5_KDB_UK_RERROR (-1780008445L) #define KRB5_KDB_UNAUTH (-1780008444L) #define KRB5_KDB_NOENTRY (-1780008443L) #define KRB5_KDB_ILL_WILDCARD (-1780008442L) #define KRB5_KDB_DB_INUSE (-1780008441L) #define KRB5_KDB_DB_CHANGED (-1780008440L) #define KRB5_KDB_TRUNCATED_RECORD (-1780008439L) #define KRB5_KDB_RECURSIVELOCK (-1780008438L) #define KRB5_KDB_NOTLOCKED (-1780008437L) #define KRB5_KDB_BADLOCKMODE (-1780008436L) #define KRB5_KDB_DBNOTINITED (-1780008435L) #define KRB5_KDB_DBINITED (-1780008434L) #define KRB5_KDB_ILLDIRECTION (-1780008433L) #define KRB5_KDB_NOMASTERKEY (-1780008432L) #define KRB5_KDB_BADMASTERKEY (-1780008431L) #define KRB5_KDB_INVALIDKEYSIZE (-1780008430L) #define KRB5_KDB_CANTREAD_STORED (-1780008429L) #define KRB5_KDB_BADSTORED_MKEY (-1780008428L) #define KRB5_KDB_NOACTMASTERKEY (-1780008427L) #define KRB5_KDB_KVNONOMATCH (-1780008426L) #define KRB5_KDB_STORED_MKEY_NOTCURRENT (-1780008425L) #define KRB5_KDB_CANTLOCK_DB (-1780008424L) #define KRB5_KDB_DB_CORRUPT (-1780008423L) #define KRB5_KDB_BAD_VERSION (-1780008422L) #define KRB5_KDB_BAD_SALTTYPE (-1780008421L) #define KRB5_KDB_BAD_ENCTYPE (-1780008420L) #define KRB5_KDB_BAD_CREATEFLAGS (-1780008419L) #define KRB5_KDB_NO_PERMITTED_KEY (-1780008418L) #define KRB5_KDB_NO_MATCHING_KEY (-1780008417L) #define KRB5_KDB_DBTYPE_NOTFOUND (-1780008416L) #define KRB5_KDB_DBTYPE_NOSUP (-1780008415L) #define KRB5_KDB_DBTYPE_INIT (-1780008414L) #define KRB5_KDB_SERVER_INTERNAL_ERR (-1780008413L) #define KRB5_KDB_ACCESS_ERROR (-1780008412L) #define KRB5_KDB_INTERNAL_ERROR (-1780008411L) #define KRB5_KDB_CONSTRAINT_VIOLATION (-1780008410L) #define KRB5_LOG_CONV (-1780008409L) #define KRB5_LOG_UNSTABLE (-1780008408L) #define KRB5_LOG_CORRUPT (-1780008407L) #define KRB5_LOG_ERROR (-1780008406L) #define KRB5_KDB_DBTYPE_MISMATCH (-1780008405L) #define KRB5_KDB_POLICY_REF (-1780008404L) #define KRB5_KDB_STRINGS_TOOLONG (-1780008403L) extern const struct error_table et_kdb5_error_table; extern void initialize_kdb5_error_table(void); /* For compatibility with Heimdal */ extern void initialize_kdb5_error_table_r(struct et_list **list); #define ERROR_TABLE_BASE_kdb5 (-1780008448L) /* for compatibility with older versions... */ #define init_kdb5_err_tbl initialize_kdb5_error_table #define kdb5_err_base ERROR_TABLE_BASE_kdb5 /* * et-h-kv5m_err.h: * This file is automatically generated; please do not edit it. */ #include <et/com_err.h> #define KV5M_NONE (-1760647424L) #define KV5M_PRINCIPAL (-1760647423L) #define KV5M_DATA (-1760647422L) #define KV5M_KEYBLOCK (-1760647421L) #define KV5M_CHECKSUM (-1760647420L) #define KV5M_ENCRYPT_BLOCK (-1760647419L) #define KV5M_ENC_DATA (-1760647418L) #define KV5M_CRYPTOSYSTEM_ENTRY (-1760647417L) #define KV5M_CS_TABLE_ENTRY (-1760647416L) #define KV5M_CHECKSUM_ENTRY (-1760647415L) #define KV5M_AUTHDATA (-1760647414L) #define KV5M_TRANSITED (-1760647413L) #define KV5M_ENC_TKT_PART (-1760647412L) #define KV5M_TICKET (-1760647411L) #define KV5M_AUTHENTICATOR (-1760647410L) #define KV5M_TKT_AUTHENT (-1760647409L) #define KV5M_CREDS (-1760647408L) #define KV5M_LAST_REQ_ENTRY (-1760647407L) #define KV5M_PA_DATA (-1760647406L) #define KV5M_KDC_REQ (-1760647405L) #define KV5M_ENC_KDC_REP_PART (-1760647404L) #define KV5M_KDC_REP (-1760647403L) #define KV5M_ERROR (-1760647402L) #define KV5M_AP_REQ (-1760647401L) #define KV5M_AP_REP (-1760647400L) #define KV5M_AP_REP_ENC_PART (-1760647399L) #define KV5M_RESPONSE (-1760647398L) #define KV5M_SAFE (-1760647397L) #define KV5M_PRIV (-1760647396L) #define KV5M_PRIV_ENC_PART (-1760647395L) #define KV5M_CRED (-1760647394L) #define KV5M_CRED_INFO (-1760647393L) #define KV5M_CRED_ENC_PART (-1760647392L) #define KV5M_PWD_DATA (-1760647391L) #define KV5M_ADDRESS (-1760647390L) #define KV5M_KEYTAB_ENTRY (-1760647389L) #define KV5M_CONTEXT (-1760647388L) #define KV5M_OS_CONTEXT (-1760647387L) #define KV5M_ALT_METHOD (-1760647386L) #define KV5M_ETYPE_INFO_ENTRY (-1760647385L) #define KV5M_DB_CONTEXT (-1760647384L) #define KV5M_AUTH_CONTEXT (-1760647383L) #define KV5M_KEYTAB (-1760647382L) #define KV5M_RCACHE (-1760647381L) #define KV5M_CCACHE (-1760647380L) #define KV5M_PREAUTH_OPS (-1760647379L) #define KV5M_SAM_CHALLENGE (-1760647378L) #define KV5M_SAM_CHALLENGE_2 (-1760647377L) #define KV5M_SAM_KEY (-1760647376L) #define KV5M_ENC_SAM_RESPONSE_ENC (-1760647375L) #define KV5M_ENC_SAM_RESPONSE_ENC_2 (-1760647374L) #define KV5M_SAM_RESPONSE (-1760647373L) #define KV5M_SAM_RESPONSE_2 (-1760647372L) #define KV5M_PREDICTED_SAM_RESPONSE (-1760647371L) #define KV5M_PASSWD_PHRASE_ELEMENT (-1760647370L) #define KV5M_GSS_OID (-1760647369L) #define KV5M_GSS_QUEUE (-1760647368L) #define KV5M_FAST_ARMORED_REQ (-1760647367L) #define KV5M_FAST_REQ (-1760647366L) #define KV5M_FAST_RESPONSE (-1760647365L) #define KV5M_AUTHDATA_CONTEXT (-1760647364L) extern const struct error_table et_kv5m_error_table; extern void initialize_kv5m_error_table(void); /* For compatibility with Heimdal */ extern void initialize_kv5m_error_table_r(struct et_list **list); #define ERROR_TABLE_BASE_kv5m (-1760647424L) /* for compatibility with older versions... */ #define init_kv5m_err_tbl initialize_kv5m_error_table #define kv5m_err_base ERROR_TABLE_BASE_kv5m /* * et-h-krb524_err.h: * This file is automatically generated; please do not edit it. */ #include <et/com_err.h> #define KRB524_BADKEY (-1750206208L) #define KRB524_BADADDR (-1750206207L) #define KRB524_BADPRINC (-1750206206L) #define KRB524_BADREALM (-1750206205L) #define KRB524_V4ERR (-1750206204L) #define KRB524_ENCFULL (-1750206203L) #define KRB524_DECEMPTY (-1750206202L) #define KRB524_NOTRESP (-1750206201L) #define KRB524_KRB4_DISABLED (-1750206200L) extern const struct error_table et_k524_error_table; extern void initialize_k524_error_table(void); /* For compatibility with Heimdal */ extern void initialize_k524_error_table_r(struct et_list **list); #define ERROR_TABLE_BASE_k524 (-1750206208L) /* for compatibility with older versions... */ #define init_k524_err_tbl initialize_k524_error_table #define k524_err_base ERROR_TABLE_BASE_k524 /* * et-h-asn1_err.h: * This file is automatically generated; please do not edit it. */ #include <et/com_err.h> #define ASN1_BAD_TIMEFORMAT (1859794432L) #define ASN1_MISSING_FIELD (1859794433L) #define ASN1_MISPLACED_FIELD (1859794434L) #define ASN1_TYPE_MISMATCH (1859794435L) #define ASN1_OVERFLOW (1859794436L) #define ASN1_OVERRUN (1859794437L) #define ASN1_BAD_ID (1859794438L) #define ASN1_BAD_LENGTH (1859794439L) #define ASN1_BAD_FORMAT (1859794440L) #define ASN1_PARSE_ERROR (1859794441L) #define ASN1_BAD_GMTIME (1859794442L) #define ASN1_MISMATCH_INDEF (1859794443L) #define ASN1_MISSING_EOC (1859794444L) #define ASN1_OMITTED (1859794445L) extern const struct error_table et_asn1_error_table; extern void initialize_asn1_error_table(void); /* For compatibility with Heimdal */ extern void initialize_asn1_error_table_r(struct et_list **list); #define ERROR_TABLE_BASE_asn1 (1859794432L) /* for compatibility with older versions... */ #define init_asn1_err_tbl initialize_asn1_error_table #define asn1_err_base ERROR_TABLE_BASE_asn1 #endif /* KRB5_KRB5_H_INCLUDED */ krb5/pwqual_plugin.h 0000644 00000010512 15146341150 0010446 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2010 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * Declarations for password quality plugin module implementors. * * The password quality pluggable interface currently has only one supported * major version, which is 1. Major version 1 has a current minor version * number of 1. * * Password quality plugin modules should define a function named * pwqual_<modulename>_initvt, matching the signature: * * krb5_error_code * pwqual_modname_initvt(krb5_context context, int maj_ver, int min_ver, * krb5_plugin_vtable vtable); * * The initvt function should: * * - Check that the supplied maj_ver number is supported by the module, or * return KRB5_PLUGIN_VER_NOTSUPP if it is not. * * - Cast the vtable pointer as appropriate for maj_ver: * maj_ver == 1: Cast to krb5_pwqual_vtable * * - Initialize the methods of the vtable, stopping as appropriate for the * supplied min_ver. Optional methods may be left uninitialized. * * Memory for the vtable is allocated by the caller, not by the module. */ #ifndef KRB5_PWQUAL_PLUGIN_H #define KRB5_PWQUAL_PLUGIN_H #include <krb5/krb5.h> #include <krb5/plugin.h> #include <kadm5/admin.h> /* An abstract type for password quality module data. */ typedef struct krb5_pwqual_moddata_st *krb5_pwqual_moddata; /*** Method type declarations ***/ /* Optional: Initialize module data. dictfile is the realm's configured * dictionary filename. */ typedef krb5_error_code (*krb5_pwqual_open_fn)(krb5_context context, const char *dict_file, krb5_pwqual_moddata *data); /* * Mandatory: Check a password for the principal princ, which has an associated * password policy named policy_name (or no associated policy if policy_name is * NULL). The parameter languages, if not NULL, contains a null-terminated * list of client-specified language tags as defined in RFC 5646. The method * should return one of the following errors if the password fails quality * standards: * * - KADM5_PASS_Q_TOOSHORT: password should be longer * - KADM5_PASS_Q_CLASS: password must have more character classes * - KADM5_PASS_Q_DICT: password contains dictionary words * - KADM5_PASS_Q_GENERIC: unspecified quality failure * * The module should also set an extended error message with * krb5_set_error_message(). The message may be localized according to one of * the language tags in languages. */ typedef krb5_error_code (*krb5_pwqual_check_fn)(krb5_context context, krb5_pwqual_moddata data, const char *password, const char *policy_name, krb5_principal princ, const char **languages); /* Optional: Release resources used by module data. */ typedef void (*krb5_pwqual_close_fn)(krb5_context context, krb5_pwqual_moddata data); /*** vtable declarations **/ /* Password quality plugin vtable for major version 1. */ typedef struct krb5_pwqual_vtable_st { const char *name; /* Mandatory: name of module. */ krb5_pwqual_open_fn open; krb5_pwqual_check_fn check; krb5_pwqual_close_fn close; /* Minor version 1 ends here. */ } *krb5_pwqual_vtable; #endif /* KRB5_PWQUAL_PLUGIN_H */ krb5/kdcpreauth_plugin.h 0000644 00000042172 15146341150 0011276 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 2006 Red Hat, Inc. * Portions copyright (c) 2006, 2011 Massachusetts Institute of Technology * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Red Hat, Inc., 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER * 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. */ /* * Declarations for kdcpreauth plugin module implementors. * * The kdcpreauth interface has a single supported major version, which is 1. * Major version 1 has a current minor version of 2. kdcpreauth modules should * define a function named kdcpreauth_<modulename>_initvt, matching the * signature: * * krb5_error_code * kdcpreauth_modname_initvt(krb5_context context, int maj_ver, int min_ver, * krb5_plugin_vtable vtable); * * The initvt function should: * * - Check that the supplied maj_ver number is supported by the module, or * return KRB5_PLUGIN_VER_NOTSUPP if it is not. * * - Cast the vtable pointer as appropriate for the interface and maj_ver: * kdcpreauth, maj_ver == 1: Cast to krb5_kdcpreauth_vtable * * - Initialize the methods of the vtable, stopping as appropriate for the * supplied min_ver. Optional methods may be left uninitialized. * * Memory for the vtable is allocated by the caller, not by the module. */ #ifndef KRB5_KDCPREAUTH_PLUGIN_H #define KRB5_KDCPREAUTH_PLUGIN_H #include <krb5/krb5.h> #include <krb5/plugin.h> /* kdcpreauth mechanism property flags */ /* * Causes the KDC to include this mechanism in a list of supported preauth * types if the user's DB entry flags the user as requiring hardware-based * preauthentication. */ #define PA_HARDWARE 0x00000004 /* * Causes the KDC to include this mechanism in a list of supported preauth * types if the user's DB entry flags the user as requiring preauthentication, * and to fail preauthentication if we can't verify the client data. The * flipside of PA_SUFFICIENT. */ #define PA_REQUIRED 0x00000008 /* * Causes the KDC to include this mechanism in a list of supported preauth * types if the user's DB entry flags the user as requiring preauthentication, * and to mark preauthentication as successful if we can verify the client * data. The flipside of PA_REQUIRED. */ #define PA_SUFFICIENT 0x00000010 /* * Marks this preauthentication mechanism as one which changes the key which is * used for encrypting the response to the client. Modules which have this * flag have their server_return_fn called before modules which do not, and are * passed over if a previously-called module has modified the encrypting key. */ #define PA_REPLACES_KEY 0x00000020 /* * Not really a padata type, so don't include it in any list of preauth types * which gets sent over the wire. */ #define PA_PSEUDO 0x00000080 /* * Indicates that e_data in non-FAST errors should be encoded as typed data * instead of padata. */ #define PA_TYPED_E_DATA 0x00000100 /* Abstract type for a KDC callback data handle. */ typedef struct krb5_kdcpreauth_rock_st *krb5_kdcpreauth_rock; /* Abstract type for module data and per-request module data. */ typedef struct krb5_kdcpreauth_moddata_st *krb5_kdcpreauth_moddata; typedef struct krb5_kdcpreauth_modreq_st *krb5_kdcpreauth_modreq; /* The verto context structure type (typedef is in verto.h; we want to avoid a * header dependency for the moment). */ struct verto_ctx; /* Before using a callback after version 1, modules must check the vers * field of the callback structure. */ typedef struct krb5_kdcpreauth_callbacks_st { int vers; krb5_deltat (*max_time_skew)(krb5_context context, krb5_kdcpreauth_rock rock); /* * Get an array of krb5_keyblock structures containing the client keys * matching the request enctypes, terminated by an entry with key type = 0. * Returns ENOENT if no keys are available for the request enctypes. Free * the resulting object with the free_keys callback. */ krb5_error_code (*client_keys)(krb5_context context, krb5_kdcpreauth_rock rock, krb5_keyblock **keys_out); /* Free the result of client_keys. */ void (*free_keys)(krb5_context context, krb5_kdcpreauth_rock rock, krb5_keyblock *keys); /* * Get the encoded request body, which is sometimes needed for checksums. * For a FAST request this is the encoded inner request body. The returned * pointer is an alias and should not be freed. */ krb5_data *(*request_body)(krb5_context context, krb5_kdcpreauth_rock rock); /* Get a pointer to the FAST armor key, or NULL if the request did not use * FAST. The returned pointer is an alias and should not be freed. */ krb5_keyblock *(*fast_armor)(krb5_context context, krb5_kdcpreauth_rock rock); /* Retrieve a string attribute from the client DB entry, or NULL if no such * attribute is set. Free the result with the free_string callback. */ krb5_error_code (*get_string)(krb5_context context, krb5_kdcpreauth_rock rock, const char *key, char **value_out); /* Free the result of get_string. */ void (*free_string)(krb5_context context, krb5_kdcpreauth_rock rock, char *string); /* Get a pointer to the client DB entry (returned as a void pointer to * avoid a dependency on a libkdb5 type). */ void *(*client_entry)(krb5_context context, krb5_kdcpreauth_rock rock); /* Get a pointer to the verto context which should be used by an * asynchronous edata or verify method. */ struct verto_ctx *(*event_context)(krb5_context context, krb5_kdcpreauth_rock rock); /* End of version 1 kdcpreauth callbacks. */ /* Return true if the client DB entry contains any keys matching the * request enctypes. */ krb5_boolean (*have_client_keys)(krb5_context context, krb5_kdcpreauth_rock rock); /* End of version 2 kdcpreauth callbacks. */ /* * Get the decrypted client long-term key chosen according to the request * enctype list, or NULL if no matching key was found. The returned * pointer is an alias and should not be freed. If invoked from * return_padata, the result will be the same as the encrypting_key * parameter if it is not NULL, and will therefore reflect the modified * reply key if a return_padata handler has replaced the reply key. */ const krb5_keyblock *(*client_keyblock)(krb5_context context, krb5_kdcpreauth_rock rock); /* Assert an authentication indicator in the AS-REP authdata. Duplicate * indicators will be ignored. */ krb5_error_code (*add_auth_indicator)(krb5_context context, krb5_kdcpreauth_rock rock, const char *indicator); /* * Read a data value for pa_type from the request cookie, placing it in * *out. The value placed there is an alias and must not be freed. * Returns true if a value for pa_type was retrieved, false if not. */ krb5_boolean (*get_cookie)(krb5_context context, krb5_kdcpreauth_rock rock, krb5_preauthtype pa_type, krb5_data *out); /* * Set a data value for pa_type to be sent in a secure cookie in the next * error response. If pa_type is already present, the value is ignored. * If the preauth mechanism has different preauth types for requests and * responses, use the request type. Secure cookies are encrypted in a key * known only to the KDCs, but can be replayed within a short time window * for requests using the same client principal. */ krb5_error_code (*set_cookie)(krb5_context context, krb5_kdcpreauth_rock rock, krb5_preauthtype pa_type, const krb5_data *data); /* End of version 3 kdcpreauth callbacks. */ /* * Return true if princ matches the principal named in the request or the * client principal (possibly canonicalized). If princ does not match, * attempt a database lookup of princ with aliases allowed and compare the * result to the client principal, returning true if it matches. * Otherwise, return false. */ krb5_boolean (*match_client)(krb5_context context, krb5_kdcpreauth_rock rock, krb5_principal princ); /* * Get an alias to the client DB entry principal (possibly canonicalized). */ krb5_principal (*client_name)(krb5_context context, krb5_kdcpreauth_rock rock); /* End of version 4 kdcpreauth callbacks. */ /* * Instruct the KDC to send a freshness token in the method data * accompanying a PREAUTH_REQUIRED or PREAUTH_FAILED error, if the client * indicated support for freshness tokens. This callback should only be * invoked from the edata method. */ void (*send_freshness_token)(krb5_context context, krb5_kdcpreauth_rock rock); /* Validate a freshness token sent by the client. Return 0 on success, * KRB5KDC_ERR_PREAUTH_EXPIRED on error. */ krb5_error_code (*check_freshness_token)(krb5_context context, krb5_kdcpreauth_rock rock, const krb5_data *token); /* End of version 5 kdcpreauth callbacks. */ } *krb5_kdcpreauth_callbacks; /* Optional: preauth plugin initialization function. */ typedef krb5_error_code (*krb5_kdcpreauth_init_fn)(krb5_context context, krb5_kdcpreauth_moddata *moddata_out, const char **realmnames); /* Optional: preauth plugin cleanup function. */ typedef void (*krb5_kdcpreauth_fini_fn)(krb5_context context, krb5_kdcpreauth_moddata moddata); /* * Optional: return the flags which the KDC should use for this module. This * is a callback instead of a static value because the module may or may not * wish to count itself as a hardware preauthentication module (in other words, * the flags may be affected by the configuration, for example if a site * administrator can force a particular preauthentication type to be supported * using only hardware). This function is called for each entry entry in the * server_pa_type_list. */ typedef int (*krb5_kdcpreauth_flags_fn)(krb5_context context, krb5_preauthtype pa_type); /* * Responder for krb5_kdcpreauth_edata_fn. If invoked with a non-zero code, pa * will be ignored and the padata type will not be included in the hint list. * If invoked with a zero code and a null pa value, the padata type will be * included in the list with an empty value. If invoked with a zero code and a * non-null pa value, pa will be included in the hint list and will later be * freed by the KDC. */ typedef void (*krb5_kdcpreauth_edata_respond_fn)(void *arg, krb5_error_code code, krb5_pa_data *pa); /* * Optional: provide pa_data to send to the client as part of the "you need to * use preauthentication" error. The implementation must invoke the respond * when complete, whether successful or not, either before returning or * asynchronously using the verto context returned by cb->event_context(). * * This function is not allowed to create a modreq object because we have no * guarantee that the client will ever make a follow-up request, or that it * will hit this KDC if it does. */ typedef void (*krb5_kdcpreauth_edata_fn)(krb5_context context, krb5_kdc_req *request, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_preauthtype pa_type, krb5_kdcpreauth_edata_respond_fn respond, void *arg); /* * Responder for krb5_kdcpreauth_verify_fn. Invoke with the arg parameter * supplied to verify, the error code (0 for success), an optional module * request state object to be consumed by return_fn or free_modreq_fn, optional * e_data to be passed to the caller if code is nonzero, and optional * authorization data to be included in the ticket. In non-FAST replies, * e_data will be encoded as typed-data if the module sets the PA_TYPED_E_DATA * flag, and as pa-data otherwise. e_data and authz_data will be freed by the * KDC. */ typedef void (*krb5_kdcpreauth_verify_respond_fn)(void *arg, krb5_error_code code, krb5_kdcpreauth_modreq modreq, krb5_pa_data **e_data, krb5_authdata **authz_data); /* * Optional: verify preauthentication data sent by the client, setting the * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags" * field as appropriate. The implementation must invoke the respond function * when complete, whether successful or not, either before returning or * asynchronously using the verto context returned by cb->event_context(). */ typedef void (*krb5_kdcpreauth_verify_fn)(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *data, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_verify_respond_fn respond, void *arg); /* * Optional: generate preauthentication response data to send to the client as * part of the AS-REP. If it needs to override the key which is used to * encrypt the response, it can do so. */ typedef krb5_error_code (*krb5_kdcpreauth_return_fn)(krb5_context context, krb5_pa_data *padata, krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply, krb5_keyblock *encrypting_key, krb5_pa_data **send_pa_out, krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq); /* Optional: free a per-request context. */ typedef void (*krb5_kdcpreauth_free_modreq_fn)(krb5_context, krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq); /* Optional: invoked after init_fn to provide the module with a pointer to the * verto main loop. */ typedef krb5_error_code (*krb5_kdcpreauth_loop_fn)(krb5_context context, krb5_kdcpreauth_moddata moddata, struct verto_ctx *ctx); typedef struct krb5_kdcpreauth_vtable_st { /* Mandatory: name of module. */ char *name; /* Mandatory: pointer to zero-terminated list of pa_types which this module * can provide services for. */ krb5_preauthtype *pa_type_list; krb5_kdcpreauth_init_fn init; krb5_kdcpreauth_fini_fn fini; krb5_kdcpreauth_flags_fn flags; krb5_kdcpreauth_edata_fn edata; krb5_kdcpreauth_verify_fn verify; krb5_kdcpreauth_return_fn return_padata; krb5_kdcpreauth_free_modreq_fn free_modreq; /* Minor 1 ends here. */ krb5_kdcpreauth_loop_fn loop; /* Minor 2 ends here. */ } *krb5_kdcpreauth_vtable; #endif /* KRB5_KDCPREAUTH_PLUGIN_H */ krb5/certauth_plugin.h 0000644 00000011771 15146341150 0010764 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* include/krb5/certauth_plugin.h - certauth plugin header. */ /* * Copyright (C) 2017 by Red Hat, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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 COPYRIGHT HOLDERS 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 * COPYRIGHT HOLDER 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. */ /* * Declarations for certauth plugin module implementors. * * The certauth pluggable interface currently has only one supported major * version, which is 1. Major version 1 has a current minor version number of * 1. * * certauth plugin modules should define a function named * certauth_<modulename>_initvt, matching the signature: * * krb5_error_code * certauth_modname_initvt(krb5_context context, int maj_ver, int min_ver, * krb5_plugin_vtable vtable); * * The initvt function should: * * - Check that the supplied maj_ver number is supported by the module, or * return KRB5_PLUGIN_VER_NOTSUPP if it is not. * * - Cast the vtable pointer as appropriate for maj_ver: * maj_ver == 1: Cast to krb5_certauth_vtable * * - Initialize the methods of the vtable, stopping as appropriate for the * supplied min_ver. Optional methods may be left uninitialized. * * Memory for the vtable is allocated by the caller, not by the module. */ #ifndef KRB5_CERTAUTH_PLUGIN_H #define KRB5_CERTAUTH_PLUGIN_H #include <krb5/krb5.h> #include <krb5/plugin.h> /* Abstract module data type. */ typedef struct krb5_certauth_moddata_st *krb5_certauth_moddata; /* A module can optionally include <kdb.h> to inspect the client principal * entry when authorizing a request. */ struct _krb5_db_entry_new; /* * Optional: Initialize module data. */ typedef krb5_error_code (*krb5_certauth_init_fn)(krb5_context context, krb5_certauth_moddata *moddata_out); /* * Optional: Clean up the module data. */ typedef void (*krb5_certauth_fini_fn)(krb5_context context, krb5_certauth_moddata moddata); /* * Mandatory: return 0 or KRB5_CERTAUTH_HWAUTH if the DER-encoded cert is * authorized for PKINIT authentication by princ; otherwise return one of the * following error codes: * - KRB5KDC_ERR_CLIENT_NAME_MISMATCH - incorrect SAN value * - KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE - incorrect EKU * - KRB5KDC_ERR_CERTIFICATE_MISMATCH - other extension error * - KRB5_PLUGIN_NO_HANDLE - the module has no opinion about cert * * Returning KRB5_CERTAUTH_HWAUTH will cause the hw-authent flag to be set in * the issued ticket (new in release 1.19). * * - opts is used by built-in modules to receive internal data, and must be * ignored by other modules. * - db_entry receives the client principal database entry, and can be ignored * by modules that do not link with libkdb5. * - *authinds_out optionally returns a null-terminated list of authentication * indicator strings upon KRB5_PLUGIN_NO_HANDLE or accepted authorization. */ typedef krb5_error_code (*krb5_certauth_authorize_fn)(krb5_context context, krb5_certauth_moddata moddata, const uint8_t *cert, size_t cert_len, krb5_const_principal princ, const void *opts, const struct _krb5_db_entry_new *db_entry, char ***authinds_out); /* * Free indicators allocated by a module. Mandatory if authorize returns * authentication indicators. */ typedef void (*krb5_certauth_free_indicator_fn)(krb5_context context, krb5_certauth_moddata moddata, char **authinds); typedef struct krb5_certauth_vtable_st { const char *name; krb5_certauth_init_fn init; krb5_certauth_fini_fn fini; krb5_certauth_authorize_fn authorize; krb5_certauth_free_indicator_fn free_ind; } *krb5_certauth_vtable; #endif /* KRB5_CERTAUTH_PLUGIN_H */ krb5/kdcpolicy_plugin.h 0000644 00000012310 15146341150 0011114 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* include/krb5/kdcpolicy_plugin.h - KDC policy plugin interface */ /* * Copyright (C) 2017 by Red Hat, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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 COPYRIGHT HOLDERS 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 * COPYRIGHT HOLDER 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. */ /* * Declarations for kdcpolicy plugin module implementors. * * The kdcpolicy pluggable interface currently has only one supported major * version, which is 1. Major version 1 has a current minor version number of * 1. * * kdcpolicy plugin modules should define a function named * kdcpolicy_<modulename>_initvt, matching the signature: * * krb5_error_code * kdcpolicy_modname_initvt(krb5_context context, int maj_ver, int min_ver, * krb5_plugin_vtable vtable); * * The initvt function should: * * - Check that the supplied maj_ver number is supported by the module, or * return KRB5_PLUGIN_VER_NOTSUPP if it is not. * * - Cast the vtable pointer as appropriate for maj_ver: * maj_ver == 1: Cast to krb5_kdcpolicy_vtable * * - Initialize the methods of the vtable, stopping as appropriate for the * supplied min_ver. Optional methods may be left uninitialized. * * Memory for the vtable is allocated by the caller, not by the module. */ #ifndef KRB5_POLICY_PLUGIN_H #define KRB5_POLICY_PLUGIN_H #include <krb5/krb5.h> /* Abstract module datatype. */ typedef struct krb5_kdcpolicy_moddata_st *krb5_kdcpolicy_moddata; /* A module can optionally include kdb.h to inspect principal entries when * authorizing requests. */ struct _krb5_db_entry_new; /* * Optional: Initialize module data. Return 0 on success, * KRB5_PLUGIN_NO_HANDLE if the module is inoperable (due to configuration, for * example), and any other error code to abort KDC startup. Optionally set * *data_out to a module data object to be passed to future calls. */ typedef krb5_error_code (*krb5_kdcpolicy_init_fn)(krb5_context context, krb5_kdcpolicy_moddata *data_out); /* Optional: Clean up module data. */ typedef krb5_error_code (*krb5_kdcpolicy_fini_fn)(krb5_context context, krb5_kdcpolicy_moddata moddata); /* * Optional: return an error code and set status to an appropriate string * literal to deny an AS request; otherwise return 0. lifetime_out, if set, * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the * ticket renewable lifetime. */ typedef krb5_error_code (*krb5_kdcpolicy_check_as_fn)(krb5_context context, krb5_kdcpolicy_moddata moddata, const krb5_kdc_req *request, const struct _krb5_db_entry_new *client, const struct _krb5_db_entry_new *server, const char *const *auth_indicators, const char **status, krb5_deltat *lifetime_out, krb5_deltat *renew_lifetime_out); /* * Optional: return an error code and set status to an appropriate string * literal to deny a TGS request; otherwise return 0. lifetime_out, if set, * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the * ticket renewable lifetime. */ typedef krb5_error_code (*krb5_kdcpolicy_check_tgs_fn)(krb5_context context, krb5_kdcpolicy_moddata moddata, const krb5_kdc_req *request, const struct _krb5_db_entry_new *server, const krb5_ticket *ticket, const char *const *auth_indicators, const char **status, krb5_deltat *lifetime_out, krb5_deltat *renew_lifetime_out); typedef struct krb5_kdcpolicy_vtable_st { const char *name; krb5_kdcpolicy_init_fn init; krb5_kdcpolicy_fini_fn fini; krb5_kdcpolicy_check_as_fn check_as; krb5_kdcpolicy_check_tgs_fn check_tgs; } *krb5_kdcpolicy_vtable; #endif /* KRB5_POLICY_PLUGIN_H */ krb5/hostrealm_plugin.h 0000644 00000012524 15146341150 0011140 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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 COPYRIGHT HOLDERS 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 * COPYRIGHT HOLDER 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. */ /* * Declarations for hostrealm plugin module implementors. * * The hostrealm pluggable interface currently has only one supported major * version, which is 1. Major version 1 has a current minor version number of * 1. * * Hostrealm plugin modules should define a function named * hostrealm_<modulename>_initvt, matching the signature: * * krb5_error_code * hostrealm_modname_initvt(krb5_context context, int maj_ver, int min_ver, * krb5_plugin_vtable vtable); * * The initvt function should: * * - Check that the supplied maj_ver number is supported by the module, or * return KRB5_PLUGIN_VER_NOTSUPP if it is not. * * - Cast the vtable pointer as appropriate for maj_ver: * maj_ver == 1: Cast to krb5_hostrealm_vtable * * - Initialize the methods of the vtable, stopping as appropriate for the * supplied min_ver. Optional methods may be left uninitialized. * * Memory for the vtable is allocated by the caller, not by the module. */ #ifndef KRB5_HOSTREALM_PLUGIN_H #define KRB5_HOSTREALM_PLUGIN_H #include <krb5/krb5.h> #include <krb5/plugin.h> /* An abstract type for hostrealm module data. */ typedef struct krb5_hostrealm_moddata_st *krb5_hostrealm_moddata; /*** Method type declarations ***/ /* Optional: Initialize module data. */ typedef krb5_error_code (*krb5_hostrealm_init_fn)(krb5_context context, krb5_hostrealm_moddata *data); /* * Optional: Determine the possible realms of a hostname, using only secure, * authoritative mechanisms (ones which should be used prior to trying * referrals when getting a service ticket). Return success with a * null-terminated list of realms in *realms_out, KRB5_PLUGIN_NO_HANDLE to * defer to later modules, or another error to terminate processing. */ typedef krb5_error_code (*krb5_hostrealm_host_realm_fn)(krb5_context context, krb5_hostrealm_moddata data, const char *host, char ***realms_out); /* * Optional: Determine the possible realms of a hostname, using heuristic or * less secure mechanisms (ones which should be used after trying referrals * when getting a service ticket). Return success with a null-terminated list * of realms in *realms_out, KRB5_PLUGIN_NO_HANDLE to defer to later modules, * or another error to terminate processing. */ typedef krb5_error_code (*krb5_hostrealm_fallback_realm_fn)(krb5_context context, krb5_hostrealm_moddata data, const char *host, char ***realms_out); /* * Optional: Determine the possible default realms of the local host. Return * success with a null-terminated list of realms in *realms_out, * KRB5_PLUGIN_NO_HANDLE to defer to later modules, or another error to * terminate processing. */ typedef krb5_error_code (*krb5_hostrealm_default_realm_fn)(krb5_context context, krb5_hostrealm_moddata data, char ***realms_out); /* * Mandatory (if any of the query methods are implemented): Release the memory * returned by one of the interface methods. */ typedef void (*krb5_hostrealm_free_list_fn)(krb5_context context, krb5_hostrealm_moddata data, char **list); /* Optional: Release resources used by module data. */ typedef void (*krb5_hostrealm_fini_fn)(krb5_context context, krb5_hostrealm_moddata data); /* hostrealm vtable for major version 1. */ typedef struct krb5_hostrealm_vtable_st { const char *name; /* Mandatory: name of module. */ krb5_hostrealm_init_fn init; krb5_hostrealm_fini_fn fini; krb5_hostrealm_host_realm_fn host_realm; krb5_hostrealm_fallback_realm_fn fallback_realm; krb5_hostrealm_default_realm_fn default_realm; krb5_hostrealm_free_list_fn free_list; /* Minor version 1 ends here. */ } *krb5_hostrealm_vtable; #endif /* KRB5_HOSTREALM_PLUGIN_H */ krb5/localauth_plugin.h 0000644 00000013371 15146341150 0011117 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2013 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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 COPYRIGHT HOLDERS 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 * COPYRIGHT HOLDER 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. */ /* * Declarations for localauth plugin module implementors. * * The localauth pluggable interface currently has only one supported major * version, which is 1. Major version 1 has a current minor version number of * 1. * * Localauth plugin modules should define a function named * localauth_<modulename>_initvt, matching the signature: * * krb5_error_code * localauth_modname_initvt(krb5_context context, int maj_ver, int min_ver, * krb5_plugin_vtable vtable); * * The initvt function should: * * - Check that the supplied maj_ver number is supported by the module, or * return KRB5_PLUGIN_VER_NOTSUPP if it is not. * * - Cast the vtable pointer as appropriate for maj_ver: * maj_ver == 1: Cast to krb5_localauth_vtable * * - Initialize the methods of the vtable, stopping as appropriate for the * supplied min_ver. Optional methods may be left uninitialized. * * Memory for the vtable is allocated by the caller, not by the module. */ #ifndef KRB5_LOCALAUTH_PLUGIN_H #define KRB5_LOCALAUTH_PLUGIN_H #include <krb5/krb5.h> #include <krb5/plugin.h> /* An abstract type for localauth module data. */ typedef struct krb5_localauth_moddata_st *krb5_localauth_moddata; /*** Method type declarations ***/ /* Optional: Initialize module data. */ typedef krb5_error_code (*krb5_localauth_init_fn)(krb5_context context, krb5_localauth_moddata *data); /* Optional: Release resources used by module data. */ typedef void (*krb5_localauth_fini_fn)(krb5_context context, krb5_localauth_moddata data); /* * Optional: Determine whether aname is authorized to log in as the local * account lname. Return 0 if aname is authorized, EPERM if aname is * authoritatively not authorized, KRB5_PLUGIN_NO_HANDLE if the module cannot * determine whether aname is authorized, and any other error code for a * serious failure to process the request. aname will be considered authorized * if at least one module returns 0 and all other modules return * KRB5_PLUGIN_NO_HANDLE. */ typedef krb5_error_code (*krb5_localauth_userok_fn)(krb5_context context, krb5_localauth_moddata data, krb5_const_principal aname, const char *lname); /* * Optional (mandatory if an2ln_types is set): Determine the local account name * corresponding to aname. Return 0 and set *lname_out if a mapping can be * determined; the contents of *lname_out will later be released with a call to * the module's free_string method. Return KRB5_LNAME_NOTRANS if no mapping * can be determined. Return any other error code for a serious failure to * process the request; this will halt the krb5_aname_to_localname operation. * * If the module's an2ln_types field is set, this method will only be invoked * when a profile "auth_to_local" value references one of the module's types. * type and residual will be set to the type and residual of the auth_to_local * value. * * If the module's an2ln_types field is not set but the an2ln method is * implemented, this method will be invoked independently of the profile's * auth_to_local settings, with type and residual set to NULL. If multiple * modules are registered with an2ln methods but no an2ln_types field, the * order of invocation is not defined, but all such modules will be consulted * before the built-in mechanisms are tried. */ typedef krb5_error_code (*krb5_localauth_an2ln_fn)(krb5_context context, krb5_localauth_moddata data, const char *type, const char *residual, krb5_const_principal aname, char **lname_out); /* * Optional (mandatory if an2ln is implemented): Release the memory returned by * an invocation of an2ln. */ typedef void (*krb5_localauth_free_string_fn)(krb5_context context, krb5_localauth_moddata data, char *str); /* localauth vtable for major version 1. */ typedef struct krb5_localauth_vtable_st { const char *name; /* Mandatory: name of module. */ const char **an2ln_types; /* Optional: uppercase auth_to_local types */ krb5_localauth_init_fn init; krb5_localauth_fini_fn fini; krb5_localauth_userok_fn userok; krb5_localauth_an2ln_fn an2ln; krb5_localauth_free_string_fn free_string; /* Minor version 1 ends here. */ } *krb5_localauth_vtable; #endif /* KRB5_LOCALAUTH_PLUGIN_H */ krb5/clpreauth_plugin.h 0000644 00000036243 15146341150 0011135 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 2006 Red Hat, Inc. * Portions copyright (c) 2006, 2011 Massachusetts Institute of Technology * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Red Hat, Inc., 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER * 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. */ /* * Declarations for clpreauth plugin module implementors. * * The clpreauth interface has a single supported major version, which is * 1. Major version 1 has a current minor version of 2. clpreauth modules * should define a function named clpreauth_<modulename>_initvt, matching * the signature: * * krb5_error_code * clpreauth_modname_initvt(krb5_context context, int maj_ver, * int min_ver, krb5_plugin_vtable vtable); * The initvt function should: * * - Check that the supplied maj_ver number is supported by the module, or * return KRB5_PLUGIN_VER_NOTSUPP if it is not. * * - Cast the vtable pointer as appropriate for the interface and maj_ver: * maj_ver == 1: Cast to krb5_clpreauth_vtable * * - Initialize the methods of the vtable, stopping as appropriate for the * supplied min_ver. Optional methods may be left uninitialized. * * Memory for the vtable is allocated by the caller, not by the module. */ #ifndef KRB5_CLPREAUTH_PLUGIN_H #define KRB5_CLPREAUTH_PLUGIN_H #include <krb5/krb5.h> #include <krb5/plugin.h> /* clpreauth mechanism property flags */ /* Provides a real answer which we can send back to the KDC. The client * assumes that one real answer will be enough. */ #define PA_REAL 0x00000001 /* Doesn't provide a real answer, but must be given a chance to run before any * REAL mechanism callbacks. */ #define PA_INFO 0x00000002 /* Abstract type for a client request information handle. */ typedef struct krb5_clpreauth_rock_st *krb5_clpreauth_rock; /* Abstract types for module data and per-request module data. */ typedef struct krb5_clpreauth_moddata_st *krb5_clpreauth_moddata; typedef struct krb5_clpreauth_modreq_st *krb5_clpreauth_modreq; /* Before using a callback after version 1, modules must check the vers * field of the callback structure. */ typedef struct krb5_clpreauth_callbacks_st { int vers; /* * If an AS-REP has been received, return the enctype of the AS-REP * encrypted part. Otherwise return the enctype chosen from etype-info, or * the first requested enctype if no etype-info was received. */ krb5_enctype (*get_etype)(krb5_context context, krb5_clpreauth_rock rock); /* Get a pointer to the FAST armor key, or NULL if the client is not using * FAST. The returned pointer is an alias and should not be freed. */ krb5_keyblock *(*fast_armor)(krb5_context context, krb5_clpreauth_rock rock); /* * Get a pointer to the client-supplied reply key, possibly invoking the * prompter to ask for a password if this has not already been done. The * returned pointer is an alias and should not be freed. */ krb5_error_code (*get_as_key)(krb5_context context, krb5_clpreauth_rock rock, krb5_keyblock **keyblock); /* Replace the reply key to be used to decrypt the AS response. */ krb5_error_code (*set_as_key)(krb5_context context, krb5_clpreauth_rock rock, const krb5_keyblock *keyblock); /* End of version 1 clpreauth callbacks. */ /* * Get the current time for use in a preauth response. If * allow_unauth_time is true and the library has been configured to allow * it, the current time will be offset using unauthenticated timestamp * information received from the KDC in the preauth-required error, if one * has been received. Otherwise, the timestamp in a preauth-required error * will only be used if it is protected by a FAST channel. Only set * allow_unauth_time if using an unauthenticated time offset would not * create a security issue. */ krb5_error_code (*get_preauth_time)(krb5_context context, krb5_clpreauth_rock rock, krb5_boolean allow_unauth_time, krb5_timestamp *time_out, krb5_int32 *usec_out); /* Set a question to be answered by the responder and optionally provide * a challenge. */ krb5_error_code (*ask_responder_question)(krb5_context context, krb5_clpreauth_rock rock, const char *question, const char *challenge); /* Get an answer from the responder, or NULL if the question was * unanswered. */ const char *(*get_responder_answer)(krb5_context context, krb5_clpreauth_rock rock, const char *question); /* Indicate interest in the AS key through the responder interface. */ void (*need_as_key)(krb5_context context, krb5_clpreauth_rock rock); /* * Get a configuration/state item from an input ccache, which may allow it * to retrace the steps it took last time. The returned data string is an * alias and should not be freed. */ const char *(*get_cc_config)(krb5_context context, krb5_clpreauth_rock rock, const char *key); /* * Set a configuration/state item which will be recorded to an output * ccache, if the calling application supplied one. Both key and data * should be valid UTF-8 text. */ krb5_error_code (*set_cc_config)(krb5_context context, krb5_clpreauth_rock rock, const char *key, const char *data); /* End of version 2 clpreauth callbacks (added in 1.11). */ /* * Prevent further fallbacks to other preauth mechanisms if the KDC replies * with an error. (The module itself can still respond to errors with its * tryagain method, or continue after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED * errors with its process method.) A module should invoke this callback * from the process method when it generates an authenticated request using * credentials; often this will be the first or only client message * generated by the mechanism. */ void (*disable_fallback)(krb5_context context, krb5_clpreauth_rock rock); /* End of version 3 clpreauth callbacks (added in 1.17). */ } *krb5_clpreauth_callbacks; /* * Optional: per-plugin initialization/cleanup. The init function is called by * libkrb5 when the plugin is loaded, and the fini function is called before * the plugin is unloaded. These may be called multiple times in case the * plugin is used in multiple contexts. The returned context lives the * lifetime of the krb5_context. */ typedef krb5_error_code (*krb5_clpreauth_init_fn)(krb5_context context, krb5_clpreauth_moddata *moddata_out); typedef void (*krb5_clpreauth_fini_fn)(krb5_context context, krb5_clpreauth_moddata moddata); /* * Optional (mandatory before MIT krb5 1.12): pa_type will be a member of the * vtable's pa_type_list. Return PA_REAL if pa_type is a real * preauthentication type or PA_INFO if it is an informational type. If this * function is not defined in 1.12 or later, all pa_type values advertised by * the module will be assumed to be real. */ typedef int (*krb5_clpreauth_get_flags_fn)(krb5_context context, krb5_preauthtype pa_type); /* * Optional: per-request initialization/cleanup. The request_init function is * called when beginning to process a get_init_creds request and the * request_fini function is called when processing of the request is complete. * This is optional. It may be called multiple times in the lifetime of a * krb5_context. */ typedef void (*krb5_clpreauth_request_init_fn)(krb5_context context, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq *modreq_out); typedef void (*krb5_clpreauth_request_fini_fn)(krb5_context context, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq); /* * Optional: process server-supplied data in pa_data and set responder * questions. * * encoded_previous_request may be NULL if there has been no previous request * in the AS exchange. */ typedef krb5_error_code (*krb5_clpreauth_prep_questions_fn)(krb5_context context, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, krb5_pa_data *pa_data); /* * Mandatory: process server-supplied data in pa_data and return created data * in pa_data_out. Also called after the AS-REP is received if the AS-REP * includes preauthentication data of the associated type. * * as_key contains the client-supplied key if known, or an empty keyblock if * not. If it is empty, the module may use gak_fct to fill it in. * * encoded_previous_request may be NULL if there has been no previous request * in the AS exchange. */ typedef krb5_error_code (*krb5_clpreauth_process_fn)(krb5_context context, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, krb5_pa_data *pa_data, krb5_prompter_fct prompter, void *prompter_data, krb5_pa_data ***pa_data_out); /* * Optional: Attempt to use error and error_padata to try to recover from the * given error. To work with both FAST and non-FAST errors, an implementation * should generally consult error_padata rather than decoding error->e_data. * For non-FAST errors, it contains the e_data decoded as either pa-data or * typed-data. * * If this function is provided, and it returns 0 and stores data in * pa_data_out, then the client library will retransmit the request. */ typedef krb5_error_code (*krb5_clpreauth_tryagain_fn)(krb5_context context, krb5_clpreauth_moddata moddata, krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock, krb5_kdc_req *request, krb5_data *encoded_request_body, krb5_data *encoded_previous_request, krb5_preauthtype pa_type, krb5_error *error, krb5_pa_data **error_padata, krb5_prompter_fct prompter, void *prompter_data, krb5_pa_data ***pa_data_out); /* * Optional: receive krb5_get_init_creds_opt information. The attr and value * information supplied should be copied into moddata by the module if it * wishes to reference it after returning from this call. */ typedef krb5_error_code (*krb5_clpreauth_supply_gic_opts_fn)(krb5_context context, krb5_clpreauth_moddata moddata, krb5_get_init_creds_opt *opt, const char *attr, const char *value); typedef struct krb5_clpreauth_vtable_st { /* Mandatory: name of module. */ char *name; /* Mandatory: pointer to zero-terminated list of pa_types which this module * can provide services for. */ krb5_preauthtype *pa_type_list; /* Optional: pointer to zero-terminated list of enc_types which this module * claims to add support for. */ krb5_enctype *enctype_list; krb5_clpreauth_init_fn init; krb5_clpreauth_fini_fn fini; krb5_clpreauth_get_flags_fn flags; krb5_clpreauth_request_init_fn request_init; krb5_clpreauth_request_fini_fn request_fini; krb5_clpreauth_process_fn process; krb5_clpreauth_tryagain_fn tryagain; krb5_clpreauth_supply_gic_opts_fn gic_opts; /* Minor version 1 ends here. */ krb5_clpreauth_prep_questions_fn prep_questions; /* Minor version 2 ends here. */ } *krb5_clpreauth_vtable; /* * This function allows a clpreauth plugin to obtain preauth options. The * preauth_data returned from this function should be freed by calling * krb5_get_init_creds_opt_free_pa(). */ krb5_error_code KRB5_CALLCONV krb5_get_init_creds_opt_get_pa(krb5_context context, krb5_get_init_creds_opt *opt, int *num_preauth_data, krb5_gic_opt_pa_data **preauth_data); /* * This function frees the preauth_data that was returned by * krb5_get_init_creds_opt_get_pa(). */ void KRB5_CALLCONV krb5_get_init_creds_opt_free_pa(krb5_context context, int num_preauth_data, krb5_gic_opt_pa_data *preauth_data); #endif /* KRB5_CLPREAUTH_PLUGIN_H */ krb5/locate_plugin.h 0000644 00000005100 15146341150 0010401 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2006 Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * Service location plugin definitions for Kerberos 5. */ #ifndef KRB5_LOCATE_PLUGIN_H_INCLUDED #define KRB5_LOCATE_PLUGIN_H_INCLUDED #include <krb5/krb5.h> enum locate_service_type { locate_service_kdc = 1, locate_service_master_kdc, locate_service_kadmin, locate_service_krb524, locate_service_kpasswd }; typedef struct krb5plugin_service_locate_ftable { int minor_version; /* currently 0 */ /* Per-context setup and teardown. Returned void* blob is private to the plugin. */ krb5_error_code (*init)(krb5_context, void **); void (*fini)(void *); /* Callback function returns non-zero if the plugin function should quit and return; this may be because of an error, or may indicate we've already contacted the service, whatever. The lookup function should only return an error if it detects a problem, not if the callback function tells it to quit. */ krb5_error_code (*lookup)(void *, enum locate_service_type svc, const char *realm, int socktype, int family, int (*cbfunc)(void *,int,struct sockaddr *), void *cbdata); } krb5plugin_service_locate_ftable; /* extern krb5plugin_service_locate_ftable service_locator; */ #endif krb5/kadm5_auth_plugin.h 0000644 00000030302 15146341150 0011156 0 ustar 00 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2017 by the Massachusetts Institute of Technology. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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 COPYRIGHT HOLDERS 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 * COPYRIGHT HOLDER 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. */ /* * Declarations for kadm5_auth plugin module implementors. * * The kadm5_auth pluggable interface currently has only one supported major * version, which is 1. Major version 1 has a current minor version number of * 1. * * kadm5_auth plugin modules should define a function named * kadm5_auth_<modulename>_initvt, matching the signature: * * krb5_error_code * kadm5_auth_modname_initvt(krb5_context context, int maj_ver, int min_ver, * krb5_plugin_vtable vtable); * * The initvt function should: * * - Check that the supplied maj_ver number is supported by the module, or * return KRB5_PLUGIN_VER_NOTSUPP if it is not. * * - Cast the vtable pointer as appropriate for maj_ver: * maj_ver == 1: Cast to krb5_kadm5_auth_vtable * * - Initialize the methods of the vtable, stopping as appropriate for the * supplied min_ver. Optional methods may be left uninitialized. * * Memory for the vtable is allocated by the caller, not by the module. */ #ifndef KRB5_KADM5_AUTH_PLUGIN_H #define KRB5_KADM5_AUTH_PLUGIN_H #include <krb5/krb5.h> #include <krb5/plugin.h> /* An abstract type for kadm5_auth module data. */ typedef struct kadm5_auth_moddata_st *kadm5_auth_moddata; /* * A module can optionally include <kadm5/admin.h> to inspect principal or * policy records from requests that add or modify principals or policies. * Note that fields of principal and policy structures are only valid if the * corresponding bit is set in the accompanying mask parameter. */ struct _kadm5_principal_ent_t; struct _kadm5_policy_ent_t; /* * A module can optionally generate restrictions when checking permissions for * adding or modifying a principal entry. Restriction fields will only be * honored if the corresponding mask bit is set. The operable mask bits are * defined in <kadmin/admin.h> and are: * * - KADM5_ATTRIBUTES for require_attrs, forbid_attrs * - KADM5_POLICY for policy * - KADM5_POLICY_CLR to require that policy be unset * - KADM5_PRINC_EXPIRE_TIME for princ_lifetime * - KADM5_PW_EXPIRATION for pw_lifetime * - KADM5_MAX_LIFE for max_life * - KADM5_MAX_RLIFE for max_renewable_life */ struct kadm5_auth_restrictions { long mask; krb5_flags require_attrs; krb5_flags forbid_attrs; krb5_deltat princ_lifetime; krb5_deltat pw_lifetime; krb5_deltat max_life; krb5_deltat max_renewable_life; char *policy; }; /*** Method type declarations ***/ /* * Optional: Initialize module data. acl_file is the realm's configured ACL * file, or NULL if none was configured. Return 0 on success, * KRB5_PLUGIN_NO_HANDLE if the module is inoperable (due to configuration, for * example), and any other error code to abort kadmind startup. Optionally set * *data_out to a module data object to be passed to future calls. */ typedef krb5_error_code (*kadm5_auth_init_fn)(krb5_context context, const char *acl_file, kadm5_auth_moddata *data_out); /* Optional: Release resources used by module data. */ typedef void (*kadm5_auth_fini_fn)(krb5_context context, kadm5_auth_moddata data); /* * Each check method below should return 0 to explicitly authorize the request, * KRB5_PLUGIN_NO_HANDLE to neither authorize nor deny the request, and any * other error code (such as EPERM) to explicitly deny the request. If a check * method is not defined, the module will neither authorize nor deny the * request. A request succeeds if at least one kadm5_auth module explicitly * authorizes the request and none of the modules explicitly deny it. */ /* Optional: authorize an add-principal operation, and optionally generate * restrictions. */ typedef krb5_error_code (*kadm5_auth_addprinc_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target, const struct _kadm5_principal_ent_t *ent, long mask, struct kadm5_auth_restrictions **rs_out); /* Optional: authorize a modify-principal operation, and optionally generate * restrictions. */ typedef krb5_error_code (*kadm5_auth_modprinc_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target, const struct _kadm5_principal_ent_t *ent, long mask, struct kadm5_auth_restrictions **rs_out); /* Optional: authorize a set-string operation. */ typedef krb5_error_code (*kadm5_auth_setstr_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target, const char *key, const char *value); /* Optional: authorize a change-password operation. */ typedef krb5_error_code (*kadm5_auth_cpw_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target); /* Optional: authorize a randomize-keys operation. */ typedef krb5_error_code (*kadm5_auth_chrand_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target); /* Optional: authorize a set-key operation. */ typedef krb5_error_code (*kadm5_auth_setkey_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target); /* Optional: authorize a purgekeys operation. */ typedef krb5_error_code (*kadm5_auth_purgekeys_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target); /* Optional: authorize a delete-principal operation. */ typedef krb5_error_code (*kadm5_auth_delprinc_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target); /* Optional: authorize a rename-principal operation. */ typedef krb5_error_code (*kadm5_auth_renprinc_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal src, krb5_const_principal dest); /* Optional: authorize a get-principal operation. */ typedef krb5_error_code (*kadm5_auth_getprinc_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target); /* Optional: authorize a get-strings operation. */ typedef krb5_error_code (*kadm5_auth_getstrs_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target); /* Optional: authorize an extract-keys operation. */ typedef krb5_error_code (*kadm5_auth_extract_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, krb5_const_principal target); /* Optional: authorize a list-principals operation. */ typedef krb5_error_code (*kadm5_auth_listprincs_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client); /* Optional: authorize an add-policy operation. */ typedef krb5_error_code (*kadm5_auth_addpol_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, const char *policy, const struct _kadm5_policy_ent_t *ent, long mask); /* Optional: authorize a modify-policy operation. */ typedef krb5_error_code (*kadm5_auth_modpol_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, const char *policy, const struct _kadm5_policy_ent_t *ent, long mask); /* Optional: authorize a delete-policy operation. */ typedef krb5_error_code (*kadm5_auth_delpol_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, const char *policy); /* Optional: authorize a get-policy operation. client_policy is the client * principal's policy name, or NULL if it does not have one. */ typedef krb5_error_code (*kadm5_auth_getpol_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client, const char *policy, const char *client_policy); /* Optional: authorize a list-policies operation. */ typedef krb5_error_code (*kadm5_auth_listpols_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client); /* Optional: authorize an iprop operation. */ typedef krb5_error_code (*kadm5_auth_iprop_fn)(krb5_context context, kadm5_auth_moddata data, krb5_const_principal client); /* * Optional: receive a notification that the most recent authorized operation * has ended. If a kadm5_auth module is also a KDB module, it can assume that * all KDB methods invoked between a kadm5_auth authorization method invocation * and a kadm5_auth end invocation are performed as part of the authorized * operation. * * The end method may be invoked without a preceding authorization method in * some cases; the module must be prepared to ignore such calls. */ typedef void (*kadm5_auth_end_fn)(krb5_context context, kadm5_auth_moddata data); /* * Optional: free a restrictions object. This method does not need to be * defined if the module does not generate restrictions objects, or if it * returns aliases to restrictions objects contained from within the module * data. */ typedef void (*kadm5_auth_free_restrictions_fn)(krb5_context context, kadm5_auth_moddata data, struct kadm5_auth_restrictions *rs); /* kadm5_auth vtable for major version 1. */ typedef struct kadm5_auth_vtable_st { const char *name; /* Mandatory: name of module. */ kadm5_auth_init_fn init; kadm5_auth_fini_fn fini; kadm5_auth_addprinc_fn addprinc; kadm5_auth_modprinc_fn modprinc; kadm5_auth_setstr_fn setstr; kadm5_auth_cpw_fn cpw; kadm5_auth_chrand_fn chrand; kadm5_auth_setkey_fn setkey; kadm5_auth_purgekeys_fn purgekeys; kadm5_auth_delprinc_fn delprinc; kadm5_auth_renprinc_fn renprinc; kadm5_auth_getprinc_fn getprinc; kadm5_auth_getstrs_fn getstrs; kadm5_auth_extract_fn extract; kadm5_auth_listprincs_fn listprincs; kadm5_auth_addpol_fn addpol; kadm5_auth_modpol_fn modpol; kadm5_auth_delpol_fn delpol; kadm5_auth_getpol_fn getpol; kadm5_auth_listpols_fn listpols; kadm5_auth_iprop_fn iprop; kadm5_auth_end_fn end; kadm5_auth_free_restrictions_fn free_restrictions; /* Minor version 1 ends here. */ } *kadm5_auth_vtable; #endif /* KRB5_KADM5_AUTH_PLUGIN_H */ jconfig-64.h 0000644 00000004261 15146341150 0006566 0 ustar 00 /* jconfig.h. Generated from jconfig.h.in by configure. */ /* Version ID for the JPEG library. * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". */ #define JPEG_LIB_VERSION 62 /* libjpeg-turbo version */ #define LIBJPEG_TURBO_VERSION 1.5.3 /* libjpeg-turbo version in integer form */ #define LIBJPEG_TURBO_VERSION_NUMBER 1005003 /* Support arithmetic encoding */ #define C_ARITH_CODING_SUPPORTED 1 /* Support arithmetic decoding */ #define D_ARITH_CODING_SUPPORTED 1 /* * Define BITS_IN_JSAMPLE as either * 8 for 8-bit sample values (the usual setting) * 12 for 12-bit sample values * Only 8 and 12 are legal data precisions for lossy JPEG according to the * JPEG standard, and the IJG code does not support anything else! * We do not support run-time selection of data precision, sorry. */ #define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ /* Define to 1 if you have the <locale.h> header file. */ #define HAVE_LOCALE_H 1 /* Define to 1 if you have the <stddef.h> header file. */ #define HAVE_STDDEF_H 1 /* Define to 1 if you have the <stdlib.h> header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if the system has the type `unsigned char'. */ #define HAVE_UNSIGNED_CHAR 1 /* Define to 1 if the system has the type `unsigned short'. */ #define HAVE_UNSIGNED_SHORT 1 /* Compiler does not support pointers to undefined structures. */ /* #undef INCOMPLETE_TYPES_BROKEN */ /* Support in-memory source/destination managers */ #define MEM_SRCDST_SUPPORTED 1 /* Define if you have BSD-like bzero and bcopy in <strings.h> rather than memset/memcpy in <string.h>. */ /* #undef NEED_BSD_STRINGS */ /* Define if you need to include <sys/types.h> to get size_t. */ #define NEED_SYS_TYPES_H 1 /* Define if your (broken) compiler shifts signed values as if they were unsigned. */ /* #undef RIGHT_SHIFT_IS_UNSIGNED */ /* Use accelerated SIMD routines. */ #define WITH_SIMD 1 /* Define to 1 if type `char' is unsigned and you are not using gcc. */ #ifndef __CHAR_UNSIGNED__ /* # undef __CHAR_UNSIGNED__ */ #endif /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `unsigned int' if <sys/types.h> does not define. */ /* #undef size_t */ netdb.h 0000644 00000066703 15146341150 0006025 0 ustar 00 /* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* All data returned by the network data base library are supplied in host order and returned in network order (suitable for use in system calls). */ #ifndef _NETDB_H #define _NETDB_H 1 #include <features.h> #include <netinet/in.h> #include <bits/stdint-uintn.h> #ifdef __USE_MISC /* This is necessary to make this include file properly replace the Sun version. */ # include <rpc/netdb.h> #endif #ifdef __USE_GNU # include <bits/types/sigevent_t.h> # include <bits/types/struct_timespec.h> #endif #include <bits/netdb.h> /* Absolute file name for network data base files. */ #define _PATH_HEQUIV "/etc/hosts.equiv" #define _PATH_HOSTS "/etc/hosts" #define _PATH_NETWORKS "/etc/networks" #define _PATH_NSSWITCH_CONF "/etc/nsswitch.conf" #define _PATH_PROTOCOLS "/etc/protocols" #define _PATH_SERVICES "/etc/services" __BEGIN_DECLS #if defined __USE_MISC || !defined __USE_XOPEN2K8 /* Error status for non-reentrant lookup functions. We use a macro to access always the thread-specific `h_errno' variable. */ # define h_errno (*__h_errno_location ()) /* Function to get address of global `h_errno' variable. */ extern int *__h_errno_location (void) __THROW __attribute__ ((__const__)); /* Possible values left in `h_errno'. */ # define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */ # define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */ # define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */ # define NO_DATA 4 /* Valid name, no data record of requested type. */ #endif #ifdef __USE_MISC # define NETDB_INTERNAL -1 /* See errno. */ # define NETDB_SUCCESS 0 /* No problem. */ # define NO_ADDRESS NO_DATA /* No address, look for MX record. */ #endif #if defined __USE_XOPEN2K || defined __USE_XOPEN_EXTENDED /* Highest reserved Internet port number. */ # define IPPORT_RESERVED 1024 #endif #ifdef __USE_GNU /* Scope delimiter for getaddrinfo(), getnameinfo(). */ # define SCOPE_DELIMITER '%' #endif #ifdef __USE_MISC /* Print error indicated by `h_errno' variable on standard error. STR if non-null is printed before the error string. */ extern void herror (const char *__str) __THROW; /* Return string associated with error ERR_NUM. */ extern const char *hstrerror (int __err_num) __THROW; #endif /* Description of data base entry for a single host. */ struct hostent { char *h_name; /* Official name of host. */ char **h_aliases; /* Alias list. */ int h_addrtype; /* Host address type. */ int h_length; /* Length of address. */ char **h_addr_list; /* List of addresses from name server. */ #ifdef __USE_MISC # define h_addr h_addr_list[0] /* Address, for backward compatibility.*/ #endif }; /* Open host data base files and mark them as staying open even after a later search if STAY_OPEN is non-zero. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void sethostent (int __stay_open); /* Close host data base files and clear `stay open' flag. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void endhostent (void); /* Get next entry from host data base file. Open data base if necessary. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct hostent *gethostent (void); /* Return entry from host data base which address match ADDR with length LEN and type TYPE. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct hostent *gethostbyaddr (const void *__addr, __socklen_t __len, int __type); /* Return entry from host data base for host with NAME. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct hostent *gethostbyname (const char *__name); #ifdef __USE_MISC /* Return entry from host data base for host with NAME. AF must be set to the address type which is `AF_INET' for IPv4 or `AF_INET6' for IPv6. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern struct hostent *gethostbyname2 (const char *__name, int __af); /* Reentrant versions of the functions above. The additional arguments specify a buffer of BUFLEN starting at BUF. The last argument is a pointer to a variable which gets the value which would be stored in the global variable `herrno' by the non-reentrant functions. These functions are not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation they are cancellation points and therefore not marked with __THROW. */ extern int gethostent_r (struct hostent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct hostent **__restrict __result, int *__restrict __h_errnop); extern int gethostbyaddr_r (const void *__restrict __addr, __socklen_t __len, int __type, struct hostent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct hostent **__restrict __result, int *__restrict __h_errnop); extern int gethostbyname_r (const char *__restrict __name, struct hostent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct hostent **__restrict __result, int *__restrict __h_errnop); extern int gethostbyname2_r (const char *__restrict __name, int __af, struct hostent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct hostent **__restrict __result, int *__restrict __h_errnop); #endif /* misc */ /* Open network data base files and mark them as staying open even after a later search if STAY_OPEN is non-zero. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void setnetent (int __stay_open); /* Close network data base files and clear `stay open' flag. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void endnetent (void); /* Get next entry from network data base file. Open data base if necessary. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct netent *getnetent (void); /* Return entry from network data base which address match NET and type TYPE. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct netent *getnetbyaddr (uint32_t __net, int __type); /* Return entry from network data base for network with NAME. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct netent *getnetbyname (const char *__name); #ifdef __USE_MISC /* Reentrant versions of the functions above. The additional arguments specify a buffer of BUFLEN starting at BUF. The last argument is a pointer to a variable which gets the value which would be stored in the global variable `herrno' by the non-reentrant functions. These functions are not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation they are cancellation points and therefore not marked with __THROW. */ extern int getnetent_r (struct netent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct netent **__restrict __result, int *__restrict __h_errnop); extern int getnetbyaddr_r (uint32_t __net, int __type, struct netent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct netent **__restrict __result, int *__restrict __h_errnop); extern int getnetbyname_r (const char *__restrict __name, struct netent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct netent **__restrict __result, int *__restrict __h_errnop); #endif /* misc */ /* Description of data base entry for a single service. */ struct servent { char *s_name; /* Official service name. */ char **s_aliases; /* Alias list. */ int s_port; /* Port number. */ char *s_proto; /* Protocol to use. */ }; /* Open service data base files and mark them as staying open even after a later search if STAY_OPEN is non-zero. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void setservent (int __stay_open); /* Close service data base files and clear `stay open' flag. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void endservent (void); /* Get next entry from service data base file. Open data base if necessary. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct servent *getservent (void); /* Return entry from network data base for network with NAME and protocol PROTO. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct servent *getservbyname (const char *__name, const char *__proto); /* Return entry from service data base which matches port PORT and protocol PROTO. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct servent *getservbyport (int __port, const char *__proto); #ifdef __USE_MISC /* Reentrant versions of the functions above. The additional arguments specify a buffer of BUFLEN starting at BUF. These functions are not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation they are cancellation points and therefore not marked with __THROW. */ extern int getservent_r (struct servent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct servent **__restrict __result); extern int getservbyname_r (const char *__restrict __name, const char *__restrict __proto, struct servent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct servent **__restrict __result); extern int getservbyport_r (int __port, const char *__restrict __proto, struct servent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct servent **__restrict __result); #endif /* misc */ /* Description of data base entry for a single service. */ struct protoent { char *p_name; /* Official protocol name. */ char **p_aliases; /* Alias list. */ int p_proto; /* Protocol number. */ }; /* Open protocol data base files and mark them as staying open even after a later search if STAY_OPEN is non-zero. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void setprotoent (int __stay_open); /* Close protocol data base files and clear `stay open' flag. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void endprotoent (void); /* Get next entry from protocol data base file. Open data base if necessary. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct protoent *getprotoent (void); /* Return entry from protocol data base for network with NAME. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct protoent *getprotobyname (const char *__name); /* Return entry from protocol data base which number is PROTO. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct protoent *getprotobynumber (int __proto); #ifdef __USE_MISC /* Reentrant versions of the functions above. The additional arguments specify a buffer of BUFLEN starting at BUF. These functions are not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation they are cancellation points and therefore not marked with __THROW. */ extern int getprotoent_r (struct protoent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct protoent **__restrict __result); extern int getprotobyname_r (const char *__restrict __name, struct protoent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct protoent **__restrict __result); extern int getprotobynumber_r (int __proto, struct protoent *__restrict __result_buf, char *__restrict __buf, size_t __buflen, struct protoent **__restrict __result); /* Establish network group NETGROUP for enumeration. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int setnetgrent (const char *__netgroup); /* Free all space allocated by previous `setnetgrent' call. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern void endnetgrent (void); /* Get next member of netgroup established by last `setnetgrent' call and return pointers to elements in HOSTP, USERP, and DOMAINP. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int getnetgrent (char **__restrict __hostp, char **__restrict __userp, char **__restrict __domainp); /* Test whether NETGROUP contains the triple (HOST,USER,DOMAIN). This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int innetgr (const char *__netgroup, const char *__host, const char *__user, const char *__domain); /* Reentrant version of `getnetgrent' where result is placed in BUFFER. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int getnetgrent_r (char **__restrict __hostp, char **__restrict __userp, char **__restrict __domainp, char *__restrict __buffer, size_t __buflen); #endif /* misc */ #ifdef __USE_MISC /* Call `rshd' at port RPORT on remote machine *AHOST to execute CMD. The local user is LOCUSER, on the remote machine the command is executed as REMUSER. In *FD2P the descriptor to the socket for the connection is returned. The caller must have the right to use a reserved port. When the function returns *AHOST contains the official host name. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int rcmd (char **__restrict __ahost, unsigned short int __rport, const char *__restrict __locuser, const char *__restrict __remuser, const char *__restrict __cmd, int *__restrict __fd2p); /* This is the equivalent function where the protocol can be selected and which therefore can be used for IPv6. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int rcmd_af (char **__restrict __ahost, unsigned short int __rport, const char *__restrict __locuser, const char *__restrict __remuser, const char *__restrict __cmd, int *__restrict __fd2p, sa_family_t __af); /* Call `rexecd' at port RPORT on remote machine *AHOST to execute CMD. The process runs at the remote machine using the ID of user NAME whose cleartext password is PASSWD. In *FD2P the descriptor to the socket for the connection is returned. When the function returns *AHOST contains the official host name. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int rexec (char **__restrict __ahost, int __rport, const char *__restrict __name, const char *__restrict __pass, const char *__restrict __cmd, int *__restrict __fd2p); /* This is the equivalent function where the protocol can be selected and which therefore can be used for IPv6. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int rexec_af (char **__restrict __ahost, int __rport, const char *__restrict __name, const char *__restrict __pass, const char *__restrict __cmd, int *__restrict __fd2p, sa_family_t __af); /* Check whether user REMUSER on system RHOST is allowed to login as LOCUSER. If SUSER is not zero the user tries to become superuser. Return 0 if it is possible. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int ruserok (const char *__rhost, int __suser, const char *__remuser, const char *__locuser); /* This is the equivalent function where the protocol can be selected and which therefore can be used for IPv6. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int ruserok_af (const char *__rhost, int __suser, const char *__remuser, const char *__locuser, sa_family_t __af); /* Check whether user REMUSER on system indicated by IPv4 address RADDR is allowed to login as LOCUSER. Non-IPv4 (e.g., IPv6) are not supported. If SUSER is not zero the user tries to become superuser. Return 0 if it is possible. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int iruserok (uint32_t __raddr, int __suser, const char *__remuser, const char *__locuser); /* This is the equivalent function where the pfamiliy if the address pointed to by RADDR is determined by the value of AF. It therefore can be used for IPv6 This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int iruserok_af (const void *__raddr, int __suser, const char *__remuser, const char *__locuser, sa_family_t __af); /* Try to allocate reserved port, returning a descriptor for a socket opened at this port or -1 if unsuccessful. The search for an available port will start at ALPORT and continues with lower numbers. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int rresvport (int *__alport); /* This is the equivalent function where the protocol can be selected and which therefore can be used for IPv6. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int rresvport_af (int *__alport, sa_family_t __af); #endif /* Extension from POSIX.1:2001. */ #ifdef __USE_XOPEN2K /* Structure to contain information about address of a service provider. */ struct addrinfo { int ai_flags; /* Input flags. */ int ai_family; /* Protocol family for socket. */ int ai_socktype; /* Socket type. */ int ai_protocol; /* Protocol for socket. */ socklen_t ai_addrlen; /* Length of socket address. */ struct sockaddr *ai_addr; /* Socket address for socket. */ char *ai_canonname; /* Canonical name for service location. */ struct addrinfo *ai_next; /* Pointer to next in list. */ }; # ifdef __USE_GNU /* Structure used as control block for asynchronous lookup. */ struct gaicb { const char *ar_name; /* Name to look up. */ const char *ar_service; /* Service name. */ const struct addrinfo *ar_request; /* Additional request specification. */ struct addrinfo *ar_result; /* Pointer to result. */ /* The following are internal elements. */ int __return; int __glibc_reserved[5]; }; /* Lookup mode. */ # define GAI_WAIT 0 # define GAI_NOWAIT 1 # endif /* Possible values for `ai_flags' field in `addrinfo' structure. */ # define AI_PASSIVE 0x0001 /* Socket address is intended for `bind'. */ # define AI_CANONNAME 0x0002 /* Request for canonical name. */ # define AI_NUMERICHOST 0x0004 /* Don't use name resolution. */ # define AI_V4MAPPED 0x0008 /* IPv4 mapped addresses are acceptable. */ # define AI_ALL 0x0010 /* Return IPv4 mapped and IPv6 addresses. */ # define AI_ADDRCONFIG 0x0020 /* Use configuration of this host to choose returned address type.. */ # ifdef __USE_GNU # define AI_IDN 0x0040 /* IDN encode input (assuming it is encoded in the current locale's character set) before looking it up. */ # define AI_CANONIDN 0x0080 /* Translate canonical name from IDN format. */ # define AI_IDN_ALLOW_UNASSIGNED \ __glibc_macro_warning ("AI_IDN_ALLOW_UNASSIGNED is deprecated") 0x0100 # define AI_IDN_USE_STD3_ASCII_RULES \ __glibc_macro_warning ("AI_IDN_USE_STD3_ASCII_RULES is deprecated") 0x0200 # endif # define AI_NUMERICSERV 0x0400 /* Don't use name resolution. */ /* Error values for `getaddrinfo' function. */ # define EAI_BADFLAGS -1 /* Invalid value for `ai_flags' field. */ # define EAI_NONAME -2 /* NAME or SERVICE is unknown. */ # define EAI_AGAIN -3 /* Temporary failure in name resolution. */ # define EAI_FAIL -4 /* Non-recoverable failure in name res. */ # define EAI_FAMILY -6 /* `ai_family' not supported. */ # define EAI_SOCKTYPE -7 /* `ai_socktype' not supported. */ # define EAI_SERVICE -8 /* SERVICE not supported for `ai_socktype'. */ # define EAI_MEMORY -10 /* Memory allocation failure. */ # define EAI_SYSTEM -11 /* System error returned in `errno'. */ # define EAI_OVERFLOW -12 /* Argument buffer overflow. */ # ifdef __USE_GNU # define EAI_NODATA -5 /* No address associated with NAME. */ # define EAI_ADDRFAMILY -9 /* Address family for NAME not supported. */ # define EAI_INPROGRESS -100 /* Processing request in progress. */ # define EAI_CANCELED -101 /* Request canceled. */ # define EAI_NOTCANCELED -102 /* Request not canceled. */ # define EAI_ALLDONE -103 /* All requests done. */ # define EAI_INTR -104 /* Interrupted by a signal. */ # define EAI_IDN_ENCODE -105 /* IDN encoding failed. */ # endif # ifdef __USE_MISC # define NI_MAXHOST 1025 # define NI_MAXSERV 32 # endif # define NI_NUMERICHOST 1 /* Don't try to look up hostname. */ # define NI_NUMERICSERV 2 /* Don't convert port number to name. */ # define NI_NOFQDN 4 /* Only return nodename portion. */ # define NI_NAMEREQD 8 /* Don't return numeric addresses. */ # define NI_DGRAM 16 /* Look up UDP service rather than TCP. */ # ifdef __USE_GNU # define NI_IDN 32 /* Convert name from IDN format. */ # define NI_IDN_ALLOW_UNASSIGNED \ __glibc_macro_warning ("NI_IDN_ALLOW_UNASSIGNED is deprecated") 64 # define NI_IDN_USE_STD3_ASCII_RULES \ __glibc_macro_warning ("NI_IDN_USE_STD3_ASCII_RULES is deprecated") 128 # endif /* Translate name of a service location and/or a service name to set of socket addresses. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int getaddrinfo (const char *__restrict __name, const char *__restrict __service, const struct addrinfo *__restrict __req, struct addrinfo **__restrict __pai); /* Free `addrinfo' structure AI including associated storage. */ extern void freeaddrinfo (struct addrinfo *__ai) __THROW; /* Convert error return from getaddrinfo() to a string. */ extern const char *gai_strerror (int __ecode) __THROW; /* Translate a socket address to a location and service name. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int getnameinfo (const struct sockaddr *__restrict __sa, socklen_t __salen, char *__restrict __host, socklen_t __hostlen, char *__restrict __serv, socklen_t __servlen, int __flags); #endif /* POSIX */ #ifdef __USE_GNU /* Enqueue ENT requests from the LIST. If MODE is GAI_WAIT wait until all requests are handled. If WAIT is GAI_NOWAIT return immediately after queueing the requests and signal completion according to SIG. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int getaddrinfo_a (int __mode, struct gaicb *__list[__restrict_arr], int __ent, struct sigevent *__restrict __sig); /* Suspend execution of the thread until at least one of the ENT requests in LIST is handled. If TIMEOUT is not a null pointer it specifies the longest time the function keeps waiting before returning with an error. This function is not part of POSIX and therefore no official cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ extern int gai_suspend (const struct gaicb *const __list[], int __ent, const struct timespec *__timeout); /* Get the error status of the request REQ. */ extern int gai_error (struct gaicb *__req) __THROW; /* Cancel the requests associated with GAICBP. */ extern int gai_cancel (struct gaicb *__gaicbp) __THROW; #endif /* GNU */ __END_DECLS #endif /* netdb.h */ arpa/tftp.h 0000644 00000005753 15146341150 0006627 0 ustar 00 /* * Copyright (c) 1983, 1993 * The Regents of the University of California. 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. * 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. * * @(#)tftp.h 8.1 (Berkeley) 6/2/93 */ #ifndef _ARPA_TFTP_H #define _ARPA_TFTP_H 1 /* * Trivial File Transfer Protocol (IEN-133) */ #define SEGSIZE 512 /* data segment size */ /* * Packet types. */ #define RRQ 01 /* read request */ #define WRQ 02 /* write request */ #define DATA 03 /* data packet */ #define ACK 04 /* acknowledgement */ #define ERROR 05 /* error code */ struct tftphdr { short th_opcode; /* packet type */ union { char tu_padding[3]; /* sizeof() compat */ struct { union { unsigned short tu_block; /* block # */ short tu_code; /* error code */ } __attribute__ ((__packed__)) th_u3; char tu_data[0]; /* data or error string */ } __attribute__ ((__packed__)) th_u2; char tu_stuff[0]; /* request packet stuff */ } __attribute__ ((__packed__)) th_u1; } __attribute__ ((__packed__)); #define th_block th_u1.th_u2.th_u3.tu_block #define th_code th_u1.th_u2.th_u3.tu_code #define th_stuff th_u1.tu_stuff #define th_data th_u1.th_u2.tu_data #define th_msg th_u1.th_u2.tu_data /* * Error codes. */ #define EUNDEF 0 /* not defined */ #define ENOTFOUND 1 /* file not found */ #define EACCESS 2 /* access violation */ #define ENOSPACE 3 /* disk full or allocation exceeded */ #define EBADOP 4 /* illegal TFTP operation */ #define EBADID 5 /* unknown transfer ID */ #define EEXISTS 6 /* file already exists */ #define ENOUSER 7 /* no such user */ #endif /* arpa/tftp.h */ arpa/inet.h 0000644 00000010264 15146341150 0006602 0 ustar 00 /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _ARPA_INET_H #define _ARPA_INET_H 1 #include <features.h> #include <netinet/in.h> /* To define `struct in_addr'. */ /* Type for length arguments in socket calls. */ #ifndef __socklen_t_defined typedef __socklen_t socklen_t; # define __socklen_t_defined #endif __BEGIN_DECLS /* Convert Internet host address from numbers-and-dots notation in CP into binary data in network byte order. */ extern in_addr_t inet_addr (const char *__cp) __THROW; /* Return the local host address part of the Internet address in IN. */ extern in_addr_t inet_lnaof (struct in_addr __in) __THROW; /* Make Internet host address in network byte order by combining the network number NET with the local address HOST. */ extern struct in_addr inet_makeaddr (in_addr_t __net, in_addr_t __host) __THROW; /* Return network number part of the Internet address IN. */ extern in_addr_t inet_netof (struct in_addr __in) __THROW; /* Extract the network number in network byte order from the address in numbers-and-dots natation starting at CP. */ extern in_addr_t inet_network (const char *__cp) __THROW; /* Convert Internet number in IN to ASCII representation. The return value is a pointer to an internal array containing the string. */ extern char *inet_ntoa (struct in_addr __in) __THROW; /* Convert from presentation format of an Internet number in buffer starting at CP to the binary network format and store result for interface type AF in buffer starting at BUF. */ extern int inet_pton (int __af, const char *__restrict __cp, void *__restrict __buf) __THROW; /* Convert a Internet address in binary network format for interface type AF in buffer starting at CP to presentation form and place result in buffer of length LEN astarting at BUF. */ extern const char *inet_ntop (int __af, const void *__restrict __cp, char *__restrict __buf, socklen_t __len) __THROW; /* The following functions are not part of XNS 5.2. */ #ifdef __USE_MISC /* Convert Internet host address from numbers-and-dots notation in CP into binary data and store the result in the structure INP. */ extern int inet_aton (const char *__cp, struct in_addr *__inp) __THROW; /* Format a network number NET into presentation format and place result in buffer starting at BUF with length of LEN bytes. */ extern char *inet_neta (in_addr_t __net, char *__buf, size_t __len) __THROW; /* Convert network number for interface type AF in buffer starting at CP to presentation format. The result will specifiy BITS bits of the number. */ extern char *inet_net_ntop (int __af, const void *__cp, int __bits, char *__buf, size_t __len) __THROW; /* Convert network number for interface type AF from presentation in buffer starting at CP to network format and store result int buffer starting at BUF of size LEN. */ extern int inet_net_pton (int __af, const char *__cp, void *__buf, size_t __len) __THROW; /* Convert ASCII representation in hexadecimal form of the Internet address to binary form and place result in buffer of length LEN starting at BUF. */ extern unsigned int inet_nsap_addr (const char *__cp, unsigned char *__buf, int __len) __THROW; /* Convert internet address in binary form in LEN bytes starting at CP a presentation form and place result in BUF. */ extern char *inet_nsap_ntoa (int __len, const unsigned char *__cp, char *__buf) __THROW; #endif __END_DECLS #endif /* arpa/inet.h */ arpa/nameser_compat.h 0000644 00000015601 15146341150 0010640 0 ustar 00 /* Copyright (c) 1983, 1989 * The Regents of the University of California. 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. * 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. */ #ifndef _ARPA_NAMESER_COMPAT_ #define _ARPA_NAMESER_COMPAT_ #include <endian.h> /*% * Structure for query header. The order of the fields is machine- and * compiler-dependent, depending on the byte/bit order and the layout * of bit fields. We use bit fields only in int variables, as this * is all ANSI requires. This requires a somewhat confusing rearrangement. */ typedef struct { unsigned id :16; /*%< query identification number */ #if __BYTE_ORDER == __BIG_ENDIAN /* fields in third byte */ unsigned qr: 1; /*%< response flag */ unsigned opcode: 4; /*%< purpose of message */ unsigned aa: 1; /*%< authoritive answer */ unsigned tc: 1; /*%< truncated message */ unsigned rd: 1; /*%< recursion desired */ /* fields in fourth byte */ unsigned ra: 1; /*%< recursion available */ unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ unsigned ad: 1; /*%< authentic data from named */ unsigned cd: 1; /*%< checking disabled by resolver */ unsigned rcode :4; /*%< response code */ #endif #if __BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __PDP_ENDIAN /* fields in third byte */ unsigned rd :1; /*%< recursion desired */ unsigned tc :1; /*%< truncated message */ unsigned aa :1; /*%< authoritive answer */ unsigned opcode :4; /*%< purpose of message */ unsigned qr :1; /*%< response flag */ /* fields in fourth byte */ unsigned rcode :4; /*%< response code */ unsigned cd: 1; /*%< checking disabled by resolver */ unsigned ad: 1; /*%< authentic data from named */ unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ unsigned ra :1; /*%< recursion available */ #endif /* remaining bytes */ unsigned qdcount :16; /*%< number of question entries */ unsigned ancount :16; /*%< number of answer entries */ unsigned nscount :16; /*%< number of authority entries */ unsigned arcount :16; /*%< number of resource entries */ } HEADER; #define PACKETSZ NS_PACKETSZ #define MAXDNAME NS_MAXDNAME #define MAXCDNAME NS_MAXCDNAME #define MAXLABEL NS_MAXLABEL #define HFIXEDSZ NS_HFIXEDSZ #define QFIXEDSZ NS_QFIXEDSZ #define RRFIXEDSZ NS_RRFIXEDSZ #define INT32SZ NS_INT32SZ #define INT16SZ NS_INT16SZ #define INT8SZ NS_INT8SZ #define INADDRSZ NS_INADDRSZ #define IN6ADDRSZ NS_IN6ADDRSZ #define INDIR_MASK NS_CMPRSFLGS #define NAMESERVER_PORT NS_DEFAULTPORT #define S_ZONE ns_s_zn #define S_PREREQ ns_s_pr #define S_UPDATE ns_s_ud #define S_ADDT ns_s_ar #define QUERY ns_o_query #define IQUERY ns_o_iquery #define STATUS ns_o_status #define NS_NOTIFY_OP ns_o_notify #define NS_UPDATE_OP ns_o_update #define NOERROR ns_r_noerror #define FORMERR ns_r_formerr #define SERVFAIL ns_r_servfail #define NXDOMAIN ns_r_nxdomain #define NOTIMP ns_r_notimpl #define REFUSED ns_r_refused #define YXDOMAIN ns_r_yxdomain #define YXRRSET ns_r_yxrrset #define NXRRSET ns_r_nxrrset #define NOTAUTH ns_r_notauth #define NOTZONE ns_r_notzone /*#define BADSIG ns_r_badsig*/ /*#define BADKEY ns_r_badkey*/ /*#define BADTIME ns_r_badtime*/ #define DELETE ns_uop_delete #define ADD ns_uop_add #define T_A ns_t_a #define T_NS ns_t_ns #define T_MD ns_t_md #define T_MF ns_t_mf #define T_CNAME ns_t_cname #define T_SOA ns_t_soa #define T_MB ns_t_mb #define T_MG ns_t_mg #define T_MR ns_t_mr #define T_NULL ns_t_null #define T_WKS ns_t_wks #define T_PTR ns_t_ptr #define T_HINFO ns_t_hinfo #define T_MINFO ns_t_minfo #define T_MX ns_t_mx #define T_TXT ns_t_txt #define T_RP ns_t_rp #define T_AFSDB ns_t_afsdb #define T_X25 ns_t_x25 #define T_ISDN ns_t_isdn #define T_RT ns_t_rt #define T_NSAP ns_t_nsap #define T_NSAP_PTR ns_t_nsap_ptr #define T_SIG ns_t_sig #define T_KEY ns_t_key #define T_PX ns_t_px #define T_GPOS ns_t_gpos #define T_AAAA ns_t_aaaa #define T_LOC ns_t_loc #define T_NXT ns_t_nxt #define T_EID ns_t_eid #define T_NIMLOC ns_t_nimloc #define T_SRV ns_t_srv #define T_ATMA ns_t_atma #define T_NAPTR ns_t_naptr #define T_KX ns_t_kx #define T_CERT ns_t_cert #define T_A6 ns_t_a6 #define T_DNAME ns_t_dname #define T_SINK ns_t_sink #define T_OPT ns_t_opt #define T_APL ns_t_apl #define T_DS ns_t_ds #define T_SSHFP ns_t_sshfp #define T_IPSECKEY ns_t_ipseckey #define T_RRSIG ns_t_rrsig #define T_NSEC ns_t_nsec #define T_DNSKEY ns_t_dnskey #define T_DHCID ns_t_dhcid #define T_NSEC3 ns_t_nsec3 #define T_NSEC3PARAM ns_t_nsec3param #define T_TLSA ns_t_tlsa #define T_SMIMEA ns_t_smimea #define T_HIP ns_t_hip #define T_NINFO ns_t_ninfo #define T_RKEY ns_t_rkey #define T_TALINK ns_t_talink #define T_CDS ns_t_cds #define T_CDNSKEY ns_t_cdnskey #define T_OPENPGPKEY ns_t_openpgpkey #define T_CSYNC ns_t_csync #define T_SPF ns_t_spf #define T_UINFO ns_t_uinfo #define T_UID ns_t_uid #define T_GID ns_t_gid #define T_UNSPEC ns_t_unspec #define T_NID ns_t_nid #define T_L32 ns_t_l32 #define T_L64 ns_t_l64 #define T_LP ns_t_lp #define T_EUI48 ns_t_eui48 #define T_EUI64 ns_t_eui64 #define T_TKEY ns_t_tkey #define T_TSIG ns_t_tsig #define T_IXFR ns_t_ixfr #define T_AXFR ns_t_axfr #define T_MAILB ns_t_mailb #define T_MAILA ns_t_maila #define T_ANY ns_t_any #define T_URI ns_t_uri #define T_CAA ns_t_caa #define T_AVC ns_t_avc #define T_TA ns_t_ta #define T_DLV ns_t_dlv #define C_IN ns_c_in #define C_CHAOS ns_c_chaos #define C_HS ns_c_hs /* BIND_UPDATE */ #define C_NONE ns_c_none #define C_ANY ns_c_any #define GETSHORT NS_GET16 #define GETLONG NS_GET32 #define PUTSHORT NS_PUT16 #define PUTLONG NS_PUT32 #endif /* _ARPA_NAMESER_COMPAT_ */ /*! \file */ arpa/ftp.h 0000644 00000006550 15146341150 0006437 0 ustar 00 /* * Copyright (c) 1983, 1989, 1993 * The Regents of the University of California. 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. * 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. * * @(#)ftp.h 8.1 (Berkeley) 6/2/93 */ #ifndef _ARPA_FTP_H #define _ARPA_FTP_H 1 /* Definitions for FTP; see RFC-765. */ /* * Reply codes. */ #define PRELIM 1 /* positive preliminary */ #define COMPLETE 2 /* positive completion */ #define CONTINUE 3 /* positive intermediate */ #define TRANSIENT 4 /* transient negative completion */ #define ERROR 5 /* permanent negative completion */ /* * Type codes */ #define TYPE_A 1 /* ASCII */ #define TYPE_E 2 /* EBCDIC */ #define TYPE_I 3 /* image */ #define TYPE_L 4 /* local byte size */ #ifdef FTP_NAMES char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" }; #endif /* * Form codes */ #define FORM_N 1 /* non-print */ #define FORM_T 2 /* telnet format effectors */ #define FORM_C 3 /* carriage control (ASA) */ #ifdef FTP_NAMES char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" }; #endif /* * Structure codes */ #define STRU_F 1 /* file (no record structure) */ #define STRU_R 2 /* record structure */ #define STRU_P 3 /* page structure */ #ifdef FTP_NAMES char *strunames[] = {"0", "File", "Record", "Page" }; #endif /* * Mode types */ #define MODE_S 1 /* stream */ #define MODE_B 2 /* block */ #define MODE_C 3 /* compressed */ #ifdef FTP_NAMES char *modenames[] = {"0", "Stream", "Block", "Compressed" }; #endif /* * Record Tokens */ #define REC_ESC '\377' /* Record-mode Escape */ #define REC_EOR '\001' /* Record-mode End-of-Record */ #define REC_EOF '\002' /* Record-mode End-of-File */ /* * Block Header */ #define BLK_EOR 0x80 /* Block is End-of-Record */ #define BLK_EOF 0x40 /* Block is End-of-File */ #define BLK_ERRORS 0x20 /* Block is suspected of containing errors */ #define BLK_RESTART 0x10 /* Block is Restart Marker */ #define BLK_BYTECOUNT 2 /* Bytes in this block */ #endif /* arpa/ftp.h */ arpa/nameser.h 0000644 00000033563 15146341150 0007304 0 ustar 00 /* * Copyright (c) 1983, 1989, 1993 * The Regents of the University of California. 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. * 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. */ /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #ifndef _ARPA_NAMESER_H_ #define _ARPA_NAMESER_H_ #include <sys/param.h> #include <sys/types.h> #include <stdint.h> /* * Define constants based on RFC 883, RFC 1034, RFC 1035 */ #define NS_PACKETSZ 512 /*%< default UDP packet size */ #define NS_MAXDNAME 1025 /*%< maximum domain name */ #define NS_MAXMSG 65535 /*%< maximum message size */ #define NS_MAXCDNAME 255 /*%< maximum compressed domain name */ #define NS_MAXLABEL 63 /*%< maximum length of domain label */ #define NS_HFIXEDSZ 12 /*%< #/bytes of fixed data in header */ #define NS_QFIXEDSZ 4 /*%< #/bytes of fixed data in query */ #define NS_RRFIXEDSZ 10 /*%< #/bytes of fixed data in r record */ #define NS_INT32SZ 4 /*%< #/bytes of data in a uint32_t */ #define NS_INT16SZ 2 /*%< #/bytes of data in a uint16_t */ #define NS_INT8SZ 1 /*%< #/bytes of data in a uint8_t */ #define NS_INADDRSZ 4 /*%< IPv4 T_A */ #define NS_IN6ADDRSZ 16 /*%< IPv6 T_AAAA */ #define NS_CMPRSFLGS 0xc0 /*%< Flag bits indicating name compression. */ #define NS_DEFAULTPORT 53 /*%< For both TCP and UDP. */ /* * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord() * in synch with it. */ typedef enum __ns_sect { ns_s_qd = 0, /*%< Query: Question. */ ns_s_zn = 0, /*%< Update: Zone. */ ns_s_an = 1, /*%< Query: Answer. */ ns_s_pr = 1, /*%< Update: Prerequisites. */ ns_s_ns = 2, /*%< Query: Name servers. */ ns_s_ud = 2, /*%< Update: Update. */ ns_s_ar = 3, /*%< Query|Update: Additional records. */ ns_s_max = 4 } ns_sect; /*% * This is a message handle. It is caller allocated and has no dynamic data. * This structure is intended to be opaque to all but ns_parse.c, thus the * leading _'s on the member names. Use the accessor functions, not the _'s. */ typedef struct __ns_msg { const unsigned char *_msg, *_eom; uint16_t _id, _flags, _counts[ns_s_max]; const unsigned char *_sections[ns_s_max]; ns_sect _sect; int _rrnum; const unsigned char *_msg_ptr; } ns_msg; /* Private data structure - do not use from outside library. */ struct _ns_flagdata { int mask, shift; }; extern const struct _ns_flagdata _ns_flagdata[]; /* Accessor macros - this is part of the public interface. */ #define ns_msg_id(handle) ((handle)._id + 0) #define ns_msg_base(handle) ((handle)._msg + 0) #define ns_msg_end(handle) ((handle)._eom + 0) #define ns_msg_size(handle) ((handle)._eom - (handle)._msg) #define ns_msg_count(handle, section) ((handle)._counts[section] + 0) /*% * This is a parsed record. It is caller allocated and has no dynamic data. */ typedef struct __ns_rr { char name[NS_MAXDNAME]; uint16_t type; uint16_t rr_class; uint32_t ttl; uint16_t rdlength; const unsigned char * rdata; } ns_rr; /* Accessor macros - this is part of the public interface. */ #define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".") #define ns_rr_type(rr) ((ns_type)((rr).type + 0)) #define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0)) #define ns_rr_ttl(rr) ((rr).ttl + 0) #define ns_rr_rdlen(rr) ((rr).rdlength + 0) #define ns_rr_rdata(rr) ((rr).rdata + 0) /*% * These don't have to be in the same order as in the packet flags word, * and they can even overlap in some cases, but they will need to be kept * in synch with ns_parse.c:ns_flagdata[]. */ typedef enum __ns_flag { ns_f_qr, /*%< Question/Response. */ ns_f_opcode, /*%< Operation code. */ ns_f_aa, /*%< Authoritative Answer. */ ns_f_tc, /*%< Truncation occurred. */ ns_f_rd, /*%< Recursion Desired. */ ns_f_ra, /*%< Recursion Available. */ ns_f_z, /*%< MBZ. */ ns_f_ad, /*%< Authentic Data (DNSSEC). */ ns_f_cd, /*%< Checking Disabled (DNSSEC). */ ns_f_rcode, /*%< Response code. */ ns_f_max } ns_flag; /*% * Currently defined opcodes. */ typedef enum __ns_opcode { ns_o_query = 0, /*%< Standard query. */ ns_o_iquery = 1, /*%< Inverse query (deprecated/unsupported). */ ns_o_status = 2, /*%< Name server status query (unsupported). */ /* Opcode 3 is undefined/reserved. */ ns_o_notify = 4, /*%< Zone change notification. */ ns_o_update = 5, /*%< Zone update message. */ ns_o_max = 6 } ns_opcode; /*% * Currently defined response codes. */ typedef enum __ns_rcode { ns_r_noerror = 0, /*%< No error occurred. */ ns_r_formerr = 1, /*%< Format error. */ ns_r_servfail = 2, /*%< Server failure. */ ns_r_nxdomain = 3, /*%< Name error. */ ns_r_notimpl = 4, /*%< Unimplemented. */ ns_r_refused = 5, /*%< Operation refused. */ /* these are for BIND_UPDATE */ ns_r_yxdomain = 6, /*%< Name exists */ ns_r_yxrrset = 7, /*%< RRset exists */ ns_r_nxrrset = 8, /*%< RRset does not exist */ ns_r_notauth = 9, /*%< Not authoritative for zone */ ns_r_notzone = 10, /*%< Zone of record different from zone section */ ns_r_max = 11, /* The following are EDNS extended rcodes */ ns_r_badvers = 16, /* The following are TSIG errors */ ns_r_badsig = 16, ns_r_badkey = 17, ns_r_badtime = 18 } ns_rcode; /* BIND_UPDATE */ typedef enum __ns_update_operation { ns_uop_delete = 0, ns_uop_add = 1, ns_uop_max = 2 } ns_update_operation; /*% * This structure is used for TSIG authenticated messages */ struct ns_tsig_key { char name[NS_MAXDNAME], alg[NS_MAXDNAME]; unsigned char *data; int len; }; typedef struct ns_tsig_key ns_tsig_key; /*% * This structure is used for TSIG authenticated TCP messages */ struct ns_tcp_tsig_state { int counter; struct dst_key *key; void *ctx; unsigned char sig[NS_PACKETSZ]; int siglen; }; typedef struct ns_tcp_tsig_state ns_tcp_tsig_state; #define NS_TSIG_FUDGE 300 #define NS_TSIG_TCP_COUNT 100 #define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT" #define NS_TSIG_ERROR_NO_TSIG -10 #define NS_TSIG_ERROR_NO_SPACE -11 #define NS_TSIG_ERROR_FORMERR -12 /*% * Currently defined type values for resources and queries. */ typedef enum __ns_type { ns_t_invalid = 0, ns_t_a = 1, ns_t_ns = 2, ns_t_md = 3, ns_t_mf = 4, ns_t_cname = 5, ns_t_soa = 6, ns_t_mb = 7, ns_t_mg = 8, ns_t_mr = 9, ns_t_null = 10, ns_t_wks = 11, ns_t_ptr = 12, ns_t_hinfo = 13, ns_t_minfo = 14, ns_t_mx = 15, ns_t_txt = 16, ns_t_rp = 17, ns_t_afsdb = 18, ns_t_x25 = 19, ns_t_isdn = 20, ns_t_rt = 21, ns_t_nsap = 22, ns_t_nsap_ptr = 23, ns_t_sig = 24, ns_t_key = 25, ns_t_px = 26, ns_t_gpos = 27, ns_t_aaaa = 28, ns_t_loc = 29, ns_t_nxt = 30, ns_t_eid = 31, ns_t_nimloc = 32, ns_t_srv = 33, ns_t_atma = 34, ns_t_naptr = 35, ns_t_kx = 36, ns_t_cert = 37, ns_t_a6 = 38, ns_t_dname = 39, ns_t_sink = 40, ns_t_opt = 41, ns_t_apl = 42, ns_t_ds = 43, ns_t_sshfp = 44, ns_t_ipseckey = 45, ns_t_rrsig = 46, ns_t_nsec = 47, ns_t_dnskey = 48, ns_t_dhcid = 49, ns_t_nsec3 = 50, ns_t_nsec3param = 51, ns_t_tlsa = 52, ns_t_smimea = 53, ns_t_hip = 55, ns_t_ninfo = 56, ns_t_rkey = 57, ns_t_talink = 58, ns_t_cds = 59, ns_t_cdnskey = 60, ns_t_openpgpkey = 61, ns_t_csync = 62, ns_t_spf = 99, ns_t_uinfo = 100, ns_t_uid = 101, ns_t_gid = 102, ns_t_unspec = 103, ns_t_nid = 104, ns_t_l32 = 105, ns_t_l64 = 106, ns_t_lp = 107, ns_t_eui48 = 108, ns_t_eui64 = 109, ns_t_tkey = 249, ns_t_tsig = 250, ns_t_ixfr = 251, ns_t_axfr = 252, ns_t_mailb = 253, ns_t_maila = 254, ns_t_any = 255, ns_t_uri = 256, ns_t_caa = 257, ns_t_avc = 258, ns_t_ta = 32768, ns_t_dlv = 32769, ns_t_max = 65536 } ns_type; /*% * Values for class field */ typedef enum __ns_class { ns_c_invalid = 0, /*%< Cookie. */ ns_c_in = 1, /*%< Internet. */ ns_c_2 = 2, /*%< unallocated/unsupported. */ ns_c_chaos = 3, /*%< MIT Chaos-net. */ ns_c_hs = 4, /*%< MIT Hesiod. */ /* Query class values which do not appear in resource records */ ns_c_none = 254, /*%< for prereq. sections in update requests */ ns_c_any = 255, /*%< Wildcard match. */ ns_c_max = 65536 } ns_class; /* Certificate type values in CERT resource records. */ typedef enum __ns_cert_types { cert_t_pkix = 1, /*%< PKIX (X.509v3) */ cert_t_spki = 2, /*%< SPKI */ cert_t_pgp = 3, /*%< PGP */ cert_t_url = 253, /*%< URL private type */ cert_t_oid = 254 /*%< OID private type */ } ns_cert_types; /*% * EDNS0 extended flags and option codes, host order. */ #define NS_OPT_DNSSEC_OK 0x8000U #define NS_OPT_NSID 3 /*% * Inline versions of get/put short/long. Pointer is advanced. */ #define NS_GET16(s, cp) do { \ const unsigned char *t_cp = (const unsigned char *)(cp); \ (s) = ((uint16_t)t_cp[0] << 8) \ | ((uint16_t)t_cp[1]) \ ; \ (cp) += NS_INT16SZ; \ } while (0) #define NS_GET32(l, cp) do { \ const unsigned char *t_cp = (const unsigned char *)(cp); \ (l) = ((uint32_t)t_cp[0] << 24) \ | ((uint32_t)t_cp[1] << 16) \ | ((uint32_t)t_cp[2] << 8) \ | ((uint32_t)t_cp[3]) \ ; \ (cp) += NS_INT32SZ; \ } while (0) #define NS_PUT16(s, cp) do { \ uint16_t t_s = (uint16_t)(s); \ unsigned char *t_cp = (unsigned char *)(cp); \ *t_cp++ = t_s >> 8; \ *t_cp = t_s; \ (cp) += NS_INT16SZ; \ } while (0) #define NS_PUT32(l, cp) do { \ uint32_t t_l = (uint32_t)(l); \ unsigned char *t_cp = (unsigned char *)(cp); \ *t_cp++ = t_l >> 24; \ *t_cp++ = t_l >> 16; \ *t_cp++ = t_l >> 8; \ *t_cp = t_l; \ (cp) += NS_INT32SZ; \ } while (0) __BEGIN_DECLS int ns_msg_getflag (ns_msg, int) __THROW; unsigned int ns_get16 (const unsigned char *) __THROW; unsigned long ns_get32 (const unsigned char *) __THROW; void ns_put16 (unsigned int, unsigned char *) __THROW; void ns_put32 (unsigned long, unsigned char *) __THROW; int ns_initparse (const unsigned char *, int, ns_msg *) __THROW; int ns_skiprr (const unsigned char *, const unsigned char *, ns_sect, int) __THROW; int ns_parserr (ns_msg *, ns_sect, int, ns_rr *) __THROW; int ns_sprintrr (const ns_msg *, const ns_rr *, const char *, const char *, char *, size_t) __THROW; int ns_sprintrrf (const unsigned char *, size_t, const char *, ns_class, ns_type, unsigned long, const unsigned char *, size_t, const char *, const char *, char *, size_t) __THROW; int ns_format_ttl (unsigned long, char *, size_t) __THROW; int ns_parse_ttl (const char *, unsigned long *) __THROW; uint32_t ns_datetosecs (const char *, int *) __THROW; int ns_name_ntol (const unsigned char *, unsigned char *, size_t) __THROW; int ns_name_ntop (const unsigned char *, char *, size_t) __THROW; int ns_name_pton (const char *, unsigned char *, size_t) __THROW; int ns_name_unpack (const unsigned char *, const unsigned char *, const unsigned char *, unsigned char *, size_t) __THROW; int ns_name_pack (const unsigned char *, unsigned char *, int, const unsigned char **, const unsigned char **) __THROW; int ns_name_uncompress (const unsigned char *, const unsigned char *, const unsigned char *, char *, size_t) __THROW; int ns_name_compress (const char *, unsigned char *, size_t, const unsigned char **, const unsigned char **) __THROW; int ns_name_skip (const unsigned char **, const unsigned char *) __THROW; void ns_name_rollback (const unsigned char *, const unsigned char **, const unsigned char **) __THROW; int ns_samedomain (const char *, const char *) __THROW; int ns_subdomain (const char *, const char *) __THROW; int ns_makecanon (const char *, char *, size_t) __THROW; int ns_samename (const char *, const char *) __THROW; __END_DECLS #include <arpa/nameser_compat.h> #endif /* !_ARPA_NAMESER_H_ */ /*! \file */ arpa/telnet.h 0000644 00000024027 15146341150 0007140 0 ustar 00 /* * Copyright (c) 1983, 1993 * The Regents of the University of California. 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. * 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. * * @(#)telnet.h 8.2 (Berkeley) 12/15/93 */ #ifndef _ARPA_TELNET_H #define _ARPA_TELNET_H 1 /* * Definitions for the TELNET protocol. */ #define IAC 255 /* interpret as command: */ #define DONT 254 /* you are not to use option */ #define DO 253 /* please, you use option */ #define WONT 252 /* I won't use option */ #define WILL 251 /* I will use option */ #define SB 250 /* interpret as subnegotiation */ #define GA 249 /* you may reverse the line */ #define EL 248 /* erase the current line */ #define EC 247 /* erase the current character */ #define AYT 246 /* are you there */ #define AO 245 /* abort output--but let prog finish */ #define IP 244 /* interrupt process--permanently */ #define BREAK 243 /* break */ #define DM 242 /* data mark--for connect. cleaning */ #define NOP 241 /* nop */ #define SE 240 /* end sub negotiation */ #define EOR 239 /* end of record (transparent mode) */ #define ABORT 238 /* Abort process */ #define SUSP 237 /* Suspend process */ #define xEOF 236 /* End of file: EOF is already used... */ #define SYNCH 242 /* for telfunc calls */ #ifdef TELCMDS char *telcmds[] = { "EOF", "SUSP", "ABORT", "EOR", "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0, }; #else extern char *telcmds[]; #endif #define TELCMD_FIRST xEOF #define TELCMD_LAST IAC #define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \ (unsigned int)(x) >= TELCMD_FIRST) #define TELCMD(x) telcmds[(x)-TELCMD_FIRST] /* telnet options */ #define TELOPT_BINARY 0 /* 8-bit data path */ #define TELOPT_ECHO 1 /* echo */ #define TELOPT_RCP 2 /* prepare to reconnect */ #define TELOPT_SGA 3 /* suppress go ahead */ #define TELOPT_NAMS 4 /* approximate message size */ #define TELOPT_STATUS 5 /* give status */ #define TELOPT_TM 6 /* timing mark */ #define TELOPT_RCTE 7 /* remote controlled transmission and echo */ #define TELOPT_NAOL 8 /* negotiate about output line width */ #define TELOPT_NAOP 9 /* negotiate about output page size */ #define TELOPT_NAOCRD 10 /* negotiate about CR disposition */ #define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */ #define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */ #define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */ #define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */ #define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */ #define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */ #define TELOPT_XASCII 17 /* extended ascii character set */ #define TELOPT_LOGOUT 18 /* force logout */ #define TELOPT_BM 19 /* byte macro */ #define TELOPT_DET 20 /* data entry terminal */ #define TELOPT_SUPDUP 21 /* supdup protocol */ #define TELOPT_SUPDUPOUTPUT 22 /* supdup output */ #define TELOPT_SNDLOC 23 /* send location */ #define TELOPT_TTYPE 24 /* terminal type */ #define TELOPT_EOR 25 /* end or record */ #define TELOPT_TUID 26 /* TACACS user identification */ #define TELOPT_OUTMRK 27 /* output marking */ #define TELOPT_TTYLOC 28 /* terminal location number */ #define TELOPT_3270REGIME 29 /* 3270 regime */ #define TELOPT_X3PAD 30 /* X.3 PAD */ #define TELOPT_NAWS 31 /* window size */ #define TELOPT_TSPEED 32 /* terminal speed */ #define TELOPT_LFLOW 33 /* remote flow control */ #define TELOPT_LINEMODE 34 /* Linemode option */ #define TELOPT_XDISPLOC 35 /* X Display Location */ #define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */ #define TELOPT_AUTHENTICATION 37/* Authenticate */ #define TELOPT_ENCRYPT 38 /* Encryption option */ #define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */ #define TELOPT_EXOPL 255 /* extended-options-list */ #define NTELOPTS (1+TELOPT_NEW_ENVIRON) #ifdef TELOPTS char *telopts[NTELOPTS+1] = { "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING", "TTYLOC", "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW", "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON", 0, }; #define TELOPT_FIRST TELOPT_BINARY #define TELOPT_LAST TELOPT_NEW_ENVIRON #define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) #define TELOPT(x) telopts[(x)-TELOPT_FIRST] #endif /* sub-option qualifiers */ #define TELQUAL_IS 0 /* option is... */ #define TELQUAL_SEND 1 /* send option */ #define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */ #define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */ #define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */ #define LFLOW_OFF 0 /* Disable remote flow control */ #define LFLOW_ON 1 /* Enable remote flow control */ #define LFLOW_RESTART_ANY 2 /* Restart output on any char */ #define LFLOW_RESTART_XON 3 /* Restart output only on XON */ /* * LINEMODE suboptions */ #define LM_MODE 1 #define LM_FORWARDMASK 2 #define LM_SLC 3 #define MODE_EDIT 0x01 #define MODE_TRAPSIG 0x02 #define MODE_ACK 0x04 #define MODE_SOFT_TAB 0x08 #define MODE_LIT_ECHO 0x10 #define MODE_MASK 0x1f /* Not part of protocol, but needed to simplify things... */ #define MODE_FLOW 0x0100 #define MODE_ECHO 0x0200 #define MODE_INBIN 0x0400 #define MODE_OUTBIN 0x0800 #define MODE_FORCE 0x1000 #define SLC_SYNCH 1 #define SLC_BRK 2 #define SLC_IP 3 #define SLC_AO 4 #define SLC_AYT 5 #define SLC_EOR 6 #define SLC_ABORT 7 #define SLC_EOF 8 #define SLC_SUSP 9 #define SLC_EC 10 #define SLC_EL 11 #define SLC_EW 12 #define SLC_RP 13 #define SLC_LNEXT 14 #define SLC_XON 15 #define SLC_XOFF 16 #define SLC_FORW1 17 #define SLC_FORW2 18 #define NSLC 18 /* * For backwards compatibility, we define SLC_NAMES to be the * list of names if SLC_NAMES is not defined. */ #define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \ "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \ "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0, #ifdef SLC_NAMES char *slc_names[] = { SLC_NAMELIST }; #else extern char *slc_names[]; #define SLC_NAMES SLC_NAMELIST #endif #define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC) #define SLC_NAME(x) slc_names[x] #define SLC_NOSUPPORT 0 #define SLC_CANTCHANGE 1 #define SLC_VARIABLE 2 #define SLC_DEFAULT 3 #define SLC_LEVELBITS 0x03 #define SLC_FUNC 0 #define SLC_FLAGS 1 #define SLC_VALUE 2 #define SLC_ACK 0x80 #define SLC_FLUSHIN 0x40 #define SLC_FLUSHOUT 0x20 #define OLD_ENV_VAR 1 #define OLD_ENV_VALUE 0 #define NEW_ENV_VAR 0 #define NEW_ENV_VALUE 1 #define ENV_ESC 2 #define ENV_USERVAR 3 /* * AUTHENTICATION suboptions */ /* * Who is authenticating who ... */ #define AUTH_WHO_CLIENT 0 /* Client authenticating server */ #define AUTH_WHO_SERVER 1 /* Server authenticating client */ #define AUTH_WHO_MASK 1 /* * amount of authentication done */ #define AUTH_HOW_ONE_WAY 0 #define AUTH_HOW_MUTUAL 2 #define AUTH_HOW_MASK 2 #define AUTHTYPE_NULL 0 #define AUTHTYPE_KERBEROS_V4 1 #define AUTHTYPE_KERBEROS_V5 2 #define AUTHTYPE_SPX 3 #define AUTHTYPE_MINK 4 #define AUTHTYPE_CNT 5 #define AUTHTYPE_TEST 99 #ifdef AUTH_NAMES char *authtype_names[] = { "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0, }; #else extern char *authtype_names[]; #endif #define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT) #define AUTHTYPE_NAME(x) authtype_names[x] /* * ENCRYPTion suboptions */ #define ENCRYPT_IS 0 /* I pick encryption type ... */ #define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ #define ENCRYPT_REPLY 2 /* Initial setup response */ #define ENCRYPT_START 3 /* Am starting to send encrypted */ #define ENCRYPT_END 4 /* Am ending encrypted */ #define ENCRYPT_REQSTART 5 /* Request you start encrypting */ #define ENCRYPT_REQEND 6 /* Request you send encrypting */ #define ENCRYPT_ENC_KEYID 7 #define ENCRYPT_DEC_KEYID 8 #define ENCRYPT_CNT 9 #define ENCTYPE_ANY 0 #define ENCTYPE_DES_CFB64 1 #define ENCTYPE_DES_OFB64 2 #define ENCTYPE_CNT 3 #ifdef ENCRYPT_NAMES char *encrypt_names[] = { "IS", "SUPPORT", "REPLY", "START", "END", "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID", 0, }; char *enctype_names[] = { "ANY", "DES_CFB64", "DES_OFB64", 0, }; #else extern char *encrypt_names[]; extern char *enctype_names[]; #endif #define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT) #define ENCRYPT_NAME(x) encrypt_names[x] #define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT) #define ENCTYPE_NAME(x) enctype_names[x] #endif /* arpa/telnet.h */ cursesf.h 0000644 00000066311 15146341150 0006376 0 ustar 00 // * This makes emacs happy -*-Mode: C++;-*- /**************************************************************************** * Copyright (c) 1998-2012,2014 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, distribute with modifications, sublicense, and/or sell * * copies of the Software, and to permit persons to whom the Software is * * furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included * * in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * * * Except as contained in this notice, the name(s) of the above copyright * * holders shall not be used in advertising or otherwise to promote the * * sale, use or other dealings in this Software without prior written * * authorization. * ****************************************************************************/ /**************************************************************************** * Author: Juergen Pfeifer, 1997 * ****************************************************************************/ // $Id: cursesf.h,v 1.32 2014/08/09 22:06:11 Adam.Jiang Exp $ #ifndef NCURSES_CURSESF_H_incl #define NCURSES_CURSESF_H_incl 1 #include <cursesp.h> #ifndef __EXT_QNX #include <string.h> #endif extern "C" { # include <form.h> } // // ------------------------------------------------------------------------- // The abstract base class for buitin and user defined Fieldtypes. // ------------------------------------------------------------------------- // class NCURSES_IMPEXP NCursesFormField; // forward declaration // Class to represent builtin field types as well as C++ written new // fieldtypes (see classes UserDefineFieldType... class NCURSES_IMPEXP NCursesFieldType { friend class NCursesFormField; protected: FIELDTYPE* fieldtype; inline void OnError(int err) const THROW2(NCursesException const, NCursesFormException) { if (err!=E_OK) THROW(new NCursesFormException (err)); } NCursesFieldType(FIELDTYPE *f) : fieldtype(f) { } virtual ~NCursesFieldType() {} // Set the fields f fieldtype to this one. virtual void set(NCursesFormField& f) = 0; public: NCursesFieldType() : fieldtype(STATIC_CAST(FIELDTYPE*)(0)) { } NCursesFieldType& operator=(const NCursesFieldType& rhs) { if (this != &rhs) { *this = rhs; } return *this; } NCursesFieldType(const NCursesFieldType& rhs) : fieldtype(rhs.fieldtype) { } }; // // ------------------------------------------------------------------------- // The class representing a forms field, wrapping the lowlevel FIELD struct // ------------------------------------------------------------------------- // class NCURSES_IMPEXP NCursesFormField { friend class NCursesForm; protected: FIELD *field; // lowlevel structure NCursesFieldType* ftype; // Associated field type // Error handler inline void OnError (int err) const THROW2(NCursesException const, NCursesFormException) { if (err != E_OK) THROW(new NCursesFormException (err)); } public: // Create a 'Null' field. Can be used to delimit a field list NCursesFormField() : field(STATIC_CAST(FIELD*)(0)), ftype(STATIC_CAST(NCursesFieldType*)(0)) { } // Create a new field NCursesFormField (int rows, int ncols, int first_row = 0, int first_col = 0, int offscreen_rows = 0, int additional_buffers = 0) : field(0), ftype(STATIC_CAST(NCursesFieldType*)(0)) { field = ::new_field(rows, ncols, first_row, first_col, offscreen_rows, additional_buffers); if (!field) OnError(errno); } NCursesFormField& operator=(const NCursesFormField& rhs) { if (this != &rhs) { *this = rhs; } return *this; } NCursesFormField(const NCursesFormField& rhs) : field(rhs.field), ftype(rhs.ftype) { } virtual ~NCursesFormField (); // Duplicate the field at a new position inline NCursesFormField* dup(int first_row, int first_col) { NCursesFormField* f = new NCursesFormField(); if (!f) OnError(E_SYSTEM_ERROR); else { f->ftype = ftype; f->field = ::dup_field(field,first_row,first_col); if (!f->field) OnError(errno); } return f; } // Link the field to a new location inline NCursesFormField* link(int first_row, int first_col) { NCursesFormField* f = new NCursesFormField(); if (!f) OnError(E_SYSTEM_ERROR); else { f->ftype = ftype; f->field = ::link_field(field,first_row,first_col); if (!f->field) OnError(errno); } return f; } // Get the lowlevel field representation inline FIELD* get_field() const { return field; } // Retrieve info about the field inline void info(int& rows, int& ncols, int& first_row, int& first_col, int& offscreen_rows, int& additional_buffers) const { OnError(::field_info(field, &rows, &ncols, &first_row, &first_col, &offscreen_rows, &additional_buffers)); } // Retrieve info about the fields dynamic properties. inline void dynamic_info(int& dynamic_rows, int& dynamic_cols, int& max_growth) const { OnError(::dynamic_field_info(field, &dynamic_rows, &dynamic_cols, &max_growth)); } // For a dynamic field you may set the maximum growth limit. // A zero means unlimited growth. inline void set_maximum_growth(int growth = 0) { OnError(::set_max_field(field,growth)); } // Move the field to a new position inline void move(int row, int col) { OnError(::move_field(field,row,col)); } // Mark the field to start a new page inline void new_page(bool pageFlag = FALSE) { OnError(::set_new_page(field,pageFlag)); } // Retrieve whether or not the field starts a new page. inline bool is_new_page() const { return ::new_page(field); } // Set the justification for the field inline void set_justification(int just) { OnError(::set_field_just(field,just)); } // Retrieve the fields justification inline int justification() const { return ::field_just(field); } // Set the foreground attribute for the field inline void set_foreground(chtype foreground) { OnError(::set_field_fore(field,foreground)); } // Retrieve the fields foreground attribute inline chtype fore() const { return ::field_fore(field); } // Set the background attribute for the field inline void set_background(chtype background) { OnError(::set_field_back(field,background)); } // Retrieve the fields background attribute inline chtype back() const { return ::field_back(field); } // Set the padding character for the field inline void set_pad_character(int padding) { OnError(::set_field_pad(field, padding)); } // Retrieve the fields padding character inline int pad() const { return ::field_pad(field); } // Switch on the fields options inline void options_on (Field_Options opts) { OnError (::field_opts_on (field, opts)); } // Switch off the fields options inline void options_off (Field_Options opts) { OnError (::field_opts_off (field, opts)); } // Retrieve the fields options inline Field_Options options () const { return ::field_opts (field); } // Set the fields options inline void set_options (Field_Options opts) { OnError (::set_field_opts (field, opts)); } // Mark the field as changed inline void set_changed(bool changeFlag = TRUE) { OnError(::set_field_status(field,changeFlag)); } // Test whether or not the field is marked as changed inline bool changed() const { return ::field_status(field); } // Return the index of the field in the field array of a form // or -1 if the field is not associated to a form inline int (index)() const { return ::field_index(field); } // Store a value in a fields buffer. The default buffer is nr. 0 inline void set_value(const char *val, int buffer = 0) { OnError(::set_field_buffer(field,buffer,val)); } // Retrieve the value of a fields buffer. The default buffer is nr. 0 inline char* value(int buffer = 0) const { return ::field_buffer(field,buffer); } // Set the validation type of the field. inline void set_fieldtype(NCursesFieldType& f) { ftype = &f; f.set(*this); // A good friend may do that... } // Retrieve the validation type of the field. inline NCursesFieldType* fieldtype() const { return ftype; } }; // This are the built-in hook functions in this C++ binding. In C++ we use // virtual member functions (see below On_..._Init and On_..._Termination) // to provide this functionality in an object oriented manner. extern "C" { void _nc_xx_frm_init(FORM *); void _nc_xx_frm_term(FORM *); void _nc_xx_fld_init(FORM *); void _nc_xx_fld_term(FORM *); } // // ------------------------------------------------------------------------- // The class representing a form, wrapping the lowlevel FORM struct // ------------------------------------------------------------------------- // class NCURSES_IMPEXP NCursesForm : public NCursesPanel { protected: FORM* form; // the lowlevel structure private: NCursesWindow* sub; // the subwindow object bool b_sub_owner; // is this our own subwindow? bool b_framed; // has the form a border? bool b_autoDelete; // Delete fields when deleting form? NCursesFormField** my_fields; // The array of fields for this form // This structure is used for the form's user data field to link the // FORM* to the C++ object and to provide extra space for a user pointer. typedef struct { void* m_user; // the pointer for the user's data const NCursesForm* m_back; // backward pointer to C++ object const FORM* m_owner; } UserHook; // Get the backward pointer to the C++ object from a FORM static inline NCursesForm* getHook(const FORM *f) { UserHook* hook = reinterpret_cast<UserHook*>(::form_userptr(f)); assert(hook != 0 && hook->m_owner==f); return const_cast<NCursesForm*>(hook->m_back); } friend void _nc_xx_frm_init(FORM *); friend void _nc_xx_frm_term(FORM *); friend void _nc_xx_fld_init(FORM *); friend void _nc_xx_fld_term(FORM *); // Calculate FIELD* array for the menu FIELD** mapFields(NCursesFormField* nfields[]); protected: // internal routines inline void set_user(void *user) { UserHook* uptr = reinterpret_cast<UserHook*>(::form_userptr (form)); assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form); uptr->m_user = user; } inline void *get_user() { UserHook* uptr = reinterpret_cast<UserHook*>(::form_userptr (form)); assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form); return uptr->m_user; } void InitForm (NCursesFormField* Fields[], bool with_frame, bool autoDeleteFields); inline void OnError (int err) const THROW2(NCursesException const, NCursesFormException) { if (err != E_OK) THROW(new NCursesFormException (err)); } // this wraps the form_driver call. virtual int driver (int c) ; // 'Internal' constructor, builds an object without association to a // field array. NCursesForm( int nlines, int ncols, int begin_y = 0, int begin_x = 0) : NCursesPanel(nlines, ncols, begin_y, begin_x), form (STATIC_CAST(FORM*)(0)), sub(0), b_sub_owner(0), b_framed(0), b_autoDelete(0), my_fields(0) { } public: // Create form for the default panel. NCursesForm (NCursesFormField* Fields[], bool with_frame=FALSE, // reserve space for a frame? bool autoDelete_Fields=FALSE) // do automatic cleanup? : NCursesPanel(), form(0), sub(0), b_sub_owner(0), b_framed(0), b_autoDelete(0), my_fields(0) { InitForm(Fields, with_frame, autoDelete_Fields); } // Create a form in a panel with the given position and size. NCursesForm (NCursesFormField* Fields[], int nlines, int ncols, int begin_y, int begin_x, bool with_frame=FALSE, // reserve space for a frame? bool autoDelete_Fields=FALSE) // do automatic cleanup? : NCursesPanel(nlines, ncols, begin_y, begin_x), form(0), sub(0), b_sub_owner(0), b_framed(0), b_autoDelete(0), my_fields(0) { InitForm(Fields, with_frame, autoDelete_Fields); } NCursesForm& operator=(const NCursesForm& rhs) { if (this != &rhs) { *this = rhs; NCursesPanel::operator=(rhs); } return *this; } NCursesForm(const NCursesForm& rhs) : NCursesPanel(rhs), form(rhs.form), sub(rhs.sub), b_sub_owner(rhs.b_sub_owner), b_framed(rhs.b_framed), b_autoDelete(rhs.b_autoDelete), my_fields(rhs.my_fields) { } virtual ~NCursesForm(); // Set the default attributes for the form virtual void setDefaultAttributes(); // Retrieve current field of the form. inline NCursesFormField* current_field() const { return my_fields[::field_index(::current_field(form))]; } // Set the forms subwindow void setSubWindow(NCursesWindow& sub); // Set these fields for the form inline void setFields(NCursesFormField* Fields[]) { OnError(::set_form_fields(form,mapFields(Fields))); } // Remove the form from the screen inline void unpost (void) { OnError (::unpost_form (form)); } // Post the form to the screen if flag is true, unpost it otherwise inline void post(bool flag = TRUE) { OnError (flag ? ::post_form(form) : ::unpost_form (form)); } // Decorations inline void frame(const char *title=NULL, const char* btitle=NULL) { if (b_framed) NCursesPanel::frame(title,btitle); else OnError(E_SYSTEM_ERROR); } inline void boldframe(const char *title=NULL, const char* btitle=NULL) { if (b_framed) NCursesPanel::boldframe(title,btitle); else OnError(E_SYSTEM_ERROR); } inline void label(const char *topLabel, const char *bottomLabel) { if (b_framed) NCursesPanel::label(topLabel,bottomLabel); else OnError(E_SYSTEM_ERROR); } // ----- // Hooks // ----- // Called after the form gets repositioned in its window. // This is especially true if the form is posted. virtual void On_Form_Init(); // Called before the form gets repositioned in its window. // This is especially true if the form is unposted. virtual void On_Form_Termination(); // Called after the field became the current field virtual void On_Field_Init(NCursesFormField& field); // Called before this field is left as current field. virtual void On_Field_Termination(NCursesFormField& field); // Calculate required window size for the form. void scale(int& rows, int& ncols) const { OnError(::scale_form(form,&rows,&ncols)); } // Retrieve number of fields in the form. int count() const { return ::field_count(form); } // Make the page the current page of the form. void set_page(int pageNum) { OnError(::set_form_page(form, pageNum)); } // Retrieve current page number int page() const { return ::form_page(form); } // Switch on the forms options inline void options_on (Form_Options opts) { OnError (::form_opts_on (form, opts)); } // Switch off the forms options inline void options_off (Form_Options opts) { OnError (::form_opts_off (form, opts)); } // Retrieve the forms options inline Form_Options options () const { return ::form_opts (form); } // Set the forms options inline void set_options (Form_Options opts) { OnError (::set_form_opts (form, opts)); } // Are there more data in the current field after the data shown inline bool data_ahead() const { return ::data_ahead(form); } // Are there more data in the current field before the data shown inline bool data_behind() const { return ::data_behind(form); } // Position the cursor to the current field inline void position_cursor () { OnError (::pos_form_cursor (form)); } // Set the current field inline void set_current(NCursesFormField& F) { OnError (::set_current_field(form, F.field)); } // Provide a default key virtualization. Translate the keyboard // code c into a form request code. // The default implementation provides a hopefully straightforward // mapping for the most common keystrokes and form requests. virtual int virtualize(int c); // Operators inline NCursesFormField* operator[](int i) const { if ( (i < 0) || (i >= ::field_count (form)) ) OnError (E_BAD_ARGUMENT); return my_fields[i]; } // Perform the menu's operation // Return the field where you left the form. virtual NCursesFormField* operator()(void); // Exception handlers. The default is a Beep. virtual void On_Request_Denied(int c) const; virtual void On_Invalid_Field(int c) const; virtual void On_Unknown_Command(int c) const; }; // // ------------------------------------------------------------------------- // This is the typical C++ typesafe way to allow to attach // user data to a field of a form. Its assumed that the user // data belongs to some class T. Use T as template argument // to create a UserField. // ------------------------------------------------------------------------- template<class T> class NCURSES_IMPEXP NCursesUserField : public NCursesFormField { public: NCursesUserField (int rows, int ncols, int first_row = 0, int first_col = 0, const T* p_UserData = STATIC_CAST(T*)(0), int offscreen_rows = 0, int additional_buffers = 0) : NCursesFormField (rows, ncols, first_row, first_col, offscreen_rows, additional_buffers) { if (field) OnError(::set_field_userptr(field, STATIC_CAST(void *)(p_UserData))); } virtual ~NCursesUserField() {}; inline const T* UserData (void) const { return reinterpret_cast<const T*>(::field_userptr (field)); } inline virtual void setUserData(const T* p_UserData) { if (field) OnError (::set_field_userptr (field, STATIC_CAST(void *)(p_UserData))); } }; // // ------------------------------------------------------------------------- // The same mechanism is used to attach user data to a form // ------------------------------------------------------------------------- // template<class T> class NCURSES_IMPEXP NCursesUserForm : public NCursesForm { protected: // 'Internal' constructor, builds an object without association to a // field array. NCursesUserForm( int nlines, int ncols, int begin_y = 0, int begin_x = 0, const T* p_UserData = STATIC_CAST(T*)(0)) : NCursesForm(nlines,ncols,begin_y,begin_x) { if (form) set_user (const_cast<void *>(reinterpret_cast<const void*> (p_UserData))); } public: NCursesUserForm (NCursesFormField* Fields[], const T* p_UserData = STATIC_CAST(T*)(0), bool with_frame=FALSE, bool autoDelete_Fields=FALSE) : NCursesForm (Fields, with_frame, autoDelete_Fields) { if (form) set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData))); }; NCursesUserForm (NCursesFormField* Fields[], int nlines, int ncols, int begin_y = 0, int begin_x = 0, const T* p_UserData = STATIC_CAST(T*)(0), bool with_frame=FALSE, bool autoDelete_Fields=FALSE) : NCursesForm (Fields, nlines, ncols, begin_y, begin_x, with_frame, autoDelete_Fields) { if (form) set_user (const_cast<void *>(reinterpret_cast<const void*> (p_UserData))); }; virtual ~NCursesUserForm() { }; inline T* UserData (void) { return reinterpret_cast<T*>(get_user ()); }; inline virtual void setUserData (const T* p_UserData) { if (form) set_user (const_cast<void *>(reinterpret_cast<const void*>(p_UserData))); } }; // // ------------------------------------------------------------------------- // Builtin Fieldtypes // ------------------------------------------------------------------------- // class NCURSES_IMPEXP Alpha_Field : public NCursesFieldType { private: int min_field_width; void set(NCursesFormField& f) { OnError(::set_field_type(f.get_field(),fieldtype,min_field_width)); } public: Alpha_Field(int width) : NCursesFieldType(TYPE_ALPHA), min_field_width(width) { } }; class NCURSES_IMPEXP Alphanumeric_Field : public NCursesFieldType { private: int min_field_width; void set(NCursesFormField& f) { OnError(::set_field_type(f.get_field(),fieldtype,min_field_width)); } public: Alphanumeric_Field(int width) : NCursesFieldType(TYPE_ALNUM), min_field_width(width) { } }; class NCURSES_IMPEXP Integer_Field : public NCursesFieldType { private: int precision; long lower_limit, upper_limit; void set(NCursesFormField& f) { OnError(::set_field_type(f.get_field(),fieldtype, precision,lower_limit,upper_limit)); } public: Integer_Field(int prec, long low=0L, long high=0L) : NCursesFieldType(TYPE_INTEGER), precision(prec), lower_limit(low), upper_limit(high) { } }; class NCURSES_IMPEXP Numeric_Field : public NCursesFieldType { private: int precision; double lower_limit, upper_limit; void set(NCursesFormField& f) { OnError(::set_field_type(f.get_field(),fieldtype, precision,lower_limit,upper_limit)); } public: Numeric_Field(int prec, double low=0.0, double high=0.0) : NCursesFieldType(TYPE_NUMERIC), precision(prec), lower_limit(low), upper_limit(high) { } }; class NCURSES_IMPEXP Regular_Expression_Field : public NCursesFieldType { private: char* regex; void set(NCursesFormField& f) { OnError(::set_field_type(f.get_field(),fieldtype,regex)); } void copy_regex(const char *source) { regex = new char[1 + ::strlen(source)]; (::strcpy)(regex, source); } public: Regular_Expression_Field(const char *expr) : NCursesFieldType(TYPE_REGEXP), regex(NULL) { copy_regex(expr); } Regular_Expression_Field& operator=(const Regular_Expression_Field& rhs) { if (this != &rhs) { *this = rhs; copy_regex(rhs.regex); NCursesFieldType::operator=(rhs); } return *this; } Regular_Expression_Field(const Regular_Expression_Field& rhs) : NCursesFieldType(rhs), regex(NULL) { copy_regex(rhs.regex); } ~Regular_Expression_Field() { delete[] regex; } }; class NCURSES_IMPEXP Enumeration_Field : public NCursesFieldType { private: const char** list; int case_sensitive; int non_unique_matches; void set(NCursesFormField& f) { OnError(::set_field_type(f.get_field(),fieldtype, list,case_sensitive,non_unique_matches)); } public: Enumeration_Field(const char* enums[], bool case_sens=FALSE, bool non_unique=FALSE) : NCursesFieldType(TYPE_ENUM), list(enums), case_sensitive(case_sens ? -1 : 0), non_unique_matches(non_unique ? -1 : 0) { } Enumeration_Field& operator=(const Enumeration_Field& rhs) { if (this != &rhs) { *this = rhs; NCursesFieldType::operator=(rhs); } return *this; } Enumeration_Field(const Enumeration_Field& rhs) : NCursesFieldType(rhs), list(rhs.list), case_sensitive(rhs.case_sensitive), non_unique_matches(rhs.non_unique_matches) { } }; class NCURSES_IMPEXP IPV4_Address_Field : public NCursesFieldType { private: void set(NCursesFormField& f) { OnError(::set_field_type(f.get_field(),fieldtype)); } public: IPV4_Address_Field() : NCursesFieldType(TYPE_IPV4) { } }; extern "C" { bool _nc_xx_fld_fcheck(FIELD *, const void*); bool _nc_xx_fld_ccheck(int c, const void *); void* _nc_xx_fld_makearg(va_list*); } // // ------------------------------------------------------------------------- // Abstract base class for User-Defined Fieldtypes // ------------------------------------------------------------------------- // class NCURSES_IMPEXP UserDefinedFieldType : public NCursesFieldType { friend class UDF_Init; // Internal helper to set up statics private: // For all C++ defined fieldtypes we need only one generic lowlevel // FIELDTYPE* element. static FIELDTYPE* generic_fieldtype; protected: // This are the functions required by the low level libforms functions // to construct a fieldtype. friend bool _nc_xx_fld_fcheck(FIELD *, const void*); friend bool _nc_xx_fld_ccheck(int c, const void *); friend void* _nc_xx_fld_makearg(va_list*); void set(NCursesFormField& f) { OnError(::set_field_type(f.get_field(),fieldtype,&f)); } protected: // Redefine this function to do a field validation. The argument // is a reference to the field you should validate. virtual bool field_check(NCursesFormField& f) = 0; // Redefine this function to do a character validation. The argument // is the character to be validated. virtual bool char_check (int c) = 0; public: UserDefinedFieldType() : NCursesFieldType(generic_fieldtype) { } }; extern "C" { bool _nc_xx_next_choice(FIELD*, const void *); bool _nc_xx_prev_choice(FIELD*, const void *); } // // ------------------------------------------------------------------------- // Abstract base class for User-Defined Fieldtypes with Choice functions // ------------------------------------------------------------------------- // class NCURSES_IMPEXP UserDefinedFieldType_With_Choice : public UserDefinedFieldType { friend class UDF_Init; // Internal helper to set up statics private: // For all C++ defined fieldtypes with choice functions we need only one // generic lowlevel FIELDTYPE* element. static FIELDTYPE* generic_fieldtype_with_choice; // This are the functions required by the low level libforms functions // to construct a fieldtype with choice functions. friend bool _nc_xx_next_choice(FIELD*, const void *); friend bool _nc_xx_prev_choice(FIELD*, const void *); protected: // Redefine this function to do the retrieval of the next choice value. // The argument is a reference to the field tobe examined. virtual bool next (NCursesFormField& f) = 0; // Redefine this function to do the retrieval of the previous choice value. // The argument is a reference to the field tobe examined. virtual bool previous(NCursesFormField& f) = 0; public: UserDefinedFieldType_With_Choice() { fieldtype = generic_fieldtype_with_choice; } }; #endif /* NCURSES_CURSESF_H_incl */ gssrpc/auth_gss.h 0000644 00000011350 15146341150 0010033 0 ustar 00 /* include/gssrpc/auth_gss.h */ /* Copyright (c) 2000 The Regents of the University of Michigan. All rights reserved. Copyright (c) 2000 Dug Song <dugsong@UMICH.EDU>. All rights reserved, all wrongs reversed. 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. 3. 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 ``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. Id: auth_gss.h,v 1.13 2002/05/08 16:54:33 andros Exp */ #ifndef GSSRPC_AUTH_GSS_H #define GSSRPC_AUTH_GSS_H #include <gssrpc/rpc.h> #include <gssrpc/clnt.h> #ifdef HAVE_HEIMDAL #include <gssapi.h> #else #include <gssapi/gssapi.h> #endif GSSRPC__BEGIN_DECLS /* RPCSEC_GSS control procedures. */ typedef enum { RPCSEC_GSS_DATA = 0, RPCSEC_GSS_INIT = 1, RPCSEC_GSS_CONTINUE_INIT = 2, RPCSEC_GSS_DESTROY = 3 } rpc_gss_proc_t; /* RPCSEC_GSS services. */ typedef enum { RPCSEC_GSS_SVC_NONE = 1, RPCSEC_GSS_SVC_INTEGRITY = 2, RPCSEC_GSS_SVC_PRIVACY = 3 } rpc_gss_svc_t; #define RPCSEC_GSS_VERSION 1 /* RPCSEC_GSS security triple. */ struct rpc_gss_sec { gss_OID mech; /* mechanism */ gss_qop_t qop; /* quality of protection */ rpc_gss_svc_t svc; /* service */ gss_cred_id_t cred; /* cred handle */ uint32_t req_flags; /* req flags for init_sec_context */ }; /* Private data required for kernel implementation */ struct authgss_private_data { gss_ctx_id_t pd_ctx; /* Session context handle */ gss_buffer_desc pd_ctx_hndl; /* Credentials context handle */ uint32_t pd_seq_win; /* Sequence window */ }; /* Krb 5 default mechanism #define KRB5OID "1.2.840.113554.1.2.2" gss_OID_desc krb5oid = { 20, KRB5OID }; */ /* struct rpc_gss_sec krb5mech = { (gss_OID)&krb5oid, GSS_QOP_DEFAULT, RPCSEC_GSS_SVC_NONE }; */ /* Credentials. */ struct rpc_gss_cred { u_int gc_v; /* version */ rpc_gss_proc_t gc_proc; /* control procedure */ uint32_t gc_seq; /* sequence number */ rpc_gss_svc_t gc_svc; /* service */ gss_buffer_desc gc_ctx; /* context handle */ }; /* Context creation response. */ struct rpc_gss_init_res { gss_buffer_desc gr_ctx; /* context handle */ uint32_t gr_major; /* major status */ uint32_t gr_minor; /* minor status */ uint32_t gr_win; /* sequence window */ gss_buffer_desc gr_token; /* token */ }; /* Maximum sequence number value. */ #define MAXSEQ 0x80000000 /* Prototypes. */ bool_t xdr_rpc_gss_buf (XDR *xdrs, gss_buffer_t, u_int maxsize); bool_t xdr_rpc_gss_cred (XDR *xdrs, struct rpc_gss_cred *p); bool_t xdr_rpc_gss_init_args (XDR *xdrs, gss_buffer_desc *p); bool_t xdr_rpc_gss_init_res (XDR *xdrs, struct rpc_gss_init_res *p); bool_t xdr_rpc_gss_data (XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr, gss_ctx_id_t ctx, gss_qop_t qop, rpc_gss_svc_t svc, uint32_t seq); bool_t xdr_rpc_gss_wrap_data (XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr, gss_ctx_id_t ctx, gss_qop_t qop, rpc_gss_svc_t svc, uint32_t seq); bool_t xdr_rpc_gss_unwrap_data (XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr, gss_ctx_id_t ctx, gss_qop_t qop, rpc_gss_svc_t svc, uint32_t seq); AUTH *authgss_create (CLIENT *, gss_name_t, struct rpc_gss_sec *); AUTH *authgss_create_default (CLIENT *, char *, struct rpc_gss_sec *); bool_t authgss_service (AUTH *auth, int svc); bool_t authgss_get_private_data (AUTH *auth, struct authgss_private_data *); #ifdef GSSRPC__IMPL void log_debug (const char *fmt, ...); void log_status (char *m, OM_uint32 major, OM_uint32 minor); void log_hexdump (const u_char *buf, int len, int offset); #endif GSSRPC__END_DECLS #endif /* !defined(GSSRPC_AUTH_GSS_H) */ gssrpc/rpc_msg.h 0000644 00000011762 15146341150 0007657 0 ustar 00 /* @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* @(#)rpc_msg.h 1.7 86/07/16 SMI */ /* * rpc_msg.h * rpc message definition */ #ifndef GSSRPC_RPC_MSG_H #define GSSRPC_RPC_MSG_H GSSRPC__BEGIN_DECLS #define RPC_MSG_VERSION ((uint32_t) 2) #define RPC_SERVICE_PORT ((u_short) 2048) /* * Bottom up definition of an rpc message. * NOTE: call and reply use the same overall stuct but * different parts of unions within it. */ enum msg_type { CALL=0, REPLY=1 }; enum reply_stat { MSG_ACCEPTED=0, MSG_DENIED=1 }; enum accept_stat { SUCCESS=0, PROG_UNAVAIL=1, PROG_MISMATCH=2, PROC_UNAVAIL=3, GARBAGE_ARGS=4, SYSTEM_ERR=5 }; enum reject_stat { RPC_MISMATCH=0, AUTH_ERROR=1 }; /* * Reply part of an rpc exchange */ /* * Reply to an rpc request that was accepted by the server. * Note: there could be an error even though the request was * accepted. */ struct accepted_reply { struct opaque_auth ar_verf; enum accept_stat ar_stat; union { struct { rpcvers_t low; rpcvers_t high; } AR_versions; struct { caddr_t where; xdrproc_t proc; } AR_results; /* and many other null cases */ } ru; #define ar_results ru.AR_results #define ar_vers ru.AR_versions }; /* * Reply to an rpc request that was rejected by the server. */ struct rejected_reply { enum reject_stat rj_stat; union { struct { rpcvers_t low; rpcvers_t high; } RJ_versions; enum auth_stat RJ_why; /* why authentication did not work */ } ru; #define rj_vers ru.RJ_versions #define rj_why ru.RJ_why }; /* * Body of a reply to an rpc request. */ struct reply_body { enum reply_stat rp_stat; union { struct accepted_reply RP_ar; struct rejected_reply RP_dr; } ru; #define rp_acpt ru.RP_ar #define rp_rjct ru.RP_dr }; /* * Body of an rpc request call. */ struct call_body { rpcvers_t cb_rpcvers; /* must be equal to two */ rpcprog_t cb_prog; rpcvers_t cb_vers; rpcproc_t cb_proc; struct opaque_auth cb_cred; struct opaque_auth cb_verf; /* protocol specific - provided by client */ }; /* * The rpc message */ struct rpc_msg { uint32_t rm_xid; enum msg_type rm_direction; union { struct call_body RM_cmb; struct reply_body RM_rmb; } ru; #define rm_call ru.RM_cmb #define rm_reply ru.RM_rmb }; #define acpted_rply ru.RM_rmb.ru.RP_ar #define rjcted_rply ru.RM_rmb.ru.RP_dr /* * XDR routine to handle a rpc message. * xdr_callmsg(xdrs, cmsg) * XDR *xdrs; * struct rpc_msg *cmsg; */ extern bool_t xdr_callmsg(XDR *, struct rpc_msg *); /* * XDR routine to pre-serialize the static part of a rpc message. * xdr_callhdr(xdrs, cmsg) * XDR *xdrs; * struct rpc_msg *cmsg; */ extern bool_t xdr_callhdr(XDR *, struct rpc_msg *); /* * XDR routine to handle a rpc reply. * xdr_replymsg(xdrs, rmsg) * XDR *xdrs; * struct rpc_msg *rmsg; */ extern bool_t xdr_replymsg(XDR *, struct rpc_msg *); /* * Fills in the error part of a reply message. * _seterr_reply(msg, error) * struct rpc_msg *msg; * struct rpc_err *error; */ /* * RENAMED: should be _seterr_reply or __seterr_reply if we can use * reserved namespace. */ extern void gssrpc__seterr_reply(struct rpc_msg *, struct rpc_err *); /* XDR the MSG_ACCEPTED part of a reply message union */ extern bool_t xdr_accepted_reply(XDR *, struct accepted_reply *); /* XDR the MSG_DENIED part of a reply message union */ extern bool_t xdr_rejected_reply(XDR *, struct rejected_reply *); GSSRPC__END_DECLS #endif /* !defined(GSSRPC_RPC_MSG_H) */ gssrpc/netdb.h 0000644 00000004612 15146341150 0007315 0 ustar 00 /* include/gssrpc/netdb.h */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* @(#)netdb.h 2.1 88/07/29 3.9 RPCSRC */ /* @(#)rpc.h 1.8 87/07/24 SMI */ #ifndef RPC_NETDB_H #define RPC_NETDB_H #include <gssrpc/types.h> /* since the gssrpc library requires that any application using it be built with these header files, I am making the decision that any app which uses the rpcent routines must use this header file, or something compatible (which most <netdb.h> are) --marc */ /* Really belongs in <netdb.h> */ #ifdef STRUCT_RPCENT_IN_RPC_NETDB_H struct rpcent { char *r_name; /* name of server for this rpc program */ char **r_aliases; /* alias list */ int r_number; /* rpc program number */ }; #endif /*STRUCT_RPCENT_IN_RPC_NETDB_H*/ struct rpcent *getrpcbyname(), *getrpcbynumber(), *getrpcent(); #endif gssrpc/svc.h 0000644 00000026513 15146341150 0007020 0 ustar 00 /* @(#)svc.h 2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* * svc.h, Server-side remote procedure call interface. */ #ifndef GSSRPC_SVC_H #define GSSRPC_SVC_H #include <gssrpc/svc_auth.h> GSSRPC__BEGIN_DECLS /* * This interface must manage two items concerning remote procedure calling: * * 1) An arbitrary number of transport connections upon which rpc requests * are received. The two most notable transports are TCP and UDP; they are * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; * they in turn call xprt_register and xprt_unregister. * * 2) An arbitrary number of locally registered services. Services are * described by the following four data: program number, version number, * "service dispatch" function, a transport handle, and a boolean that * indicates whether or not the exported program should be registered with a * local binder service; if true the program's number and version and the * port number from the transport handle are registered with the binder. * These data are registered with the rpc svc system via svc_register. * * A service's dispatch function is called whenever an rpc request comes in * on a transport. The request's program and version numbers must match * those of the registered service. The dispatch function is passed two * parameters, struct svc_req * and SVCXPRT *, defined below. */ enum xprt_stat { XPRT_DIED, XPRT_MOREREQS, XPRT_IDLE }; /* * Server side transport handle */ typedef struct SVCXPRT { #ifdef _WIN32 SOCKET xp_sock; #else int xp_sock; #endif u_short xp_port; /* associated port number */ struct xp_ops { /* receive incomming requests */ bool_t (*xp_recv)(struct SVCXPRT *, struct rpc_msg *); /* get transport status */ enum xprt_stat (*xp_stat)(struct SVCXPRT *); /* get arguments */ bool_t (*xp_getargs)(struct SVCXPRT *, xdrproc_t, void *); /* send reply */ bool_t (*xp_reply)(struct SVCXPRT *, struct rpc_msg *); /* free mem allocated for args */ bool_t (*xp_freeargs)(struct SVCXPRT *, xdrproc_t, void *); /* destroy this struct */ void (*xp_destroy)(struct SVCXPRT *); } *xp_ops; int xp_addrlen; /* length of remote address */ struct sockaddr_in xp_raddr; /* remote address */ struct opaque_auth xp_verf; /* raw response verifier */ SVCAUTH *xp_auth; /* auth flavor of current req */ void *xp_p1; /* private */ void *xp_p2; /* private */ int xp_laddrlen; /* lenght of local address */ struct sockaddr_in xp_laddr; /* local address */ } SVCXPRT; /* * Approved way of getting address of caller */ #define svc_getcaller(x) (&(x)->xp_raddr) /* * Operations defined on an SVCXPRT handle * * SVCXPRT *xprt; * struct rpc_msg *msg; * xdrproc_t xargs; * caddr_t argsp; */ #define SVC_RECV(xprt, msg) \ (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) #define svc_recv(xprt, msg) \ (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) #define SVC_STAT(xprt) \ (*(xprt)->xp_ops->xp_stat)(xprt) #define svc_stat(xprt) \ (*(xprt)->xp_ops->xp_stat)(xprt) #define SVC_GETARGS(xprt, xargs, argsp) \ (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) #define svc_getargs(xprt, xargs, argsp) \ (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) #define SVC_GETARGS_REQ(xprt, req, xargs, argsp) \ (*(xprt)->xp_ops->xp_getargs_req)((xprt), (req), (xargs), (argsp)) #define svc_getargs_req(xprt, req, xargs, argsp) \ (*(xprt)->xp_ops->xp_getargs_req)((xprt), (req), (xargs), (argsp)) #define SVC_REPLY(xprt, msg) \ (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) #define svc_reply(xprt, msg) \ (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) #define SVC_REPLY_REQ(xprt, req, msg) \ (*(xprt)->xp_ops->xp_reply_req) ((xprt), (req), (msg)) #define svc_reply_req(xprt, msg) \ (*(xprt)->xp_ops->xp_reply_req) ((xprt), (req), (msg)) #define SVC_FREEARGS(xprt, xargs, argsp) \ (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) #define svc_freeargs(xprt, xargs, argsp) \ (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) #define SVC_DESTROY(xprt) \ (*(xprt)->xp_ops->xp_destroy)(xprt) #define svc_destroy(xprt) \ (*(xprt)->xp_ops->xp_destroy)(xprt) /* * Service request */ struct svc_req { rpcprog_t rq_prog; /* service program number */ rpcvers_t rq_vers; /* service protocol version */ rpcproc_t rq_proc; /* the desired procedure */ struct opaque_auth rq_cred; /* raw creds from the wire */ void * rq_clntcred; /* read only cooked client cred */ void * rq_svccred; /* read only svc cred/context */ void * rq_clntname; /* read only client name */ SVCXPRT *rq_xprt; /* associated transport */ /* The request's auth flavor *should* be here, but the svc_req */ /* isn't passed around everywhere it is necessary. The */ /* transport *is* passed around, so the auth flavor it stored */ /* there. This means that the transport must be single */ /* threaded, but other parts of SunRPC already require that. */ /*SVCAUTH *rq_auth; associated auth flavor */ }; /* * Service registration * * svc_register(xprt, prog, vers, dispatch, protocol) * SVCXPRT *xprt; * rpcprog_t prog; * rpcvers_t vers; * void (*dispatch)(); * int protocol; like IPPROTO_TCP or _UDP; zero means do not register * * registerrpc(prog, vers, proc, routine, inproc, outproc) * returns 0 upon success, -1 if error. */ extern bool_t svc_register(SVCXPRT *, rpcprog_t, rpcvers_t, void (*)(struct svc_req *, SVCXPRT *), int); extern int registerrpc(rpcprog_t, rpcvers_t, rpcproc_t, char *(*)(void *), xdrproc_t, xdrproc_t); /* * Service un-registration * * svc_unregister(prog, vers) * rpcprog_t prog; * rpcvers_t vers; */ extern void svc_unregister(rpcprog_t, rpcvers_t); /* * Transport registration. * * xprt_register(xprt) * SVCXPRT *xprt; */ extern void xprt_register(SVCXPRT *); /* * Transport un-register * * xprt_unregister(xprt) * SVCXPRT *xprt; */ extern void xprt_unregister(SVCXPRT *); /* * When the service routine is called, it must first check to see if * it knows about the procedure; if not, it should call svcerr_noproc * and return. If so, it should deserialize its arguments via * SVC_GETARGS or the new SVC_GETARGS_REQ (both defined above). If * the deserialization does not work, svcerr_decode should be called * followed by a return. Successful decoding of the arguments should * be followed the execution of the procedure's code and a call to * svc_sendreply or the new svc_sendreply_req. * * Also, if the service refuses to execute the procedure due to too- * weak authentication parameters, svcerr_weakauth should be called. * Note: do not confuse access-control failure with weak authentication! * * NB: In pure implementations of rpc, the caller always waits for a reply * msg. This message is sent when svc_sendreply is called. * Therefore pure service implementations should always call * svc_sendreply even if the function logically returns void; use * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows * for the abuse of pure rpc via batched calling or pipelining. In the * case of a batched call, svc_sendreply should NOT be called since * this would send a return message, which is what batching tries to avoid. * It is the service/protocol writer's responsibility to know which calls are * batched and which are not. Warning: responding to batch calls may * deadlock the caller and server processes! */ extern bool_t svc_sendreply(SVCXPRT *, xdrproc_t, caddr_t); extern void svcerr_decode(SVCXPRT *); extern void svcerr_weakauth(SVCXPRT *); extern void svcerr_noproc(SVCXPRT *); extern void svcerr_progvers(SVCXPRT *, rpcvers_t, rpcvers_t); extern void svcerr_auth(SVCXPRT *, enum auth_stat); extern void svcerr_noprog(SVCXPRT *); extern void svcerr_systemerr(SVCXPRT *); /* * Lowest level dispatching -OR- who owns this process anyway. * Somebody has to wait for incoming requests and then call the correct * service routine. The routine svc_run does infinite waiting; i.e., * svc_run never returns. * Since another (co-existant) package may wish to selectively wait for * incoming calls or other events outside of the rpc architecture, the * routine svc_getreq is provided. It must be passed readfds, the * "in-place" results of a select system call (see select, section 2). */ /* * Global keeper of rpc service descriptors in use * dynamic; must be inspected before each call to select */ extern int svc_maxfd; #ifdef FD_SETSIZE extern fd_set svc_fdset; /* RENAMED */ #define gssrpc_svc_fds gsssrpc_svc_fdset.fds_bits[0] /* compatibility */ #else extern int svc_fds; #endif /* def FD_SETSIZE */ extern int svc_maxfd; /* * a small program implemented by the svc_rpc implementation itself; * also see clnt.h for protocol numbers. */ extern void rpctest_service(); extern void svc_getreq(int); #ifdef FD_SETSIZE extern void svc_getreqset(fd_set *);/* takes fdset instead of int */ extern void svc_getreqset2(fd_set *, int); #else extern void svc_getreqset(int *); #endif extern void svc_run(void); /* never returns */ /* * Socket to use on svcxxx_create call to get default socket */ #define RPC_ANYSOCK -1 /* * These are the existing service side transport implementations */ /* * Memory based rpc for testing and timing. */ extern SVCXPRT *svcraw_create(void); /* * Udp based rpc. */ extern SVCXPRT *svcudp_create(int); extern SVCXPRT *svcudp_bufcreate(int, u_int, u_int); extern int svcudp_enablecache(SVCXPRT *, uint32_t); /* * Tcp based rpc. */ extern SVCXPRT *svctcp_create(int, u_int, u_int); /* * Like svtcp_create(), except the routine takes any *open* UNIX file * descriptor as its first input. */ extern SVCXPRT *svcfd_create(int, u_int, u_int); /* XXX add auth_gsapi_log_*? */ GSSRPC__END_DECLS #endif /* !defined(GSSRPC_SVC_H) */ gssrpc/auth.h 0000644 00000014510 15146341150 0007160 0 ustar 00 /* @(#)auth.h 2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* * auth.h, Authentication interface. * * The data structures are completely opaque to the client. The client * is required to pass a AUTH * to routines that create rpc * "sessions". */ #ifndef GSSRPC_AUTH_H #define GSSRPC_AUTH_H #include <gssrpc/xdr.h> GSSRPC__BEGIN_DECLS #define MAX_AUTH_BYTES 400 #define MAXNETNAMELEN 255 /* maximum length of network user's name */ /* * Status returned from authentication check */ enum auth_stat { AUTH_OK=0, /* * failed at remote end */ AUTH_BADCRED=1, /* bogus credentials (seal broken) */ AUTH_REJECTEDCRED=2, /* client should begin new session */ AUTH_BADVERF=3, /* bogus verifier (seal broken) */ AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ AUTH_TOOWEAK=5, /* rejected due to security reasons */ /* * failed locally */ AUTH_INVALIDRESP=6, /* bogus response verifier */ AUTH_FAILED=7, /* some unknown reason */ /* * RPCSEC_GSS errors */ RPCSEC_GSS_CREDPROBLEM = 13, RPCSEC_GSS_CTXPROBLEM = 14 }; union des_block { char c[8]; }; typedef union des_block des_block; extern bool_t xdr_des_block(XDR *, des_block *); /* * Authentication info. Opaque to client. */ struct opaque_auth { enum_t oa_flavor; /* flavor of auth */ caddr_t oa_base; /* address of more auth stuff */ u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ }; /* * Auth handle, interface to client side authenticators. */ struct rpc_msg; typedef struct AUTH { struct opaque_auth ah_cred; struct opaque_auth ah_verf; union des_block ah_key; struct auth_ops { void (*ah_nextverf)(struct AUTH *); /* nextverf & serialize */ int (*ah_marshal)(struct AUTH *, XDR *); /* validate varifier */ int (*ah_validate)(struct AUTH *, struct opaque_auth *); /* refresh credentials */ int (*ah_refresh)(struct AUTH *, struct rpc_msg *); /* destroy this structure */ void (*ah_destroy)(struct AUTH *); /* encode data for wire */ int (*ah_wrap)(struct AUTH *, XDR *, xdrproc_t, caddr_t); /* decode data from wire */ int (*ah_unwrap)(struct AUTH *, XDR *, xdrproc_t, caddr_t); } *ah_ops; void *ah_private; } AUTH; /* * Authentication ops. * The ops and the auth handle provide the interface to the authenticators. * * AUTH *auth; * XDR *xdrs; * struct opaque_auth verf; */ #define AUTH_NEXTVERF(auth) \ ((*((auth)->ah_ops->ah_nextverf))(auth)) #define auth_nextverf(auth) \ ((*((auth)->ah_ops->ah_nextverf))(auth)) #define AUTH_MARSHALL(auth, xdrs) \ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) #define auth_marshall(auth, xdrs) \ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) #define AUTH_VALIDATE(auth, verfp) \ ((*((auth)->ah_ops->ah_validate))((auth), verfp)) #define auth_validate(auth, verfp) \ ((*((auth)->ah_ops->ah_validate))((auth), verfp)) #define AUTH_REFRESH(auth, msg) \ ((*((auth)->ah_ops->ah_refresh))(auth, msg)) #define auth_refresh(auth, msg) \ ((*((auth)->ah_ops->ah_refresh))(auth, msg)) #define AUTH_WRAP(auth, xdrs, xfunc, xwhere) \ ((*((auth)->ah_ops->ah_wrap))(auth, xdrs, \ xfunc, xwhere)) #define auth_wrap(auth, xdrs, xfunc, xwhere) \ ((*((auth)->ah_ops->ah_wrap))(auth, xdrs, \ xfunc, xwhere)) #define AUTH_UNWRAP(auth, xdrs, xfunc, xwhere) \ ((*((auth)->ah_ops->ah_unwrap))(auth, xdrs, \ xfunc, xwhere)) #define auth_unwrap(auth, xdrs, xfunc, xwhere) \ ((*((auth)->ah_ops->ah_unwrap))(auth, xdrs, \ xfunc, xwhere)) #define AUTH_DESTROY(auth) \ ((*((auth)->ah_ops->ah_destroy))(auth)) #define auth_destroy(auth) \ ((*((auth)->ah_ops->ah_destroy))(auth)) #ifdef GSSRPC__IMPL /* RENAMED: should be _null_auth if we can use reserved namespace. */ extern struct opaque_auth gssrpc__null_auth; #endif /* * These are the various implementations of client side authenticators. */ /* * Unix style authentication * AUTH *authunix_create(machname, uid, gid, len, aup_gids) * char *machname; * int uid; * int gid; * int len; * int *aup_gids; */ extern AUTH *authunix_create(char *machname, int uid, int gid, int len, int *aup_gids); extern AUTH *authunix_create_default(void); /* takes no parameters */ extern AUTH *authnone_create(void); /* takes no parameters */ extern AUTH *authdes_create(); extern bool_t xdr_opaque_auth(XDR *, struct opaque_auth *); #define AUTH_NONE 0 /* no authentication */ #define AUTH_NULL 0 /* backward compatibility */ #define AUTH_UNIX 1 /* unix style (uid, gids) */ #define AUTH_SHORT 2 /* short hand unix style */ #define AUTH_DES 3 /* des style (encrypted timestamps) */ #define AUTH_GSSAPI 300001 /* GSS-API style */ #define RPCSEC_GSS 6 /* RPCSEC_GSS */ GSSRPC__END_DECLS #endif /* !defined(GSSRPC_AUTH_H) */ gssrpc/types.h 0000644 00000007052 15146341150 0007366 0 ustar 00 /* @(#)types.h 2.3 88/08/15 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the “Oracle America, Inc.” 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* @(#)types.h 1.18 87/07/24 SMI */ /* * Rpc additions to <sys/types.h> */ #ifndef GSSRPC_TYPES_H #define GSSRPC_TYPES_H #include <sys/types.h> #include <sys/select.h> #include <sys/time.h> #include <unistd.h> /* * Try to get MAXHOSTNAMELEN from somewhere. */ #include <sys/param.h> /* #include <netdb.h> */ /* Get htonl(), ntohl(), etc. */ #include <netinet/in.h> #include <stdlib.h> #include <stdint.h> #include <limits.h> #ifndef GSSRPC__BEGIN_DECLS #ifdef __cplusplus #define GSSRPC__BEGIN_DECLS extern "C" { #define GSSRPC__END_DECLS } #else #define GSSRPC__BEGIN_DECLS #define GSSRPC__END_DECLS #endif #endif GSSRPC__BEGIN_DECLS #if defined(CHAR_BIT) && CHAR_BIT != 8 #error "Bytes must be exactly 8 bits." #endif /* Define if we need to fake up some BSD type aliases. */ #ifndef GSSRPC__BSD_TYPEALIASES /* Allow application to override. */ /* #undef GSSRPC__BSD_TYPEALIASES */ #endif #if GSSRPC__BSD_TYPEALIASES typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; #endif typedef uint32_t rpcprog_t; typedef uint32_t rpcvers_t; typedef uint32_t rpcprot_t; typedef uint32_t rpcproc_t; typedef uint32_t rpcport_t; typedef int32_t rpc_inline_t; /* This is for rpc/netdb.h */ #define STRUCT_RPCENT_IN_RPC_NETDB_H #define bool_t int #define enum_t int #ifndef FALSE # define FALSE (0) #endif #ifndef TRUE # define TRUE (1) #endif /* XXX namespace */ #define __dontcare__ -1 #ifndef NULL # define NULL 0 #endif /* * The below should probably be internal-only, but seem to be * traditionally exported in RPC implementations. */ #define mem_alloc(bsize) malloc(bsize) #define mem_free(ptr, bsize) free(ptr) #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK (uint32_t)0x7F000001 #endif #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 #endif GSSRPC__END_DECLS #include <gssrpc/rename.h> #endif /* !defined(GSSRPC_TYPES_H) */ gssrpc/rename.h 0000644 00000024030 15146341150 0007464 0 ustar 00 /* include/gssrpc/rename.h */ /* * Copyright (C) 2004 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may * require a specific license from the United States Government. * It is the responsibility of any person or organization contemplating * export to obtain such a license before exporting. * * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and * distribute this software and its documentation for any purpose and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of M.I.T. not be used in advertising or publicity pertaining * to distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. */ /* * * Namespace mangling for various purposes. * * Symbols in the object code need to be renamed to not conflict with * an OS-provided RPC implementation. Without renaming, the conflicts * can cause problems with things like RPC-enabled NSS * implementations. * * Symbols in headers should not conflict with implementation-reserved * namespace (prefixes "_[A-Z_]" for any purpose; prefix "_" * for file scope identifiers and tag names), or unnecessarily impinge * on user namespace. * * The renaming of the header directory is done to avoid problems when * the OS header files include <rpc/foo.h> and might get ours instead. * OS vendors should replace all the <gssrpc/foo.h> inclusions with * <rpc/foo.h> inclusions, as appropriate. Additionally, vendors * should probably put some symbols into the implementation namespace. * * For example, inclusion protection should change from "GSSRPC_*_H" * to "_RPC_*_H", struct tags should get "__" prefixes, etc. * * This implementation reserves the object code prefix "gssrpc_". * External names in the RPC API not beginning with "_" get renamed * with the prefix "gssrpc_" via #define, e.g., "foo" -> "gssrpc_foo". * External names in the RPC API beginning with "_" get textually * rewritten. */ #ifndef GSSRPC_RENAME_H #define GSSRPC_RENAME_H /* auth.h */ #define xdr_des_block gssrpc_xdr_des_block #define authany_wrap gssrpc_authany_wrap #define authany_unwrap gssrpc_authany_unwrap #define authunix_create gssrpc_authunix_create #define authunix_create_default gssrpc_authunix_create_default #define authnone_create gssrpc_authnone_create #define authdes_create gssrpc_authdes_create #define xdr_opaque_auth gssrpc_xdr_opaque_auth /* auth_gss.c */ #define auth_debug_gss gssrpc_auth_debug_gss #define misc_debug_gss gssrpc_misc_debug_gss /* auth_gss.h */ #define xdr_rpc_gss_buf gssrpc_xdr_rpc_gss_buf #define xdr_rpc_gss_cred gssrpc_xdr_rpc_gss_cred #define xdr_rpc_gss_init_args gssrpc_xdr_rpc_gss_init_args #define xdr_rpc_gss_init_res gssrpc_xdr_rpc_gss_init_res #define xdr_rpc_gss_data gssrpc_xdr_rpc_gss_data #define xdr_rpc_gss_wrap_data gssrpc_xdr_rpc_gss_wrap_data #define xdr_rpc_gss_unwrap_data gssrpc_xdr_rpc_gss_unwrap_data #define authgss_create gssrpc_authgss_create #define authgss_create_default gssrpc_authgss_create_default #define authgss_get_private_data gssrpc_authgss_get_private_data #define authgss_service gssrpc_authgss_service #ifdef GSSRPC__IMPL #define log_debug gssrpc_log_debug #define log_status gssrpc_log_status #define log_hexdump gssrpc_log_hexdump #endif /* auth_gssapi.c */ #define auth_debug_gssapi gssrpc_auth_debug_gssapi #define misc_debug_gssapi gssrpc_misc_debug_gssapi /* auth_gssapi.h */ #define xdr_gss_buf gssrpc_xdr_gss_buf #define xdr_authgssapi_creds gssrpc_xdr_authgssapi_creds #define xdr_authgssapi_init_arg gssrpc_xdr_authgssapi_init_arg #define xdr_authgssapi_init_res gssrpc_xdr_authgssapi_init_res #define auth_gssapi_wrap_data gssrpc_auth_gssapi_wrap_data #define auth_gssapi_unwrap_data gssrpc_auth_gssapi_unwrap_data #define auth_gssapi_create gssrpc_auth_gssapi_create #define auth_gssapi_create_default gssrpc_auth_gssapi_create_default #define auth_gssapi_display_status gssrpc_auth_gssapi_display_status #define auth_gssapi_seal_seq gssrpc_auth_gssapi_seal_seq #define auth_gssapi_unseal_seq gssrpc_auth_gssapi_unseal_seq #define svcauth_gssapi_set_names gssrpc_svcauth_gssapi_set_names #define svcauth_gssapi_unset_names gssrpc_svcauth_gssapi_unset_names #define svcauth_gssapi_set_log_badauth_func gssrpc_svcauth_gssapi_set_log_badauth_func #define svcauth_gssapi_set_log_badauth2_func gssrpc_svcauth_gssapi_set_log_badauth2_func #define svcauth_gssapi_set_log_badverf_func gssrpc_svcauth_gssapi_set_log_badverf_func #define svcauth_gssapi_set_log_miscerr_func gssrpc_svcauth_gssapi_set_log_miscerr_func #define svcauth_gss_set_log_badauth_func gssrpc_svcauth_gss_set_log_badauth_func #define svcauth_gss_set_log_badauth2_func gssrpc_svcauth_gss_set_log_badauth2_func #define svcauth_gss_set_log_badverf_func gssrpc_svcauth_gss_set_log_badverf_func #define svcauth_gss_set_log_miscerr_func gssrpc_svcauth_gss_set_log_miscerr_func /* auth_unix.h */ #define xdr_authunix_parms gssrpc_xdr_authunix_parms /* clnt.h */ #define clntraw_create gssrpc_clntraw_create #define clnt_create gssrpc_clnt_create #define clnttcp_create gssrpc_clnttcp_create #define clntudp_create gssrpc_clntudp_create #define clntudp_bufcreate gssrpc_clntudp_bufcreate #define clnt_pcreateerror gssrpc_clnt_pcreateerror #define clnt_spcreateerror gssrpc_clnt_spcreateerror #define clnt_perrno gssrpc_clnt_perrno #define clnt_perror gssrpc_clnt_perror #define clnt_sperror gssrpc_clnt_sperror /* XXX do we need to rename the struct? */ #define rpc_createerr gssrpc_rpc_createrr #define clnt_sperrno gssrpc_clnt_sperrno /* pmap_clnt.h */ #define pmap_set gssrpc_pmap_set #define pmap_unset gssrpc_pmap_unset #define pmap_getmaps gssrpc_pmap_getmaps #define pmap_rmtcall gssrpc_pmap_rmtcall #define clnt_broadcast gssrpc_clnt_broadcast #define pmap_getport gssrpc_pmap_getport /* pmap_prot.h */ #define xdr_pmap gssrpc_xdr_pmap #define xdr_pmaplist gssrpc_xdr_pmaplist /* pmap_rmt.h */ #define xdr_rmtcall_args gssrpc_xdr_rmtcall_args #define xdr_rmtcallres gssrpc_xdr_rmtcallres /* rpc.h */ #define get_myaddress gssrpc_get_myaddress #define bindresvport gssrpc_bindresvport #define bindresvport_sa gssrpc_bindresvport_sa #define callrpc gssrpc_callrpc #define getrpcport gssrpc_getrpcport /* rpc_msg.h */ #define xdr_callmsg gssrpc_xdr_callmsg #define xdr_callhdr gssrpc_xdr_callhdr #define xdr_replymsg gssrpc_xdr_replymsg #define xdr_accepted_reply gssrpc_xdr_accepted_reply #define xdr_rejected_reply gssrpc_xdr_rejected_reply /* svc.h */ #define svc_register gssrpc_svc_register #define registerrpc gssrpc_registerrpc #define svc_unregister gssrpc_svc_unregister #define xprt_register gssrpc_xprt_register #define xprt_unregister gssrpc_xprt_unregister #define svc_sendreply gssrpc_svc_sendreply #define svcerr_decode gssrpc_svcerr_decode #define svcerr_weakauth gssrpc_svcerr_weakauth #define svcerr_noproc gssrpc_svcerr_noproc #define svcerr_progvers gssrpc_svcerr_progvers #define svcerr_auth gssrpc_svcerr_auth #define svcerr_noprog gssrpc_svcerr_noprog #define svcerr_systemerr gssrpc_svcerr_systemerr #define svc_maxfd gssrpc_svc_maxfd #define svc_fdset gssrpc_svc_fdset #define svc_fds gssrpc_svc_fds #define rpctest_service gssrpc_rpctest_service #define svc_getreq gssrpc_svc_getreq #define svc_getreqset gssrpc_svc_getreqset #define svc_getreqset2 gssrpc_svc_getreqset2 #define svc_run gssrpc_svc_run #define svcraw_create gssrpc_svcraw_create #define svcudp_create gssrpc_svcudp_create #define svcudp_bufcreate gssrpc_svcudp_bufcreate #define svcudp_enablecache gssrpc_svcudp_enablecache #define svctcp_create gssrpc_svctcp_create #define svcfd_create gssrpc_svcfd_create /* svc_auth.h */ #define svc_auth_none_ops gssrpc_svc_auth_none_ops #define svc_auth_gssapi_ops gssrpc_svc_auth_gssapi_ops #define svc_auth_gss_ops gssrpc_svc_auth_gss_ops #define svcauth_gss_set_svc_name gssrpc_svcauth_gss_set_svc_name #define svcauth_gss_get_principal gssrpc_svcauth_gss_get_principal /* svc_auth_gss.c */ #define svc_debug_gss gssrpc_svc_debug_gss /* svc_auth_gssapi.c */ #define svc_debug_gssapi gssrpc_svc_debug_gssapi /* svc_auth_none.c */ #define svc_auth_none gssrpc_svc_auth_none /* xdr.h */ #define xdr_void gssrpc_xdr_void #define xdr_int gssrpc_xdr_int #define xdr_u_int gssrpc_xdr_u_int #define xdr_long gssrpc_xdr_long #define xdr_u_long gssrpc_xdr_u_long #define xdr_short gssrpc_xdr_short #define xdr_u_short gssrpc_xdr_u_short #define xdr_bool gssrpc_xdr_bool #define xdr_enum gssrpc_xdr_enum #define xdr_array gssrpc_xdr_array #define xdr_bytes gssrpc_xdr_bytes #define xdr_opaque gssrpc_xdr_opaque #define xdr_string gssrpc_xdr_string #define xdr_union gssrpc_xdr_union #define xdr_char gssrpc_xdr_char #define xdr_u_char gssrpc_xdr_u_char #define xdr_vector gssrpc_xdr_vector #define xdr_float gssrpc_xdr_float #define xdr_double gssrpc_xdr_double #define xdr_reference gssrpc_xdr_reference #define xdr_pointer gssrpc_xdr_pointer #define xdr_wrapstring gssrpc_xdr_wrapstring #define xdr_free gssrpc_xdr_free #define xdr_sizeof gssrpc_xdr_sizeof #define xdr_netobj gssrpc_xdr_netobj #define xdr_int32 gssrpc_xdr_int32 #define xdr_u_int32 gssrpc_xdr_u_int32 #define xdralloc_create gssrpc_xdralloc_create #define xdralloc_release gssrpc_xdralloc_release #define xdralloc_getdata gssrpc_xdralloc_getdata #define xdrmem_create gssrpc_xdrmem_create #define xdrstdio_create gssrpc_xdrstdio_create #define xdrrec_create gssrpc_xdrrec_create #define xdrrec_endofrecord gssrpc_xdrrec_endofrecord #define xdrrec_skiprecord gssrpc_xdrrec_skiprecord #define xdrrec_eof gssrpc_xdrrec_eof #endif /* !defined(GSSRPC_RENAME_H) */ gssrpc/pmap_rmt.h 0000644 00000004377 15146341150 0010050 0 ustar 00 /* @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC; from 1.2 88/02/08 SMI */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* * Structures and XDR routines for parameters to and replies from * the portmapper remote-call-service. */ #ifndef GSSRPC_PMAP_RMT_H #define GSSRPC_PMAP_RMT_H GSSRPC__BEGIN_DECLS struct rmtcallargs { rpcprog_t prog; rpcvers_t vers; rpcproc_t proc; uint32_t arglen; caddr_t args_ptr; xdrproc_t xdr_args; }; bool_t xdr_rmtcall_args(XDR *, struct rmtcallargs *); struct rmtcallres { rpcport_t *port_ptr; uint32_t resultslen; caddr_t results_ptr; xdrproc_t xdr_results; }; bool_t xdr_rmtcallres(XDR *, struct rmtcallres *); GSSRPC__END_DECLS #endif /* !defined(GSSRPC_PMAP_RMT_H) */ gssrpc/pmap_clnt.h 0000644 00000006545 15146341150 0010205 0 ustar 00 /* @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* * pmap_clnt.h * Supplies C routines to get to portmap services. */ #ifndef GSSRPC_PMAP_CLNT_H #define GSSRPC_PMAP_CLNT_H /* * Usage: * success = pmap_set(program, version, protocol, port); * success = pmap_unset(program, version); * port = pmap_getport(address, program, version, protocol); * head = pmap_getmaps(address); * clnt_stat = pmap_rmtcall(address, program, version, procedure, * xdrargs, argsp, xdrres, resp, tout, port_ptr) * (works for udp only.) * clnt_stat = clnt_broadcast(program, version, procedure, * xdrargs, argsp, xdrres, resp, eachresult) * (like pmap_rmtcall, except the call is broadcasted to all * locally connected nets. For each valid response received, * the procedure eachresult is called. Its form is: * done = eachresult(resp, raddr) * bool_t done; * caddr_t resp; * struct sockaddr_in raddr; * where resp points to the results of the call and raddr is the * address if the responder to the broadcast. */ GSSRPC__BEGIN_DECLS extern bool_t pmap_set(rpcprog_t, rpcvers_t, rpcprot_t, u_int); extern bool_t pmap_unset(rpcprog_t, rpcvers_t); extern struct pmaplist *pmap_getmaps(struct sockaddr_in *); enum clnt_stat pmap_rmtcall(struct sockaddr_in *, rpcprog_t, rpcvers_t, rpcproc_t, xdrproc_t, caddr_t, xdrproc_t, caddr_t, struct timeval, rpcport_t *); typedef bool_t (*resultproc_t)(caddr_t, struct sockaddr_in *); enum clnt_stat clnt_broadcast(rpcprog_t, rpcvers_t, rpcproc_t, xdrproc_t, caddr_t, xdrproc_t, caddr_t, resultproc_t); extern u_short pmap_getport(struct sockaddr_in *, rpcprog_t, rpcvers_t, rpcprot_t); GSSRPC__END_DECLS #endif /* !defined(GSSRPC_PMAP_CLNT_H) */ gssrpc/rpc.h 0000644 00000006107 15146341150 0007006 0 ustar 00 /* @(#)rpc.h 2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* * rpc.h, Just includes the billions of rpc header files necessary to * do remote procedure calling. */ #ifndef GSSRPC_RPC_H #define GSSRPC_RPC_H #include <gssrpc/types.h> /* some typedefs */ #include <netinet/in.h> /* external data representation interfaces */ #include <gssrpc/xdr.h> /* generic (de)serializer */ /* Client side only authentication */ #include <gssrpc/auth.h> /* generic authenticator (client side) */ /* Client side (mostly) remote procedure call */ #include <gssrpc/clnt.h> /* generic rpc stuff */ /* semi-private protocol headers */ #include <gssrpc/rpc_msg.h> /* protocol for rpc messages */ #include <gssrpc/auth_unix.h> /* protocol for unix style cred */ #include <gssrpc/auth_gss.h> /* RPCSEC_GSS */ /* Server side only remote procedure callee */ #include <gssrpc/svc_auth.h> /* service side authenticator */ #include <gssrpc/svc.h> /* service manager and multiplexer */ /* * get the local host's IP address without consulting * name service library functions */ GSSRPC__BEGIN_DECLS extern int get_myaddress(struct sockaddr_in *); extern int bindresvport(int, struct sockaddr_in *); extern int bindresvport_sa(int, struct sockaddr *); extern int callrpc(char *, rpcprog_t, rpcvers_t, rpcproc_t, xdrproc_t, char *, xdrproc_t , char *); extern int getrpcport(char *, rpcprog_t, rpcvers_t, rpcprot_t); extern int gssrpc__rpc_dtablesize(void); GSSRPC__END_DECLS #endif /* !defined(GSSRPC_RPC_H) */ gssrpc/clnt.h 0000644 00000022664 15146341150 0007170 0 ustar 00 /* @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* * clnt.h - Client side remote procedure call interface. */ #ifndef GSSRPC_CLNT_H #define GSSRPC_CLNT_H GSSRPC__BEGIN_DECLS /* * Rpc calls return an enum clnt_stat. This should be looked at more, * since each implementation is required to live with this (implementation * independent) list of errors. */ enum clnt_stat { RPC_SUCCESS=0, /* call succeeded */ /* * local errors */ RPC_CANTENCODEARGS=1, /* can't encode arguments */ RPC_CANTDECODERES=2, /* can't decode results */ RPC_CANTSEND=3, /* failure in sending call */ RPC_CANTRECV=4, /* failure in receiving result */ RPC_TIMEDOUT=5, /* call timed out */ /* * remote errors */ RPC_VERSMISMATCH=6, /* rpc versions not compatible */ RPC_AUTHERROR=7, /* authentication error */ RPC_PROGUNAVAIL=8, /* program not available */ RPC_PROGVERSMISMATCH=9, /* program version mismatched */ RPC_PROCUNAVAIL=10, /* procedure unavailable */ RPC_CANTDECODEARGS=11, /* decode arguments error */ RPC_SYSTEMERROR=12, /* generic "other problem" */ /* * callrpc & clnt_create errors */ RPC_UNKNOWNHOST=13, /* unknown host name */ RPC_UNKNOWNPROTO=17, /* unknown protocol */ /* * _ create errors */ RPC_PMAPFAILURE=14, /* the pmapper failed in its call */ RPC_PROGNOTREGISTERED=15, /* remote program is not registered */ /* * unspecified error */ RPC_FAILED=16 }; /* * Error info. */ struct rpc_err { enum clnt_stat re_status; union { int RE_errno; /* realated system error */ enum auth_stat RE_why; /* why the auth error occurred */ struct { rpcvers_t low; /* lowest verion supported */ rpcvers_t high; /* highest verion supported */ } RE_vers; struct { /* maybe meaningful if RPC_FAILED */ int32_t s1; int32_t s2; } RE_lb; /* life boot & debugging only */ } ru; #define re_errno ru.RE_errno #define re_why ru.RE_why #define re_vers ru.RE_vers #define re_lb ru.RE_lb }; /* * Client rpc handle. * Created by individual implementations, see e.g. rpc_udp.c. * Client is responsible for initializing auth, see e.g. auth_none.c. */ typedef struct CLIENT { AUTH *cl_auth; /* authenticator */ struct clnt_ops { /* call remote procedure */ enum clnt_stat (*cl_call)(struct CLIENT *, rpcproc_t, xdrproc_t, void *, xdrproc_t, void *, struct timeval); /* abort a call */ void (*cl_abort)(struct CLIENT *); /* get specific error code */ void (*cl_geterr)(struct CLIENT *, struct rpc_err *); /* frees results */ bool_t (*cl_freeres)(struct CLIENT *, xdrproc_t, void *); /* destroy this structure */ void (*cl_destroy)(struct CLIENT *); /* the ioctl() of rpc */ /* XXX CITI makes 2nd arg take u_int */ bool_t (*cl_control)(struct CLIENT *, int, void *); } *cl_ops; void *cl_private; /* private stuff */ } CLIENT; /* * client side rpc interface ops * * Parameter types are: * */ /* * enum clnt_stat * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout) * CLIENT *rh; * rpcproc_t proc; * xdrproc_t xargs; * caddr_t argsp; * xdrproc_t xres; * caddr_t resp; * struct timeval timeout; */ #define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \ ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) #define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \ ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) /* * void * CLNT_ABORT(rh); * CLIENT *rh; */ #define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh)) #define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh)) /* * struct rpc_err * CLNT_GETERR(rh); * CLIENT *rh; */ #define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) #define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) /* * bool_t * CLNT_FREERES(rh, xres, resp); * CLIENT *rh; * xdrproc_t xres; * caddr_t resp; */ #define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) #define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) /* * bool_t * CLNT_CONTROL(cl, request, info) * CLIENT *cl; * u_int request; * char *info; */ #define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) #define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) /* * control operations that apply to both udp and tcp transports */ #define CLSET_TIMEOUT 1 /* set timeout (timeval) */ #define CLGET_TIMEOUT 2 /* get timeout (timeval) */ #define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ /* * udp only control operations */ #define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */ #define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */ /* * new control operations */ #define CLGET_LOCAL_ADDR 6 /* get local address (sockaddr, getsockname)*/ /* * void * CLNT_DESTROY(rh); * CLIENT *rh; */ #define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) #define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) /* * RPCTEST is a test program which is accessable on every rpc * transport/port. It is used for testing, performance evaluation, * and network administration. */ #define RPCTEST_PROGRAM ((rpcprog_t)1) #define RPCTEST_VERSION ((rpcvers_t)1) #define RPCTEST_NULL_PROC ((rpcproc_t)2) #define RPCTEST_NULL_BATCH_PROC ((rpcproc_t)3) /* * By convention, procedure 0 takes null arguments and returns them */ #define NULLPROC ((rpcproc_t)0) /* * Below are the client handle creation routines for the various * implementations of client side rpc. They can return NULL if a * creation failure occurs. */ /* * Memory based rpc (for speed check and testing) * CLIENT * * clntraw_create(prog, vers) * rpcprog_t prog; * rpcvers_t vers; */ extern CLIENT *clntraw_create(rpcprog_t, rpcvers_t); /* * Generic client creation routine. Supported protocols are "udp" and "tcp" */ extern CLIENT *clnt_create(char *, rpcprog_t, rpcvers_t, char *); /* * TCP based rpc * CLIENT * * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) * struct sockaddr_in *raddr; * rpcprog_t prog; * rpcvers_t version; * int *sockp; * u_int sendsz; * u_int recvsz; */ extern CLIENT *clnttcp_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, int *, u_int, u_int); /* * UDP based rpc. * CLIENT * * clntudp_create(raddr, program, version, wait, sockp) * struct sockaddr_in *raddr; * rpcprog_t program; * rpcvers_t version; * struct timeval wait; * int *sockp; * * Same as above, but you specify max packet sizes. * CLIENT * * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) * struct sockaddr_in *raddr; * rpcprog_t program; * rpcvers_t version; * struct timeval wait; * int *sockp; * u_int sendsz; * u_int recvsz; */ extern CLIENT *clntudp_create(struct sockaddr_in *, rpcprog_t, rpcvers_t, struct timeval, int *); extern CLIENT *clntudp_bufcreate(struct sockaddr_in *, rpcprog_t, rpcvers_t, struct timeval, int *, u_int, u_int); /* * Print why creation failed */ void clnt_pcreateerror(char *); /* stderr */ char *clnt_spcreateerror(char *); /* string */ /* * Like clnt_perror(), but is more verbose in its output */ void clnt_perrno(enum clnt_stat); /* stderr */ /* * Print an English error message, given the client error code */ void clnt_perror(CLIENT *, char *); /* stderr */ char *clnt_sperror(CLIENT *, char *); /* string */ /* * If a creation fails, the following allows the user to figure out why. */ struct rpc_createerr { enum clnt_stat cf_stat; struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */ }; extern struct rpc_createerr rpc_createerr; /* * Copy error message to buffer. */ char *clnt_sperrno(enum clnt_stat num); /* string */ #define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */ #define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */ GSSRPC__END_DECLS #endif /* !defined(GSSRPC_CLNT_H) */ gssrpc/xdr.h 0000644 00000027003 15146341150 0007015 0 ustar 00 /* @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* @(#)xdr.h 1.19 87/04/22 SMI */ /* * xdr.h, External Data Representation Serialization Routines. */ #ifndef GSSRPC_XDR_H #define GSSRPC_XDR_H #include <stdio.h> /* for FILE */ GSSRPC__BEGIN_DECLS /* * XDR provides a conventional way for converting between C data * types and an external bit-string representation. Library supplied * routines provide for the conversion on built-in C data types. These * routines and utility routines defined here are used to help implement * a type encode/decode routine for each user-defined type. * * Each data type provides a single procedure which takes two arguments: * * bool_t * xdrproc(xdrs, argresp) * XDR *xdrs; * <type> *argresp; * * xdrs is an instance of a XDR handle, to which or from which the data * type is to be converted. argresp is a pointer to the structure to be * converted. The XDR handle contains an operation field which indicates * which of the operations (ENCODE, DECODE * or FREE) is to be performed. * * XDR_DECODE may allocate space if the pointer argresp is null. This * data can be freed with the XDR_FREE operation. * * We write only one procedure per data type to make it easy * to keep the encode and decode procedures for a data type consistent. * In many cases the same code performs all operations on a user defined type, * because all the hard work is done in the component type routines. * decode as a series of calls on the nested data types. */ /* * Xdr operations. XDR_ENCODE causes the type to be encoded into the * stream. XDR_DECODE causes the type to be extracted from the stream. * XDR_FREE can be used to release the space allocated by an XDR_DECODE * request. */ enum xdr_op { XDR_ENCODE=0, XDR_DECODE=1, XDR_FREE=2 }; /* * This is the number of bytes per unit of external data. */ #define BYTES_PER_XDR_UNIT (4) #define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ * BYTES_PER_XDR_UNIT) /* * A xdrproc_t exists for each data type which is to be encoded or decoded. * * The second argument to the xdrproc_t is a pointer to an opaque pointer. * The opaque pointer generally points to a structure of the data type * to be decoded. If this pointer is 0, then the type routines should * allocate dynamic storage of the appropriate size and return it. * bool_t (*xdrproc_t)(XDR *, caddr_t *); * * XXX can't actually prototype it, because some take three args!!! */ typedef bool_t (*xdrproc_t)(); /* * The XDR handle. * Contains operation which is being applied to the stream, * an operations vector for the paticular implementation (e.g. see xdr_mem.c), * and two private fields for the use of the particular impelementation. */ typedef struct XDR { enum xdr_op x_op; /* operation; fast additional param */ struct xdr_ops { /* get a long from underlying stream */ bool_t (*x_getlong)(struct XDR *, long *); /* put a long to underlying stream */ bool_t (*x_putlong)(struct XDR *, long *); /* get some bytes from underlying stream */ bool_t (*x_getbytes)(struct XDR *, caddr_t, u_int); /* put some bytes to underlying stream */ bool_t (*x_putbytes)(struct XDR *, caddr_t, u_int); /* returns bytes off from beginning */ u_int (*x_getpostn)(struct XDR *); /* lets you reposition the stream */ bool_t (*x_setpostn)(struct XDR *, u_int); /* buf quick ptr to buffered data */ rpc_inline_t *(*x_inline)(struct XDR *, int); /* free privates of this xdr_stream */ void (*x_destroy)(struct XDR *); } *x_ops; caddr_t x_public; /* users' data */ void * x_private; /* pointer to private data */ caddr_t x_base; /* private used for position info */ int x_handy; /* extra private word */ } XDR; /* * Operations defined on a XDR handle * * XDR *xdrs; * int32_t *longp; * caddr_t addr; * u_int len; * u_int pos; */ #define XDR_GETLONG(xdrs, longp) \ (*(xdrs)->x_ops->x_getlong)(xdrs, longp) #define xdr_getlong(xdrs, longp) \ (*(xdrs)->x_ops->x_getlong)(xdrs, longp) #define XDR_PUTLONG(xdrs, longp) \ (*(xdrs)->x_ops->x_putlong)(xdrs, longp) #define xdr_putlong(xdrs, longp) \ (*(xdrs)->x_ops->x_putlong)(xdrs, longp) #define XDR_GETBYTES(xdrs, addr, len) \ (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) #define xdr_getbytes(xdrs, addr, len) \ (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) #define XDR_PUTBYTES(xdrs, addr, len) \ (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) #define xdr_putbytes(xdrs, addr, len) \ (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) #define XDR_GETPOS(xdrs) \ (*(xdrs)->x_ops->x_getpostn)(xdrs) #define xdr_getpos(xdrs) \ (*(xdrs)->x_ops->x_getpostn)(xdrs) #define XDR_SETPOS(xdrs, pos) \ (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) #define xdr_setpos(xdrs, pos) \ (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) #define XDR_INLINE(xdrs, len) \ (*(xdrs)->x_ops->x_inline)(xdrs, len) #define xdr_inline(xdrs, len) \ (*(xdrs)->x_ops->x_inline)(xdrs, len) #define XDR_DESTROY(xdrs) \ if ((xdrs)->x_ops->x_destroy) \ (*(xdrs)->x_ops->x_destroy)(xdrs) #define xdr_destroy(xdrs) \ if ((xdrs)->x_ops->x_destroy) \ (*(xdrs)->x_ops->x_destroy)(xdrs) /* * Support struct for discriminated unions. * You create an array of xdrdiscrim structures, terminated with * a entry with a null procedure pointer. The xdr_union routine gets * the discriminant value and then searches the array of structures * for a matching value. If a match is found the associated xdr routine * is called to handle that part of the union. If there is * no match, then a default routine may be called. * If there is no match and no default routine it is an error. */ #define NULL_xdrproc_t ((xdrproc_t)0) struct xdr_discrim { int value; xdrproc_t proc; }; /* * In-line routines for fast encode/decode of primitve data types. * Caveat emptor: these use single memory cycles to get the * data from the underlying buffer, and will fail to operate * properly if the data is not aligned. The standard way to use these * is to say: * if ((buf = XDR_INLINE(xdrs, count)) == NULL) * return (FALSE); * <<< macro calls >>> * where ``count'' is the number of bytes of data occupied * by the primitive data types. * * N.B. and frozen for all time: each data type here uses 4 bytes * of external representation. */ #define IXDR_GET_INT32(buf) ((int32_t)IXDR_GET_U_INT32(buf)) #define IXDR_PUT_INT32(buf, v) IXDR_PUT_U_INT32((buf),((uint32_t)(v))) #define IXDR_GET_U_INT32(buf) (ntohl((uint32_t)*(buf)++)) #define IXDR_PUT_U_INT32(buf, v) (*(buf)++ = (int32_t)htonl((v))) #define IXDR_GET_LONG(buf) ((long)IXDR_GET_INT32(buf)) #define IXDR_PUT_LONG(buf, v) IXDR_PUT_U_INT32((buf),((uint32_t)(v))) #define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) #define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_INT32(buf)) #define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_U_INT32(buf)) #define IXDR_GET_SHORT(buf) ((short)IXDR_GET_INT32(buf)) #define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_U_INT32(buf)) #define IXDR_PUT_BOOL(buf, v) IXDR_PUT_INT32((buf),((int32_t)(v))) #define IXDR_PUT_ENUM(buf, v) IXDR_PUT_INT32((buf),((int32_t)(v))) #define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_U_INT32((buf),((uint32_t)(v))) #define IXDR_PUT_SHORT(buf, v) IXDR_PUT_INT32((buf),((int32_t)(v))) #define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_U_INT32((buf),((uint32_t)(v))) /* * These are the "generic" xdr routines. */ extern bool_t xdr_void(XDR *, void *); extern bool_t xdr_int(XDR *, int *); extern bool_t xdr_u_int(XDR *, u_int *); extern bool_t xdr_long(XDR *, long *); extern bool_t xdr_u_long(XDR *, u_long *); extern bool_t xdr_short(XDR *, short *); extern bool_t xdr_u_short(XDR *, u_short *); extern bool_t xdr_bool(XDR *, bool_t *); extern bool_t xdr_enum(XDR *, enum_t *); extern bool_t xdr_array(XDR *, caddr_t *, u_int *, u_int, u_int, xdrproc_t); extern bool_t xdr_bytes(XDR *, char **, u_int *, u_int); extern bool_t xdr_opaque(XDR *, caddr_t, u_int); extern bool_t xdr_string(XDR *, char **, u_int); extern bool_t xdr_union(XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t); extern bool_t xdr_char(XDR *, char *); extern bool_t xdr_u_char(XDR *, u_char *); extern bool_t xdr_vector(XDR *, char *, u_int, u_int, xdrproc_t); extern bool_t xdr_float(XDR *, float *); extern bool_t xdr_double(XDR *, double *); extern bool_t xdr_reference(XDR *, caddr_t *, u_int, xdrproc_t); extern bool_t xdr_pointer(XDR *, char **, u_int, xdrproc_t); extern bool_t xdr_wrapstring(XDR *, char **); extern unsigned long xdr_sizeof(xdrproc_t, void *); #define xdr_rpcprog xdr_u_int32 #define xdr_rpcvers xdr_u_int32 #define xdr_rpcprot xdr_u_int32 #define xdr_rpcproc xdr_u_int32 #define xdr_rpcport xdr_u_int32 /* * Common opaque bytes objects used by many rpc protocols; * declared here due to commonality. */ #define MAX_NETOBJ_SZ 2048 struct netobj { u_int n_len; char *n_bytes; }; typedef struct netobj netobj; extern bool_t xdr_netobj(XDR *, struct netobj *); extern bool_t xdr_int32(XDR *, int32_t *); extern bool_t xdr_u_int32(XDR *, uint32_t *); /* * These are the public routines for the various implementations of * xdr streams. */ /* XDR allocating memory buffer */ extern void xdralloc_create(XDR *, enum xdr_op); /* destroy xdralloc, save buf */ extern void xdralloc_release(XDR *); /* get buffer from xdralloc */ extern caddr_t xdralloc_getdata(XDR *); /* XDR using memory buffers */ extern void xdrmem_create(XDR *, caddr_t, u_int, enum xdr_op); /* XDR using stdio library */ extern void xdrstdio_create(XDR *, FILE *, enum xdr_op); /* XDR pseudo records for tcp */ extern void xdrrec_create(XDR *xdrs, u_int, u_int, caddr_t, int (*) (caddr_t, caddr_t, int), int (*) (caddr_t, caddr_t, int)); /* make end of xdr record */ extern bool_t xdrrec_endofrecord(XDR *, bool_t); /* move to beginning of next record */ extern bool_t xdrrec_skiprecord (XDR *xdrs); /* true if no more input */ extern bool_t xdrrec_eof (XDR *xdrs); /* free memory buffers for xdr */ extern void xdr_free (xdrproc_t, void *); GSSRPC__END_DECLS #endif /* !defined(GSSRPC_XDR_H) */ gssrpc/auth_gssapi.h 0000644 00000010355 15146341150 0010531 0 ustar 00 /* include/gssrpc/auth_gssapi.h - GSS-API style auth parameters for RPC */ /* * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved. */ #ifndef GSSRPC_AUTH_GSSAPI_H #define GSSRPC_AUTH_GSSAPI_H GSSRPC__BEGIN_DECLS #define AUTH_GSSAPI_EXIT 0 #define AUTH_GSSAPI_INIT 1 #define AUTH_GSSAPI_CONTINUE_INIT 2 #define AUTH_GSSAPI_MSG 3 #define AUTH_GSSAPI_DESTROY 4 /* * Yuck. Some sys/types.h files leak symbols */ #ifdef major #undef major #endif #ifdef minor #undef minor #endif typedef struct _auth_gssapi_name { char *name; gss_OID type; } auth_gssapi_name; typedef struct _auth_gssapi_creds { uint32_t version; bool_t auth_msg; gss_buffer_desc client_handle; } auth_gssapi_creds; typedef struct _auth_gssapi_init_arg { uint32_t version; gss_buffer_desc token; } auth_gssapi_init_arg; typedef struct _auth_gssapi_init_res { uint32_t version; gss_buffer_desc client_handle; OM_uint32 gss_major, gss_minor; gss_buffer_desc token; gss_buffer_desc signed_isn; } auth_gssapi_init_res; typedef void (*auth_gssapi_log_badauth_func) (OM_uint32 major, OM_uint32 minor, struct sockaddr_in *raddr, caddr_t data); /* auth_gssapi_log_badauth_func is IPv4-specific; this version gives the * transport handle so the fd can be used to get the address. */ typedef void (*auth_gssapi_log_badauth2_func) (OM_uint32 major, OM_uint32 minor, SVCXPRT *xprt, caddr_t data); typedef void (*auth_gssapi_log_badverf_func) (gss_name_t client, gss_name_t server, struct svc_req *rqst, struct rpc_msg *msg, caddr_t data); typedef void (*auth_gssapi_log_miscerr_func) (struct svc_req *rqst, struct rpc_msg *msg, char *error, caddr_t data); bool_t xdr_gss_buf(XDR *, gss_buffer_t); bool_t xdr_authgssapi_creds(XDR *, auth_gssapi_creds *); bool_t xdr_authgssapi_init_arg(XDR *, auth_gssapi_init_arg *); bool_t xdr_authgssapi_init_res(XDR *, auth_gssapi_init_res *); bool_t auth_gssapi_wrap_data (OM_uint32 *major, OM_uint32 *minor, gss_ctx_id_t context, uint32_t seq_num, XDR *out_xdrs, bool_t (*xdr_func)(), caddr_t xdr_ptr); bool_t auth_gssapi_unwrap_data (OM_uint32 *major, OM_uint32 *minor, gss_ctx_id_t context, uint32_t seq_num, XDR *in_xdrs, bool_t (*xdr_func)(), caddr_t xdr_ptr); AUTH *auth_gssapi_create (CLIENT *clnt, OM_uint32 *major_status, OM_uint32 *minor_status, gss_cred_id_t claimant_cred_handle, gss_name_t target_name, gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, gss_OID *actual_mech_type, OM_uint32 *ret_flags, OM_uint32 *time_rec); AUTH *auth_gssapi_create_default (CLIENT *clnt, char *service_name); void auth_gssapi_display_status (char *msg, OM_uint32 major, OM_uint32 minor); bool_t auth_gssapi_seal_seq (gss_ctx_id_t context, uint32_t seq_num, gss_buffer_t out_buf); bool_t auth_gssapi_unseal_seq (gss_ctx_id_t context, gss_buffer_t in_buf, uint32_t *seq_num); bool_t svcauth_gssapi_set_names (auth_gssapi_name *names, int num); void svcauth_gssapi_unset_names (void); void svcauth_gssapi_set_log_badauth_func (auth_gssapi_log_badauth_func func, caddr_t data); void svcauth_gssapi_set_log_badauth2_func (auth_gssapi_log_badauth2_func func, caddr_t data); void svcauth_gssapi_set_log_badverf_func (auth_gssapi_log_badverf_func func, caddr_t data); void svcauth_gssapi_set_log_miscerr_func (auth_gssapi_log_miscerr_func func, caddr_t data); void svcauth_gss_set_log_badauth_func(auth_gssapi_log_badauth_func, caddr_t); void svcauth_gss_set_log_badauth2_func(auth_gssapi_log_badauth2_func, caddr_t); void svcauth_gss_set_log_badverf_func(auth_gssapi_log_badverf_func, caddr_t); void svcauth_gss_set_log_miscerr_func(auth_gssapi_log_miscerr_func, caddr_t data); #define GSS_COPY_BUFFER(dest, src) { \ (dest).length = (src).length; \ (dest).value = (src).value; } #define GSS_DUP_BUFFER(dest, src) { \ (dest).length = (src).length; \ (dest).value = (void *) malloc((dest).length); \ memcpy((dest).value, (src).value, (dest).length); } #define GSS_BUFFERS_EQUAL(b1, b2) (((b1).length == (b2).length) && \ !memcmp((b1).value,(b2).value,(b1.length))) GSSRPC__END_DECLS #endif /* !defined(GSSRPC_AUTH_GSSAPI_H) */ gssrpc/svc_auth.h 0000644 00000007610 15146341150 0010036 0 ustar 00 /* @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* @(#)svc_auth.h 1.6 86/07/16 SMI */ /* * svc_auth.h, Service side of rpc authentication. */ /* * Interface to server-side authentication flavors. */ #ifndef GSSRPC_SVC_AUTH_H #define GSSRPC_SVC_AUTH_H #include <gssapi/gssapi.h> GSSRPC__BEGIN_DECLS struct svc_req; typedef struct SVCAUTH { struct svc_auth_ops { int (*svc_ah_wrap)(struct SVCAUTH *, XDR *, xdrproc_t, caddr_t); int (*svc_ah_unwrap)(struct SVCAUTH *, XDR *, xdrproc_t, caddr_t); int (*svc_ah_destroy)(struct SVCAUTH *); } *svc_ah_ops; void * svc_ah_private; } SVCAUTH; #ifdef GSSRPC__IMPL extern SVCAUTH svc_auth_none; extern struct svc_auth_ops svc_auth_none_ops; extern struct svc_auth_ops svc_auth_gssapi_ops; extern struct svc_auth_ops svc_auth_gss_ops; /* * Server side authenticator */ /* RENAMED: should be _authenticate. */ extern enum auth_stat gssrpc__authenticate(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch); #define SVCAUTH_WRAP(auth, xdrs, xfunc, xwhere) \ ((*((auth)->svc_ah_ops->svc_ah_wrap))(auth, xdrs, xfunc, xwhere)) #define SVCAUTH_UNWRAP(auth, xdrs, xfunc, xwhere) \ ((*((auth)->svc_ah_ops->svc_ah_unwrap))(auth, xdrs, xfunc, xwhere)) #define SVCAUTH_DESTROY(auth) \ ((*((auth)->svc_ah_ops->svc_ah_destroy))(auth)) /* no authentication */ /* RENAMED: should be _svcauth_none. */ enum auth_stat gssrpc__svcauth_none(struct svc_req *, struct rpc_msg *, bool_t *); /* unix style (uid, gids) */ /* RENAMED: shoudl be _svcauth_unix. */ enum auth_stat gssrpc__svcauth_unix(struct svc_req *, struct rpc_msg *, bool_t *); /* short hand unix style */ /* RENAMED: should be _svcauth_short. */ enum auth_stat gssrpc__svcauth_short(struct svc_req *, struct rpc_msg *, bool_t *); /* GSS-API style */ /* RENAMED: should be _svcauth_gssapi. */ enum auth_stat gssrpc__svcauth_gssapi(struct svc_req *, struct rpc_msg *, bool_t *); /* RPCSEC_GSS */ enum auth_stat gssrpc__svcauth_gss(struct svc_req *, struct rpc_msg *, bool_t *); #endif /* defined(GSSRPC__IMPL) */ /* * Approved way of getting principal of caller */ char *svcauth_gss_get_principal(SVCAUTH *auth); /* * Approved way of setting server principal */ bool_t svcauth_gss_set_svc_name(gss_name_t name); GSSRPC__END_DECLS #endif /* !defined(GSSRPC_SVC_AUTH_H) */ gssrpc/auth_unix.h 0000644 00000005520 15146341150 0010224 0 ustar 00 /* @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC; from 1.8 88/02/08 SMI */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* @(#)auth_unix.h 1.5 86/07/16 SMI */ /* * auth_unix.h, Protocol for UNIX style authentication parameters for RPC */ #ifndef GSSRPC_AUTH_UNIX_H #define GSSRPC_AUTH_UNIX_H GSSRPC__BEGIN_DECLS /* * The system is very weak. The client uses no encryption for it * credentials and only sends null verifiers. The server sends backs * null verifiers or optionally a verifier that suggests a new short hand * for the credentials. */ /* The machine name is part of a credential; it may not exceed 255 bytes */ #define MAX_MACHINE_NAME 255 /* gids compose part of a credential; there may not be more than 16 of them */ #define NGRPS 16 /* * Unix style credentials. */ struct authunix_parms { uint32_t aup_time; char *aup_machname; int aup_uid; int aup_gid; u_int aup_len; int *aup_gids; }; extern bool_t xdr_authunix_parms(XDR *, struct authunix_parms *); /* * If a response verifier has flavor AUTH_SHORT, * then the body of the response verifier encapsulates the following structure; * again it is serialized in the obvious fashion. */ struct short_hand_verf { struct opaque_auth new_cred; }; GSSRPC__END_DECLS #endif /* !defined(GSSRPC_AUTH_UNIX_H) */ gssrpc/pmap_prot.h 0000644 00000007401 15146341150 0010221 0 ustar 00 /* @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC; from 1.14 88/02/08 SMI */ /* * Copyright (c) 2010, Oracle America, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * 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. * * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDER 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. */ /* * pmap_prot.h * Protocol for the local binder service, or pmap. * * The following procedures are supported by the protocol: * * PMAPPROC_NULL() returns () * takes nothing, returns nothing * * PMAPPROC_SET(struct pmap) returns (bool_t) * TRUE is success, FALSE is failure. Registers the tuple * [prog, vers, prot, port]. * * PMAPPROC_UNSET(struct pmap) returns (bool_t) * TRUE is success, FALSE is failure. Un-registers pair * [prog, vers]. prot and port are ignored. * * PMAPPROC_GETPORT(struct pmap) returns (u_short). * 0 is failure. Otherwise returns the port number where the pair * [prog, vers] is registered. It may lie! * * PMAPPROC_DUMP() RETURNS (struct pmaplist *) * * PMAPPROC_CALLIT(rpcprog_t, rpcvers_t, rpcproc_t, string<>) * RETURNS (port, string<>); * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); * Calls the procedure on the local machine. If it is not registered, * this procedure is quite; ie it does not return error information!!! * This procedure only is supported on rpc/udp and calls via * rpc/udp. This routine only passes null authentication parameters. * This file has no interface to xdr routines for PMAPPROC_CALLIT. * * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. */ #ifndef GSSRPC_PMAP_PROT_H #define GSSRPC_PMAP_PROT_H GSSRPC__BEGIN_DECLS #define PMAPPORT ((u_short)111) #define PMAPPROG ((rpcprog_t)100000) #define PMAPVERS ((rpcvers_t)2) #define PMAPVERS_PROTO ((rpcprot_t)2) #define PMAPVERS_ORIG ((rpcvers_t)1) #define PMAPPROC_NULL ((rpcproc_t)0) #define PMAPPROC_SET ((rpcproc_t)1) #define PMAPPROC_UNSET ((rpcproc_t)2) #define PMAPPROC_GETPORT ((rpcproc_t)3) #define PMAPPROC_DUMP ((rpcproc_t)4) #define PMAPPROC_CALLIT ((rpcproc_t)5) struct pmap { rpcprog_t pm_prog; rpcvers_t pm_vers; rpcprot_t pm_prot; rpcport_t pm_port; }; extern bool_t xdr_pmap(XDR *, struct pmap *); struct pmaplist { struct pmap pml_map; struct pmaplist *pml_next; }; extern bool_t xdr_pmaplist(XDR *, struct pmaplist **); GSSRPC__END_DECLS #endif /* !defined(GSSRPC_PMAP_PROT_H) */ lber.h 0000644 00000035717 15146341150 0005656 0 ustar 00 /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 1998-2018 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in file LICENSE in the * top-level directory of the distribution or, alternatively, at * <http://www.OpenLDAP.org/license.html>. */ /* Portions Copyright (c) 1990 Regents of the University of Michigan. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of Michigan at Ann Arbor. The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. */ #ifndef _LBER_H #define _LBER_H #include <lber_types.h> #include <string.h> LDAP_BEGIN_DECL /* * ber_tag_t represents the identifier octets at the beginning of BER * elements. OpenLDAP treats them as mere big-endian unsigned integers. * * Actually the BER identifier octets look like this: * * Bits of 1st octet: * ______ * 8 7 | CLASS * 0 0 = UNIVERSAL * 0 1 = APPLICATION * 1 0 = CONTEXT-SPECIFIC * 1 1 = PRIVATE * _____ * | 6 | DATA-TYPE * 0 = PRIMITIVE * 1 = CONSTRUCTED * ___________ * | 5 ... 1 | TAG-NUMBER * * For ASN.1 tag numbers >= 0x1F, TAG-NUMBER above is 0x1F and the next * BER octets contain the actual ASN.1 tag number: Big-endian, base * 128, 8.bit = 1 in all but the last octet, minimum number of octets. */ /* BER classes and mask (in 1st identifier octet) */ #define LBER_CLASS_UNIVERSAL ((ber_tag_t) 0x00U) #define LBER_CLASS_APPLICATION ((ber_tag_t) 0x40U) #define LBER_CLASS_CONTEXT ((ber_tag_t) 0x80U) #define LBER_CLASS_PRIVATE ((ber_tag_t) 0xc0U) #define LBER_CLASS_MASK ((ber_tag_t) 0xc0U) /* BER encoding type and mask (in 1st identifier octet) */ #define LBER_PRIMITIVE ((ber_tag_t) 0x00U) #define LBER_CONSTRUCTED ((ber_tag_t) 0x20U) #define LBER_ENCODING_MASK ((ber_tag_t) 0x20U) #define LBER_BIG_TAG_MASK ((ber_tag_t) 0x1fU) #define LBER_MORE_TAG_MASK ((ber_tag_t) 0x80U) /* * LBER_ERROR and LBER_DEFAULT are values that can never appear * as valid BER tags, so it is safe to use them to report errors. * Valid tags have (tag & (ber_tag_t) 0xFF) != 0xFF. */ #define LBER_ERROR ((ber_tag_t) -1) #define LBER_DEFAULT ((ber_tag_t) -1) /* general BER types we know about */ #define LBER_BOOLEAN ((ber_tag_t) 0x01UL) #define LBER_INTEGER ((ber_tag_t) 0x02UL) #define LBER_BITSTRING ((ber_tag_t) 0x03UL) #define LBER_OCTETSTRING ((ber_tag_t) 0x04UL) #define LBER_NULL ((ber_tag_t) 0x05UL) #define LBER_ENUMERATED ((ber_tag_t) 0x0aUL) #define LBER_SEQUENCE ((ber_tag_t) 0x30UL) /* constructed */ #define LBER_SET ((ber_tag_t) 0x31UL) /* constructed */ /* LBER BerElement options */ #define LBER_USE_DER 0x01 /* get/set options for BerElement */ #define LBER_OPT_BER_OPTIONS 0x01 #define LBER_OPT_BER_DEBUG 0x02 #define LBER_OPT_BER_REMAINING_BYTES 0x03 #define LBER_OPT_BER_TOTAL_BYTES 0x04 #define LBER_OPT_BER_BYTES_TO_WRITE 0x05 #define LBER_OPT_BER_MEMCTX 0x06 #define LBER_OPT_DEBUG_LEVEL LBER_OPT_BER_DEBUG #define LBER_OPT_REMAINING_BYTES LBER_OPT_BER_REMAINING_BYTES #define LBER_OPT_TOTAL_BYTES LBER_OPT_BER_TOTAL_BYTES #define LBER_OPT_BYTES_TO_WRITE LBER_OPT_BER_BYTES_TO_WRITE #define LBER_OPT_LOG_PRINT_FN 0x8001 #define LBER_OPT_MEMORY_FNS 0x8002 #define LBER_OPT_ERROR_FN 0x8003 #define LBER_OPT_LOG_PRINT_FILE 0x8004 /* get/set Memory Debug options */ #define LBER_OPT_MEMORY_INUSE 0x8005 /* for memory debugging */ #define LBER_OPT_LOG_PROC 0x8006 /* for external logging function */ typedef int* (*BER_ERRNO_FN) LDAP_P(( void )); typedef void (*BER_LOG_PRINT_FN) LDAP_P(( LDAP_CONST char *buf )); typedef void* (BER_MEMALLOC_FN) LDAP_P(( ber_len_t size, void *ctx )); typedef void* (BER_MEMCALLOC_FN) LDAP_P(( ber_len_t n, ber_len_t size, void *ctx )); typedef void* (BER_MEMREALLOC_FN) LDAP_P(( void *p, ber_len_t size, void *ctx )); typedef void (BER_MEMFREE_FN) LDAP_P(( void *p, void *ctx )); typedef struct lber_memory_fns { BER_MEMALLOC_FN *bmf_malloc; BER_MEMCALLOC_FN *bmf_calloc; BER_MEMREALLOC_FN *bmf_realloc; BER_MEMFREE_FN *bmf_free; } BerMemoryFunctions; /* LBER Sockbuf_IO options */ #define LBER_SB_OPT_GET_FD 1 #define LBER_SB_OPT_SET_FD 2 #define LBER_SB_OPT_HAS_IO 3 #define LBER_SB_OPT_SET_NONBLOCK 4 #define LBER_SB_OPT_GET_SSL 7 #define LBER_SB_OPT_DATA_READY 8 #define LBER_SB_OPT_SET_READAHEAD 9 #define LBER_SB_OPT_DRAIN 10 #define LBER_SB_OPT_NEEDS_READ 11 #define LBER_SB_OPT_NEEDS_WRITE 12 #define LBER_SB_OPT_GET_MAX_INCOMING 13 #define LBER_SB_OPT_SET_MAX_INCOMING 14 /* Only meaningful ifdef LDAP_PF_LOCAL_SENDMSG */ #define LBER_SB_OPT_UNGET_BUF 15 /* Largest option used by the library */ #define LBER_SB_OPT_OPT_MAX 15 /* LBER IO operations stacking levels */ #define LBER_SBIOD_LEVEL_PROVIDER 10 #define LBER_SBIOD_LEVEL_TRANSPORT 20 #define LBER_SBIOD_LEVEL_APPLICATION 30 /* get/set options for Sockbuf */ #define LBER_OPT_SOCKBUF_DESC 0x1000 #define LBER_OPT_SOCKBUF_OPTIONS 0x1001 #define LBER_OPT_SOCKBUF_DEBUG 0x1002 /* on/off values */ LBER_V( char ) ber_pvt_opt_on; #define LBER_OPT_ON ((void *) &ber_pvt_opt_on) #define LBER_OPT_OFF ((void *) 0) #define LBER_OPT_SUCCESS (0) #define LBER_OPT_ERROR (-1) typedef struct berelement BerElement; typedef struct sockbuf Sockbuf; typedef struct sockbuf_io Sockbuf_IO; /* Structure for LBER IO operation descriptor */ typedef struct sockbuf_io_desc { int sbiod_level; Sockbuf *sbiod_sb; Sockbuf_IO *sbiod_io; void *sbiod_pvt; struct sockbuf_io_desc *sbiod_next; } Sockbuf_IO_Desc; /* Structure for LBER IO operation functions */ struct sockbuf_io { int (*sbi_setup)( Sockbuf_IO_Desc *sbiod, void *arg ); int (*sbi_remove)( Sockbuf_IO_Desc *sbiod ); int (*sbi_ctrl)( Sockbuf_IO_Desc *sbiod, int opt, void *arg); ber_slen_t (*sbi_read)( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len ); ber_slen_t (*sbi_write)( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len ); int (*sbi_close)( Sockbuf_IO_Desc *sbiod ); }; /* Helper macros for LBER IO functions */ #define LBER_SBIOD_READ_NEXT( sbiod, buf, len ) \ ( (sbiod)->sbiod_next->sbiod_io->sbi_read( (sbiod)->sbiod_next, \ buf, len ) ) #define LBER_SBIOD_WRITE_NEXT( sbiod, buf, len ) \ ( (sbiod)->sbiod_next->sbiod_io->sbi_write( (sbiod)->sbiod_next, \ buf, len ) ) #define LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg ) \ ( (sbiod)->sbiod_next ? \ ( (sbiod)->sbiod_next->sbiod_io->sbi_ctrl( \ (sbiod)->sbiod_next, opt, arg ) ) : 0 ) /* structure for returning a sequence of octet strings + length */ typedef struct berval { ber_len_t bv_len; char *bv_val; } BerValue; typedef BerValue *BerVarray; /* To distinguish from a single bv */ /* this should be moved to lber-int.h */ /* * in bprint.c: */ LBER_F( void ) ber_error_print LDAP_P(( LDAP_CONST char *data )); LBER_F( void ) ber_bprint LDAP_P(( LDAP_CONST char *data, ber_len_t len )); LBER_F( void ) ber_dump LDAP_P(( BerElement *ber, int inout )); /* * in decode.c: */ typedef int (*BERDecodeCallback) LDAP_P(( BerElement *ber, void *data, int mode )); LBER_F( ber_tag_t ) ber_get_tag LDAP_P(( BerElement *ber )); LBER_F( ber_tag_t ) ber_skip_tag LDAP_P(( BerElement *ber, ber_len_t *len )); LBER_F( ber_tag_t ) ber_peek_tag LDAP_P(( BerElement *ber, ber_len_t *len )); LBER_F( ber_tag_t ) ber_skip_element LDAP_P(( BerElement *ber, struct berval *bv )); LBER_F( ber_tag_t ) ber_peek_element LDAP_P(( LDAP_CONST BerElement *ber, struct berval *bv )); LBER_F( ber_tag_t ) ber_get_int LDAP_P(( BerElement *ber, ber_int_t *num )); LBER_F( ber_tag_t ) ber_get_enum LDAP_P(( BerElement *ber, ber_int_t *num )); LBER_F( ber_tag_t ) ber_get_stringb LDAP_P(( BerElement *ber, char *buf, ber_len_t *len )); #define LBER_BV_ALLOC 0x01 /* allocate/copy result, otherwise in-place */ #define LBER_BV_NOTERM 0x02 /* omit NUL-terminator if parsing in-place */ #define LBER_BV_STRING 0x04 /* fail if berval contains embedded \0 */ /* LBER_BV_STRING currently accepts a terminating \0 in the berval, because * Active Directory sends that in at least the diagonsticMessage field. */ LBER_F( ber_tag_t ) ber_get_stringbv LDAP_P(( BerElement *ber, struct berval *bv, int options )); LBER_F( ber_tag_t ) ber_get_stringa LDAP_P(( BerElement *ber, char **buf )); LBER_F( ber_tag_t ) ber_get_stringal LDAP_P(( BerElement *ber, struct berval **bv )); LBER_F( ber_tag_t ) ber_get_bitstringa LDAP_P(( BerElement *ber, char **buf, ber_len_t *len )); LBER_F( ber_tag_t ) ber_get_null LDAP_P(( BerElement *ber )); LBER_F( ber_tag_t ) ber_get_boolean LDAP_P(( BerElement *ber, ber_int_t *boolval )); LBER_F( ber_tag_t ) ber_first_element LDAP_P(( BerElement *ber, ber_len_t *len, char **last )); LBER_F( ber_tag_t ) ber_next_element LDAP_P(( BerElement *ber, ber_len_t *len, LDAP_CONST char *last )); LBER_F( ber_tag_t ) ber_scanf LDAP_P(( BerElement *ber, LDAP_CONST char *fmt, ... )); LBER_F( int ) ber_decode_oid LDAP_P(( struct berval *in, struct berval *out )); /* * in encode.c */ LBER_F( int ) ber_encode_oid LDAP_P(( struct berval *in, struct berval *out )); typedef int (*BEREncodeCallback) LDAP_P(( BerElement *ber, void *data )); LBER_F( int ) ber_put_enum LDAP_P(( BerElement *ber, ber_int_t num, ber_tag_t tag )); LBER_F( int ) ber_put_int LDAP_P(( BerElement *ber, ber_int_t num, ber_tag_t tag )); LBER_F( int ) ber_put_ostring LDAP_P(( BerElement *ber, LDAP_CONST char *str, ber_len_t len, ber_tag_t tag )); LBER_F( int ) ber_put_berval LDAP_P(( BerElement *ber, struct berval *bv, ber_tag_t tag )); LBER_F( int ) ber_put_string LDAP_P(( BerElement *ber, LDAP_CONST char *str, ber_tag_t tag )); LBER_F( int ) ber_put_bitstring LDAP_P(( BerElement *ber, LDAP_CONST char *str, ber_len_t bitlen, ber_tag_t tag )); LBER_F( int ) ber_put_null LDAP_P(( BerElement *ber, ber_tag_t tag )); LBER_F( int ) ber_put_boolean LDAP_P(( BerElement *ber, ber_int_t boolval, ber_tag_t tag )); LBER_F( int ) ber_start_seq LDAP_P(( BerElement *ber, ber_tag_t tag )); LBER_F( int ) ber_start_set LDAP_P(( BerElement *ber, ber_tag_t tag )); LBER_F( int ) ber_put_seq LDAP_P(( BerElement *ber )); LBER_F( int ) ber_put_set LDAP_P(( BerElement *ber )); LBER_F( int ) ber_printf LDAP_P(( BerElement *ber, LDAP_CONST char *fmt, ... )); /* * in io.c: */ LBER_F( ber_slen_t ) ber_skip_data LDAP_P(( BerElement *ber, ber_len_t len )); LBER_F( ber_slen_t ) ber_read LDAP_P(( BerElement *ber, char *buf, ber_len_t len )); LBER_F( ber_slen_t ) ber_write LDAP_P(( BerElement *ber, LDAP_CONST char *buf, ber_len_t len, int zero )); /* nonzero is unsupported from OpenLDAP 2.4.18 */ LBER_F( void ) ber_free LDAP_P(( BerElement *ber, int freebuf )); LBER_F( void ) ber_free_buf LDAP_P(( BerElement *ber )); LBER_F( int ) ber_flush2 LDAP_P(( Sockbuf *sb, BerElement *ber, int freeit )); #define LBER_FLUSH_FREE_NEVER (0x0) /* traditional behavior */ #define LBER_FLUSH_FREE_ON_SUCCESS (0x1) /* traditional behavior */ #define LBER_FLUSH_FREE_ON_ERROR (0x2) #define LBER_FLUSH_FREE_ALWAYS (LBER_FLUSH_FREE_ON_SUCCESS|LBER_FLUSH_FREE_ON_ERROR) LBER_F( int ) ber_flush LDAP_P(( Sockbuf *sb, BerElement *ber, int freeit )); /* DEPRECATED */ LBER_F( BerElement * ) ber_alloc LDAP_P(( void )); /* DEPRECATED */ LBER_F( BerElement * ) der_alloc LDAP_P(( void )); /* DEPRECATED */ LBER_F( BerElement * ) ber_alloc_t LDAP_P(( int beroptions )); LBER_F( BerElement * ) ber_dup LDAP_P(( BerElement *ber )); LBER_F( ber_tag_t ) ber_get_next LDAP_P(( Sockbuf *sb, ber_len_t *len, BerElement *ber )); LBER_F( void ) ber_init2 LDAP_P(( BerElement *ber, struct berval *bv, int options )); LBER_F( void ) ber_init_w_nullc LDAP_P(( /* DEPRECATED */ BerElement *ber, int options )); LBER_F( void ) ber_reset LDAP_P(( BerElement *ber, int was_writing )); LBER_F( BerElement * ) ber_init LDAP_P(( struct berval *bv )); LBER_F( int ) ber_flatten LDAP_P(( BerElement *ber, struct berval **bvPtr )); LBER_F( int ) ber_flatten2 LDAP_P(( BerElement *ber, struct berval *bv, int alloc )); LBER_F( int ) ber_remaining LDAP_P(( BerElement *ber )); /* * LBER ber accessor functions */ LBER_F( int ) ber_get_option LDAP_P(( void *item, int option, void *outvalue)); LBER_F( int ) ber_set_option LDAP_P(( void *item, int option, LDAP_CONST void *invalue)); /* * LBER sockbuf.c */ LBER_F( Sockbuf * ) ber_sockbuf_alloc LDAP_P(( void )); LBER_F( void ) ber_sockbuf_free LDAP_P(( Sockbuf *sb )); LBER_F( int ) ber_sockbuf_add_io LDAP_P(( Sockbuf *sb, Sockbuf_IO *sbio, int layer, void *arg )); LBER_F( int ) ber_sockbuf_remove_io LDAP_P(( Sockbuf *sb, Sockbuf_IO *sbio, int layer )); LBER_F( int ) ber_sockbuf_ctrl LDAP_P(( Sockbuf *sb, int opt, void *arg )); LBER_V( Sockbuf_IO ) ber_sockbuf_io_tcp; LBER_V( Sockbuf_IO ) ber_sockbuf_io_readahead; LBER_V( Sockbuf_IO ) ber_sockbuf_io_fd; LBER_V( Sockbuf_IO ) ber_sockbuf_io_debug; LBER_V( Sockbuf_IO ) ber_sockbuf_io_udp; /* * LBER memory.c */ LBER_F( void * ) ber_memalloc LDAP_P(( ber_len_t s )); LBER_F( void * ) ber_memrealloc LDAP_P(( void* p, ber_len_t s )); LBER_F( void * ) ber_memcalloc LDAP_P(( ber_len_t n, ber_len_t s )); LBER_F( void ) ber_memfree LDAP_P(( void* p )); LBER_F( void ) ber_memvfree LDAP_P(( void** vector )); LBER_F( void ) ber_bvfree LDAP_P(( struct berval *bv )); LBER_F( void ) ber_bvecfree LDAP_P(( struct berval **bv )); LBER_F( int ) ber_bvecadd LDAP_P(( struct berval ***bvec, struct berval *bv )); LBER_F( struct berval * ) ber_dupbv LDAP_P(( struct berval *dst, struct berval *src )); LBER_F( struct berval * ) ber_bvdup LDAP_P(( struct berval *src )); LBER_F( struct berval * ) ber_mem2bv LDAP_P(( LDAP_CONST char *, ber_len_t len, int duplicate, struct berval *bv)); LBER_F( struct berval * ) ber_str2bv LDAP_P(( LDAP_CONST char *, ber_len_t len, int duplicate, struct berval *bv)); #define ber_bvstr(a) ((ber_str2bv)((a), 0, 0, NULL)) #define ber_bvstrdup(a) ((ber_str2bv)((a), 0, 1, NULL)) LBER_F( char * ) ber_strdup LDAP_P(( LDAP_CONST char * )); LBER_F( ber_len_t ) ber_strnlen LDAP_P(( LDAP_CONST char *s, ber_len_t len )); LBER_F( char * ) ber_strndup LDAP_P(( LDAP_CONST char *s, ber_len_t l )); LBER_F( struct berval * ) ber_bvreplace LDAP_P(( struct berval *dst, LDAP_CONST struct berval *src )); LBER_F( void ) ber_bvarray_free LDAP_P(( BerVarray p )); LBER_F( int ) ber_bvarray_add LDAP_P(( BerVarray *p, BerValue *bv )); #define ber_bvcmp(v1,v2) \ ((v1)->bv_len < (v2)->bv_len \ ? -1 : ((v1)->bv_len > (v2)->bv_len \ ? 1 : memcmp((v1)->bv_val, (v2)->bv_val, (v1)->bv_len) )) /* * error.c */ LBER_F( int * ) ber_errno_addr LDAP_P((void)); #define ber_errno (*(ber_errno_addr)()) #define LBER_ERROR_NONE 0 #define LBER_ERROR_PARAM 0x1 #define LBER_ERROR_MEMORY 0x2 LDAP_END_DECL #endif /* _LBER_H */ panel.h 0000644 00000010033 15146341150 0006011 0 ustar 00 /**************************************************************************** * Copyright (c) 1998-2009,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, distribute with modifications, sublicense, and/or sell * * copies of the Software, and to permit persons to whom the Software is * * furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included * * in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * * * Except as contained in this notice, the name(s) of the above copyright * * holders shall not be used in advertising or otherwise to promote the * * sale, use or other dealings in this Software without prior written * * authorization. * ****************************************************************************/ /**************************************************************************** * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1995 * * and: Eric S. Raymond <esr@snark.thyrsus.com> * * and: Juergen Pfeifer 1996-1999,2008 * ****************************************************************************/ /* $Id: panel.h,v 1.12 2017/02/11 16:50:28 tom Exp $ */ /* panel.h -- interface file for panels library */ #ifndef NCURSES_PANEL_H_incl #define NCURSES_PANEL_H_incl 1 #include <curses.h> typedef struct panel #if !NCURSES_OPAQUE_PANEL { WINDOW *win; struct panel *below; struct panel *above; NCURSES_CONST void *user; } #endif /* !NCURSES_OPAQUE_PANEL */ PANEL; #if defined(__cplusplus) extern "C" { #endif extern NCURSES_EXPORT(WINDOW*) panel_window (const PANEL *); extern NCURSES_EXPORT(void) update_panels (void); extern NCURSES_EXPORT(int) hide_panel (PANEL *); extern NCURSES_EXPORT(int) show_panel (PANEL *); extern NCURSES_EXPORT(int) del_panel (PANEL *); extern NCURSES_EXPORT(int) top_panel (PANEL *); extern NCURSES_EXPORT(int) bottom_panel (PANEL *); extern NCURSES_EXPORT(PANEL*) new_panel (WINDOW *); extern NCURSES_EXPORT(PANEL*) panel_above (const PANEL *); extern NCURSES_EXPORT(PANEL*) panel_below (const PANEL *); extern NCURSES_EXPORT(int) set_panel_userptr (PANEL *, NCURSES_CONST void *); extern NCURSES_EXPORT(NCURSES_CONST void*) panel_userptr (const PANEL *); extern NCURSES_EXPORT(int) move_panel (PANEL *, int, int); extern NCURSES_EXPORT(int) replace_panel (PANEL *,WINDOW *); extern NCURSES_EXPORT(int) panel_hidden (const PANEL *); #if NCURSES_SP_FUNCS extern NCURSES_EXPORT(PANEL *) ground_panel(SCREEN *); extern NCURSES_EXPORT(PANEL *) ceiling_panel(SCREEN *); extern NCURSES_EXPORT(void) NCURSES_SP_NAME(update_panels) (SCREEN*); #endif #if defined(__cplusplus) } #endif #endif /* NCURSES_PANEL_H_incl */ /* end of panel.h */ freetype2/ft2build.h 0000644 00000004517 15146341150 0010344 0 ustar 00 /***************************************************************************/ /* */ /* ft2build.h */ /* */ /* FreeType 2 build and setup macros. */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This is the `entry point' for FreeType header file inclusions. It is */ /* the only header file which should be included directly; all other */ /* FreeType header files should be accessed with macro names (after */ /* including `ft2build.h'). */ /* */ /* A typical example is */ /* */ /* #include <ft2build.h> */ /* #include FT_FREETYPE_H */ /* */ /*************************************************************************/ #ifndef FT2BUILD_H_ #define FT2BUILD_H_ #include <freetype/config/ftheader.h> #endif /* FT2BUILD_H_ */ /* END */ freetype2/freetype/ftparams.h 0000644 00000014251 15146341150 0012265 0 ustar 00 /***************************************************************************/ /* */ /* ftparams.h */ /* */ /* FreeType API for possible FT_Parameter tags (specification only). */ /* */ /* Copyright 2017-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTPARAMS_H_ #define FTPARAMS_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /************************************************************************** * * @section: * parameter_tags * * @title: * Parameter Tags * * @abstract: * Macros for driver property and font loading parameter tags. * * @description: * This section contains macros for the @FT_Parameter structure that are * used with various functions to activate some special functionality or * different behaviour of various components of FreeType. * */ /*************************************************************************** * * @constant: * FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY * * @description: * A tag for @FT_Parameter to make @FT_Open_Face ignore typographic * family names in the `name' table (introduced in OpenType version * 1.4). Use this for backward compatibility with legacy systems that * have a four-faces-per-family restriction. * * @since: * 2.8 * */ #define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY \ FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) /* this constant is deprecated */ #define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY \ FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY /*************************************************************************** * * @constant: * FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY * * @description: * A tag for @FT_Parameter to make @FT_Open_Face ignore typographic * subfamily names in the `name' table (introduced in OpenType version * 1.4). Use this for backward compatibility with legacy systems that * have a four-faces-per-family restriction. * * @since: * 2.8 * */ #define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY \ FT_MAKE_TAG( 'i', 'g', 'p', 's' ) /* this constant is deprecated */ #define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY \ FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY /*************************************************************************** * * @constant: * FT_PARAM_TAG_INCREMENTAL * * @description: * An @FT_Parameter tag to be used with @FT_Open_Face to indicate * incremental glyph loading. * */ #define FT_PARAM_TAG_INCREMENTAL \ FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) /************************************************************************** * * @constant: * FT_PARAM_TAG_LCD_FILTER_WEIGHTS * * @description: * An @FT_Parameter tag to be used with @FT_Face_Properties. The * corresponding argument specifies the five LCD filter weights for a * given face (if using @FT_LOAD_TARGET_LCD, for example), overriding * the global default values or the values set up with * @FT_Library_SetLcdFilterWeights. * * @since: * 2.8 * */ #define FT_PARAM_TAG_LCD_FILTER_WEIGHTS \ FT_MAKE_TAG( 'l', 'c', 'd', 'f' ) /************************************************************************** * * @constant: * FT_PARAM_TAG_RANDOM_SEED * * @description: * An @FT_Parameter tag to be used with @FT_Face_Properties. The * corresponding 32bit signed integer argument overrides the font * driver's random seed value with a face-specific one; see * @random-seed. * * @since: * 2.8 * */ #define FT_PARAM_TAG_RANDOM_SEED \ FT_MAKE_TAG( 's', 'e', 'e', 'd' ) /************************************************************************** * * @constant: * FT_PARAM_TAG_STEM_DARKENING * * @description: * An @FT_Parameter tag to be used with @FT_Face_Properties. The * corresponding Boolean argument specifies whether to apply stem * darkening, overriding the global default values or the values set up * with @FT_Property_Set (see @no-stem-darkening). * * This is a passive setting that only takes effect if the font driver * or autohinter honors it, which the CFF, Type~1, and CID drivers * always do, but the autohinter only in `light' hinting mode (as of * version 2.9). * * @since: * 2.8 * */ #define FT_PARAM_TAG_STEM_DARKENING \ FT_MAKE_TAG( 'd', 'a', 'r', 'k' ) /*************************************************************************** * * @constant: * FT_PARAM_TAG_UNPATENTED_HINTING * * @description: * Deprecated, no effect. * * Previously: A constant used as the tag of an @FT_Parameter structure to * indicate that unpatented methods only should be used by the TrueType * bytecode interpreter for a typeface opened by @FT_Open_Face. * */ #define FT_PARAM_TAG_UNPATENTED_HINTING \ FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) /* */ FT_END_HEADER #endif /* FTPARAMS_H_ */ /* END */ freetype2/freetype/ftrender.h 0000644 00000026070 15146341150 0012263 0 ustar 00 /***************************************************************************/ /* */ /* ftrender.h */ /* */ /* FreeType renderer modules public interface (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTRENDER_H_ #define FTRENDER_H_ #include <ft2build.h> #include FT_MODULE_H #include FT_GLYPH_H FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* module_management */ /* */ /*************************************************************************/ /* create a new glyph object */ typedef FT_Error (*FT_Glyph_InitFunc)( FT_Glyph glyph, FT_GlyphSlot slot ); /* destroys a given glyph object */ typedef void (*FT_Glyph_DoneFunc)( FT_Glyph glyph ); typedef void (*FT_Glyph_TransformFunc)( FT_Glyph glyph, const FT_Matrix* matrix, const FT_Vector* delta ); typedef void (*FT_Glyph_GetBBoxFunc)( FT_Glyph glyph, FT_BBox* abbox ); typedef FT_Error (*FT_Glyph_CopyFunc)( FT_Glyph source, FT_Glyph target ); typedef FT_Error (*FT_Glyph_PrepareFunc)( FT_Glyph glyph, FT_GlyphSlot slot ); /* deprecated */ #define FT_Glyph_Init_Func FT_Glyph_InitFunc #define FT_Glyph_Done_Func FT_Glyph_DoneFunc #define FT_Glyph_Transform_Func FT_Glyph_TransformFunc #define FT_Glyph_BBox_Func FT_Glyph_GetBBoxFunc #define FT_Glyph_Copy_Func FT_Glyph_CopyFunc #define FT_Glyph_Prepare_Func FT_Glyph_PrepareFunc struct FT_Glyph_Class_ { FT_Long glyph_size; FT_Glyph_Format glyph_format; FT_Glyph_InitFunc glyph_init; FT_Glyph_DoneFunc glyph_done; FT_Glyph_CopyFunc glyph_copy; FT_Glyph_TransformFunc glyph_transform; FT_Glyph_GetBBoxFunc glyph_bbox; FT_Glyph_PrepareFunc glyph_prepare; }; typedef FT_Error (*FT_Renderer_RenderFunc)( FT_Renderer renderer, FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector* origin ); typedef FT_Error (*FT_Renderer_TransformFunc)( FT_Renderer renderer, FT_GlyphSlot slot, const FT_Matrix* matrix, const FT_Vector* delta ); typedef void (*FT_Renderer_GetCBoxFunc)( FT_Renderer renderer, FT_GlyphSlot slot, FT_BBox* cbox ); typedef FT_Error (*FT_Renderer_SetModeFunc)( FT_Renderer renderer, FT_ULong mode_tag, FT_Pointer mode_ptr ); /* deprecated identifiers */ #define FTRenderer_render FT_Renderer_RenderFunc #define FTRenderer_transform FT_Renderer_TransformFunc #define FTRenderer_getCBox FT_Renderer_GetCBoxFunc #define FTRenderer_setMode FT_Renderer_SetModeFunc /*************************************************************************/ /* */ /* <Struct> */ /* FT_Renderer_Class */ /* */ /* <Description> */ /* The renderer module class descriptor. */ /* */ /* <Fields> */ /* root :: The root @FT_Module_Class fields. */ /* */ /* glyph_format :: The glyph image format this renderer handles. */ /* */ /* render_glyph :: A method used to render the image that is in a */ /* given glyph slot into a bitmap. */ /* */ /* transform_glyph :: A method used to transform the image that is in */ /* a given glyph slot. */ /* */ /* get_glyph_cbox :: A method used to access the glyph's cbox. */ /* */ /* set_mode :: A method used to pass additional parameters. */ /* */ /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ /* This is a pointer to its raster's class. */ /* */ typedef struct FT_Renderer_Class_ { FT_Module_Class root; FT_Glyph_Format glyph_format; FT_Renderer_RenderFunc render_glyph; FT_Renderer_TransformFunc transform_glyph; FT_Renderer_GetCBoxFunc get_glyph_cbox; FT_Renderer_SetModeFunc set_mode; FT_Raster_Funcs* raster_class; } FT_Renderer_Class; /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Renderer */ /* */ /* <Description> */ /* Retrieve the current renderer for a given glyph format. */ /* */ /* <Input> */ /* library :: A handle to the library object. */ /* */ /* format :: The glyph format. */ /* */ /* <Return> */ /* A renderer handle. 0~if none found. */ /* */ /* <Note> */ /* An error will be returned if a module already exists by that name, */ /* or if the module requires a version of FreeType that is too great. */ /* */ /* To add a new renderer, simply use @FT_Add_Module. To retrieve a */ /* renderer by its name, use @FT_Get_Module. */ /* */ FT_EXPORT( FT_Renderer ) FT_Get_Renderer( FT_Library library, FT_Glyph_Format format ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Renderer */ /* */ /* <Description> */ /* Set the current renderer to use, and set additional mode. */ /* */ /* <InOut> */ /* library :: A handle to the library object. */ /* */ /* <Input> */ /* renderer :: A handle to the renderer object. */ /* */ /* num_params :: The number of additional parameters. */ /* */ /* parameters :: Additional parameters. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* In case of success, the renderer will be used to convert glyph */ /* images in the renderer's known format into bitmaps. */ /* */ /* This doesn't change the current renderer for other formats. */ /* */ /* Currently, no FreeType renderer module uses `parameters'; you */ /* should thus always pass NULL as the value. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Renderer( FT_Library library, FT_Renderer renderer, FT_UInt num_params, FT_Parameter* parameters ); /* */ FT_END_HEADER #endif /* FTRENDER_H_ */ /* END */ freetype2/freetype/fttrigon.h 0000644 00000020350 15146341150 0012301 0 ustar 00 /***************************************************************************/ /* */ /* fttrigon.h */ /* */ /* FreeType trigonometric functions (specification). */ /* */ /* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTTRIGON_H_ #define FTTRIGON_H_ #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* computations */ /* */ /*************************************************************************/ /************************************************************************* * * @type: * FT_Angle * * @description: * This type is used to model angle values in FreeType. Note that the * angle is a 16.16 fixed-point value expressed in degrees. * */ typedef FT_Fixed FT_Angle; /************************************************************************* * * @macro: * FT_ANGLE_PI * * @description: * The angle pi expressed in @FT_Angle units. * */ #define FT_ANGLE_PI ( 180L << 16 ) /************************************************************************* * * @macro: * FT_ANGLE_2PI * * @description: * The angle 2*pi expressed in @FT_Angle units. * */ #define FT_ANGLE_2PI ( FT_ANGLE_PI * 2 ) /************************************************************************* * * @macro: * FT_ANGLE_PI2 * * @description: * The angle pi/2 expressed in @FT_Angle units. * */ #define FT_ANGLE_PI2 ( FT_ANGLE_PI / 2 ) /************************************************************************* * * @macro: * FT_ANGLE_PI4 * * @description: * The angle pi/4 expressed in @FT_Angle units. * */ #define FT_ANGLE_PI4 ( FT_ANGLE_PI / 4 ) /************************************************************************* * * @function: * FT_Sin * * @description: * Return the sinus of a given angle in fixed-point format. * * @input: * angle :: * The input angle. * * @return: * The sinus value. * * @note: * If you need both the sinus and cosinus for a given angle, use the * function @FT_Vector_Unit. * */ FT_EXPORT( FT_Fixed ) FT_Sin( FT_Angle angle ); /************************************************************************* * * @function: * FT_Cos * * @description: * Return the cosinus of a given angle in fixed-point format. * * @input: * angle :: * The input angle. * * @return: * The cosinus value. * * @note: * If you need both the sinus and cosinus for a given angle, use the * function @FT_Vector_Unit. * */ FT_EXPORT( FT_Fixed ) FT_Cos( FT_Angle angle ); /************************************************************************* * * @function: * FT_Tan * * @description: * Return the tangent of a given angle in fixed-point format. * * @input: * angle :: * The input angle. * * @return: * The tangent value. * */ FT_EXPORT( FT_Fixed ) FT_Tan( FT_Angle angle ); /************************************************************************* * * @function: * FT_Atan2 * * @description: * Return the arc-tangent corresponding to a given vector (x,y) in * the 2d plane. * * @input: * x :: * The horizontal vector coordinate. * * y :: * The vertical vector coordinate. * * @return: * The arc-tangent value (i.e. angle). * */ FT_EXPORT( FT_Angle ) FT_Atan2( FT_Fixed x, FT_Fixed y ); /************************************************************************* * * @function: * FT_Angle_Diff * * @description: * Return the difference between two angles. The result is always * constrained to the ]-PI..PI] interval. * * @input: * angle1 :: * First angle. * * angle2 :: * Second angle. * * @return: * Constrained value of `value2-value1'. * */ FT_EXPORT( FT_Angle ) FT_Angle_Diff( FT_Angle angle1, FT_Angle angle2 ); /************************************************************************* * * @function: * FT_Vector_Unit * * @description: * Return the unit vector corresponding to a given angle. After the * call, the value of `vec.x' will be `cos(angle)', and the value of * `vec.y' will be `sin(angle)'. * * This function is useful to retrieve both the sinus and cosinus of a * given angle quickly. * * @output: * vec :: * The address of target vector. * * @input: * angle :: * The input angle. * */ FT_EXPORT( void ) FT_Vector_Unit( FT_Vector* vec, FT_Angle angle ); /************************************************************************* * * @function: * FT_Vector_Rotate * * @description: * Rotate a vector by a given angle. * * @inout: * vec :: * The address of target vector. * * @input: * angle :: * The input angle. * */ FT_EXPORT( void ) FT_Vector_Rotate( FT_Vector* vec, FT_Angle angle ); /************************************************************************* * * @function: * FT_Vector_Length * * @description: * Return the length of a given vector. * * @input: * vec :: * The address of target vector. * * @return: * The vector length, expressed in the same units that the original * vector coordinates. * */ FT_EXPORT( FT_Fixed ) FT_Vector_Length( FT_Vector* vec ); /************************************************************************* * * @function: * FT_Vector_Polarize * * @description: * Compute both the length and angle of a given vector. * * @input: * vec :: * The address of source vector. * * @output: * length :: * The vector length. * * angle :: * The vector angle. * */ FT_EXPORT( void ) FT_Vector_Polarize( FT_Vector* vec, FT_Fixed *length, FT_Angle *angle ); /************************************************************************* * * @function: * FT_Vector_From_Polar * * @description: * Compute vector coordinates from a length and angle. * * @output: * vec :: * The address of source vector. * * @input: * length :: * The vector length. * * angle :: * The vector angle. * */ FT_EXPORT( void ) FT_Vector_From_Polar( FT_Vector* vec, FT_Fixed length, FT_Angle angle ); /* */ FT_END_HEADER #endif /* FTTRIGON_H_ */ /* END */ freetype2/freetype/config/ftconfig.h 0000644 00000000401 15146341150 0013504 0 ustar 00 #ifndef __FTCONFIG_H__MULTILIB #define __FTCONFIG_H__MULTILIB #include <bits/wordsize.h> #if __WORDSIZE == 32 # include "ftconfig-32.h" #elif __WORDSIZE == 64 # include "ftconfig-64.h" #else # error "unexpected value for __WORDSIZE macro" #endif #endif freetype2/freetype/config/ftheader.h 0000644 00000061013 15146341150 0013475 0 ustar 00 /***************************************************************************/ /* */ /* ftheader.h */ /* */ /* Build macros of the FreeType 2 library. */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTHEADER_H_ #define FTHEADER_H_ /*@***********************************************************************/ /* */ /* <Macro> */ /* FT_BEGIN_HEADER */ /* */ /* <Description> */ /* This macro is used in association with @FT_END_HEADER in header */ /* files to ensure that the declarations within are properly */ /* encapsulated in an `extern "C" { .. }' block when included from a */ /* C++ compiler. */ /* */ #ifdef __cplusplus #define FT_BEGIN_HEADER extern "C" { #else #define FT_BEGIN_HEADER /* nothing */ #endif /*@***********************************************************************/ /* */ /* <Macro> */ /* FT_END_HEADER */ /* */ /* <Description> */ /* This macro is used in association with @FT_BEGIN_HEADER in header */ /* files to ensure that the declarations within are properly */ /* encapsulated in an `extern "C" { .. }' block when included from a */ /* C++ compiler. */ /* */ #ifdef __cplusplus #define FT_END_HEADER } #else #define FT_END_HEADER /* nothing */ #endif /*************************************************************************/ /* */ /* Aliases for the FreeType 2 public and configuration files. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Section> */ /* header_file_macros */ /* */ /* <Title> */ /* Header File Macros */ /* */ /* <Abstract> */ /* Macro definitions used to #include specific header files. */ /* */ /* <Description> */ /* The following macros are defined to the name of specific */ /* FreeType~2 header files. They can be used directly in #include */ /* statements as in: */ /* */ /* { */ /* #include FT_FREETYPE_H */ /* #include FT_MULTIPLE_MASTERS_H */ /* #include FT_GLYPH_H */ /* } */ /* */ /* There are several reasons why we are now using macros to name */ /* public header files. The first one is that such macros are not */ /* limited to the infamous 8.3~naming rule required by DOS (and */ /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ /* */ /* The second reason is that it allows for more flexibility in the */ /* way FreeType~2 is installed on a given system. */ /* */ /*************************************************************************/ /* configuration files */ /************************************************************************* * * @macro: * FT_CONFIG_CONFIG_H * * @description: * A macro used in #include statements to name the file containing * FreeType~2 configuration data. * */ #ifndef FT_CONFIG_CONFIG_H #define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h> #endif /************************************************************************* * * @macro: * FT_CONFIG_STANDARD_LIBRARY_H * * @description: * A macro used in #include statements to name the file containing * FreeType~2 interface to the standard C library functions. * */ #ifndef FT_CONFIG_STANDARD_LIBRARY_H #define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h> #endif /************************************************************************* * * @macro: * FT_CONFIG_OPTIONS_H * * @description: * A macro used in #include statements to name the file containing * FreeType~2 project-specific configuration options. * */ #ifndef FT_CONFIG_OPTIONS_H #define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h> #endif /************************************************************************* * * @macro: * FT_CONFIG_MODULES_H * * @description: * A macro used in #include statements to name the file containing the * list of FreeType~2 modules that are statically linked to new library * instances in @FT_Init_FreeType. * */ #ifndef FT_CONFIG_MODULES_H #define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h> #endif /* */ /* public headers */ /************************************************************************* * * @macro: * FT_FREETYPE_H * * @description: * A macro used in #include statements to name the file containing the * base FreeType~2 API. * */ #define FT_FREETYPE_H <freetype/freetype.h> /************************************************************************* * * @macro: * FT_ERRORS_H * * @description: * A macro used in #include statements to name the file containing the * list of FreeType~2 error codes (and messages). * * It is included by @FT_FREETYPE_H. * */ #define FT_ERRORS_H <freetype/fterrors.h> /************************************************************************* * * @macro: * FT_MODULE_ERRORS_H * * @description: * A macro used in #include statements to name the file containing the * list of FreeType~2 module error offsets (and messages). * */ #define FT_MODULE_ERRORS_H <freetype/ftmoderr.h> /************************************************************************* * * @macro: * FT_SYSTEM_H * * @description: * A macro used in #include statements to name the file containing the * FreeType~2 interface to low-level operations (i.e., memory management * and stream i/o). * * It is included by @FT_FREETYPE_H. * */ #define FT_SYSTEM_H <freetype/ftsystem.h> /************************************************************************* * * @macro: * FT_IMAGE_H * * @description: * A macro used in #include statements to name the file containing type * definitions related to glyph images (i.e., bitmaps, outlines, * scan-converter parameters). * * It is included by @FT_FREETYPE_H. * */ #define FT_IMAGE_H <freetype/ftimage.h> /************************************************************************* * * @macro: * FT_TYPES_H * * @description: * A macro used in #include statements to name the file containing the * basic data types defined by FreeType~2. * * It is included by @FT_FREETYPE_H. * */ #define FT_TYPES_H <freetype/fttypes.h> /************************************************************************* * * @macro: * FT_LIST_H * * @description: * A macro used in #include statements to name the file containing the * list management API of FreeType~2. * * (Most applications will never need to include this file.) * */ #define FT_LIST_H <freetype/ftlist.h> /************************************************************************* * * @macro: * FT_OUTLINE_H * * @description: * A macro used in #include statements to name the file containing the * scalable outline management API of FreeType~2. * */ #define FT_OUTLINE_H <freetype/ftoutln.h> /************************************************************************* * * @macro: * FT_SIZES_H * * @description: * A macro used in #include statements to name the file containing the * API which manages multiple @FT_Size objects per face. * */ #define FT_SIZES_H <freetype/ftsizes.h> /************************************************************************* * * @macro: * FT_MODULE_H * * @description: * A macro used in #include statements to name the file containing the * module management API of FreeType~2. * */ #define FT_MODULE_H <freetype/ftmodapi.h> /************************************************************************* * * @macro: * FT_RENDER_H * * @description: * A macro used in #include statements to name the file containing the * renderer module management API of FreeType~2. * */ #define FT_RENDER_H <freetype/ftrender.h> /************************************************************************* * * @macro: * FT_DRIVER_H * * @description: * A macro used in #include statements to name the file containing * structures and macros related to the driver modules. * */ #define FT_DRIVER_H <freetype/ftdriver.h> /************************************************************************* * * @macro: * FT_AUTOHINTER_H * * @description: * A macro used in #include statements to name the file containing * structures and macros related to the auto-hinting module. * * Deprecated since version 2.9; use @FT_DRIVER_H instead. * */ #define FT_AUTOHINTER_H FT_DRIVER_H /************************************************************************* * * @macro: * FT_CFF_DRIVER_H * * @description: * A macro used in #include statements to name the file containing * structures and macros related to the CFF driver module. * * Deprecated since version 2.9; use @FT_DRIVER_H instead. * */ #define FT_CFF_DRIVER_H FT_DRIVER_H /************************************************************************* * * @macro: * FT_TRUETYPE_DRIVER_H * * @description: * A macro used in #include statements to name the file containing * structures and macros related to the TrueType driver module. * * Deprecated since version 2.9; use @FT_DRIVER_H instead. * */ #define FT_TRUETYPE_DRIVER_H FT_DRIVER_H /************************************************************************* * * @macro: * FT_PCF_DRIVER_H * * @description: * A macro used in #include statements to name the file containing * structures and macros related to the PCF driver module. * * Deprecated since version 2.9; use @FT_DRIVER_H instead. * */ #define FT_PCF_DRIVER_H FT_DRIVER_H /************************************************************************* * * @macro: * FT_TYPE1_TABLES_H * * @description: * A macro used in #include statements to name the file containing the * types and API specific to the Type~1 format. * */ #define FT_TYPE1_TABLES_H <freetype/t1tables.h> /************************************************************************* * * @macro: * FT_TRUETYPE_IDS_H * * @description: * A macro used in #include statements to name the file containing the * enumeration values which identify name strings, languages, encodings, * etc. This file really contains a _large_ set of constant macro * definitions, taken from the TrueType and OpenType specifications. * */ #define FT_TRUETYPE_IDS_H <freetype/ttnameid.h> /************************************************************************* * * @macro: * FT_TRUETYPE_TABLES_H * * @description: * A macro used in #include statements to name the file containing the * types and API specific to the TrueType (as well as OpenType) format. * */ #define FT_TRUETYPE_TABLES_H <freetype/tttables.h> /************************************************************************* * * @macro: * FT_TRUETYPE_TAGS_H * * @description: * A macro used in #include statements to name the file containing the * definitions of TrueType four-byte `tags' which identify blocks in * SFNT-based font formats (i.e., TrueType and OpenType). * */ #define FT_TRUETYPE_TAGS_H <freetype/tttags.h> /************************************************************************* * * @macro: * FT_BDF_H * * @description: * A macro used in #include statements to name the file containing the * definitions of an API which accesses BDF-specific strings from a * face. * */ #define FT_BDF_H <freetype/ftbdf.h> /************************************************************************* * * @macro: * FT_CID_H * * @description: * A macro used in #include statements to name the file containing the * definitions of an API which access CID font information from a * face. * */ #define FT_CID_H <freetype/ftcid.h> /************************************************************************* * * @macro: * FT_GZIP_H * * @description: * A macro used in #include statements to name the file containing the * definitions of an API which supports gzip-compressed files. * */ #define FT_GZIP_H <freetype/ftgzip.h> /************************************************************************* * * @macro: * FT_LZW_H * * @description: * A macro used in #include statements to name the file containing the * definitions of an API which supports LZW-compressed files. * */ #define FT_LZW_H <freetype/ftlzw.h> /************************************************************************* * * @macro: * FT_BZIP2_H * * @description: * A macro used in #include statements to name the file containing the * definitions of an API which supports bzip2-compressed files. * */ #define FT_BZIP2_H <freetype/ftbzip2.h> /************************************************************************* * * @macro: * FT_WINFONTS_H * * @description: * A macro used in #include statements to name the file containing the * definitions of an API which supports Windows FNT files. * */ #define FT_WINFONTS_H <freetype/ftwinfnt.h> /************************************************************************* * * @macro: * FT_GLYPH_H * * @description: * A macro used in #include statements to name the file containing the * API of the optional glyph management component. * */ #define FT_GLYPH_H <freetype/ftglyph.h> /************************************************************************* * * @macro: * FT_BITMAP_H * * @description: * A macro used in #include statements to name the file containing the * API of the optional bitmap conversion component. * */ #define FT_BITMAP_H <freetype/ftbitmap.h> /************************************************************************* * * @macro: * FT_BBOX_H * * @description: * A macro used in #include statements to name the file containing the * API of the optional exact bounding box computation routines. * */ #define FT_BBOX_H <freetype/ftbbox.h> /************************************************************************* * * @macro: * FT_CACHE_H * * @description: * A macro used in #include statements to name the file containing the * API of the optional FreeType~2 cache sub-system. * */ #define FT_CACHE_H <freetype/ftcache.h> /************************************************************************* * * @macro: * FT_MAC_H * * @description: * A macro used in #include statements to name the file containing the * Macintosh-specific FreeType~2 API. The latter is used to access * fonts embedded in resource forks. * * This header file must be explicitly included by client applications * compiled on the Mac (note that the base API still works though). * */ #define FT_MAC_H <freetype/ftmac.h> /************************************************************************* * * @macro: * FT_MULTIPLE_MASTERS_H * * @description: * A macro used in #include statements to name the file containing the * optional multiple-masters management API of FreeType~2. * */ #define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h> /************************************************************************* * * @macro: * FT_SFNT_NAMES_H * * @description: * A macro used in #include statements to name the file containing the * optional FreeType~2 API which accesses embedded `name' strings in * SFNT-based font formats (i.e., TrueType and OpenType). * */ #define FT_SFNT_NAMES_H <freetype/ftsnames.h> /************************************************************************* * * @macro: * FT_OPENTYPE_VALIDATE_H * * @description: * A macro used in #include statements to name the file containing the * optional FreeType~2 API which validates OpenType tables (BASE, GDEF, * GPOS, GSUB, JSTF). * */ #define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h> /************************************************************************* * * @macro: * FT_GX_VALIDATE_H * * @description: * A macro used in #include statements to name the file containing the * optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat, * mort, morx, bsln, just, kern, opbd, trak, prop). * */ #define FT_GX_VALIDATE_H <freetype/ftgxval.h> /************************************************************************* * * @macro: * FT_PFR_H * * @description: * A macro used in #include statements to name the file containing the * FreeType~2 API which accesses PFR-specific data. * */ #define FT_PFR_H <freetype/ftpfr.h> /************************************************************************* * * @macro: * FT_STROKER_H * * @description: * A macro used in #include statements to name the file containing the * FreeType~2 API which provides functions to stroke outline paths. */ #define FT_STROKER_H <freetype/ftstroke.h> /************************************************************************* * * @macro: * FT_SYNTHESIS_H * * @description: * A macro used in #include statements to name the file containing the * FreeType~2 API which performs artificial obliquing and emboldening. */ #define FT_SYNTHESIS_H <freetype/ftsynth.h> /************************************************************************* * * @macro: * FT_FONT_FORMATS_H * * @description: * A macro used in #include statements to name the file containing the * FreeType~2 API which provides functions specific to font formats. */ #define FT_FONT_FORMATS_H <freetype/ftfntfmt.h> /* deprecated */ #define FT_XFREE86_H FT_FONT_FORMATS_H /************************************************************************* * * @macro: * FT_TRIGONOMETRY_H * * @description: * A macro used in #include statements to name the file containing the * FreeType~2 API which performs trigonometric computations (e.g., * cosines and arc tangents). */ #define FT_TRIGONOMETRY_H <freetype/fttrigon.h> /************************************************************************* * * @macro: * FT_LCD_FILTER_H * * @description: * A macro used in #include statements to name the file containing the * FreeType~2 API which performs color filtering for subpixel rendering. */ #define FT_LCD_FILTER_H <freetype/ftlcdfil.h> /************************************************************************* * * @macro: * FT_INCREMENTAL_H * * @description: * A macro used in #include statements to name the file containing the * FreeType~2 API which performs incremental glyph loading. */ #define FT_INCREMENTAL_H <freetype/ftincrem.h> /************************************************************************* * * @macro: * FT_GASP_H * * @description: * A macro used in #include statements to name the file containing the * FreeType~2 API which returns entries from the TrueType GASP table. */ #define FT_GASP_H <freetype/ftgasp.h> /************************************************************************* * * @macro: * FT_ADVANCES_H * * @description: * A macro used in #include statements to name the file containing the * FreeType~2 API which returns individual and ranged glyph advances. */ #define FT_ADVANCES_H <freetype/ftadvanc.h> /* */ /* These header files don't need to be included by the user. */ #define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h> #define FT_PARAMETER_TAGS_H <freetype/ftparams.h> /* Deprecated macros. */ #define FT_UNPATENTED_HINTING_H <freetype/ftparams.h> #define FT_TRUETYPE_UNPATENTED_H <freetype/ftparams.h> /* FT_CACHE_H is the only header file needed for the cache subsystem. */ #define FT_CACHE_IMAGE_H FT_CACHE_H #define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H #define FT_CACHE_CHARMAP_H FT_CACHE_H /* The internals of the cache sub-system are no longer exposed. We */ /* default to FT_CACHE_H at the moment just in case, but we know of */ /* no rogue client that uses them. */ /* */ #define FT_CACHE_MANAGER_H FT_CACHE_H #define FT_CACHE_INTERNAL_MRU_H FT_CACHE_H #define FT_CACHE_INTERNAL_MANAGER_H FT_CACHE_H #define FT_CACHE_INTERNAL_CACHE_H FT_CACHE_H #define FT_CACHE_INTERNAL_GLYPH_H FT_CACHE_H #define FT_CACHE_INTERNAL_IMAGE_H FT_CACHE_H #define FT_CACHE_INTERNAL_SBITS_H FT_CACHE_H /* * Include internal headers definitions from <internal/...> * only when building the library. */ #ifdef FT2_BUILD_LIBRARY #define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h> #include FT_INTERNAL_INTERNAL_H #endif /* FT2_BUILD_LIBRARY */ #endif /* FTHEADER_H_ */ /* END */ freetype2/freetype/config/ftmodule.h 0000644 00000002206 15146341150 0013531 0 ustar 00 /* This is a generated file. */ FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class ) FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class ) FT_USE_MODULE( FT_Module_Class, sfnt_module_class ) FT_USE_MODULE( FT_Module_Class, autofit_module_class ) FT_USE_MODULE( FT_Module_Class, pshinter_module_class ) FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class ) FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class ) FT_USE_MODULE( FT_Module_Class, gxv_module_class ) FT_USE_MODULE( FT_Module_Class, otv_module_class ) FT_USE_MODULE( FT_Module_Class, psaux_module_class ) FT_USE_MODULE( FT_Module_Class, psnames_module_class ) /* EOF */ freetype2/freetype/config/ftconfig-64.h 0000644 00000060737 15146341150 0013755 0 ustar 00 /* ftconfig.h. Generated from ftconfig.in by configure. */ /***************************************************************************/ /* */ /* ftconfig.in */ /* */ /* UNIX-specific configuration file (specification only). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This header file contains a number of macro definitions that are used */ /* by the rest of the engine. Most of the macros here are automatically */ /* determined at compile time, and you should not need to change it to */ /* port FreeType, except to compile the library with a non-ANSI */ /* compiler. */ /* */ /* Note however that if some specific modifications are needed, we */ /* advise you to place a modified copy in your build directory. */ /* */ /* The build directory is usually `builds/<system>', and contains */ /* system-specific files that are always included first when building */ /* the library. */ /* */ /*************************************************************************/ #ifndef FTCONFIG_H_ #define FTCONFIG_H_ #include <ft2build.h> #include FT_CONFIG_OPTIONS_H #include FT_CONFIG_STANDARD_LIBRARY_H FT_BEGIN_HEADER /*************************************************************************/ /* */ /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ /* */ /* These macros can be toggled to suit a specific system. The current */ /* ones are defaults used to compile FreeType in an ANSI C environment */ /* (16bit compilers are also supported). Copy this file to your own */ /* `builds/<system>' directory, and edit it to port the engine. */ /* */ /*************************************************************************/ #define HAVE_UNISTD_H 1 #define HAVE_FCNTL_H 1 #define HAVE_STDINT_H 1 /* There are systems (like the Texas Instruments 'C54x) where a `char' */ /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ /* is probably unexpected. */ /* */ /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ /* `char' type. */ #ifndef FT_CHAR_BIT #define FT_CHAR_BIT CHAR_BIT #endif /* #undef FT_USE_AUTOCONF_SIZEOF_TYPES */ #ifdef FT_USE_AUTOCONF_SIZEOF_TYPES #define SIZEOF_INT 4 #define SIZEOF_LONG 8 #define FT_SIZEOF_INT SIZEOF_INT #define FT_SIZEOF_LONG SIZEOF_LONG #else /* !FT_USE_AUTOCONF_SIZEOF_TYPES */ /* Following cpp computation of the bit length of int and long */ /* is copied from default include/freetype/config/ftconfig.h. */ /* If any improvement is required for this file, it should be */ /* applied to the original header file for the builders that */ /* do not use configure script. */ /* The size of an `int' type. */ #if FT_UINT_MAX == 0xFFFFUL #define FT_SIZEOF_INT (16 / FT_CHAR_BIT) #elif FT_UINT_MAX == 0xFFFFFFFFUL #define FT_SIZEOF_INT (32 / FT_CHAR_BIT) #elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL #define FT_SIZEOF_INT (64 / FT_CHAR_BIT) #else #error "Unsupported size of `int' type!" #endif /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ /* DM642) is recognized but avoided. */ #if FT_ULONG_MAX == 0xFFFFFFFFUL #define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) #elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL #define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) #elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL #define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) #else #error "Unsupported size of `long' type!" #endif #endif /* !FT_USE_AUTOCONF_SIZEOF_TYPES */ /* FT_UNUSED is a macro used to indicate that a given parameter is not */ /* used -- this is only used to get rid of unpleasant compiler warnings */ #ifndef FT_UNUSED #define FT_UNUSED( arg ) ( (arg) = (arg) ) #endif /*************************************************************************/ /* */ /* AUTOMATIC CONFIGURATION MACROS */ /* */ /* These macros are computed from the ones defined above. Don't touch */ /* their definition, unless you know precisely what you are doing. No */ /* porter should need to mess with them. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* Mac support */ /* */ /* This is the only necessary change, so it is defined here instead */ /* providing a new configuration file. */ /* */ #if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) ) /* no Carbon frameworks for 64bit 10.4.x */ /* AvailabilityMacros.h is available since Mac OS X 10.2, */ /* so guess the system version by maximum errno before inclusion */ #include <errno.h> #ifdef ECANCELED /* defined since 10.2 */ #include "AvailabilityMacros.h" #endif #if defined( __LP64__ ) && \ ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 ) #undef FT_MACINTOSH #endif #elif defined( __SC__ ) || defined( __MRC__ ) /* Classic MacOS compilers */ #include "ConditionalMacros.h" #if TARGET_OS_MAC #define FT_MACINTOSH 1 #endif #endif /* Fix compiler warning with sgi compiler */ #if defined( __sgi ) && !defined( __GNUC__ ) #if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 ) #pragma set woff 3505 #endif #endif /*************************************************************************/ /* */ /* <Section> */ /* basic_types */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Type> */ /* FT_Int16 */ /* */ /* <Description> */ /* A typedef for a 16bit signed integer type. */ /* */ typedef signed short FT_Int16; /*************************************************************************/ /* */ /* <Type> */ /* FT_UInt16 */ /* */ /* <Description> */ /* A typedef for a 16bit unsigned integer type. */ /* */ typedef unsigned short FT_UInt16; /* */ /* this #if 0 ... #endif clause is for documentation purposes */ #if 0 /*************************************************************************/ /* */ /* <Type> */ /* FT_Int32 */ /* */ /* <Description> */ /* A typedef for a 32bit signed integer type. The size depends on */ /* the configuration. */ /* */ typedef signed XXX FT_Int32; /*************************************************************************/ /* */ /* <Type> */ /* FT_UInt32 */ /* */ /* A typedef for a 32bit unsigned integer type. The size depends on */ /* the configuration. */ /* */ typedef unsigned XXX FT_UInt32; /*************************************************************************/ /* */ /* <Type> */ /* FT_Int64 */ /* */ /* A typedef for a 64bit signed integer type. The size depends on */ /* the configuration. Only defined if there is real 64bit support; */ /* otherwise, it gets emulated with a structure (if necessary). */ /* */ typedef signed XXX FT_Int64; /*************************************************************************/ /* */ /* <Type> */ /* FT_UInt64 */ /* */ /* A typedef for a 64bit unsigned integer type. The size depends on */ /* the configuration. Only defined if there is real 64bit support; */ /* otherwise, it gets emulated with a structure (if necessary). */ /* */ typedef unsigned XXX FT_UInt64; /* */ #endif #if FT_SIZEOF_INT == 4 typedef signed int FT_Int32; typedef unsigned int FT_UInt32; #elif FT_SIZEOF_LONG == 4 typedef signed long FT_Int32; typedef unsigned long FT_UInt32; #else #error "no 32bit type found -- please check your configuration files" #endif /* look up an integer type that is at least 32 bits */ #if FT_SIZEOF_INT >= 4 typedef int FT_Fast; typedef unsigned int FT_UFast; #elif FT_SIZEOF_LONG >= 4 typedef long FT_Fast; typedef unsigned long FT_UFast; #endif /* determine whether we have a 64-bit int type */ /* (mostly for environments without `autoconf') */ #if FT_SIZEOF_LONG == 8 /* FT_LONG64 must be defined if a 64-bit type is available */ #define FT_LONG64 #define FT_INT64 long #define FT_UINT64 unsigned long /* we handle the LLP64 scheme separately for GCC and clang, */ /* suppressing the `long long' warning */ #elif ( FT_SIZEOF_LONG == 4 ) && \ defined( HAVE_LONG_LONG_INT ) && \ defined( __GNUC__ ) #pragma GCC diagnostic ignored "-Wlong-long" #define FT_LONG64 #define FT_INT64 long long int #define FT_UINT64 unsigned long long int /*************************************************************************/ /* */ /* A 64-bit data type may create compilation problems if you compile */ /* in strict ANSI mode. To avoid them, we disable other 64-bit data */ /* types if __STDC__ is defined. You can however ignore this rule */ /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ /* */ #elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) #if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L #define FT_LONG64 #define FT_INT64 long long int #define FT_UINT64 unsigned long long int #elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ /* this compiler provides the __int64 type */ #define FT_LONG64 #define FT_INT64 __int64 #define FT_UINT64 unsigned __int64 #elif defined( __BORLANDC__ ) /* Borland C++ */ /* XXXX: We should probably check the value of __BORLANDC__ in order */ /* to test the compiler version. */ /* this compiler provides the __int64 type */ #define FT_LONG64 #define FT_INT64 __int64 #define FT_UINT64 unsigned __int64 #elif defined( __WATCOMC__ ) /* Watcom C++ */ /* Watcom doesn't provide 64-bit data types */ #elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ #define FT_LONG64 #define FT_INT64 long long int #define FT_UINT64 unsigned long long int #elif defined( __GNUC__ ) /* GCC provides the `long long' type */ #define FT_LONG64 #define FT_INT64 long long int #define FT_UINT64 unsigned long long int #endif /* __STDC_VERSION__ >= 199901L */ #endif /* FT_SIZEOF_LONG == 8 */ #ifdef FT_LONG64 typedef FT_INT64 FT_Int64; typedef FT_UINT64 FT_UInt64; #endif #ifdef _WIN64 /* only 64bit Windows uses the LLP64 data model, i.e., */ /* 32bit integers, 64bit pointers */ #define FT_UINT_TO_POINTER( x ) (void*)(unsigned __int64)(x) #else #define FT_UINT_TO_POINTER( x ) (void*)(unsigned long)(x) #endif /*************************************************************************/ /* */ /* miscellaneous */ /* */ /*************************************************************************/ #define FT_BEGIN_STMNT do { #define FT_END_STMNT } while ( 0 ) #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT /* typeof condition taken from gnulib's `intprops.h' header file */ #if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 ) || \ ( defined( __IBMC__ ) && __IBMC__ >= 1210 && \ defined( __IBM__TYPEOF__ ) ) || \ ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) ) #define FT_TYPEOF( type ) ( __typeof__ ( type ) ) #else #define FT_TYPEOF( type ) /* empty */ #endif /* Use FT_LOCAL and FT_LOCAL_DEF to declare and define, respectively, */ /* a function that gets used only within the scope of a module. */ /* Normally, both the header and source code files for such a */ /* function are within a single module directory. */ /* */ /* Intra-module arrays should be tagged with FT_LOCAL_ARRAY and */ /* FT_LOCAL_ARRAY_DEF. */ /* */ #ifdef FT_MAKE_OPTION_SINGLE_OBJECT #define FT_LOCAL( x ) static x #define FT_LOCAL_DEF( x ) static x #else #ifdef __cplusplus #define FT_LOCAL( x ) extern "C" x #define FT_LOCAL_DEF( x ) extern "C" x #else #define FT_LOCAL( x ) extern x #define FT_LOCAL_DEF( x ) x #endif #endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ #define FT_LOCAL_ARRAY( x ) extern const x #define FT_LOCAL_ARRAY_DEF( x ) const x /* Use FT_BASE and FT_BASE_DEF to declare and define, respectively, */ /* functions that are used in more than a single module. In the */ /* current setup this implies that the declaration is in a header */ /* file in the `include/freetype/internal' directory, and the */ /* function body is in a file in `src/base'. */ /* */ #ifndef FT_BASE #ifdef __cplusplus #define FT_BASE( x ) extern "C" x #else #define FT_BASE( x ) extern x #endif #endif /* !FT_BASE */ #ifndef FT_BASE_DEF #ifdef __cplusplus #define FT_BASE_DEF( x ) x #else #define FT_BASE_DEF( x ) x #endif #endif /* !FT_BASE_DEF */ /* When compiling FreeType as a DLL or DSO with hidden visibility */ /* some systems/compilers need a special attribute in front OR after */ /* the return type of function declarations. */ /* */ /* Two macros are used within the FreeType source code to define */ /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ /* */ /* FT_EXPORT( return_type ) */ /* */ /* is used in a function declaration, as in */ /* */ /* FT_EXPORT( FT_Error ) */ /* FT_Init_FreeType( FT_Library* alibrary ); */ /* */ /* */ /* FT_EXPORT_DEF( return_type ) */ /* */ /* is used in a function definition, as in */ /* */ /* FT_EXPORT_DEF( FT_Error ) */ /* FT_Init_FreeType( FT_Library* alibrary ) */ /* { */ /* ... some code ... */ /* return FT_Err_Ok; */ /* } */ /* */ /* You can provide your own implementation of FT_EXPORT and */ /* FT_EXPORT_DEF here if you want. */ /* */ /* To export a variable, use FT_EXPORT_VAR. */ /* */ #ifndef FT_EXPORT #ifdef FT2_BUILD_LIBRARY #if defined( _WIN32 ) && ( defined( _DLL ) || defined( DLL_EXPORT ) ) #define FT_EXPORT( x ) __declspec( dllexport ) x #elif defined( __GNUC__ ) && __GNUC__ >= 4 #define FT_EXPORT( x ) __attribute__(( visibility( "default" ) )) x #elif defined( __cplusplus ) #define FT_EXPORT( x ) extern "C" x #else #define FT_EXPORT( x ) extern x #endif #else #if defined( FT2_DLLIMPORT ) #define FT_EXPORT( x ) __declspec( dllimport ) x #elif defined( __cplusplus ) #define FT_EXPORT( x ) extern "C" x #else #define FT_EXPORT( x ) extern x #endif #endif #endif /* !FT_EXPORT */ #ifndef FT_EXPORT_DEF #ifdef __cplusplus #define FT_EXPORT_DEF( x ) extern "C" x #else #define FT_EXPORT_DEF( x ) extern x #endif #endif /* !FT_EXPORT_DEF */ #ifndef FT_EXPORT_VAR #ifdef __cplusplus #define FT_EXPORT_VAR( x ) extern "C" x #else #define FT_EXPORT_VAR( x ) extern x #endif #endif /* !FT_EXPORT_VAR */ /* The following macros are needed to compile the library with a */ /* C++ compiler and with 16bit compilers. */ /* */ /* This is special. Within C++, you must specify `extern "C"' for */ /* functions which are used via function pointers, and you also */ /* must do that for structures which contain function pointers to */ /* assure C linkage -- it's not possible to have (local) anonymous */ /* functions which are accessed by (global) function pointers. */ /* */ /* */ /* FT_CALLBACK_DEF is used to _define_ a callback function, */ /* located in the same source code file as the structure that uses */ /* it. */ /* */ /* FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare */ /* and define a callback function, respectively, in a similar way */ /* as FT_BASE and FT_BASE_DEF work. */ /* */ /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ /* contains pointers to callback functions. */ /* */ /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ /* that contains pointers to callback functions. */ /* */ /* */ /* Some 16bit compilers have to redefine these macros to insert */ /* the infamous `_cdecl' or `__fastcall' declarations. */ /* */ #ifndef FT_CALLBACK_DEF #ifdef __cplusplus #define FT_CALLBACK_DEF( x ) extern "C" x #else #define FT_CALLBACK_DEF( x ) static x #endif #endif /* FT_CALLBACK_DEF */ #ifndef FT_BASE_CALLBACK #ifdef __cplusplus #define FT_BASE_CALLBACK( x ) extern "C" x #define FT_BASE_CALLBACK_DEF( x ) extern "C" x #else #define FT_BASE_CALLBACK( x ) extern x #define FT_BASE_CALLBACK_DEF( x ) x #endif #endif /* FT_BASE_CALLBACK */ #ifndef FT_CALLBACK_TABLE #ifdef __cplusplus #define FT_CALLBACK_TABLE extern "C" #define FT_CALLBACK_TABLE_DEF extern "C" #else #define FT_CALLBACK_TABLE extern #define FT_CALLBACK_TABLE_DEF /* nothing */ #endif #endif /* FT_CALLBACK_TABLE */ FT_END_HEADER #endif /* FTCONFIG_H_ */ /* END */ freetype2/freetype/config/ftstdlib.h 0000644 00000016200 15146341150 0013524 0 ustar 00 /***************************************************************************/ /* */ /* ftstdlib.h */ /* */ /* ANSI-specific library and header configuration file (specification */ /* only). */ /* */ /* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This file is used to group all #includes to the ANSI C library that */ /* FreeType normally requires. It also defines macros to rename the */ /* standard functions within the FreeType source code. */ /* */ /* Load a file which defines FTSTDLIB_H_ before this one to override it. */ /* */ /*************************************************************************/ #ifndef FTSTDLIB_H_ #define FTSTDLIB_H_ #include <stddef.h> #define ft_ptrdiff_t ptrdiff_t /**********************************************************************/ /* */ /* integer limits */ /* */ /* UINT_MAX and ULONG_MAX are used to automatically compute the size */ /* of `int' and `long' in bytes at compile-time. So far, this works */ /* for all platforms the library has been tested on. */ /* */ /* Note that on the extremely rare platforms that do not provide */ /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some */ /* old Crays where `int' is 36 bits), we do not make any guarantee */ /* about the correct behaviour of FT2 with all fonts. */ /* */ /* In these case, `ftconfig.h' will refuse to compile anyway with a */ /* message like `couldn't find 32-bit type' or something similar. */ /* */ /**********************************************************************/ #include <limits.h> #define FT_CHAR_BIT CHAR_BIT #define FT_USHORT_MAX USHRT_MAX #define FT_INT_MAX INT_MAX #define FT_INT_MIN INT_MIN #define FT_UINT_MAX UINT_MAX #define FT_LONG_MIN LONG_MIN #define FT_LONG_MAX LONG_MAX #define FT_ULONG_MAX ULONG_MAX /**********************************************************************/ /* */ /* character and string processing */ /* */ /**********************************************************************/ #include <string.h> #define ft_memchr memchr #define ft_memcmp memcmp #define ft_memcpy memcpy #define ft_memmove memmove #define ft_memset memset #define ft_strcat strcat #define ft_strcmp strcmp #define ft_strcpy strcpy #define ft_strlen strlen #define ft_strncmp strncmp #define ft_strncpy strncpy #define ft_strrchr strrchr #define ft_strstr strstr /**********************************************************************/ /* */ /* file handling */ /* */ /**********************************************************************/ #include <stdio.h> #define FT_FILE FILE #define ft_fclose fclose #define ft_fopen fopen #define ft_fread fread #define ft_fseek fseek #define ft_ftell ftell #define ft_sprintf sprintf /**********************************************************************/ /* */ /* sorting */ /* */ /**********************************************************************/ #include <stdlib.h> #define ft_qsort qsort /**********************************************************************/ /* */ /* memory allocation */ /* */ /**********************************************************************/ #define ft_scalloc calloc #define ft_sfree free #define ft_smalloc malloc #define ft_srealloc realloc /**********************************************************************/ /* */ /* miscellaneous */ /* */ /**********************************************************************/ #define ft_strtol strtol #define ft_getenv getenv /**********************************************************************/ /* */ /* execution control */ /* */ /**********************************************************************/ #include <setjmp.h> #define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ /* jmp_buf is defined as a macro */ /* on certain platforms */ #define ft_longjmp longjmp #define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */ /* the following is only used for debugging purposes, i.e., if */ /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined */ #include <stdarg.h> #endif /* FTSTDLIB_H_ */ /* END */ freetype2/freetype/config/ftoption.h 0000644 00000170066 15146341150 0013566 0 ustar 00 /***************************************************************************/ /* */ /* ftoption.h */ /* */ /* User-selectable configuration macros (specification only). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTOPTION_H_ #define FTOPTION_H_ #include <ft2build.h> FT_BEGIN_HEADER /*************************************************************************/ /* */ /* USER-SELECTABLE CONFIGURATION MACROS */ /* */ /* This file contains the default configuration macro definitions for */ /* a standard build of the FreeType library. There are three ways to */ /* use this file to build project-specific versions of the library: */ /* */ /* - You can modify this file by hand, but this is not recommended in */ /* cases where you would like to build several versions of the */ /* library from a single source directory. */ /* */ /* - You can put a copy of this file in your build directory, more */ /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ /* is the name of a directory that is included _before_ the FreeType */ /* include path during compilation. */ /* */ /* The default FreeType Makefiles and Jamfiles use the build */ /* directory `builds/<system>' by default, but you can easily change */ /* that for your own projects. */ /* */ /* - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it */ /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ /* locate this file during the build. For example, */ /* */ /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ /* #include <freetype/config/ftheader.h> */ /* */ /* will use `$BUILD/myftoptions.h' instead of this file for macro */ /* definitions. */ /* */ /* Note also that you can similarly pre-define the macro */ /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ /* that are statically linked to the library at compile time. By */ /* default, this file is <freetype/config/ftmodule.h>. */ /* */ /* We highly recommend using the third method whenever possible. */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*#***********************************************************************/ /* */ /* If you enable this configuration option, FreeType recognizes an */ /* environment variable called `FREETYPE_PROPERTIES', which can be used */ /* to control the various font drivers and modules. The controllable */ /* properties are listed in the section @properties. */ /* */ /* You have to undefine this configuration option on platforms that lack */ /* the concept of environment variables (and thus don't have the */ /* `getenv' function), for example Windows CE. */ /* */ /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */ /* multiple lines for better readability). */ /* */ /* { */ /* <optional whitespace> */ /* <module-name1> ':' */ /* <property-name1> '=' <property-value1> */ /* <whitespace> */ /* <module-name2> ':' */ /* <property-name2> '=' <property-value2> */ /* ... */ /* } */ /* */ /* Example: */ /* */ /* FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ */ /* cff:no-stem-darkening=1 \ */ /* autofitter:warping=1 */ /* */ #define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES /*************************************************************************/ /* */ /* Uncomment the line below if you want to activate LCD rendering */ /* technology similar to ClearType in this build of the library. This */ /* technology triples the resolution in the direction color subpixels. */ /* To mitigate color fringes inherent to this technology, you also need */ /* to explicitly set up LCD filtering. */ /* */ /* Note that this feature is covered by several Microsoft patents */ /* and should not be activated in any default build of the library. */ /* When this macro is not defined, FreeType offers alternative LCD */ /* rendering technology that produces excellent output without LCD */ /* filtering. */ /* */ #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING /*************************************************************************/ /* */ /* Many compilers provide a non-ANSI 64-bit data type that can be used */ /* by FreeType to speed up some computations. However, this will create */ /* some problems when compiling the library in strict ANSI mode. */ /* */ /* For this reason, the use of 64-bit integers is normally disabled when */ /* the __STDC__ macro is defined. You can however disable this by */ /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ /* */ /* For most compilers, this will only create compilation warnings when */ /* building the library. */ /* */ /* ObNote: The compiler-specific 64-bit integers are detected in the */ /* file `ftconfig.h' either statically or through the */ /* `configure' script on supported platforms. */ /* */ #undef FT_CONFIG_OPTION_FORCE_INT64 /*************************************************************************/ /* */ /* If this macro is defined, do not try to use an assembler version of */ /* performance-critical functions (e.g. FT_MulFix). You should only do */ /* that to verify that the assembler function works properly, or to */ /* execute benchmark tests of the various implementations. */ /* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ /*************************************************************************/ /* */ /* If this macro is defined, try to use an inlined assembler version of */ /* the `FT_MulFix' function, which is a `hotspot' when loading and */ /* hinting glyphs, and which should be executed as fast as possible. */ /* */ /* Note that if your compiler or CPU is not supported, this will default */ /* to the standard and portable implementation found in `ftcalc.c'. */ /* */ #define FT_CONFIG_OPTION_INLINE_MULFIX /*************************************************************************/ /* */ /* LZW-compressed file support. */ /* */ /* FreeType now handles font files that have been compressed with the */ /* `compress' program. This is mostly used to parse many of the PCF */ /* files that come with various X11 distributions. The implementation */ /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ /* (see src/lzw/ftgzip.c). */ /* */ /* Define this macro if you want to enable this `feature'. */ /* */ #define FT_CONFIG_OPTION_USE_LZW /*************************************************************************/ /* */ /* Gzip-compressed file support. */ /* */ /* FreeType now handles font files that have been compressed with the */ /* `gzip' program. This is mostly used to parse many of the PCF files */ /* that come with XFree86. The implementation uses `zlib' to */ /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ /* */ /* Define this macro if you want to enable this `feature'. See also */ /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ /* */ #define FT_CONFIG_OPTION_USE_ZLIB /*************************************************************************/ /* */ /* ZLib library selection */ /* */ /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ /* It allows FreeType's `ftgzip' component to link to the system's */ /* installation of the ZLib library. This is useful on systems like */ /* Unix or VMS where it generally is already available. */ /* */ /* If you let it undefined, the component will use its own copy */ /* of the zlib sources instead. These have been modified to be */ /* included directly within the component and *not* export external */ /* function names. This allows you to link any program with FreeType */ /* _and_ ZLib without linking conflicts. */ /* */ /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ /* If you use a build system like cmake or the `configure' script, */ /* options set by those programs have precendence, overwriting the */ /* value here with the configured one. */ /* */ #define FT_CONFIG_OPTION_SYSTEM_ZLIB /*************************************************************************/ /* */ /* Bzip2-compressed file support. */ /* */ /* FreeType now handles font files that have been compressed with the */ /* `bzip2' program. This is mostly used to parse many of the PCF */ /* files that come with XFree86. The implementation uses `libbz2' to */ /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ /* Contrary to gzip, bzip2 currently is not included and need to use */ /* the system available bzip2 implementation. */ /* */ /* Define this macro if you want to enable this `feature'. */ /* */ /* If you use a build system like cmake or the `configure' script, */ /* options set by those programs have precendence, overwriting the */ /* value here with the configured one. */ /* */ #define FT_CONFIG_OPTION_USE_BZIP2 /*************************************************************************/ /* */ /* Define to disable the use of file stream functions and types, FILE, */ /* fopen() etc. Enables the use of smaller system libraries on embedded */ /* systems that have multiple system libraries, some with or without */ /* file stream support, in the cases where file stream support is not */ /* necessary such as memory loading of font files. */ /* */ /* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ /*************************************************************************/ /* */ /* PNG bitmap support. */ /* */ /* FreeType now handles loading color bitmap glyphs in the PNG format. */ /* This requires help from the external libpng library. Uncompressed */ /* color bitmaps do not need any external libraries and will be */ /* supported regardless of this configuration. */ /* */ /* Define this macro if you want to enable this `feature'. */ /* */ /* If you use a build system like cmake or the `configure' script, */ /* options set by those programs have precendence, overwriting the */ /* value here with the configured one. */ /* */ #define FT_CONFIG_OPTION_USE_PNG /*************************************************************************/ /* */ /* HarfBuzz support. */ /* */ /* FreeType uses the HarfBuzz library to improve auto-hinting of */ /* OpenType fonts. If available, many glyphs not directly addressable */ /* by a font's character map will be hinted also. */ /* */ /* Define this macro if you want to enable this `feature'. */ /* */ /* If you use a build system like cmake or the `configure' script, */ /* options set by those programs have precendence, overwriting the */ /* value here with the configured one. */ /* */ /* #undef FT_CONFIG_OPTION_USE_HARFBUZZ */ /*************************************************************************/ /* */ /* Glyph Postscript Names handling */ /* */ /* By default, FreeType 2 is compiled with the `psnames' module. This */ /* module is in charge of converting a glyph name string into a */ /* Unicode value, or return a Macintosh standard glyph name for the */ /* use with the TrueType `post' table. */ /* */ /* Undefine this macro if you do not want `psnames' compiled in your */ /* build of FreeType. This has the following effects: */ /* */ /* - The TrueType driver will provide its own set of glyph names, */ /* if you build it to support postscript names in the TrueType */ /* `post' table, but will not synthesize a missing Unicode charmap. */ /* */ /* - The Type 1 driver will not be able to synthesize a Unicode */ /* charmap out of the glyphs found in the fonts. */ /* */ /* You would normally undefine this configuration macro when building */ /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ /* */ #define FT_CONFIG_OPTION_POSTSCRIPT_NAMES /*************************************************************************/ /* */ /* Postscript Names to Unicode Values support */ /* */ /* By default, FreeType 2 is built with the `PSNames' module compiled */ /* in. Among other things, the module is used to convert a glyph name */ /* into a Unicode value. This is especially useful in order to */ /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ /* through a big table named the `Adobe Glyph List' (AGL). */ /* */ /* Undefine this macro if you do not want the Adobe Glyph List */ /* compiled in your `PSNames' module. The Type 1 driver will not be */ /* able to synthesize a Unicode charmap out of the glyphs found in the */ /* fonts. */ /* */ #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST /*************************************************************************/ /* */ /* Support for Mac fonts */ /* */ /* Define this macro if you want support for outline fonts in Mac */ /* format (mac dfont, mac resource, macbinary containing a mac */ /* resource) on non-Mac platforms. */ /* */ /* Note that the `FOND' resource isn't checked. */ /* */ #define FT_CONFIG_OPTION_MAC_FONTS /*************************************************************************/ /* */ /* Guessing methods to access embedded resource forks */ /* */ /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ /* GNU/Linux). */ /* */ /* Resource forks which include fonts data are stored sometimes in */ /* locations which users or developers don't expected. In some cases, */ /* resource forks start with some offset from the head of a file. In */ /* other cases, the actual resource fork is stored in file different */ /* from what the user specifies. If this option is activated, */ /* FreeType tries to guess whether such offsets or different file */ /* names must be used. */ /* */ /* Note that normal, direct access of resource forks is controlled via */ /* the FT_CONFIG_OPTION_MAC_FONTS option. */ /* */ #ifdef FT_CONFIG_OPTION_MAC_FONTS #define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK #endif /*************************************************************************/ /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ /* contain no glyph data, but supply it via a callback function. */ /* This is required by clients supporting document formats which */ /* supply font data incrementally as the document is parsed, such */ /* as the Ghostscript interpreter for the PostScript language. */ /* */ #define FT_CONFIG_OPTION_INCREMENTAL /*************************************************************************/ /* */ /* The size in bytes of the render pool used by the scan-line converter */ /* to do all of its work. */ /* */ #define FT_RENDER_POOL_SIZE 16384L /*************************************************************************/ /* */ /* FT_MAX_MODULES */ /* */ /* The maximum number of modules that can be registered in a single */ /* FreeType library object. 32 is the default. */ /* */ #define FT_MAX_MODULES 32 /*************************************************************************/ /* */ /* Debug level */ /* */ /* FreeType can be compiled in debug or trace mode. In debug mode, */ /* errors are reported through the `ftdebug' component. In trace */ /* mode, additional messages are sent to the standard output during */ /* execution. */ /* */ /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ /* */ /* Don't define any of these macros to compile in `release' mode! */ /* */ /* Do not #undef these macros here since the build system might define */ /* them for certain configurations only. */ /* */ /* #define FT_DEBUG_LEVEL_ERROR */ /* #define FT_DEBUG_LEVEL_TRACE */ /*************************************************************************/ /* */ /* Autofitter debugging */ /* */ /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ /* control the autofitter behaviour for debugging purposes with global */ /* boolean variables (consequently, you should *never* enable this */ /* while compiling in `release' mode): */ /* */ /* _af_debug_disable_horz_hints */ /* _af_debug_disable_vert_hints */ /* _af_debug_disable_blue_hints */ /* */ /* Additionally, the following functions provide dumps of various */ /* internal autofit structures to stdout (using `printf'): */ /* */ /* af_glyph_hints_dump_points */ /* af_glyph_hints_dump_segments */ /* af_glyph_hints_dump_edges */ /* af_glyph_hints_get_num_segments */ /* af_glyph_hints_get_segment_offset */ /* */ /* As an argument, they use another global variable: */ /* */ /* _af_debug_hints */ /* */ /* Please have a look at the `ftgrid' demo program to see how those */ /* variables and macros should be used. */ /* */ /* Do not #undef these macros here since the build system might define */ /* them for certain configurations only. */ /* */ /* #define FT_DEBUG_AUTOFIT */ /*************************************************************************/ /* */ /* Memory Debugging */ /* */ /* FreeType now comes with an integrated memory debugger that is */ /* capable of detecting simple errors like memory leaks or double */ /* deletes. To compile it within your build of the library, you */ /* should define FT_DEBUG_MEMORY here. */ /* */ /* Note that the memory debugger is only activated at runtime when */ /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ /* */ /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ /* #define FT_DEBUG_MEMORY */ /*************************************************************************/ /* */ /* Module errors */ /* */ /* If this macro is set (which is _not_ the default), the higher byte */ /* of an error code gives the module in which the error has occurred, */ /* while the lower byte is the real error code. */ /* */ /* Setting this macro makes sense for debugging purposes only, since */ /* it would break source compatibility of certain programs that use */ /* FreeType 2. */ /* */ /* More details can be found in the files ftmoderr.h and fterrors.h. */ /* */ #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS /*************************************************************************/ /* */ /* Position Independent Code */ /* */ /* If this macro is set (which is _not_ the default), FreeType2 will */ /* avoid creating constants that require address fixups. Instead the */ /* constants will be moved into a struct and additional intialization */ /* code will be used. */ /* */ /* Setting this macro is needed for systems that prohibit address */ /* fixups, such as BREW. [Note that standard compilers like gcc or */ /* clang handle PIC generation automatically; you don't have to set */ /* FT_CONFIG_OPTION_PIC, which is only necessary for very special */ /* compilers.] */ /* */ /* Note that FT_CONFIG_OPTION_PIC support is not available for all */ /* modules (see `modules.cfg' for a complete list). For building with */ /* FT_CONFIG_OPTION_PIC support, do the following. */ /* */ /* 0. Clone the repository. */ /* 1. Define FT_CONFIG_OPTION_PIC. */ /* 2. Remove all subdirectories in `src' that don't have */ /* FT_CONFIG_OPTION_PIC support. */ /* 3. Comment out the corresponding modules in `modules.cfg'. */ /* 4. Compile. */ /* */ /* #define FT_CONFIG_OPTION_PIC */ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ /* embedded bitmaps in all formats using the SFNT module (namely */ /* TrueType & OpenType). */ /* */ #define TT_CONFIG_OPTION_EMBEDDED_BITMAPS /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ /* load and enumerate the glyph Postscript names in a TrueType or */ /* OpenType file. */ /* */ /* Note that when you do not compile the `PSNames' module by undefining */ /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ /* contain additional code used to read the PS Names table from a font. */ /* */ /* (By default, the module uses `PSNames' to extract glyph names.) */ /* */ #define TT_CONFIG_OPTION_POSTSCRIPT_NAMES /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ /* access the internal name table in a SFNT-based format like TrueType */ /* or OpenType. The name table contains various strings used to */ /* describe the font, like family name, copyright, version, etc. It */ /* does not contain any glyph name though. */ /* */ /* Accessing SFNT names is done through the functions declared in */ /* `ftsnames.h'. */ /* */ #define TT_CONFIG_OPTION_SFNT_NAMES /*************************************************************************/ /* */ /* TrueType CMap support */ /* */ /* Here you can fine-tune which TrueType CMap table format shall be */ /* supported. */ #define TT_CONFIG_CMAP_FORMAT_0 #define TT_CONFIG_CMAP_FORMAT_2 #define TT_CONFIG_CMAP_FORMAT_4 #define TT_CONFIG_CMAP_FORMAT_6 #define TT_CONFIG_CMAP_FORMAT_8 #define TT_CONFIG_CMAP_FORMAT_10 #define TT_CONFIG_CMAP_FORMAT_12 #define TT_CONFIG_CMAP_FORMAT_13 #define TT_CONFIG_CMAP_FORMAT_14 /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ /* a bytecode interpreter in the TrueType driver. */ /* */ /* By undefining this, you will only compile the code necessary to load */ /* TrueType glyphs without hinting. */ /* */ /* Do not #undef this macro here, since the build system might */ /* define it for certain configurations only. */ /* */ #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ /* subpixel hinting support into the TrueType driver. This modifies the */ /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */ /* requested. */ /* */ /* In particular, it modifies the bytecode interpreter to interpret (or */ /* not) instructions in a certain way so that all TrueType fonts look */ /* like they do in a Windows ClearType (DirectWrite) environment. See */ /* [1] for a technical overview on what this means. See `ttinterp.h' */ /* for more details on the LEAN option. */ /* */ /* There are three possible values. */ /* */ /* Value 1: */ /* This value is associated with the `Infinality' moniker, */ /* contributed by an individual nicknamed Infinality with the goal of */ /* making TrueType fonts render better than on Windows. A high */ /* amount of configurability and flexibility, down to rules for */ /* single glyphs in fonts, but also very slow. Its experimental and */ /* slow nature and the original developer losing interest meant that */ /* this option was never enabled in default builds. */ /* */ /* The corresponding interpreter version is v38. */ /* */ /* Value 2: */ /* The new default mode for the TrueType driver. The Infinality code */ /* base was stripped to the bare minimum and all configurability */ /* removed in the name of speed and simplicity. The configurability */ /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */ /* Courier. Legacy fonts are fonts that modify vertical stems to */ /* achieve clean black-and-white bitmaps. The new mode focuses on */ /* applying a minimal set of rules to all fonts indiscriminately so */ /* that modern and web fonts render well while legacy fonts render */ /* okay. */ /* */ /* The corresponding interpreter version is v40. */ /* */ /* Value 3: */ /* Compile both, making both v38 and v40 available (the latter is the */ /* default). */ /* */ /* By undefining these, you get rendering behavior like on Windows */ /* without ClearType, i.e., Windows XP without ClearType enabled and */ /* Win9x (interpreter version v35). Or not, depending on how much */ /* hinting blood and testing tears the font designer put into a given */ /* font. If you define one or both subpixel hinting options, you can */ /* switch between between v35 and the ones you define (using */ /* `FT_Property_Set'). */ /* */ /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ /* defined. */ /* */ /* [1] https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ /* */ /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 /* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ /* TrueType glyph loader to use Apple's definition of how to handle */ /* component offsets in composite glyphs. */ /* */ /* Apple and MS disagree on the default behavior of component offsets */ /* in composites. Apple says that they should be scaled by the scaling */ /* factors in the transformation matrix (roughly, it's more complex) */ /* while MS says they should not. OpenType defines two bits in the */ /* composite flags array which can be used to disambiguate, but old */ /* fonts will not have them. */ /* */ /* https://www.microsoft.com/typography/otspec/glyf.htm */ /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */ /* */ #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ /* support for Apple's distortable font technology (fvar, gvar, cvar, */ /* and avar tables). This has many similarities to Type 1 Multiple */ /* Masters support. */ /* */ #define TT_CONFIG_OPTION_GX_VAR_SUPPORT /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ /* an embedded `BDF ' table within SFNT-based bitmap formats. */ /* */ #define TT_CONFIG_OPTION_BDF /*************************************************************************/ /* */ /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum */ /* number of bytecode instructions executed for a single run of the */ /* bytecode interpreter, needed to prevent infinite loops. You don't */ /* want to change this except for very special situations (e.g., making */ /* a library fuzzer spend less time to handle broken fonts). */ /* */ /* It is not expected that this value is ever modified by a configuring */ /* script; instead, it gets surrounded with #ifndef ... #endif so that */ /* the value can be set as a preprocessor option on the compiler's */ /* command line. */ /* */ #ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES #define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L #endif /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and */ /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ /* required. */ /* */ #define T1_MAX_DICT_DEPTH 5 /*************************************************************************/ /* */ /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ /* calls during glyph loading. */ /* */ #define T1_MAX_SUBRS_CALLS 16 /*************************************************************************/ /* */ /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ /* minimum of 16 is required. */ /* */ /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ /* */ #define T1_MAX_CHARSTRINGS_OPERANDS 256 /*************************************************************************/ /* */ /* Define this configuration macro if you want to prevent the */ /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ /* files into an existing face. Note that if set, the T1 driver will be */ /* unable to produce kerning distances. */ /* */ #undef T1_CONFIG_OPTION_NO_AFM /*************************************************************************/ /* */ /* Define this configuration macro if you want to prevent the */ /* compilation of the Multiple Masters font support in the Type 1 */ /* driver. */ /* */ #undef T1_CONFIG_OPTION_NO_MM_SUPPORT /*************************************************************************/ /* */ /* T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1 */ /* engine gets compiled into FreeType. If defined, it is possible to */ /* switch between the two engines using the `hinting-engine' property of */ /* the type1 driver module. */ /* */ /* #define T1_CONFIG_OPTION_OLD_ENGINE */ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** C F F D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is */ /* possible to set up the default values of the four control points that */ /* define the stem darkening behaviour of the (new) CFF engine. For */ /* more details please read the documentation of the */ /* `darkening-parameters' property (file `ftdriver.h'), which allows the */ /* control at run-time. */ /* */ /* Do *not* undefine these macros! */ /* */ #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333 #define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0 /*************************************************************************/ /* */ /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF */ /* engine gets compiled into FreeType. If defined, it is possible to */ /* switch between the two engines using the `hinting-engine' property of */ /* the cff driver module. */ /* */ /* #define CFF_CONFIG_OPTION_OLD_ENGINE */ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** P C F D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* There are many PCF fonts just called `Fixed' which look completely */ /* different, and which have nothing to do with each other. When */ /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */ /* random, the style changes often if one changes the size and one */ /* cannot select some fonts at all. This option makes the PCF module */ /* prepend the foundry name (plus a space) to the family name. */ /* */ /* We also check whether we have `wide' characters; all put together, we */ /* get family names like `Sony Fixed' or `Misc Fixed Wide'. */ /* */ /* If this option is activated, it can be controlled with the */ /* `no-long-family-names' property of the pcf driver module. */ /* */ /* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ /* support. */ /* */ #define AF_CONFIG_OPTION_CJK /*************************************************************************/ /* */ /* Compile autofit module with fallback Indic script support, covering */ /* some scripts that the `latin' submodule of the autofit module doesn't */ /* (yet) handle. */ /* */ #define AF_CONFIG_OPTION_INDIC /*************************************************************************/ /* */ /* Compile autofit module with warp hinting. The idea of the warping */ /* code is to slightly scale and shift a glyph within a single dimension */ /* so that as much of its segments are aligned (more or less) on the */ /* grid. To find out the optimal scaling and shifting value, various */ /* parameter combinations are tried and scored. */ /* */ /* This experimental option is active only if the rendering mode is */ /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the */ /* `warping' property of the auto-hinter (see file `ftdriver.h' for more */ /* information; by default it is switched off). */ /* */ #define AF_CONFIG_OPTION_USE_WARPER /*************************************************************************/ /* */ /* Use TrueType-like size metrics for `light' auto-hinting. */ /* */ /* It is strongly recommended to avoid this option, which exists only to */ /* help some legacy applications retain its appearance and behaviour */ /* with respect to auto-hinted TrueType fonts. */ /* */ /* The very reason this option exists at all are GNU/Linux distributions */ /* like Fedora that did not un-patch the following change (which was */ /* present in FreeType between versions 2.4.6 and 2.7.1, inclusive). */ /* */ /* 2011-07-16 Steven Chu <steven.f.chu@gmail.com> */ /* */ /* [truetype] Fix metrics on size request for scalable fonts. */ /* */ /* This problematic commit is now reverted (more or less). */ /* */ /* #define AF_CONFIG_OPTION_TT_SIZE_METRICS */ /* */ /* * This macro is obsolete. Support has been removed in FreeType * version 2.5. */ /* #define FT_CONFIG_OPTION_OLD_INTERNALS */ /* * This macro is defined if native TrueType hinting is requested by the * definitions above. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING #if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1 #define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY #endif #if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2 #define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL #endif #endif #endif /* * Check CFF darkening parameters. The checks are the same as in function * `cff_property_set' in file `cffdrivr.c'. */ #if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0 || \ \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0 || \ \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 > \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 > \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 > \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 || \ \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500 #error "Invalid CFF darkening parameters!" #endif FT_END_HEADER #endif /* FTOPTION_H_ */ /* END */ freetype2/freetype/ftbitmap.h 0000644 00000034550 15146341150 0012262 0 ustar 00 /***************************************************************************/ /* */ /* ftbitmap.h */ /* */ /* FreeType utility functions for bitmaps (specification). */ /* */ /* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTBITMAP_H_ #define FTBITMAP_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* bitmap_handling */ /* */ /* <Title> */ /* Bitmap Handling */ /* */ /* <Abstract> */ /* Handling FT_Bitmap objects. */ /* */ /* <Description> */ /* This section contains functions for handling @FT_Bitmap objects. */ /* Note that none of the functions changes the bitmap's `flow' (as */ /* indicated by the sign of the `pitch' field in `FT_Bitmap'). */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_Bitmap_Init */ /* */ /* <Description> */ /* Initialize a pointer to an @FT_Bitmap structure. */ /* */ /* <InOut> */ /* abitmap :: A pointer to the bitmap structure. */ /* */ /* <Note> */ /* A deprecated name for the same function is `FT_Bitmap_New'. */ /* */ FT_EXPORT( void ) FT_Bitmap_Init( FT_Bitmap *abitmap ); /* deprecated */ FT_EXPORT( void ) FT_Bitmap_New( FT_Bitmap *abitmap ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Bitmap_Copy */ /* */ /* <Description> */ /* Copy a bitmap into another one. */ /* */ /* <Input> */ /* library :: A handle to a library object. */ /* */ /* source :: A handle to the source bitmap. */ /* */ /* <Output> */ /* target :: A handle to the target bitmap. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Bitmap_Copy( FT_Library library, const FT_Bitmap *source, FT_Bitmap *target ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Bitmap_Embolden */ /* */ /* <Description> */ /* Embolden a bitmap. The new bitmap will be about `xStrength' */ /* pixels wider and `yStrength' pixels higher. The left and bottom */ /* borders are kept unchanged. */ /* */ /* <Input> */ /* library :: A handle to a library object. */ /* */ /* xStrength :: How strong the glyph is emboldened horizontally. */ /* Expressed in 26.6 pixel format. */ /* */ /* yStrength :: How strong the glyph is emboldened vertically. */ /* Expressed in 26.6 pixel format. */ /* */ /* <InOut> */ /* bitmap :: A handle to the target bitmap. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The current implementation restricts `xStrength' to be less than */ /* or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ /* */ /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ /* you should call @FT_GlyphSlot_Own_Bitmap on the slot first. */ /* */ /* Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format */ /* are converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp). */ /* */ FT_EXPORT( FT_Error ) FT_Bitmap_Embolden( FT_Library library, FT_Bitmap* bitmap, FT_Pos xStrength, FT_Pos yStrength ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Bitmap_Convert */ /* */ /* <Description> */ /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp */ /* to a bitmap object with depth 8bpp, making the number of used */ /* bytes line (a.k.a. the `pitch') a multiple of `alignment'. */ /* */ /* <Input> */ /* library :: A handle to a library object. */ /* */ /* source :: The source bitmap. */ /* */ /* alignment :: The pitch of the bitmap is a multiple of this */ /* parameter. Common values are 1, 2, or 4. */ /* */ /* <Output> */ /* target :: The target bitmap. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* It is possible to call @FT_Bitmap_Convert multiple times without */ /* calling @FT_Bitmap_Done (the memory is simply reallocated). */ /* */ /* Use @FT_Bitmap_Done to finally remove the bitmap object. */ /* */ /* The `library' argument is taken to have access to FreeType's */ /* memory handling functions. */ /* */ FT_EXPORT( FT_Error ) FT_Bitmap_Convert( FT_Library library, const FT_Bitmap *source, FT_Bitmap *target, FT_Int alignment ); /*************************************************************************/ /* */ /* <Function> */ /* FT_GlyphSlot_Own_Bitmap */ /* */ /* <Description> */ /* Make sure that a glyph slot owns `slot->bitmap'. */ /* */ /* <Input> */ /* slot :: The glyph slot. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* This function is to be used in combination with */ /* @FT_Bitmap_Embolden. */ /* */ FT_EXPORT( FT_Error ) FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Bitmap_Done */ /* */ /* <Description> */ /* Destroy a bitmap object initialized with @FT_Bitmap_Init. */ /* */ /* <Input> */ /* library :: A handle to a library object. */ /* */ /* bitmap :: The bitmap object to be freed. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The `library' argument is taken to have access to FreeType's */ /* memory handling functions. */ /* */ FT_EXPORT( FT_Error ) FT_Bitmap_Done( FT_Library library, FT_Bitmap *bitmap ); /* */ FT_END_HEADER #endif /* FTBITMAP_H_ */ /* END */ freetype2/freetype/ftadvanc.h 0000644 00000024614 15146341150 0012242 0 ustar 00 /***************************************************************************/ /* */ /* ftadvanc.h */ /* */ /* Quick computation of advance widths (specification only). */ /* */ /* Copyright 2008-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTADVANC_H_ #define FTADVANC_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /************************************************************************** * * @section: * quick_advance * * @title: * Quick retrieval of advance values * * @abstract: * Retrieve horizontal and vertical advance values without processing * glyph outlines, if possible. * * @description: * This section contains functions to quickly extract advance values * without handling glyph outlines, if possible. * * @order: * FT_Get_Advance * FT_Get_Advances * */ /*************************************************************************/ /* */ /* <Const> */ /* FT_ADVANCE_FLAG_FAST_ONLY */ /* */ /* <Description> */ /* A bit-flag to be OR-ed with the `flags' parameter of the */ /* @FT_Get_Advance and @FT_Get_Advances functions. */ /* */ /* If set, it indicates that you want these functions to fail if the */ /* corresponding hinting mode or font driver doesn't allow for very */ /* quick advance computation. */ /* */ /* Typically, glyphs that are either unscaled, unhinted, bitmapped, */ /* or light-hinted can have their advance width computed very */ /* quickly. */ /* */ /* Normal and bytecode hinted modes that require loading, scaling, */ /* and hinting of the glyph outline, are extremely slow by */ /* comparison. */ /* */ #define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000L /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Advance */ /* */ /* <Description> */ /* Retrieve the advance value of a given glyph outline in an */ /* @FT_Face. */ /* */ /* <Input> */ /* face :: The source @FT_Face handle. */ /* */ /* gindex :: The glyph index. */ /* */ /* load_flags :: A set of bit flags similar to those used when */ /* calling @FT_Load_Glyph, used to determine what kind */ /* of advances you need. */ /* <Output> */ /* padvance :: The advance value. If scaling is performed (based on */ /* the value of `load_flags'), the advance value is in */ /* 16.16 format. Otherwise, it is in font units. */ /* */ /* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the */ /* vertical advance corresponding to a vertical layout. */ /* Otherwise, it is the horizontal advance in a */ /* horizontal layout. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ /* <Note> */ /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ /* if the corresponding font backend doesn't have a quick way to */ /* retrieve the advances. */ /* */ /* A scaled advance is returned in 16.16 format but isn't transformed */ /* by the affine transformation specified by @FT_Set_Transform. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Advance( FT_Face face, FT_UInt gindex, FT_Int32 load_flags, FT_Fixed *padvance ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Advances */ /* */ /* <Description> */ /* Retrieve the advance values of several glyph outlines in an */ /* @FT_Face. */ /* */ /* <Input> */ /* face :: The source @FT_Face handle. */ /* */ /* start :: The first glyph index. */ /* */ /* count :: The number of advance values you want to retrieve. */ /* */ /* load_flags :: A set of bit flags similar to those used when */ /* calling @FT_Load_Glyph. */ /* */ /* <Output> */ /* padvance :: The advance values. This array, to be provided by the */ /* caller, must contain at least `count' elements. */ /* */ /* If scaling is performed (based on the value of */ /* `load_flags'), the advance values are in 16.16 format. */ /* Otherwise, they are in font units. */ /* */ /* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the */ /* vertical advances corresponding to a vertical layout. */ /* Otherwise, they are the horizontal advances in a */ /* horizontal layout. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ /* <Note> */ /* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and */ /* if the corresponding font backend doesn't have a quick way to */ /* retrieve the advances. */ /* */ /* Scaled advances are returned in 16.16 format but aren't */ /* transformed by the affine transformation specified by */ /* @FT_Set_Transform. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Advances( FT_Face face, FT_UInt start, FT_UInt count, FT_Int32 load_flags, FT_Fixed *padvances ); /* */ FT_END_HEADER #endif /* FTADVANC_H_ */ /* END */ freetype2/freetype/ftgxval.h 0000644 00000032116 15146341150 0012123 0 ustar 00 /***************************************************************************/ /* */ /* ftgxval.h */ /* */ /* FreeType API for validating TrueTypeGX/AAT tables (specification). */ /* */ /* Copyright 2004-2018 by */ /* Masatake YAMATO, Redhat K.K, */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /***************************************************************************/ /* */ /* gxvalid is derived from both gxlayout module and otvalid module. */ /* Development of gxlayout is supported by the Information-technology */ /* Promotion Agency(IPA), Japan. */ /* */ /***************************************************************************/ #ifndef FTGXVAL_H_ #define FTGXVAL_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* gx_validation */ /* */ /* <Title> */ /* TrueTypeGX/AAT Validation */ /* */ /* <Abstract> */ /* An API to validate TrueTypeGX/AAT tables. */ /* */ /* <Description> */ /* This section contains the declaration of functions to validate */ /* some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, */ /* trak, prop, lcar). */ /* */ /* <Order> */ /* FT_TrueTypeGX_Validate */ /* FT_TrueTypeGX_Free */ /* */ /* FT_ClassicKern_Validate */ /* FT_ClassicKern_Free */ /* */ /* FT_VALIDATE_GX_LENGTH */ /* FT_VALIDATE_GXXXX */ /* FT_VALIDATE_CKERNXXX */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* */ /* Warning: Use FT_VALIDATE_XXX to validate a table. */ /* Following definitions are for gxvalid developers. */ /* */ /* */ /*************************************************************************/ #define FT_VALIDATE_feat_INDEX 0 #define FT_VALIDATE_mort_INDEX 1 #define FT_VALIDATE_morx_INDEX 2 #define FT_VALIDATE_bsln_INDEX 3 #define FT_VALIDATE_just_INDEX 4 #define FT_VALIDATE_kern_INDEX 5 #define FT_VALIDATE_opbd_INDEX 6 #define FT_VALIDATE_trak_INDEX 7 #define FT_VALIDATE_prop_INDEX 8 #define FT_VALIDATE_lcar_INDEX 9 #define FT_VALIDATE_GX_LAST_INDEX FT_VALIDATE_lcar_INDEX /************************************************************************* * * @macro: * FT_VALIDATE_GX_LENGTH * * @description: * The number of tables checked in this module. Use it as a parameter * for the `table-length' argument of function @FT_TrueTypeGX_Validate. */ #define FT_VALIDATE_GX_LENGTH ( FT_VALIDATE_GX_LAST_INDEX + 1 ) /* */ /* Up to 0x1000 is used by otvalid. Ox2xxx is reserved for feature OT extension. */ #define FT_VALIDATE_GX_START 0x4000 #define FT_VALIDATE_GX_BITFIELD( tag ) \ ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX ) /********************************************************************** * * @enum: * FT_VALIDATE_GXXXX * * @description: * A list of bit-field constants used with @FT_TrueTypeGX_Validate to * indicate which TrueTypeGX/AAT Type tables should be validated. * * @values: * FT_VALIDATE_feat :: * Validate `feat' table. * * FT_VALIDATE_mort :: * Validate `mort' table. * * FT_VALIDATE_morx :: * Validate `morx' table. * * FT_VALIDATE_bsln :: * Validate `bsln' table. * * FT_VALIDATE_just :: * Validate `just' table. * * FT_VALIDATE_kern :: * Validate `kern' table. * * FT_VALIDATE_opbd :: * Validate `opbd' table. * * FT_VALIDATE_trak :: * Validate `trak' table. * * FT_VALIDATE_prop :: * Validate `prop' table. * * FT_VALIDATE_lcar :: * Validate `lcar' table. * * FT_VALIDATE_GX :: * Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern, * opbd, trak, prop and lcar). * */ #define FT_VALIDATE_feat FT_VALIDATE_GX_BITFIELD( feat ) #define FT_VALIDATE_mort FT_VALIDATE_GX_BITFIELD( mort ) #define FT_VALIDATE_morx FT_VALIDATE_GX_BITFIELD( morx ) #define FT_VALIDATE_bsln FT_VALIDATE_GX_BITFIELD( bsln ) #define FT_VALIDATE_just FT_VALIDATE_GX_BITFIELD( just ) #define FT_VALIDATE_kern FT_VALIDATE_GX_BITFIELD( kern ) #define FT_VALIDATE_opbd FT_VALIDATE_GX_BITFIELD( opbd ) #define FT_VALIDATE_trak FT_VALIDATE_GX_BITFIELD( trak ) #define FT_VALIDATE_prop FT_VALIDATE_GX_BITFIELD( prop ) #define FT_VALIDATE_lcar FT_VALIDATE_GX_BITFIELD( lcar ) #define FT_VALIDATE_GX ( FT_VALIDATE_feat | \ FT_VALIDATE_mort | \ FT_VALIDATE_morx | \ FT_VALIDATE_bsln | \ FT_VALIDATE_just | \ FT_VALIDATE_kern | \ FT_VALIDATE_opbd | \ FT_VALIDATE_trak | \ FT_VALIDATE_prop | \ FT_VALIDATE_lcar ) /********************************************************************** * * @function: * FT_TrueTypeGX_Validate * * @description: * Validate various TrueTypeGX tables to assure that all offsets and * indices are valid. The idea is that a higher-level library that * actually does the text layout can access those tables without * error checking (which can be quite time consuming). * * @input: * face :: * A handle to the input face. * * validation_flags :: * A bit field that specifies the tables to be validated. See * @FT_VALIDATE_GXXXX for possible values. * * table_length :: * The size of the `tables' array. Normally, @FT_VALIDATE_GX_LENGTH * should be passed. * * @output: * tables :: * The array where all validated sfnt tables are stored. * The array itself must be allocated by a client. * * @return: * FreeType error code. 0~means success. * * @note: * This function only works with TrueTypeGX fonts, returning an error * otherwise. * * After use, the application should deallocate the buffers pointed to by * each `tables' element, by calling @FT_TrueTypeGX_Free. A NULL value * indicates that the table either doesn't exist in the font, the * application hasn't asked for validation, or the validator doesn't have * the ability to validate the sfnt table. */ FT_EXPORT( FT_Error ) FT_TrueTypeGX_Validate( FT_Face face, FT_UInt validation_flags, FT_Bytes tables[FT_VALIDATE_GX_LENGTH], FT_UInt table_length ); /********************************************************************** * * @function: * FT_TrueTypeGX_Free * * @description: * Free the buffer allocated by TrueTypeGX validator. * * @input: * face :: * A handle to the input face. * * table :: * The pointer to the buffer allocated by * @FT_TrueTypeGX_Validate. * * @note: * This function must be used to free the buffer allocated by * @FT_TrueTypeGX_Validate only. */ FT_EXPORT( void ) FT_TrueTypeGX_Free( FT_Face face, FT_Bytes table ); /********************************************************************** * * @enum: * FT_VALIDATE_CKERNXXX * * @description: * A list of bit-field constants used with @FT_ClassicKern_Validate * to indicate the classic kern dialect or dialects. If the selected * type doesn't fit, @FT_ClassicKern_Validate regards the table as * invalid. * * @values: * FT_VALIDATE_MS :: * Handle the `kern' table as a classic Microsoft kern table. * * FT_VALIDATE_APPLE :: * Handle the `kern' table as a classic Apple kern table. * * FT_VALIDATE_CKERN :: * Handle the `kern' as either classic Apple or Microsoft kern table. */ #define FT_VALIDATE_MS ( FT_VALIDATE_GX_START << 0 ) #define FT_VALIDATE_APPLE ( FT_VALIDATE_GX_START << 1 ) #define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE ) /********************************************************************** * * @function: * FT_ClassicKern_Validate * * @description: * Validate classic (16-bit format) kern table to assure that the offsets * and indices are valid. The idea is that a higher-level library that * actually does the text layout can access those tables without error * checking (which can be quite time consuming). * * The `kern' table validator in @FT_TrueTypeGX_Validate deals with both * the new 32-bit format and the classic 16-bit format, while * FT_ClassicKern_Validate only supports the classic 16-bit format. * * @input: * face :: * A handle to the input face. * * validation_flags :: * A bit field that specifies the dialect to be validated. See * @FT_VALIDATE_CKERNXXX for possible values. * * @output: * ckern_table :: * A pointer to the kern table. * * @return: * FreeType error code. 0~means success. * * @note: * After use, the application should deallocate the buffers pointed to by * `ckern_table', by calling @FT_ClassicKern_Free. A NULL value * indicates that the table doesn't exist in the font. */ FT_EXPORT( FT_Error ) FT_ClassicKern_Validate( FT_Face face, FT_UInt validation_flags, FT_Bytes *ckern_table ); /********************************************************************** * * @function: * FT_ClassicKern_Free * * @description: * Free the buffer allocated by classic Kern validator. * * @input: * face :: * A handle to the input face. * * table :: * The pointer to the buffer that is allocated by * @FT_ClassicKern_Validate. * * @note: * This function must be used to free the buffer allocated by * @FT_ClassicKern_Validate only. */ FT_EXPORT( void ) FT_ClassicKern_Free( FT_Face face, FT_Bytes table ); /* */ FT_END_HEADER #endif /* FTGXVAL_H_ */ /* END */ freetype2/freetype/ftdriver.h 0000644 00000135631 15146341150 0012303 0 ustar 00 /***************************************************************************/ /* */ /* ftdriver.h */ /* */ /* FreeType API for controlling driver modules (specification only). */ /* */ /* Copyright 2017-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTDRIVER_H_ #define FTDRIVER_H_ #include <ft2build.h> #include FT_FREETYPE_H #include FT_PARAMETER_TAGS_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /************************************************************************** * * @section: * auto_hinter * * @title: * The auto-hinter * * @abstract: * Controlling the auto-hinting module. * * @description: * While FreeType's auto-hinter doesn't expose API functions by itself, * it is possible to control its behaviour with @FT_Property_Set and * @FT_Property_Get. The following lists the available properties * together with the necessary macros and structures. * * Note that the auto-hinter's module name is `autofitter' for * historical reasons. * * Available properties are @increase-x-height, @no-stem-darkening * (experimental), @darkening-parameters (experimental), @warping * (experimental), @glyph-to-script-map (experimental), @fallback-script * (experimental), and @default-script (experimental), as documented in * the @properties section. * */ /************************************************************************** * * @section: * cff_driver * * @title: * The CFF driver * * @abstract: * Controlling the CFF driver module. * * @description: * While FreeType's CFF driver doesn't expose API functions by itself, * it is possible to control its behaviour with @FT_Property_Set and * @FT_Property_Get. * * The CFF driver's module name is `cff'. * * Available properties are @hinting-engine, @no-stem-darkening, * @darkening-parameters, and @random-seed, as documented in the * @properties section. * * * *Hinting* *and* *antialiasing* *principles* *of* *the* *new* *engine* * * The rasterizer is positioning horizontal features (e.g., ascender * height & x-height, or crossbars) on the pixel grid and minimizing the * amount of antialiasing applied to them, while placing vertical * features (vertical stems) on the pixel grid without hinting, thus * representing the stem position and weight accurately. Sometimes the * vertical stems may be only partially black. In this context, * `antialiasing' means that stems are not positioned exactly on pixel * borders, causing a fuzzy appearance. * * There are two principles behind this approach. * * 1) No hinting in the horizontal direction: Unlike `superhinted' * TrueType, which changes glyph widths to accommodate regular * inter-glyph spacing, Adobe's approach is `faithful to the design' in * representing both the glyph width and the inter-glyph spacing * designed for the font. This makes the screen display as close as it * can be to the result one would get with infinite resolution, while * preserving what is considered the key characteristics of each glyph. * Note that the distances between unhinted and grid-fitted positions at * small sizes are comparable to kerning values and thus would be * noticeable (and distracting) while reading if hinting were applied. * * One of the reasons to not hint horizontally is antialiasing for LCD * screens: The pixel geometry of modern displays supplies three * vertical subpixels as the eye moves horizontally across each visible * pixel. On devices where we can be certain this characteristic is * present a rasterizer can take advantage of the subpixels to add * increments of weight. In Western writing systems this turns out to * be the more critical direction anyway; the weights and spacing of * vertical stems (see above) are central to Armenian, Cyrillic, Greek, * and Latin type designs. Even when the rasterizer uses greyscale * antialiasing instead of color (a necessary compromise when one * doesn't know the screen characteristics), the unhinted vertical * features preserve the design's weight and spacing much better than * aliased type would. * * 2) Alignment in the vertical direction: Weights and spacing along the * y~axis are less critical; what is much more important is the visual * alignment of related features (like cap-height and x-height). The * sense of alignment for these is enhanced by the sharpness of grid-fit * edges, while the cruder vertical resolution (full pixels instead of * 1/3 pixels) is less of a problem. * * On the technical side, horizontal alignment zones for ascender, * x-height, and other important height values (traditionally called * `blue zones') as defined in the font are positioned independently, * each being rounded to the nearest pixel edge, taking care of * overshoot suppression at small sizes, stem darkening, and scaling. * * Hstems (this is, hint values defined in the font to help align * horizontal features) that fall within a blue zone are said to be * `captured' and are aligned to that zone. Uncaptured stems are moved * in one of four ways, top edge up or down, bottom edge up or down. * Unless there are conflicting hstems, the smallest movement is taken * to minimize distortion. * */ /************************************************************************** * * @section: * pcf_driver * * @title: * The PCF driver * * @abstract: * Controlling the PCF driver module. * * @description: * While FreeType's PCF driver doesn't expose API functions by itself, * it is possible to control its behaviour with @FT_Property_Set and * @FT_Property_Get. Right now, there is a single property * @no-long-family-names available if FreeType is compiled with * PCF_CONFIG_OPTION_LONG_FAMILY_NAMES. * * The PCF driver's module name is `pcf'. * */ /************************************************************************** * * @section: * t1_cid_driver * * @title: * The Type 1 and CID drivers * * @abstract: * Controlling the Type~1 and CID driver modules. * * @description: * It is possible to control the behaviour of FreeType's Type~1 and * Type~1 CID drivers with @FT_Property_Set and @FT_Property_Get. * * Behind the scenes, both drivers use the Adobe CFF engine for hinting; * however, the used properties must be specified separately. * * The Type~1 driver's module name is `type1'; the CID driver's module * name is `t1cid'. * * Available properties are @hinting-engine, @no-stem-darkening, * @darkening-parameters, and @random-seed, as documented in the * @properties section. * * Please see the @cff_driver section for more details on the new * hinting engine. * */ /************************************************************************** * * @section: * tt_driver * * @title: * The TrueType driver * * @abstract: * Controlling the TrueType driver module. * * @description: * While FreeType's TrueType driver doesn't expose API functions by * itself, it is possible to control its behaviour with @FT_Property_Set * and @FT_Property_Get. The following lists the available properties * together with the necessary macros and structures. * * The TrueType driver's module name is `truetype'. * * A single property @interpreter-version is available, as documented in * the @properties section. * * We start with a list of definitions, kindly provided by Greg * Hitchcock. * * _Bi-Level_ _Rendering_ * * Monochromatic rendering, exclusively used in the early days of * TrueType by both Apple and Microsoft. Microsoft's GDI interface * supported hinting of the right-side bearing point, such that the * advance width could be non-linear. Most often this was done to * achieve some level of glyph symmetry. To enable reasonable * performance (e.g., not having to run hinting on all glyphs just to * get the widths) there was a bit in the head table indicating if the * side bearing was hinted, and additional tables, `hdmx' and `LTSH', to * cache hinting widths across multiple sizes and device aspect ratios. * * _Font_ _Smoothing_ * * Microsoft's GDI implementation of anti-aliasing. Not traditional * anti-aliasing as the outlines were hinted before the sampling. The * widths matched the bi-level rendering. * * _ClearType_ _Rendering_ * * Technique that uses physical subpixels to improve rendering on LCD * (and other) displays. Because of the higher resolution, many methods * of improving symmetry in glyphs through hinting the right-side * bearing were no longer necessary. This lead to what GDI calls * `natural widths' ClearType, see * http://www.beatstamm.com/typography/RTRCh4.htm#Sec21. Since hinting * has extra resolution, most non-linearity went away, but it is still * possible for hints to change the advance widths in this mode. * * _ClearType_ _Compatible_ _Widths_ * * One of the earliest challenges with ClearType was allowing the * implementation in GDI to be selected without requiring all UI and * documents to reflow. To address this, a compatible method of * rendering ClearType was added where the font hints are executed once * to determine the width in bi-level rendering, and then re-run in * ClearType, with the difference in widths being absorbed in the font * hints for ClearType (mostly in the white space of hints); see * http://www.beatstamm.com/typography/RTRCh4.htm#Sec20. Somewhat by * definition, compatible width ClearType allows for non-linear widths, * but only when the bi-level version has non-linear widths. * * _ClearType_ _Subpixel_ _Positioning_ * * One of the nice benefits of ClearType is the ability to more crisply * display fractional widths; unfortunately, the GDI model of integer * bitmaps did not support this. However, the WPF and Direct Write * frameworks do support fractional widths. DWrite calls this `natural * mode', not to be confused with GDI's `natural widths'. Subpixel * positioning, in the current implementation of Direct Write, * unfortunately does not support hinted advance widths, see * http://www.beatstamm.com/typography/RTRCh4.htm#Sec22. Note that the * TrueType interpreter fully allows the advance width to be adjusted in * this mode, just the DWrite client will ignore those changes. * * _ClearType_ _Backward_ _Compatibility_ * * This is a set of exceptions made in the TrueType interpreter to * minimize hinting techniques that were problematic with the extra * resolution of ClearType; see * http://www.beatstamm.com/typography/RTRCh4.htm#Sec1 and * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx. * This technique is not to be confused with ClearType compatible * widths. ClearType backward compatibility has no direct impact on * changing advance widths, but there might be an indirect impact on * disabling some deltas. This could be worked around in backward * compatibility mode. * * _Native_ _ClearType_ _Mode_ * * (Not to be confused with `natural widths'.) This mode removes all * the exceptions in the TrueType interpreter when running with * ClearType. Any issues on widths would still apply, though. * */ /************************************************************************** * * @section: * properties * * @title: * Driver properties * * @abstract: * Controlling driver modules. * * @description: * Driver modules can be controlled by setting and unsetting properties, * using the functions @FT_Property_Set and @FT_Property_Get. This * section documents the available properties, together with auxiliary * macros and structures. * */ /************************************************************************** * * @enum: * FT_HINTING_XXX * * @description: * A list of constants used for the @hinting-engine property to * select the hinting engine for CFF, Type~1, and CID fonts. * * @values: * FT_HINTING_FREETYPE :: * Use the old FreeType hinting engine. * * FT_HINTING_ADOBE :: * Use the hinting engine contributed by Adobe. * * @since: * 2.9 * */ #define FT_HINTING_FREETYPE 0 #define FT_HINTING_ADOBE 1 /* these constants (introduced in 2.4.12) are deprecated */ #define FT_CFF_HINTING_FREETYPE FT_HINTING_FREETYPE #define FT_CFF_HINTING_ADOBE FT_HINTING_ADOBE /************************************************************************** * * @property: * hinting-engine * * @description: * Thanks to Adobe, which contributed a new hinting (and parsing) * engine, an application can select between `freetype' and `adobe' if * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration * macro isn't defined, `hinting-engine' does nothing. * * The same holds for the Type~1 and CID modules if compiled with * T1_CONFIG_OPTION_OLD_ENGINE. * * For the `cff' module, the default engine is `freetype' if * CFF_CONFIG_OPTION_OLD_ENGINE is defined, and `adobe' otherwise. * * For both the `type1' and `t1cid' modules, the default engine is * `freetype' if T1_CONFIG_OPTION_OLD_ENGINE is defined, and `adobe' * otherwise. * * The following example code demonstrates how to select Adobe's hinting * engine for the `cff' module (omitting the error handling). * * { * FT_Library library; * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; * * * FT_Init_FreeType( &library ); * * FT_Property_Set( library, "cff", * "hinting-engine", &hinting_engine ); * } * * @note: * This property can be used with @FT_Property_Get also. * * This property can be set via the `FREETYPE_PROPERTIES' environment * variable (using values `adobe' or `freetype'). * * @since: * 2.4.12 (for `cff' module) * * 2.9 (for `type1' and `t1cid' modules) * */ /************************************************************************** * * @property: * no-stem-darkening * * @description: * All glyphs that pass through the auto-hinter will be emboldened * unless this property is set to TRUE. The same is true for the CFF, * Type~1, and CID font modules if the `Adobe' engine is selected (which * is the default). * * Stem darkening emboldens glyphs at smaller sizes to make them more * readable on common low-DPI screens when using linear alpha blending * and gamma correction, see @FT_Render_Glyph. When not using linear * alpha blending and gamma correction, glyphs will appear heavy and * fuzzy! * * Gamma correction essentially lightens fonts since shades of grey are * shifted to higher pixel values (=~higher brightness) to match the * original intention to the reality of our screens. The side-effect is * that glyphs `thin out'. Mac OS~X and Adobe's proprietary font * rendering library implement a counter-measure: stem darkening at * smaller sizes where shades of gray dominate. By emboldening a glyph * slightly in relation to its pixel size, individual pixels get higher * coverage of filled-in outlines and are therefore `blacker'. This * counteracts the `thinning out' of glyphs, making text remain readable * at smaller sizes. * * By default, the Adobe engines for CFF, Type~1, and CID fonts darken * stems at smaller sizes, regardless of hinting, to enhance contrast. * Setting this property, stem darkening gets switched off. * * For the auto-hinter, stem-darkening is experimental currently and * thus switched off by default (this is, `no-stem-darkening' is set to * TRUE by default). Total consistency with the CFF driver is not * achieved right now because the emboldening method differs and glyphs * must be scaled down on the Y-axis to keep outline points inside their * precomputed blue zones. The smaller the size (especially 9ppem and * down), the higher the loss of emboldening versus the CFF driver. * * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is * set. * * { * FT_Library library; * FT_Bool no_stem_darkening = TRUE; * * * FT_Init_FreeType( &library ); * * FT_Property_Set( library, "cff", * "no-stem-darkening", &no_stem_darkening ); * } * * @note: * This property can be used with @FT_Property_Get also. * * This property can be set via the `FREETYPE_PROPERTIES' environment * variable (using values 1 and 0 for `on' and `off', respectively). * It can also be set per face using @FT_Face_Properties with * @FT_PARAM_TAG_STEM_DARKENING. * * @since: * 2.4.12 (for `cff' module) * * 2.6.2 (for `autofitter' module) * * 2.9 (for `type1' and `t1cid' modules) * */ /************************************************************************** * * @property: * darkening-parameters * * @description: * By default, the Adobe hinting engine, as used by the CFF, Type~1, and * CID font drivers, darkens stems as follows (if the * `no-stem-darkening' property isn't set): * * { * stem width <= 0.5px: darkening amount = 0.4px * stem width = 1px: darkening amount = 0.275px * stem width = 1.667px: darkening amount = 0.275px * stem width >= 2.333px: darkening amount = 0px * } * * and piecewise linear in-between. At configuration time, these four * control points can be set with the macro * `CFF_CONFIG_OPTION_DARKENING_PARAMETERS'; the CFF, Type~1, and CID * drivers share these values. At runtime, the control points can be * changed using the `darkening-parameters' property, as the following * example demonstrates for the Type~1 driver. * * { * FT_Library library; * FT_Int darken_params[8] = { 500, 300, // x1, y1 * 1000, 200, // x2, y2 * 1500, 100, // x3, y3 * 2000, 0 }; // x4, y4 * * * FT_Init_FreeType( &library ); * * FT_Property_Set( library, "type1", * "darkening-parameters", darken_params ); * } * * The x~values give the stem width, and the y~values the darkening * amount. The unit is 1000th of pixels. All coordinate values must be * positive; the x~values must be monotonically increasing; the * y~values must be monotonically decreasing and smaller than or * equal to 500 (corresponding to half a pixel); the slope of each * linear piece must be shallower than -1 (e.g., -.4). * * The auto-hinter provides this property, too, as an experimental * feature. See @no-stem-darkening for more. * * @note: * This property can be used with @FT_Property_Get also. * * This property can be set via the `FREETYPE_PROPERTIES' environment * variable, using eight comma-separated integers without spaces. Here * the above example, using `\' to break the line for readability. * * { * FREETYPE_PROPERTIES=\ * type1:darkening-parameters=500,300,1000,200,1500,100,2000,0 * } * * @since: * 2.5.1 (for `cff' module) * * 2.6.2 (for `autofitter' module) * * 2.9 (for `type1' and `t1cid' modules) * */ /************************************************************************** * * @property: * random-seed * * @description: * By default, the seed value for the CFF `random' operator and the * similar `0 28 callothersubr pop' command for the Type~1 and CID * drivers is set to a random value. However, mainly for debugging * purposes, it is often necessary to use a known value as a seed so * that the pseudo-random number sequences generated by `random' are * repeatable. * * The `random-seed' property does that. Its argument is a signed 32bit * integer; if the value is zero or negative, the seed given by the * `intitialRandomSeed' private DICT operator in a CFF file gets used * (or a default value if there is no such operator). If the value is * positive, use it instead of `initialRandomSeed', which is * consequently ignored. * * @note: * This property can be set via the `FREETYPE_PROPERTIES' environment * variable. It can also be set per face using @FT_Face_Properties with * @FT_PARAM_TAG_RANDOM_SEED. * * @since: * 2.8 (for `cff' module) * * 2.9 (for `type1' and `t1cid' modules) * */ /************************************************************************** * * @property: * no-long-family-names * * @description: * If PCF_CONFIG_OPTION_LONG_FAMILY_NAMES is active while compiling * FreeType, the PCF driver constructs long family names. * * There are many PCF fonts just called `Fixed' which look completely * different, and which have nothing to do with each other. When * selecting `Fixed' in KDE or Gnome one gets results that appear rather * random, the style changes often if one changes the size and one * cannot select some fonts at all. The improve this situation, the PCF * module prepends the foundry name (plus a space) to the family name. * It also checks whether there are `wide' characters; all put together, * family names like `Sony Fixed' or `Misc Fixed Wide' are constructed. * * If `no-long-family-names' is set, this feature gets switched off. * * { * FT_Library library; * FT_Bool no_long_family_names = TRUE; * * * FT_Init_FreeType( &library ); * * FT_Property_Set( library, "pcf", * "no-long-family-names", * &no_long_family_names ); * } * * @note: * This property can be used with @FT_Property_Get also. * * This property can be set via the `FREETYPE_PROPERTIES' environment * variable (using values 1 and 0 for `on' and `off', respectively). * * @since: * 2.8 */ /************************************************************************** * * @enum: * TT_INTERPRETER_VERSION_XXX * * @description: * A list of constants used for the @interpreter-version property to * select the hinting engine for Truetype fonts. * * The numeric value in the constant names represents the version * number as returned by the `GETINFO' bytecode instruction. * * @values: * TT_INTERPRETER_VERSION_35 :: * Version~35 corresponds to MS rasterizer v.1.7 as used e.g. in * Windows~98; only grayscale and B/W rasterizing is supported. * * TT_INTERPRETER_VERSION_38 :: * Version~38 corresponds to MS rasterizer v.1.9; it is roughly * equivalent to the hinting provided by DirectWrite ClearType (as can * be found, for example, in the Internet Explorer~9 running on * Windows~7). It is used in FreeType to select the `Infinality' * subpixel hinting code. The code may be removed in a future * version. * * TT_INTERPRETER_VERSION_40 :: * Version~40 corresponds to MS rasterizer v.2.1; it is roughly * equivalent to the hinting provided by DirectWrite ClearType (as can * be found, for example, in Microsoft's Edge Browser on Windows~10). * It is used in FreeType to select the `minimal' subpixel hinting * code, a stripped-down and higher performance version of the * `Infinality' code. * * @note: * This property controls the behaviour of the bytecode interpreter * and thus how outlines get hinted. It does *not* control how glyph * get rasterized! In particular, it does not control subpixel color * filtering. * * If FreeType has not been compiled with the configuration option * TT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 or~40 causes * an `FT_Err_Unimplemented_Feature' error. * * Depending on the graphics framework, Microsoft uses different * bytecode and rendering engines. As a consequence, the version * numbers returned by a call to the `GETINFO' bytecode instruction are * more convoluted than desired. * * Here are two tables that try to shed some light on the possible * values for the MS rasterizer engine, together with the additional * features introduced by it. * * { * GETINFO framework version feature * ------------------------------------------------------------------- * 3 GDI (Win 3.1), v1.0 16-bit, first version * TrueImage * 33 GDI (Win NT 3.1), v1.5 32-bit * HP Laserjet * 34 GDI (Win 95) v1.6 font smoothing, * new SCANTYPE opcode * 35 GDI (Win 98/2000) v1.7 (UN)SCALED_COMPONENT_OFFSET * bits in composite glyphs * 36 MGDI (Win CE 2) v1.6+ classic ClearType * 37 GDI (XP and later), v1.8 ClearType * GDI+ old (before Vista) * 38 GDI+ old (Vista, Win 7), v1.9 subpixel ClearType, * WPF Y-direction ClearType, * additional error checking * 39 DWrite (before Win 8) v2.0 subpixel ClearType flags * in GETINFO opcode, * bug fixes * 40 GDI+ (after Win 7), v2.1 Y-direction ClearType flag * DWrite (Win 8) in GETINFO opcode, * Gray ClearType * } * * The `version' field gives a rough orientation only, since some * applications provided certain features much earlier (as an example, * Microsoft Reader used subpixel and Y-direction ClearType already in * Windows 2000). Similarly, updates to a given framework might include * improved hinting support. * * { * version sampling rendering comment * x y x y * -------------------------------------------------------------- * v1.0 normal normal B/W B/W bi-level * v1.6 high high gray gray grayscale * v1.8 high normal color-filter B/W (GDI) ClearType * v1.9 high high color-filter gray Color ClearType * v2.1 high normal gray B/W Gray ClearType * v2.1 high high gray gray Gray ClearType * } * * Color and Gray ClearType are the two available variants of * `Y-direction ClearType', meaning grayscale rasterization along the * Y-direction; the name used in the TrueType specification for this * feature is `symmetric smoothing'. `Classic ClearType' is the * original algorithm used before introducing a modified version in * Win~XP. Another name for v1.6's grayscale rendering is `font * smoothing', and `Color ClearType' is sometimes also called `DWrite * ClearType'. To differentiate between today's Color ClearType and the * earlier ClearType variant with B/W rendering along the vertical axis, * the latter is sometimes called `GDI ClearType'. * * `Normal' and `high' sampling describe the (virtual) resolution to * access the rasterized outline after the hinting process. `Normal' * means 1 sample per grid line (i.e., B/W). In the current Microsoft * implementation, `high' means an extra virtual resolution of 16x16 (or * 16x1) grid lines per pixel for bytecode instructions like `MIRP'. * After hinting, these 16 grid lines are mapped to 6x5 (or 6x1) grid * lines for color filtering if Color ClearType is activated. * * Note that `Gray ClearType' is essentially the same as v1.6's * grayscale rendering. However, the GETINFO instruction handles it * differently: v1.6 returns bit~12 (hinting for grayscale), while v2.1 * returns bits~13 (hinting for ClearType), 18 (symmetrical smoothing), * and~19 (Gray ClearType). Also, this mode respects bits 2 and~3 for * the version~1 gasp table exclusively (like Color ClearType), while * v1.6 only respects the values of version~0 (bits 0 and~1). * * Keep in mind that the features of the above interpreter versions * might not map exactly to FreeType features or behavior because it is * a fundamentally different library with different internals. * */ #define TT_INTERPRETER_VERSION_35 35 #define TT_INTERPRETER_VERSION_38 38 #define TT_INTERPRETER_VERSION_40 40 /************************************************************************** * * @property: * interpreter-version * * @description: * Currently, three versions are available, two representing the * bytecode interpreter with subpixel hinting support (old `Infinality' * code and new stripped-down and higher performance `minimal' code) and * one without, respectively. The default is subpixel support if * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel support * otherwise (since it isn't available then). * * If subpixel hinting is on, many TrueType bytecode instructions behave * differently compared to B/W or grayscale rendering (except if `native * ClearType' is selected by the font). Microsoft's main idea is to * render at a much increased horizontal resolution, then sampling down * the created output to subpixel precision. However, many older fonts * are not suited to this and must be specially taken care of by * applying (hardcoded) tweaks in Microsoft's interpreter. * * Details on subpixel hinting and some of the necessary tweaks can be * found in Greg Hitchcock's whitepaper at * `https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. * Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2, * or 6x5 supersampling) like discussed in the paper. Depending on the * chosen interpreter, it simply ignores instructions on vertical stems * to arrive at very similar results. * * The following example code demonstrates how to deactivate subpixel * hinting (omitting the error handling). * * { * FT_Library library; * FT_Face face; * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_35; * * * FT_Init_FreeType( &library ); * * FT_Property_Set( library, "truetype", * "interpreter-version", * &interpreter_version ); * } * * @note: * This property can be used with @FT_Property_Get also. * * This property can be set via the `FREETYPE_PROPERTIES' environment * variable (using values `35', `38', or `40'). * * @since: * 2.5 */ /************************************************************************** * * @property: * glyph-to-script-map * * @description: * *Experimental* *only* * * The auto-hinter provides various script modules to hint glyphs. * Examples of supported scripts are Latin or CJK. Before a glyph is * auto-hinted, the Unicode character map of the font gets examined, and * the script is then determined based on Unicode character ranges, see * below. * * OpenType fonts, however, often provide much more glyphs than * character codes (small caps, superscripts, ligatures, swashes, etc.), * to be controlled by so-called `features'. Handling OpenType features * can be quite complicated and thus needs a separate library on top of * FreeType. * * The mapping between glyph indices and scripts (in the auto-hinter * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an * array with `num_glyphs' elements, as found in the font's @FT_Face * structure. The `glyph-to-script-map' property returns a pointer to * this array, which can be modified as needed. Note that the * modification should happen before the first glyph gets processed by * the auto-hinter so that the global analysis of the font shapes * actually uses the modified mapping. * * The following example code demonstrates how to access it (omitting * the error handling). * * { * FT_Library library; * FT_Face face; * FT_Prop_GlyphToScriptMap prop; * * * FT_Init_FreeType( &library ); * FT_New_Face( library, "foo.ttf", 0, &face ); * * prop.face = face; * * FT_Property_Get( library, "autofitter", * "glyph-to-script-map", &prop ); * * // adjust `prop.map' as needed right here * * FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT ); * } * * @since: * 2.4.11 * */ /************************************************************************** * * @enum: * FT_AUTOHINTER_SCRIPT_XXX * * @description: * *Experimental* *only* * * A list of constants used for the @glyph-to-script-map property to * specify the script submodule the auto-hinter should use for hinting a * particular glyph. * * @values: * FT_AUTOHINTER_SCRIPT_NONE :: * Don't auto-hint this glyph. * * FT_AUTOHINTER_SCRIPT_LATIN :: * Apply the latin auto-hinter. For the auto-hinter, `latin' is a * very broad term, including Cyrillic and Greek also since characters * from those scripts share the same design constraints. * * By default, characters from the following Unicode ranges are * assigned to this submodule. * * { * U+0020 - U+007F // Basic Latin (no control characters) * U+00A0 - U+00FF // Latin-1 Supplement (no control characters) * U+0100 - U+017F // Latin Extended-A * U+0180 - U+024F // Latin Extended-B * U+0250 - U+02AF // IPA Extensions * U+02B0 - U+02FF // Spacing Modifier Letters * U+0300 - U+036F // Combining Diacritical Marks * U+0370 - U+03FF // Greek and Coptic * U+0400 - U+04FF // Cyrillic * U+0500 - U+052F // Cyrillic Supplement * U+1D00 - U+1D7F // Phonetic Extensions * U+1D80 - U+1DBF // Phonetic Extensions Supplement * U+1DC0 - U+1DFF // Combining Diacritical Marks Supplement * U+1E00 - U+1EFF // Latin Extended Additional * U+1F00 - U+1FFF // Greek Extended * U+2000 - U+206F // General Punctuation * U+2070 - U+209F // Superscripts and Subscripts * U+20A0 - U+20CF // Currency Symbols * U+2150 - U+218F // Number Forms * U+2460 - U+24FF // Enclosed Alphanumerics * U+2C60 - U+2C7F // Latin Extended-C * U+2DE0 - U+2DFF // Cyrillic Extended-A * U+2E00 - U+2E7F // Supplemental Punctuation * U+A640 - U+A69F // Cyrillic Extended-B * U+A720 - U+A7FF // Latin Extended-D * U+FB00 - U+FB06 // Alphab. Present. Forms (Latin Ligatures) * U+1D400 - U+1D7FF // Mathematical Alphanumeric Symbols * U+1F100 - U+1F1FF // Enclosed Alphanumeric Supplement * } * * FT_AUTOHINTER_SCRIPT_CJK :: * Apply the CJK auto-hinter, covering Chinese, Japanese, Korean, old * Vietnamese, and some other scripts. * * By default, characters from the following Unicode ranges are * assigned to this submodule. * * { * U+1100 - U+11FF // Hangul Jamo * U+2E80 - U+2EFF // CJK Radicals Supplement * U+2F00 - U+2FDF // Kangxi Radicals * U+2FF0 - U+2FFF // Ideographic Description Characters * U+3000 - U+303F // CJK Symbols and Punctuation * U+3040 - U+309F // Hiragana * U+30A0 - U+30FF // Katakana * U+3100 - U+312F // Bopomofo * U+3130 - U+318F // Hangul Compatibility Jamo * U+3190 - U+319F // Kanbun * U+31A0 - U+31BF // Bopomofo Extended * U+31C0 - U+31EF // CJK Strokes * U+31F0 - U+31FF // Katakana Phonetic Extensions * U+3200 - U+32FF // Enclosed CJK Letters and Months * U+3300 - U+33FF // CJK Compatibility * U+3400 - U+4DBF // CJK Unified Ideographs Extension A * U+4DC0 - U+4DFF // Yijing Hexagram Symbols * U+4E00 - U+9FFF // CJK Unified Ideographs * U+A960 - U+A97F // Hangul Jamo Extended-A * U+AC00 - U+D7AF // Hangul Syllables * U+D7B0 - U+D7FF // Hangul Jamo Extended-B * U+F900 - U+FAFF // CJK Compatibility Ideographs * U+FE10 - U+FE1F // Vertical forms * U+FE30 - U+FE4F // CJK Compatibility Forms * U+FF00 - U+FFEF // Halfwidth and Fullwidth Forms * U+1B000 - U+1B0FF // Kana Supplement * U+1D300 - U+1D35F // Tai Xuan Hing Symbols * U+1F200 - U+1F2FF // Enclosed Ideographic Supplement * U+20000 - U+2A6DF // CJK Unified Ideographs Extension B * U+2A700 - U+2B73F // CJK Unified Ideographs Extension C * U+2B740 - U+2B81F // CJK Unified Ideographs Extension D * U+2F800 - U+2FA1F // CJK Compatibility Ideographs Supplement * } * * FT_AUTOHINTER_SCRIPT_INDIC :: * Apply the indic auto-hinter, covering all major scripts from the * Indian sub-continent and some other related scripts like Thai, Lao, * or Tibetan. * * By default, characters from the following Unicode ranges are * assigned to this submodule. * * { * U+0900 - U+0DFF // Indic Range * U+0F00 - U+0FFF // Tibetan * U+1900 - U+194F // Limbu * U+1B80 - U+1BBF // Sundanese * U+A800 - U+A82F // Syloti Nagri * U+ABC0 - U+ABFF // Meetei Mayek * U+11800 - U+118DF // Sharada * } * * Note that currently Indic support is rudimentary only, missing blue * zone support. * * @since: * 2.4.11 * */ #define FT_AUTOHINTER_SCRIPT_NONE 0 #define FT_AUTOHINTER_SCRIPT_LATIN 1 #define FT_AUTOHINTER_SCRIPT_CJK 2 #define FT_AUTOHINTER_SCRIPT_INDIC 3 /************************************************************************** * * @struct: * FT_Prop_GlyphToScriptMap * * @description: * *Experimental* *only* * * The data exchange structure for the @glyph-to-script-map property. * * @since: * 2.4.11 * */ typedef struct FT_Prop_GlyphToScriptMap_ { FT_Face face; FT_UShort* map; } FT_Prop_GlyphToScriptMap; /************************************************************************** * * @property: * fallback-script * * @description: * *Experimental* *only* * * If no auto-hinter script module can be assigned to a glyph, a * fallback script gets assigned to it (see also the * @glyph-to-script-map property). By default, this is * @FT_AUTOHINTER_SCRIPT_CJK. Using the `fallback-script' property, * this fallback value can be changed. * * { * FT_Library library; * FT_UInt fallback_script = FT_AUTOHINTER_SCRIPT_NONE; * * * FT_Init_FreeType( &library ); * * FT_Property_Set( library, "autofitter", * "fallback-script", &fallback_script ); * } * * @note: * This property can be used with @FT_Property_Get also. * * It's important to use the right timing for changing this value: The * creation of the glyph-to-script map that eventually uses the * fallback script value gets triggered either by setting or reading a * face-specific property like @glyph-to-script-map, or by auto-hinting * any glyph from that face. In particular, if you have already created * an @FT_Face structure but not loaded any glyph (using the * auto-hinter), a change of the fallback script will affect this face. * * @since: * 2.4.11 * */ /************************************************************************** * * @property: * default-script * * @description: * *Experimental* *only* * * If FreeType gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make * the HarfBuzz library access OpenType features for getting better * glyph coverages, this property sets the (auto-fitter) script to be * used for the default (OpenType) script data of a font's GSUB table. * Features for the default script are intended for all scripts not * explicitly handled in GSUB; an example is a `dlig' feature, * containing the combination of the characters `T', `E', and `L' to * form a `TEL' ligature. * * By default, this is @FT_AUTOHINTER_SCRIPT_LATIN. Using the * `default-script' property, this default value can be changed. * * { * FT_Library library; * FT_UInt default_script = FT_AUTOHINTER_SCRIPT_NONE; * * * FT_Init_FreeType( &library ); * * FT_Property_Set( library, "autofitter", * "default-script", &default_script ); * } * * @note: * This property can be used with @FT_Property_Get also. * * It's important to use the right timing for changing this value: The * creation of the glyph-to-script map that eventually uses the * default script value gets triggered either by setting or reading a * face-specific property like @glyph-to-script-map, or by auto-hinting * any glyph from that face. In particular, if you have already created * an @FT_Face structure but not loaded any glyph (using the * auto-hinter), a change of the default script will affect this face. * * @since: * 2.5.3 * */ /************************************************************************** * * @property: * increase-x-height * * @description: * For ppem values in the range 6~<= ppem <= `increase-x-height', round * up the font's x~height much more often than normally. If the value * is set to~0, which is the default, this feature is switched off. Use * this property to improve the legibility of small font sizes if * necessary. * * { * FT_Library library; * FT_Face face; * FT_Prop_IncreaseXHeight prop; * * * FT_Init_FreeType( &library ); * FT_New_Face( library, "foo.ttf", 0, &face ); * FT_Set_Char_Size( face, 10 * 64, 0, 72, 0 ); * * prop.face = face; * prop.limit = 14; * * FT_Property_Set( library, "autofitter", * "increase-x-height", &prop ); * } * * @note: * This property can be used with @FT_Property_Get also. * * Set this value right after calling @FT_Set_Char_Size, but before * loading any glyph (using the auto-hinter). * * @since: * 2.4.11 * */ /************************************************************************** * * @struct: * FT_Prop_IncreaseXHeight * * @description: * The data exchange structure for the @increase-x-height property. * */ typedef struct FT_Prop_IncreaseXHeight_ { FT_Face face; FT_UInt limit; } FT_Prop_IncreaseXHeight; /************************************************************************** * * @property: * warping * * @description: * *Experimental* *only* * * If FreeType gets compiled with option AF_CONFIG_OPTION_USE_WARPER to * activate the warp hinting code in the auto-hinter, this property * switches warping on and off. * * Warping only works in `normal' auto-hinting mode replacing it. * The idea of the code is to slightly scale and shift a glyph along * the non-hinted dimension (which is usually the horizontal axis) so * that as much of its segments are aligned (more or less) to the grid. * To find out a glyph's optimal scaling and shifting value, various * parameter combinations are tried and scored. * * By default, warping is off. The example below shows how to switch on * warping (omitting the error handling). * * { * FT_Library library; * FT_Bool warping = 1; * * * FT_Init_FreeType( &library ); * * FT_Property_Set( library, "autofitter", * "warping", &warping ); * } * * @note: * This property can be used with @FT_Property_Get also. * * This property can be set via the `FREETYPE_PROPERTIES' environment * variable (using values 1 and 0 for `on' and `off', respectively). * * The warping code can also change advance widths. Have a look at the * `lsb_delta' and `rsb_delta' fields in the @FT_GlyphSlotRec structure * for details on improving inter-glyph distances while rendering. * * Since warping is a global property of the auto-hinter it is best to * change its value before rendering any face. Otherwise, you should * reload all faces that get auto-hinted in `normal' hinting mode. * * @since: * 2.6 * */ /* */ FT_END_HEADER #endif /* FTDRIVER_H_ */ /* END */ freetype2/freetype/ftstroke.h 0000644 00000053425 15146341150 0012317 0 ustar 00 /***************************************************************************/ /* */ /* ftstroke.h */ /* */ /* FreeType path stroker (specification). */ /* */ /* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTSTROKE_H_ #define FTSTROKE_H_ #include <ft2build.h> #include FT_OUTLINE_H #include FT_GLYPH_H FT_BEGIN_HEADER /************************************************************************ * * @section: * glyph_stroker * * @title: * Glyph Stroker * * @abstract: * Generating bordered and stroked glyphs. * * @description: * This component generates stroked outlines of a given vectorial * glyph. It also allows you to retrieve the `outside' and/or the * `inside' borders of the stroke. * * This can be useful to generate `bordered' glyph, i.e., glyphs * displayed with a coloured (and anti-aliased) border around their * shape. * * @order: * FT_Stroker * * FT_Stroker_LineJoin * FT_Stroker_LineCap * FT_StrokerBorder * * FT_Outline_GetInsideBorder * FT_Outline_GetOutsideBorder * * FT_Glyph_Stroke * FT_Glyph_StrokeBorder * * FT_Stroker_New * FT_Stroker_Set * FT_Stroker_Rewind * FT_Stroker_ParseOutline * FT_Stroker_Done * * FT_Stroker_BeginSubPath * FT_Stroker_EndSubPath * * FT_Stroker_LineTo * FT_Stroker_ConicTo * FT_Stroker_CubicTo * * FT_Stroker_GetBorderCounts * FT_Stroker_ExportBorder * FT_Stroker_GetCounts * FT_Stroker_Export * */ /************************************************************** * * @type: * FT_Stroker * * @description: * Opaque handle to a path stroker object. */ typedef struct FT_StrokerRec_* FT_Stroker; /************************************************************** * * @enum: * FT_Stroker_LineJoin * * @description: * These values determine how two joining lines are rendered * in a stroker. * * @values: * FT_STROKER_LINEJOIN_ROUND :: * Used to render rounded line joins. Circular arcs are used * to join two lines smoothly. * * FT_STROKER_LINEJOIN_BEVEL :: * Used to render beveled line joins. The outer corner of * the joined lines is filled by enclosing the triangular * region of the corner with a straight line between the * outer corners of each stroke. * * FT_STROKER_LINEJOIN_MITER_FIXED :: * Used to render mitered line joins, with fixed bevels if the * miter limit is exceeded. The outer edges of the strokes * for the two segments are extended until they meet at an * angle. If the segments meet at too sharp an angle (such * that the miter would extend from the intersection of the * segments a distance greater than the product of the miter * limit value and the border radius), then a bevel join (see * above) is used instead. This prevents long spikes being * created. FT_STROKER_LINEJOIN_MITER_FIXED generates a miter * line join as used in PostScript and PDF. * * FT_STROKER_LINEJOIN_MITER_VARIABLE :: * FT_STROKER_LINEJOIN_MITER :: * Used to render mitered line joins, with variable bevels if * the miter limit is exceeded. The intersection of the * strokes is clipped at a line perpendicular to the bisector * of the angle between the strokes, at the distance from the * intersection of the segments equal to the product of the * miter limit value and the border radius. This prevents * long spikes being created. * FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line * join as used in XPS. FT_STROKER_LINEJOIN_MITER is an alias * for FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for * backward compatibility. */ typedef enum FT_Stroker_LineJoin_ { FT_STROKER_LINEJOIN_ROUND = 0, FT_STROKER_LINEJOIN_BEVEL = 1, FT_STROKER_LINEJOIN_MITER_VARIABLE = 2, FT_STROKER_LINEJOIN_MITER = FT_STROKER_LINEJOIN_MITER_VARIABLE, FT_STROKER_LINEJOIN_MITER_FIXED = 3 } FT_Stroker_LineJoin; /************************************************************** * * @enum: * FT_Stroker_LineCap * * @description: * These values determine how the end of opened sub-paths are * rendered in a stroke. * * @values: * FT_STROKER_LINECAP_BUTT :: * The end of lines is rendered as a full stop on the last * point itself. * * FT_STROKER_LINECAP_ROUND :: * The end of lines is rendered as a half-circle around the * last point. * * FT_STROKER_LINECAP_SQUARE :: * The end of lines is rendered as a square around the * last point. */ typedef enum FT_Stroker_LineCap_ { FT_STROKER_LINECAP_BUTT = 0, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINECAP_SQUARE } FT_Stroker_LineCap; /************************************************************** * * @enum: * FT_StrokerBorder * * @description: * These values are used to select a given stroke border * in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. * * @values: * FT_STROKER_BORDER_LEFT :: * Select the left border, relative to the drawing direction. * * FT_STROKER_BORDER_RIGHT :: * Select the right border, relative to the drawing direction. * * @note: * Applications are generally interested in the `inside' and `outside' * borders. However, there is no direct mapping between these and the * `left' and `right' ones, since this really depends on the glyph's * drawing orientation, which varies between font formats. * * You can however use @FT_Outline_GetInsideBorder and * @FT_Outline_GetOutsideBorder to get these. */ typedef enum FT_StrokerBorder_ { FT_STROKER_BORDER_LEFT = 0, FT_STROKER_BORDER_RIGHT } FT_StrokerBorder; /************************************************************** * * @function: * FT_Outline_GetInsideBorder * * @description: * Retrieve the @FT_StrokerBorder value corresponding to the * `inside' borders of a given outline. * * @input: * outline :: * The source outline handle. * * @return: * The border index. @FT_STROKER_BORDER_RIGHT for empty or invalid * outlines. */ FT_EXPORT( FT_StrokerBorder ) FT_Outline_GetInsideBorder( FT_Outline* outline ); /************************************************************** * * @function: * FT_Outline_GetOutsideBorder * * @description: * Retrieve the @FT_StrokerBorder value corresponding to the * `outside' borders of a given outline. * * @input: * outline :: * The source outline handle. * * @return: * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid * outlines. */ FT_EXPORT( FT_StrokerBorder ) FT_Outline_GetOutsideBorder( FT_Outline* outline ); /************************************************************** * * @function: * FT_Stroker_New * * @description: * Create a new stroker object. * * @input: * library :: * FreeType library handle. * * @output: * astroker :: * A new stroker object handle. NULL in case of error. * * @return: * FreeType error code. 0~means success. */ FT_EXPORT( FT_Error ) FT_Stroker_New( FT_Library library, FT_Stroker *astroker ); /************************************************************** * * @function: * FT_Stroker_Set * * @description: * Reset a stroker object's attributes. * * @input: * stroker :: * The target stroker handle. * * radius :: * The border radius. * * line_cap :: * The line cap style. * * line_join :: * The line join style. * * miter_limit :: * The miter limit for the FT_STROKER_LINEJOIN_MITER_FIXED and * FT_STROKER_LINEJOIN_MITER_VARIABLE line join styles, * expressed as 16.16 fixed-point value. * * @note: * The radius is expressed in the same units as the outline * coordinates. * * This function calls @FT_Stroker_Rewind automatically. */ FT_EXPORT( void ) FT_Stroker_Set( FT_Stroker stroker, FT_Fixed radius, FT_Stroker_LineCap line_cap, FT_Stroker_LineJoin line_join, FT_Fixed miter_limit ); /************************************************************** * * @function: * FT_Stroker_Rewind * * @description: * Reset a stroker object without changing its attributes. * You should call this function before beginning a new * series of calls to @FT_Stroker_BeginSubPath or * @FT_Stroker_EndSubPath. * * @input: * stroker :: * The target stroker handle. */ FT_EXPORT( void ) FT_Stroker_Rewind( FT_Stroker stroker ); /************************************************************** * * @function: * FT_Stroker_ParseOutline * * @description: * A convenience function used to parse a whole outline with * the stroker. The resulting outline(s) can be retrieved * later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export. * * @input: * stroker :: * The target stroker handle. * * outline :: * The source outline. * * opened :: * A boolean. If~1, the outline is treated as an open path instead * of a closed one. * * @return: * FreeType error code. 0~means success. * * @note: * If `opened' is~0 (the default), the outline is treated as a closed * path, and the stroker generates two distinct `border' outlines. * * If `opened' is~1, the outline is processed as an open path, and the * stroker generates a single `stroke' outline. * * This function calls @FT_Stroker_Rewind automatically. */ FT_EXPORT( FT_Error ) FT_Stroker_ParseOutline( FT_Stroker stroker, FT_Outline* outline, FT_Bool opened ); /************************************************************** * * @function: * FT_Stroker_BeginSubPath * * @description: * Start a new sub-path in the stroker. * * @input: * stroker :: * The target stroker handle. * * to :: * A pointer to the start vector. * * open :: * A boolean. If~1, the sub-path is treated as an open one. * * @return: * FreeType error code. 0~means success. * * @note: * This function is useful when you need to stroke a path that is * not stored as an @FT_Outline object. */ FT_EXPORT( FT_Error ) FT_Stroker_BeginSubPath( FT_Stroker stroker, FT_Vector* to, FT_Bool open ); /************************************************************** * * @function: * FT_Stroker_EndSubPath * * @description: * Close the current sub-path in the stroker. * * @input: * stroker :: * The target stroker handle. * * @return: * FreeType error code. 0~means success. * * @note: * You should call this function after @FT_Stroker_BeginSubPath. * If the subpath was not `opened', this function `draws' a * single line segment to the start position when needed. */ FT_EXPORT( FT_Error ) FT_Stroker_EndSubPath( FT_Stroker stroker ); /************************************************************** * * @function: * FT_Stroker_LineTo * * @description: * `Draw' a single line segment in the stroker's current sub-path, * from the last position. * * @input: * stroker :: * The target stroker handle. * * to :: * A pointer to the destination point. * * @return: * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and * @FT_Stroker_EndSubPath. */ FT_EXPORT( FT_Error ) FT_Stroker_LineTo( FT_Stroker stroker, FT_Vector* to ); /************************************************************** * * @function: * FT_Stroker_ConicTo * * @description: * `Draw' a single quadratic Bezier in the stroker's current sub-path, * from the last position. * * @input: * stroker :: * The target stroker handle. * * control :: * A pointer to a Bezier control point. * * to :: * A pointer to the destination point. * * @return: * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and * @FT_Stroker_EndSubPath. */ FT_EXPORT( FT_Error ) FT_Stroker_ConicTo( FT_Stroker stroker, FT_Vector* control, FT_Vector* to ); /************************************************************** * * @function: * FT_Stroker_CubicTo * * @description: * `Draw' a single cubic Bezier in the stroker's current sub-path, * from the last position. * * @input: * stroker :: * The target stroker handle. * * control1 :: * A pointer to the first Bezier control point. * * control2 :: * A pointer to second Bezier control point. * * to :: * A pointer to the destination point. * * @return: * FreeType error code. 0~means success. * * @note: * You should call this function between @FT_Stroker_BeginSubPath and * @FT_Stroker_EndSubPath. */ FT_EXPORT( FT_Error ) FT_Stroker_CubicTo( FT_Stroker stroker, FT_Vector* control1, FT_Vector* control2, FT_Vector* to ); /************************************************************** * * @function: * FT_Stroker_GetBorderCounts * * @description: * Call this function once you have finished parsing your paths * with the stroker. It returns the number of points and * contours necessary to export one of the `border' or `stroke' * outlines generated by the stroker. * * @input: * stroker :: * The target stroker handle. * * border :: * The border index. * * @output: * anum_points :: * The number of points. * * anum_contours :: * The number of contours. * * @return: * FreeType error code. 0~means success. * * @note: * When an outline, or a sub-path, is `closed', the stroker generates * two independent `border' outlines, named `left' and `right'. * * When the outline, or a sub-path, is `opened', the stroker merges * the `border' outlines with caps. The `left' border receives all * points, while the `right' border becomes empty. * * Use the function @FT_Stroker_GetCounts instead if you want to * retrieve the counts associated to both borders. */ FT_EXPORT( FT_Error ) FT_Stroker_GetBorderCounts( FT_Stroker stroker, FT_StrokerBorder border, FT_UInt *anum_points, FT_UInt *anum_contours ); /************************************************************** * * @function: * FT_Stroker_ExportBorder * * @description: * Call this function after @FT_Stroker_GetBorderCounts to * export the corresponding border to your own @FT_Outline * structure. * * Note that this function appends the border points and * contours to your outline, but does not try to resize its * arrays. * * @input: * stroker :: * The target stroker handle. * * border :: * The border index. * * outline :: * The target outline handle. * * @note: * Always call this function after @FT_Stroker_GetBorderCounts to * get sure that there is enough room in your @FT_Outline object to * receive all new data. * * When an outline, or a sub-path, is `closed', the stroker generates * two independent `border' outlines, named `left' and `right'. * * When the outline, or a sub-path, is `opened', the stroker merges * the `border' outlines with caps. The `left' border receives all * points, while the `right' border becomes empty. * * Use the function @FT_Stroker_Export instead if you want to * retrieve all borders at once. */ FT_EXPORT( void ) FT_Stroker_ExportBorder( FT_Stroker stroker, FT_StrokerBorder border, FT_Outline* outline ); /************************************************************** * * @function: * FT_Stroker_GetCounts * * @description: * Call this function once you have finished parsing your paths * with the stroker. It returns the number of points and * contours necessary to export all points/borders from the stroked * outline/path. * * @input: * stroker :: * The target stroker handle. * * @output: * anum_points :: * The number of points. * * anum_contours :: * The number of contours. * * @return: * FreeType error code. 0~means success. */ FT_EXPORT( FT_Error ) FT_Stroker_GetCounts( FT_Stroker stroker, FT_UInt *anum_points, FT_UInt *anum_contours ); /************************************************************** * * @function: * FT_Stroker_Export * * @description: * Call this function after @FT_Stroker_GetBorderCounts to * export all borders to your own @FT_Outline structure. * * Note that this function appends the border points and * contours to your outline, but does not try to resize its * arrays. * * @input: * stroker :: * The target stroker handle. * * outline :: * The target outline handle. */ FT_EXPORT( void ) FT_Stroker_Export( FT_Stroker stroker, FT_Outline* outline ); /************************************************************** * * @function: * FT_Stroker_Done * * @description: * Destroy a stroker object. * * @input: * stroker :: * A stroker handle. Can be NULL. */ FT_EXPORT( void ) FT_Stroker_Done( FT_Stroker stroker ); /************************************************************** * * @function: * FT_Glyph_Stroke * * @description: * Stroke a given outline glyph object with a given stroker. * * @inout: * pglyph :: * Source glyph handle on input, new glyph handle on output. * * @input: * stroker :: * A stroker handle. * * destroy :: * A Boolean. If~1, the source glyph object is destroyed * on success. * * @return: * FreeType error code. 0~means success. * * @note: * The source glyph is untouched in case of error. * * Adding stroke may yield a significantly wider and taller glyph * depending on how large of a radius was used to stroke the glyph. You * may need to manually adjust horizontal and vertical advance amounts * to account for this added size. */ FT_EXPORT( FT_Error ) FT_Glyph_Stroke( FT_Glyph *pglyph, FT_Stroker stroker, FT_Bool destroy ); /************************************************************** * * @function: * FT_Glyph_StrokeBorder * * @description: * Stroke a given outline glyph object with a given stroker, but * only return either its inside or outside border. * * @inout: * pglyph :: * Source glyph handle on input, new glyph handle on output. * * @input: * stroker :: * A stroker handle. * * inside :: * A Boolean. If~1, return the inside border, otherwise * the outside border. * * destroy :: * A Boolean. If~1, the source glyph object is destroyed * on success. * * @return: * FreeType error code. 0~means success. * * @note: * The source glyph is untouched in case of error. * * Adding stroke may yield a significantly wider and taller glyph * depending on how large of a radius was used to stroke the glyph. You * may need to manually adjust horizontal and vertical advance amounts * to account for this added size. */ FT_EXPORT( FT_Error ) FT_Glyph_StrokeBorder( FT_Glyph *pglyph, FT_Stroker stroker, FT_Bool inside, FT_Bool destroy ); /* */ FT_END_HEADER #endif /* FTSTROKE_H_ */ /* END */ /* Local Variables: */ /* coding: utf-8 */ /* End: */ freetype2/freetype/tttables.h 0000644 00000131224 15146341150 0012272 0 ustar 00 /***************************************************************************/ /* */ /* tttables.h */ /* */ /* Basic SFNT/TrueType tables definitions and interface */ /* (specification only). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef TTTABLES_H_ #define TTTABLES_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* truetype_tables */ /* */ /* <Title> */ /* TrueType Tables */ /* */ /* <Abstract> */ /* TrueType specific table types and functions. */ /* */ /* <Description> */ /* This section contains definitions of some basic tables specific to */ /* TrueType and OpenType as well as some routines used to access and */ /* process them. */ /* */ /* <Order> */ /* TT_Header */ /* TT_HoriHeader */ /* TT_VertHeader */ /* TT_OS2 */ /* TT_Postscript */ /* TT_PCLT */ /* TT_MaxProfile */ /* */ /* FT_Sfnt_Tag */ /* FT_Get_Sfnt_Table */ /* FT_Load_Sfnt_Table */ /* FT_Sfnt_Table_Info */ /* */ /* FT_Get_CMap_Language_ID */ /* FT_Get_CMap_Format */ /* */ /* FT_PARAM_TAG_UNPATENTED_HINTING */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Struct> */ /* TT_Header */ /* */ /* <Description> */ /* A structure to model a TrueType font header table. All fields */ /* follow the OpenType specification. */ /* */ typedef struct TT_Header_ { FT_Fixed Table_Version; FT_Fixed Font_Revision; FT_Long CheckSum_Adjust; FT_Long Magic_Number; FT_UShort Flags; FT_UShort Units_Per_EM; FT_Long Created [2]; FT_Long Modified[2]; FT_Short xMin; FT_Short yMin; FT_Short xMax; FT_Short yMax; FT_UShort Mac_Style; FT_UShort Lowest_Rec_PPEM; FT_Short Font_Direction; FT_Short Index_To_Loc_Format; FT_Short Glyph_Data_Format; } TT_Header; /*************************************************************************/ /* */ /* <Struct> */ /* TT_HoriHeader */ /* */ /* <Description> */ /* A structure to model a TrueType horizontal header, the `hhea' */ /* table, as well as the corresponding horizontal metrics table, */ /* `hmtx'. */ /* */ /* <Fields> */ /* Version :: The table version. */ /* */ /* Ascender :: The font's ascender, i.e., the distance */ /* from the baseline to the top-most of all */ /* glyph points found in the font. */ /* */ /* This value is invalid in many fonts, as */ /* it is usually set by the font designer, */ /* and often reflects only a portion of the */ /* glyphs found in the font (maybe ASCII). */ /* */ /* You should use the `sTypoAscender' field */ /* of the `OS/2' table instead if you want */ /* the correct one. */ /* */ /* Descender :: The font's descender, i.e., the distance */ /* from the baseline to the bottom-most of */ /* all glyph points found in the font. It */ /* is negative. */ /* */ /* This value is invalid in many fonts, as */ /* it is usually set by the font designer, */ /* and often reflects only a portion of the */ /* glyphs found in the font (maybe ASCII). */ /* */ /* You should use the `sTypoDescender' */ /* field of the `OS/2' table instead if you */ /* want the correct one. */ /* */ /* Line_Gap :: The font's line gap, i.e., the distance */ /* to add to the ascender and descender to */ /* get the BTB, i.e., the */ /* baseline-to-baseline distance for the */ /* font. */ /* */ /* advance_Width_Max :: This field is the maximum of all advance */ /* widths found in the font. It can be */ /* used to compute the maximum width of an */ /* arbitrary string of text. */ /* */ /* min_Left_Side_Bearing :: The minimum left side bearing of all */ /* glyphs within the font. */ /* */ /* min_Right_Side_Bearing :: The minimum right side bearing of all */ /* glyphs within the font. */ /* */ /* xMax_Extent :: The maximum horizontal extent (i.e., the */ /* `width' of a glyph's bounding box) for */ /* all glyphs in the font. */ /* */ /* caret_Slope_Rise :: The rise coefficient of the cursor's */ /* slope of the cursor (slope=rise/run). */ /* */ /* caret_Slope_Run :: The run coefficient of the cursor's */ /* slope. */ /* */ /* caret_Offset :: The cursor's offset for slanted fonts. */ /* */ /* Reserved :: 8~reserved bytes. */ /* */ /* metric_Data_Format :: Always~0. */ /* */ /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ /* table -- this value can be smaller than */ /* the total number of glyphs in the font. */ /* */ /* long_metrics :: A pointer into the `hmtx' table. */ /* */ /* short_metrics :: A pointer into the `hmtx' table. */ /* */ /* <Note> */ /* For an OpenType variation font, the values of the following fields */ /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ /* friends) if the font contains an `MVAR' table: `caret_Slope_Rise', */ /* `caret_Slope_Run', and `caret_Offset'. */ /* */ typedef struct TT_HoriHeader_ { FT_Fixed Version; FT_Short Ascender; FT_Short Descender; FT_Short Line_Gap; FT_UShort advance_Width_Max; /* advance width maximum */ FT_Short min_Left_Side_Bearing; /* minimum left-sb */ FT_Short min_Right_Side_Bearing; /* minimum right-sb */ FT_Short xMax_Extent; /* xmax extents */ FT_Short caret_Slope_Rise; FT_Short caret_Slope_Run; FT_Short caret_Offset; FT_Short Reserved[4]; FT_Short metric_Data_Format; FT_UShort number_Of_HMetrics; /* The following fields are not defined by the OpenType specification */ /* but they are used to connect the metrics header to the relevant */ /* `hmtx' table. */ void* long_metrics; void* short_metrics; } TT_HoriHeader; /*************************************************************************/ /* */ /* <Struct> */ /* TT_VertHeader */ /* */ /* <Description> */ /* A structure used to model a TrueType vertical header, the `vhea' */ /* table, as well as the corresponding vertical metrics table, */ /* `vmtx'. */ /* */ /* <Fields> */ /* Version :: The table version. */ /* */ /* Ascender :: The font's ascender, i.e., the distance */ /* from the baseline to the top-most of */ /* all glyph points found in the font. */ /* */ /* This value is invalid in many fonts, as */ /* it is usually set by the font designer, */ /* and often reflects only a portion of */ /* the glyphs found in the font (maybe */ /* ASCII). */ /* */ /* You should use the `sTypoAscender' */ /* field of the `OS/2' table instead if */ /* you want the correct one. */ /* */ /* Descender :: The font's descender, i.e., the */ /* distance from the baseline to the */ /* bottom-most of all glyph points found */ /* in the font. It is negative. */ /* */ /* This value is invalid in many fonts, as */ /* it is usually set by the font designer, */ /* and often reflects only a portion of */ /* the glyphs found in the font (maybe */ /* ASCII). */ /* */ /* You should use the `sTypoDescender' */ /* field of the `OS/2' table instead if */ /* you want the correct one. */ /* */ /* Line_Gap :: The font's line gap, i.e., the distance */ /* to add to the ascender and descender to */ /* get the BTB, i.e., the */ /* baseline-to-baseline distance for the */ /* font. */ /* */ /* advance_Height_Max :: This field is the maximum of all */ /* advance heights found in the font. It */ /* can be used to compute the maximum */ /* height of an arbitrary string of text. */ /* */ /* min_Top_Side_Bearing :: The minimum top side bearing of all */ /* glyphs within the font. */ /* */ /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ /* glyphs within the font. */ /* */ /* yMax_Extent :: The maximum vertical extent (i.e., the */ /* `height' of a glyph's bounding box) for */ /* all glyphs in the font. */ /* */ /* caret_Slope_Rise :: The rise coefficient of the cursor's */ /* slope of the cursor (slope=rise/run). */ /* */ /* caret_Slope_Run :: The run coefficient of the cursor's */ /* slope. */ /* */ /* caret_Offset :: The cursor's offset for slanted fonts. */ /* */ /* Reserved :: 8~reserved bytes. */ /* */ /* metric_Data_Format :: Always~0. */ /* */ /* number_Of_VMetrics :: Number of VMetrics entries in the */ /* `vmtx' table -- this value can be */ /* smaller than the total number of glyphs */ /* in the font. */ /* */ /* long_metrics :: A pointer into the `vmtx' table. */ /* */ /* short_metrics :: A pointer into the `vmtx' table. */ /* */ /* <Note> */ /* For an OpenType variation font, the values of the following fields */ /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ /* friends) if the font contains an `MVAR' table: `Ascender', */ /* `Descender', `Line_Gap', `caret_Slope_Rise', `caret_Slope_Run', */ /* and `caret_Offset'. */ /* */ typedef struct TT_VertHeader_ { FT_Fixed Version; FT_Short Ascender; FT_Short Descender; FT_Short Line_Gap; FT_UShort advance_Height_Max; /* advance height maximum */ FT_Short min_Top_Side_Bearing; /* minimum top-sb */ FT_Short min_Bottom_Side_Bearing; /* minimum bottom-sb */ FT_Short yMax_Extent; /* ymax extents */ FT_Short caret_Slope_Rise; FT_Short caret_Slope_Run; FT_Short caret_Offset; FT_Short Reserved[4]; FT_Short metric_Data_Format; FT_UShort number_Of_VMetrics; /* The following fields are not defined by the OpenType specification */ /* but they are used to connect the metrics header to the relevant */ /* `vmtx' table. */ void* long_metrics; void* short_metrics; } TT_VertHeader; /*************************************************************************/ /* */ /* <Struct> */ /* TT_OS2 */ /* */ /* <Description> */ /* A structure to model a TrueType `OS/2' table. All fields comply */ /* to the OpenType specification. */ /* */ /* Note that we now support old Mac fonts that do not include an */ /* `OS/2' table. In this case, the `version' field is always set to */ /* 0xFFFF. */ /* */ /* <Note> */ /* For an OpenType variation font, the values of the following fields */ /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ /* friends) if the font contains an `MVAR' table: `sCapHeight', */ /* `sTypoAscender', `sTypoDescender', `sTypoLineGap', `sxHeight', */ /* `usWinAscent', `usWinDescent', `yStrikeoutPosition', */ /* `yStrikeoutSize', `ySubscriptXOffset', `ySubScriptXSize', */ /* `ySubscriptYOffset', `ySubscriptYSize', `ySuperscriptXOffset', */ /* `ySuperscriptXSize', `ySuperscriptYOffset', and */ /* `ySuperscriptYSize'. */ /* */ /* Possible values for bits in the `ulUnicodeRangeX' fields are given */ /* by the @TT_UCR_XXX macros. */ /* */ typedef struct TT_OS2_ { FT_UShort version; /* 0x0001 - more or 0xFFFF */ FT_Short xAvgCharWidth; FT_UShort usWeightClass; FT_UShort usWidthClass; FT_UShort fsType; FT_Short ySubscriptXSize; FT_Short ySubscriptYSize; FT_Short ySubscriptXOffset; FT_Short ySubscriptYOffset; FT_Short ySuperscriptXSize; FT_Short ySuperscriptYSize; FT_Short ySuperscriptXOffset; FT_Short ySuperscriptYOffset; FT_Short yStrikeoutSize; FT_Short yStrikeoutPosition; FT_Short sFamilyClass; FT_Byte panose[10]; FT_ULong ulUnicodeRange1; /* Bits 0-31 */ FT_ULong ulUnicodeRange2; /* Bits 32-63 */ FT_ULong ulUnicodeRange3; /* Bits 64-95 */ FT_ULong ulUnicodeRange4; /* Bits 96-127 */ FT_Char achVendID[4]; FT_UShort fsSelection; FT_UShort usFirstCharIndex; FT_UShort usLastCharIndex; FT_Short sTypoAscender; FT_Short sTypoDescender; FT_Short sTypoLineGap; FT_UShort usWinAscent; FT_UShort usWinDescent; /* only version 1 and higher: */ FT_ULong ulCodePageRange1; /* Bits 0-31 */ FT_ULong ulCodePageRange2; /* Bits 32-63 */ /* only version 2 and higher: */ FT_Short sxHeight; FT_Short sCapHeight; FT_UShort usDefaultChar; FT_UShort usBreakChar; FT_UShort usMaxContext; /* only version 5 and higher: */ FT_UShort usLowerOpticalPointSize; /* in twips (1/20th points) */ FT_UShort usUpperOpticalPointSize; /* in twips (1/20th points) */ } TT_OS2; /*************************************************************************/ /* */ /* <Struct> */ /* TT_Postscript */ /* */ /* <Description> */ /* A structure to model a TrueType `post' table. All fields comply */ /* to the OpenType specification. This structure does not reference */ /* a font's PostScript glyph names; use @FT_Get_Glyph_Name to */ /* retrieve them. */ /* */ /* <Note> */ /* For an OpenType variation font, the values of the following fields */ /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ /* friends) if the font contains an `MVAR' table: `underlinePosition' */ /* and `underlineThickness'. */ /* */ typedef struct TT_Postscript_ { FT_Fixed FormatType; FT_Fixed italicAngle; FT_Short underlinePosition; FT_Short underlineThickness; FT_ULong isFixedPitch; FT_ULong minMemType42; FT_ULong maxMemType42; FT_ULong minMemType1; FT_ULong maxMemType1; /* Glyph names follow in the `post' table, but we don't */ /* load them by default. */ } TT_Postscript; /*************************************************************************/ /* */ /* <Struct> */ /* TT_PCLT */ /* */ /* <Description> */ /* A structure to model a TrueType `PCLT' table. All fields comply */ /* to the OpenType specification. */ /* */ typedef struct TT_PCLT_ { FT_Fixed Version; FT_ULong FontNumber; FT_UShort Pitch; FT_UShort xHeight; FT_UShort Style; FT_UShort TypeFamily; FT_UShort CapHeight; FT_UShort SymbolSet; FT_Char TypeFace[16]; FT_Char CharacterComplement[8]; FT_Char FileName[6]; FT_Char StrokeWeight; FT_Char WidthType; FT_Byte SerifStyle; FT_Byte Reserved; } TT_PCLT; /*************************************************************************/ /* */ /* <Struct> */ /* TT_MaxProfile */ /* */ /* <Description> */ /* The maximum profile (`maxp') table contains many max values, which */ /* can be used to pre-allocate arrays for speeding up glyph loading */ /* and hinting. */ /* */ /* <Fields> */ /* version :: The version number. */ /* */ /* numGlyphs :: The number of glyphs in this TrueType */ /* font. */ /* */ /* maxPoints :: The maximum number of points in a */ /* non-composite TrueType glyph. See also */ /* `maxCompositePoints'. */ /* */ /* maxContours :: The maximum number of contours in a */ /* non-composite TrueType glyph. See also */ /* `maxCompositeContours'. */ /* */ /* maxCompositePoints :: The maximum number of points in a */ /* composite TrueType glyph. See also */ /* `maxPoints'. */ /* */ /* maxCompositeContours :: The maximum number of contours in a */ /* composite TrueType glyph. See also */ /* `maxContours'. */ /* */ /* maxZones :: The maximum number of zones used for */ /* glyph hinting. */ /* */ /* maxTwilightPoints :: The maximum number of points in the */ /* twilight zone used for glyph hinting. */ /* */ /* maxStorage :: The maximum number of elements in the */ /* storage area used for glyph hinting. */ /* */ /* maxFunctionDefs :: The maximum number of function */ /* definitions in the TrueType bytecode for */ /* this font. */ /* */ /* maxInstructionDefs :: The maximum number of instruction */ /* definitions in the TrueType bytecode for */ /* this font. */ /* */ /* maxStackElements :: The maximum number of stack elements used */ /* during bytecode interpretation. */ /* */ /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ /* used for glyph hinting. */ /* */ /* maxComponentElements :: The maximum number of simple (i.e., non- */ /* composite) glyphs in a composite glyph. */ /* */ /* maxComponentDepth :: The maximum nesting depth of composite */ /* glyphs. */ /* */ /* <Note> */ /* This structure is only used during font loading. */ /* */ typedef struct TT_MaxProfile_ { FT_Fixed version; FT_UShort numGlyphs; FT_UShort maxPoints; FT_UShort maxContours; FT_UShort maxCompositePoints; FT_UShort maxCompositeContours; FT_UShort maxZones; FT_UShort maxTwilightPoints; FT_UShort maxStorage; FT_UShort maxFunctionDefs; FT_UShort maxInstructionDefs; FT_UShort maxStackElements; FT_UShort maxSizeOfInstructions; FT_UShort maxComponentElements; FT_UShort maxComponentDepth; } TT_MaxProfile; /*************************************************************************/ /* */ /* <Enum> */ /* FT_Sfnt_Tag */ /* */ /* <Description> */ /* An enumeration to specify indices of SFNT tables loaded and parsed */ /* by FreeType during initialization of an SFNT font. Used in the */ /* @FT_Get_Sfnt_Table API function. */ /* */ /* <Values> */ /* FT_SFNT_HEAD :: To access the font's @TT_Header structure. */ /* */ /* FT_SFNT_MAXP :: To access the font's @TT_MaxProfile structure. */ /* */ /* FT_SFNT_OS2 :: To access the font's @TT_OS2 structure. */ /* */ /* FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure. */ /* */ /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader structure. */ /* */ /* FT_SFNT_POST :: To access the font's @TT_Postscript structure. */ /* */ /* FT_SFNT_PCLT :: To access the font's @TT_PCLT structure. */ /* */ typedef enum FT_Sfnt_Tag_ { FT_SFNT_HEAD, FT_SFNT_MAXP, FT_SFNT_OS2, FT_SFNT_HHEA, FT_SFNT_VHEA, FT_SFNT_POST, FT_SFNT_PCLT, FT_SFNT_MAX } FT_Sfnt_Tag; /* these constants are deprecated; use the corresponding `FT_Sfnt_Tag' */ /* values instead */ #define ft_sfnt_head FT_SFNT_HEAD #define ft_sfnt_maxp FT_SFNT_MAXP #define ft_sfnt_os2 FT_SFNT_OS2 #define ft_sfnt_hhea FT_SFNT_HHEA #define ft_sfnt_vhea FT_SFNT_VHEA #define ft_sfnt_post FT_SFNT_POST #define ft_sfnt_pclt FT_SFNT_PCLT /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Sfnt_Table */ /* */ /* <Description> */ /* Return a pointer to a given SFNT table stored within a face. */ /* */ /* <Input> */ /* face :: A handle to the source. */ /* */ /* tag :: The index of the SFNT table. */ /* */ /* <Return> */ /* A type-less pointer to the table. This will be NULL in case of */ /* error, or if the corresponding table was not found *OR* loaded */ /* from the file. */ /* */ /* Use a typecast according to `tag' to access the structure */ /* elements. */ /* */ /* <Note> */ /* The table is owned by the face object and disappears with it. */ /* */ /* This function is only useful to access SFNT tables that are loaded */ /* by the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for */ /* a list. */ /* */ /* Here an example how to access the `vhea' table: */ /* */ /* { */ /* TT_VertHeader* vert_header; */ /* */ /* */ /* vert_header = */ /* (TT_VertHeader*)FT_Get_Sfnt_Table( face, FT_SFNT_VHEA ); */ /* } */ /* */ FT_EXPORT( void* ) FT_Get_Sfnt_Table( FT_Face face, FT_Sfnt_Tag tag ); /************************************************************************** * * @function: * FT_Load_Sfnt_Table * * @description: * Load any SFNT font table into client memory. * * @input: * face :: * A handle to the source face. * * tag :: * The four-byte tag of the table to load. Use value~0 if you want * to access the whole font file. Otherwise, you can use one of the * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new * one with @FT_MAKE_TAG. * * offset :: * The starting offset in the table (or file if tag~==~0). * * @output: * buffer :: * The target buffer address. The client must ensure that the memory * array is big enough to hold the data. * * @inout: * length :: * If the `length' parameter is NULL, try to load the whole table. * Return an error code if it fails. * * Else, if `*length' is~0, exit immediately while returning the * table's (or file) full size in it. * * Else the number of bytes to read from the table or file, from the * starting offset. * * @return: * FreeType error code. 0~means success. * * @note: * If you need to determine the table's length you should first call this * function with `*length' set to~0, as in the following example: * * { * FT_ULong length = 0; * * * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); * if ( error ) { ... table does not exist ... } * * buffer = malloc( length ); * if ( buffer == NULL ) { ... not enough memory ... } * * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); * if ( error ) { ... could not load table ... } * } * * Note that structures like @TT_Header or @TT_OS2 can't be used with * this function; they are limited to @FT_Get_Sfnt_Table. Reason is that * those structures depend on the processor architecture, with varying * size (e.g. 32bit vs. 64bit) or order (big endian vs. little endian). * */ FT_EXPORT( FT_Error ) FT_Load_Sfnt_Table( FT_Face face, FT_ULong tag, FT_Long offset, FT_Byte* buffer, FT_ULong* length ); /************************************************************************** * * @function: * FT_Sfnt_Table_Info * * @description: * Return information on an SFNT table. * * @input: * face :: * A handle to the source face. * * table_index :: * The index of an SFNT table. The function returns * FT_Err_Table_Missing for an invalid value. * * @inout: * tag :: * The name tag of the SFNT table. If the value is NULL, `table_index' * is ignored, and `length' returns the number of SFNT tables in the * font. * * @output: * length :: * The length of the SFNT table (or the number of SFNT tables, depending * on `tag'). * * @return: * FreeType error code. 0~means success. * * @note: * While parsing fonts, FreeType handles SFNT tables with length zero as * missing. * */ FT_EXPORT( FT_Error ) FT_Sfnt_Table_Info( FT_Face face, FT_UInt table_index, FT_ULong *tag, FT_ULong *length ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_CMap_Language_ID */ /* */ /* <Description> */ /* Return cmap language ID as specified in the OpenType standard. */ /* Definitions of language ID values are in file @FT_TRUETYPE_IDS_H. */ /* */ /* <Input> */ /* charmap :: */ /* The target charmap. */ /* */ /* <Return> */ /* The language ID of `charmap'. If `charmap' doesn't belong to an */ /* SFNT face, just return~0 as the default value. */ /* */ /* For a format~14 cmap (to access Unicode IVS), the return value is */ /* 0xFFFFFFFF. */ /* */ FT_EXPORT( FT_ULong ) FT_Get_CMap_Language_ID( FT_CharMap charmap ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_CMap_Format */ /* */ /* <Description> */ /* Return the format of an SFNT `cmap' table. */ /* */ /* <Input> */ /* charmap :: */ /* The target charmap. */ /* */ /* <Return> */ /* The format of `charmap'. If `charmap' doesn't belong to an SFNT */ /* face, return -1. */ /* */ FT_EXPORT( FT_Long ) FT_Get_CMap_Format( FT_CharMap charmap ); /* */ FT_END_HEADER #endif /* TTTABLES_H_ */ /* END */ freetype2/freetype/ftglyph.h 0000644 00000114731 15146341150 0012131 0 ustar 00 /***************************************************************************/ /* */ /* ftglyph.h */ /* */ /* FreeType convenience functions to handle glyphs (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This file contains the definition of several convenience functions */ /* that can be used by client applications to easily retrieve glyph */ /* bitmaps and outlines from a given face. */ /* */ /* These functions should be optional if you are writing a font server */ /* or text layout engine on top of FreeType. However, they are pretty */ /* handy for many other simple uses of the library. */ /* */ /*************************************************************************/ #ifndef FTGLYPH_H_ #define FTGLYPH_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* glyph_management */ /* */ /* <Title> */ /* Glyph Management */ /* */ /* <Abstract> */ /* Generic interface to manage individual glyph data. */ /* */ /* <Description> */ /* This section contains definitions used to manage glyph data */ /* through generic FT_Glyph objects. Each of them can contain a */ /* bitmap, a vector outline, or even images in other formats. */ /* */ /*************************************************************************/ /* forward declaration to a private type */ typedef struct FT_Glyph_Class_ FT_Glyph_Class; /*************************************************************************/ /* */ /* <Type> */ /* FT_Glyph */ /* */ /* <Description> */ /* Handle to an object used to model generic glyph images. It is a */ /* pointer to the @FT_GlyphRec structure and can contain a glyph */ /* bitmap or pointer. */ /* */ /* <Note> */ /* Glyph objects are not owned by the library. You must thus release */ /* them manually (through @FT_Done_Glyph) _before_ calling */ /* @FT_Done_FreeType. */ /* */ typedef struct FT_GlyphRec_* FT_Glyph; /*************************************************************************/ /* */ /* <Struct> */ /* FT_GlyphRec */ /* */ /* <Description> */ /* The root glyph structure contains a given glyph image plus its */ /* advance width in 16.16 fixed-point format. */ /* */ /* <Fields> */ /* library :: A handle to the FreeType library object. */ /* */ /* clazz :: A pointer to the glyph's class. Private. */ /* */ /* format :: The format of the glyph's image. */ /* */ /* advance :: A 16.16 vector that gives the glyph's advance width. */ /* */ typedef struct FT_GlyphRec_ { FT_Library library; const FT_Glyph_Class* clazz; FT_Glyph_Format format; FT_Vector advance; } FT_GlyphRec; /*************************************************************************/ /* */ /* <Type> */ /* FT_BitmapGlyph */ /* */ /* <Description> */ /* A handle to an object used to model a bitmap glyph image. This is */ /* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. */ /* */ typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph; /*************************************************************************/ /* */ /* <Struct> */ /* FT_BitmapGlyphRec */ /* */ /* <Description> */ /* A structure used for bitmap glyph images. This really is a */ /* `sub-class' of @FT_GlyphRec. */ /* */ /* <Fields> */ /* root :: The root @FT_Glyph fields. */ /* */ /* left :: The left-side bearing, i.e., the horizontal distance */ /* from the current pen position to the left border of the */ /* glyph bitmap. */ /* */ /* top :: The top-side bearing, i.e., the vertical distance from */ /* the current pen position to the top border of the glyph */ /* bitmap. This distance is positive for upwards~y! */ /* */ /* bitmap :: A descriptor for the bitmap. */ /* */ /* <Note> */ /* You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have */ /* `glyph->format == FT_GLYPH_FORMAT_BITMAP'. This lets you access */ /* the bitmap's contents easily. */ /* */ /* The corresponding pixel buffer is always owned by @FT_BitmapGlyph */ /* and is thus created and destroyed with it. */ /* */ typedef struct FT_BitmapGlyphRec_ { FT_GlyphRec root; FT_Int left; FT_Int top; FT_Bitmap bitmap; } FT_BitmapGlyphRec; /*************************************************************************/ /* */ /* <Type> */ /* FT_OutlineGlyph */ /* */ /* <Description> */ /* A handle to an object used to model an outline glyph image. This */ /* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */ /* */ typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph; /*************************************************************************/ /* */ /* <Struct> */ /* FT_OutlineGlyphRec */ /* */ /* <Description> */ /* A structure used for outline (vectorial) glyph images. This */ /* really is a `sub-class' of @FT_GlyphRec. */ /* */ /* <Fields> */ /* root :: The root @FT_Glyph fields. */ /* */ /* outline :: A descriptor for the outline. */ /* */ /* <Note> */ /* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have */ /* `glyph->format == FT_GLYPH_FORMAT_OUTLINE'. This lets you access */ /* the outline's content easily. */ /* */ /* As the outline is extracted from a glyph slot, its coordinates are */ /* expressed normally in 26.6 pixels, unless the flag */ /* @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char(). */ /* */ /* The outline's tables are always owned by the object and are */ /* destroyed with it. */ /* */ typedef struct FT_OutlineGlyphRec_ { FT_GlyphRec root; FT_Outline outline; } FT_OutlineGlyphRec; /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Glyph */ /* */ /* <Description> */ /* A function used to extract a glyph image from a slot. Note that */ /* the created @FT_Glyph object must be released with @FT_Done_Glyph. */ /* */ /* <Input> */ /* slot :: A handle to the source glyph slot. */ /* */ /* <Output> */ /* aglyph :: A handle to the glyph object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* Because `*aglyph->advance.x' and '*aglyph->advance.y' are 16.16 */ /* fixed-point numbers, `slot->advance.x' and `slot->advance.y' */ /* (which are in 26.6 fixed-point format) must be in the range */ /* ]-32768;32768[. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph( FT_GlyphSlot slot, FT_Glyph *aglyph ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Glyph_Copy */ /* */ /* <Description> */ /* A function used to copy a glyph image. Note that the created */ /* @FT_Glyph object must be released with @FT_Done_Glyph. */ /* */ /* <Input> */ /* source :: A handle to the source glyph object. */ /* */ /* <Output> */ /* target :: A handle to the target glyph object. 0~in case of */ /* error. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Glyph_Copy( FT_Glyph source, FT_Glyph *target ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Glyph_Transform */ /* */ /* <Description> */ /* Transform a glyph image if its format is scalable. */ /* */ /* <InOut> */ /* glyph :: A handle to the target glyph object. */ /* */ /* <Input> */ /* matrix :: A pointer to a 2x2 matrix to apply. */ /* */ /* delta :: A pointer to a 2d vector to apply. Coordinates are */ /* expressed in 1/64th of a pixel. */ /* */ /* <Return> */ /* FreeType error code (if not 0, the glyph format is not scalable). */ /* */ /* <Note> */ /* The 2x2 transformation matrix is also applied to the glyph's */ /* advance vector. */ /* */ FT_EXPORT( FT_Error ) FT_Glyph_Transform( FT_Glyph glyph, FT_Matrix* matrix, FT_Vector* delta ); /*************************************************************************/ /* */ /* <Enum> */ /* FT_Glyph_BBox_Mode */ /* */ /* <Description> */ /* The mode how the values of @FT_Glyph_Get_CBox are returned. */ /* */ /* <Values> */ /* FT_GLYPH_BBOX_UNSCALED :: */ /* Return unscaled font units. */ /* */ /* FT_GLYPH_BBOX_SUBPIXELS :: */ /* Return unfitted 26.6 coordinates. */ /* */ /* FT_GLYPH_BBOX_GRIDFIT :: */ /* Return grid-fitted 26.6 coordinates. */ /* */ /* FT_GLYPH_BBOX_TRUNCATE :: */ /* Return coordinates in integer pixels. */ /* */ /* FT_GLYPH_BBOX_PIXELS :: */ /* Return grid-fitted pixel coordinates. */ /* */ typedef enum FT_Glyph_BBox_Mode_ { FT_GLYPH_BBOX_UNSCALED = 0, FT_GLYPH_BBOX_SUBPIXELS = 0, FT_GLYPH_BBOX_GRIDFIT = 1, FT_GLYPH_BBOX_TRUNCATE = 2, FT_GLYPH_BBOX_PIXELS = 3 } FT_Glyph_BBox_Mode; /* these constants are deprecated; use the corresponding */ /* `FT_Glyph_BBox_Mode' values instead */ #define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED #define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS #define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT #define ft_glyph_bbox_truncate FT_GLYPH_BBOX_TRUNCATE #define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS /*************************************************************************/ /* */ /* <Function> */ /* FT_Glyph_Get_CBox */ /* */ /* <Description> */ /* Return a glyph's `control box'. The control box encloses all the */ /* outline's points, including Bezier control points. Though it */ /* coincides with the exact bounding box for most glyphs, it can be */ /* slightly larger in some situations (like when rotating an outline */ /* that contains Bezier outside arcs). */ /* */ /* Computing the control box is very fast, while getting the bounding */ /* box can take much more time as it needs to walk over all segments */ /* and arcs in the outline. To get the latter, you can use the */ /* `ftbbox' component, which is dedicated to this single task. */ /* */ /* <Input> */ /* glyph :: A handle to the source glyph object. */ /* */ /* mode :: The mode that indicates how to interpret the returned */ /* bounding box values. */ /* */ /* <Output> */ /* acbox :: The glyph coordinate bounding box. Coordinates are */ /* expressed in 1/64th of pixels if it is grid-fitted. */ /* */ /* <Note> */ /* Coordinates are relative to the glyph origin, using the y~upwards */ /* convention. */ /* */ /* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' */ /* must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font */ /* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS */ /* is another name for this constant. */ /* */ /* If the font is tricky and the glyph has been loaded with */ /* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get */ /* reasonable values for the CBox it is necessary to load the glyph */ /* at a large ppem value (so that the hinting instructions can */ /* properly shift and scale the subglyphs), then extracting the CBox, */ /* which can be eventually converted back to font units. */ /* */ /* Note that the maximum coordinates are exclusive, which means that */ /* one can compute the width and height of the glyph image (be it in */ /* integer or 26.6 pixels) as: */ /* */ /* { */ /* width = bbox.xMax - bbox.xMin; */ /* height = bbox.yMax - bbox.yMin; */ /* } */ /* */ /* Note also that for 26.6 coordinates, if `bbox_mode' is set to */ /* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, */ /* which corresponds to: */ /* */ /* { */ /* bbox.xMin = FLOOR(bbox.xMin); */ /* bbox.yMin = FLOOR(bbox.yMin); */ /* bbox.xMax = CEILING(bbox.xMax); */ /* bbox.yMax = CEILING(bbox.yMax); */ /* } */ /* */ /* To get the bbox in pixel coordinates, set `bbox_mode' to */ /* @FT_GLYPH_BBOX_TRUNCATE. */ /* */ /* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' */ /* to @FT_GLYPH_BBOX_PIXELS. */ /* */ FT_EXPORT( void ) FT_Glyph_Get_CBox( FT_Glyph glyph, FT_UInt bbox_mode, FT_BBox *acbox ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Glyph_To_Bitmap */ /* */ /* <Description> */ /* Convert a given glyph object to a bitmap glyph object. */ /* */ /* <InOut> */ /* the_glyph :: A pointer to a handle to the target glyph. */ /* */ /* <Input> */ /* render_mode :: An enumeration that describes how the data is */ /* rendered. */ /* */ /* origin :: A pointer to a vector used to translate the glyph */ /* image before rendering. Can be~0 (if no */ /* translation). The origin is expressed in */ /* 26.6 pixels. */ /* */ /* destroy :: A boolean that indicates that the original glyph */ /* image should be destroyed by this function. It is */ /* never destroyed in case of error. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* This function does nothing if the glyph format isn't scalable. */ /* */ /* The glyph image is translated with the `origin' vector before */ /* rendering. */ /* */ /* The first parameter is a pointer to an @FT_Glyph handle, that will */ /* be _replaced_ by this function (with newly allocated data). */ /* Typically, you would use (omitting error handling): */ /* */ /* */ /* { */ /* FT_Glyph glyph; */ /* FT_BitmapGlyph glyph_bitmap; */ /* */ /* */ /* // load glyph */ /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAULT ); */ /* */ /* // extract glyph image */ /* error = FT_Get_Glyph( face->glyph, &glyph ); */ /* */ /* // convert to a bitmap (default render mode + destroying old) */ /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ /* { */ /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL, */ /* 0, 1 ); */ /* if ( error ) // `glyph' unchanged */ /* ... */ /* } */ /* */ /* // access bitmap content by typecasting */ /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ /* */ /* // do funny stuff with it, like blitting/drawing */ /* ... */ /* */ /* // discard glyph image (bitmap or not) */ /* FT_Done_Glyph( glyph ); */ /* } */ /* */ /* */ /* Here another example, again without error handling: */ /* */ /* */ /* { */ /* FT_Glyph glyphs[MAX_GLYPHS] */ /* */ /* */ /* ... */ /* */ /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ /* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) || */ /* FT_Get_Glyph ( face->glyph, &glyph[idx] ); */ /* */ /* ... */ /* */ /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ /* { */ /* FT_Glyph bitmap = glyphs[idx]; */ /* */ /* */ /* ... */ /* */ /* // after this call, `bitmap' no longer points into */ /* // the `glyphs' array (and the old value isn't destroyed) */ /* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 ); */ /* */ /* ... */ /* */ /* FT_Done_Glyph( bitmap ); */ /* } */ /* */ /* ... */ /* */ /* for ( idx = 0; i < MAX_GLYPHS; i++ ) */ /* FT_Done_Glyph( glyphs[idx] ); */ /* } */ /* */ FT_EXPORT( FT_Error ) FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, FT_Render_Mode render_mode, FT_Vector* origin, FT_Bool destroy ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Done_Glyph */ /* */ /* <Description> */ /* Destroy a given glyph. */ /* */ /* <Input> */ /* glyph :: A handle to the target glyph object. */ /* */ FT_EXPORT( void ) FT_Done_Glyph( FT_Glyph glyph ); /* */ /* other helpful functions */ /*************************************************************************/ /* */ /* <Section> */ /* computations */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_Matrix_Multiply */ /* */ /* <Description> */ /* Perform the matrix operation `b = a*b'. */ /* */ /* <Input> */ /* a :: A pointer to matrix `a'. */ /* */ /* <InOut> */ /* b :: A pointer to matrix `b'. */ /* */ /* <Note> */ /* The result is undefined if either `a' or `b' is zero. */ /* */ /* Since the function uses wrap-around arithmetic, results become */ /* meaningless if the arguments are very large. */ /* */ FT_EXPORT( void ) FT_Matrix_Multiply( const FT_Matrix* a, FT_Matrix* b ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Matrix_Invert */ /* */ /* <Description> */ /* Invert a 2x2 matrix. Return an error if it can't be inverted. */ /* */ /* <InOut> */ /* matrix :: A pointer to the target matrix. Remains untouched in */ /* case of error. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Matrix_Invert( FT_Matrix* matrix ); /* */ FT_END_HEADER #endif /* FTGLYPH_H_ */ /* END */ /* Local Variables: */ /* coding: utf-8 */ /* End: */ freetype2/freetype/ftlcdfil.h 0000644 00000027547 15146341150 0012253 0 ustar 00 /***************************************************************************/ /* */ /* ftlcdfil.h */ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs */ /* (specification). */ /* */ /* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTLCDFIL_H_ #define FTLCDFIL_H_ #include <ft2build.h> #include FT_FREETYPE_H #include FT_PARAMETER_TAGS_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************** * * @section: * lcd_filtering * * @title: * LCD Filtering * * @abstract: * Reduce color fringes of subpixel-rendered bitmaps. * * @description: * Should you #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your * `ftoption.h', which enables patented ClearType-style rendering, * the LCD-optimized glyph bitmaps should be filtered to reduce color * fringes inherent to this technology. The default FreeType LCD * rendering uses different technology, and API described below, * although available, does nothing. * * ClearType-style LCD rendering exploits the color-striped structure of * LCD pixels, increasing the available resolution in the direction of * the stripe (usually horizontal RGB) by a factor of~3. Since these * subpixels are color pixels, using them unfiltered creates severe * color fringes. Use the @FT_Library_SetLcdFilter API to specify a * low-pass filter, which is then applied to subpixel-rendered bitmaps * generated through @FT_Render_Glyph. The filter sacrifices some of * the higher resolution to reduce color fringes, making the glyph image * slightly blurrier. Positional improvements will remain. * * A filter should have two properties: * * 1) It should be normalized, meaning the sum of the 5~components * should be 256 (0x100). It is possible to go above or under this * target sum, however: going under means tossing out contrast, going * over means invoking clamping and thereby non-linearities that * increase contrast somewhat at the expense of greater distortion * and color-fringing. Contrast is better enhanced through stem * darkening. * * 2) It should be color-balanced, meaning a filter `{~a, b, c, b, a~}' * where a~+ b~=~c. It distributes the computed coverage for one * subpixel to all subpixels equally, sacrificing some won resolution * but drastically reducing color-fringing. Positioning improvements * remain! Note that color-fringing can only really be minimized * when using a color-balanced filter and alpha-blending the glyph * onto a surface in linear space; see @FT_Render_Glyph. * * Regarding the form, a filter can be a `boxy' filter or a `beveled' * filter. Boxy filters are sharper but are less forgiving of non-ideal * gamma curves of a screen (viewing angles!), beveled filters are * fuzzier but more tolerant. * * Examples: * * - [0x10 0x40 0x70 0x40 0x10] is beveled and neither balanced nor * normalized. * * - [0x1A 0x33 0x4D 0x33 0x1A] is beveled and balanced but not * normalized. * * - [0x19 0x33 0x66 0x4c 0x19] is beveled and normalized but not * balanced. * * - [0x00 0x4c 0x66 0x4c 0x00] is boxily beveled and normalized but not * balanced. * * - [0x00 0x55 0x56 0x55 0x00] is boxy, normalized, and almost * balanced. * * - [0x08 0x4D 0x56 0x4D 0x08] is beveled, normalized and, almost * balanced. * * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, * @FT_Load_Glyph, and @FT_Load_Char. It does _not_ affect the output * of @FT_Outline_Render and @FT_Outline_Get_Bitmap. * * If this feature is activated, the dimensions of LCD glyph bitmaps are * either wider or taller than the dimensions of the corresponding * outline with regard to the pixel grid. For example, for * @FT_RENDER_MODE_LCD, the filter adds 3~subpixels to the left, and * 3~subpixels to the right. The bitmap offset values are adjusted * accordingly, so clients shouldn't need to modify their layout and * glyph positioning code when enabling the filter. * * It is important to understand that linear alpha blending and gamma * correction is critical for correctly rendering glyphs onto surfaces * without artifacts and even more critical when subpixel rendering is * involved. * * Each of the 3~alpha values (subpixels) is independently used to blend * one color channel. That is, red alpha blends the red channel of the * text color with the red channel of the background pixel. The * distribution of density values by the color-balanced filter assumes * alpha blending is done in linear space; only then color artifacts * cancel out. */ /**************************************************************************** * * @enum: * FT_LcdFilter * * @description: * A list of values to identify various types of LCD filters. * * @values: * FT_LCD_FILTER_NONE :: * Do not perform filtering. When used with subpixel rendering, this * results in sometimes severe color fringes. * * FT_LCD_FILTER_DEFAULT :: * The default filter reduces color fringes considerably, at the cost * of a slight blurriness in the output. * * It is a beveled, normalized, and color-balanced five-tap filter * that is more forgiving to screens with non-ideal gamma curves and * viewing angles. Note that while color-fringing is reduced, it can * only be minimized by using linear alpha blending and gamma * correction to render glyphs onto surfaces. The default filter * weights are [0x08 0x4D 0x56 0x4D 0x08]. * * FT_LCD_FILTER_LIGHT :: * The light filter is a variant that is sharper at the cost of * slightly more color fringes than the default one. * * It is a boxy, normalized, and color-balanced three-tap filter that * is less forgiving to screens with non-ideal gamma curves and * viewing angles. This filter works best when the rendering system * uses linear alpha blending and gamma correction to render glyphs * onto surfaces. The light filter weights are * [0x00 0x55 0x56 0x55 0x00]. * * FT_LCD_FILTER_LEGACY :: * This filter corresponds to the original libXft color filter. It * provides high contrast output but can exhibit really bad color * fringes if glyphs are not extremely well hinted to the pixel grid. * In other words, it only works well if the TrueType bytecode * interpreter is enabled *and* high-quality hinted fonts are used. * * This filter is only provided for comparison purposes, and might be * disabled or stay unsupported in the future. * * FT_LCD_FILTER_LEGACY1 :: * For historical reasons, the FontConfig library returns a different * enumeration value for legacy LCD filtering. To make code work that * (incorrectly) forwards FontConfig's enumeration value to * @FT_Library_SetLcdFilter without proper mapping, it is thus easiest * to have another enumeration value, which is completely equal to * `FT_LCD_FILTER_LEGACY'. * * @since: * 2.3.0 (`FT_LCD_FILTER_LEGACY1' since 2.6.2) */ typedef enum FT_LcdFilter_ { FT_LCD_FILTER_NONE = 0, FT_LCD_FILTER_DEFAULT = 1, FT_LCD_FILTER_LIGHT = 2, FT_LCD_FILTER_LEGACY1 = 3, FT_LCD_FILTER_LEGACY = 16, FT_LCD_FILTER_MAX /* do not remove */ } FT_LcdFilter; /************************************************************************** * * @func: * FT_Library_SetLcdFilter * * @description: * This function is used to apply color filtering to LCD decimated * bitmaps, like the ones used when calling @FT_Render_Glyph with * @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V. * * @input: * library :: * A handle to the target library instance. * * filter :: * The filter type. * * You can use @FT_LCD_FILTER_NONE here to disable this feature, or * @FT_LCD_FILTER_DEFAULT to use a default filter that should work * well on most LCD screens. * * @return: * FreeType error code. 0~means success. * * @note: * This feature is always disabled by default. Clients must make an * explicit call to this function with a `filter' value other than * @FT_LCD_FILTER_NONE in order to enable it. * * Due to *PATENTS* covering subpixel rendering, this function doesn't * do anything except returning `FT_Err_Unimplemented_Feature' if the * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not * defined in your build of the library, which should correspond to all * default builds of FreeType. * * @since: * 2.3.0 */ FT_EXPORT( FT_Error ) FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ); /************************************************************************** * * @func: * FT_Library_SetLcdFilterWeights * * @description: * This function can be used to enable LCD filter with custom weights, * instead of using presets in @FT_Library_SetLcdFilter. * * @input: * library :: * A handle to the target library instance. * * weights :: * A pointer to an array; the function copies the first five bytes and * uses them to specify the filter weights. * * @return: * FreeType error code. 0~means success. * * @note: * Due to *PATENTS* covering subpixel rendering, this function doesn't * do anything except returning `FT_Err_Unimplemented_Feature' if the * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not * defined in your build of the library, which should correspond to all * default builds of FreeType. * * LCD filter weights can also be set per face using @FT_Face_Properties * with @FT_PARAM_TAG_LCD_FILTER_WEIGHTS. * * @since: * 2.4.0 */ FT_EXPORT( FT_Error ) FT_Library_SetLcdFilterWeights( FT_Library library, unsigned char *weights ); /* * @type: * FT_LcdFiveTapFilter * * @description: * A typedef for passing the five LCD filter weights to * @FT_Face_Properties within an @FT_Parameter structure. * * @since: * 2.8 * */ #define FT_LCD_FILTER_FIVE_TAPS 5 typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS]; /* */ FT_END_HEADER #endif /* FTLCDFIL_H_ */ /* END */ freetype2/freetype/ftcid.h 0000644 00000013022 15146341150 0011534 0 ustar 00 /***************************************************************************/ /* */ /* ftcid.h */ /* */ /* FreeType API for accessing CID font information (specification). */ /* */ /* Copyright 2007-2018 by */ /* Dereg Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTCID_H_ #define FTCID_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* cid_fonts */ /* */ /* <Title> */ /* CID Fonts */ /* */ /* <Abstract> */ /* CID-keyed font specific API. */ /* */ /* <Description> */ /* This section contains the declaration of CID-keyed font specific */ /* functions. */ /* */ /*************************************************************************/ /********************************************************************** * * @function: * FT_Get_CID_Registry_Ordering_Supplement * * @description: * Retrieve the Registry/Ordering/Supplement triple (also known as the * "R/O/S") from a CID-keyed font. * * @input: * face :: * A handle to the input face. * * @output: * registry :: * The registry, as a C~string, owned by the face. * * ordering :: * The ordering, as a C~string, owned by the face. * * supplement :: * The supplement. * * @return: * FreeType error code. 0~means success. * * @note: * This function only works with CID faces, returning an error * otherwise. * * @since: * 2.3.6 */ FT_EXPORT( FT_Error ) FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, const char* *registry, const char* *ordering, FT_Int *supplement ); /********************************************************************** * * @function: * FT_Get_CID_Is_Internally_CID_Keyed * * @description: * Retrieve the type of the input face, CID keyed or not. In * contrast to the @FT_IS_CID_KEYED macro this function returns * successfully also for CID-keyed fonts in an SFNT wrapper. * * @input: * face :: * A handle to the input face. * * @output: * is_cid :: * The type of the face as an @FT_Bool. * * @return: * FreeType error code. 0~means success. * * @note: * This function only works with CID faces and OpenType fonts, * returning an error otherwise. * * @since: * 2.3.9 */ FT_EXPORT( FT_Error ) FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, FT_Bool *is_cid ); /********************************************************************** * * @function: * FT_Get_CID_From_Glyph_Index * * @description: * Retrieve the CID of the input glyph index. * * @input: * face :: * A handle to the input face. * * glyph_index :: * The input glyph index. * * @output: * cid :: * The CID as an @FT_UInt. * * @return: * FreeType error code. 0~means success. * * @note: * This function only works with CID faces and OpenType fonts, * returning an error otherwise. * * @since: * 2.3.9 */ FT_EXPORT( FT_Error ) FT_Get_CID_From_Glyph_Index( FT_Face face, FT_UInt glyph_index, FT_UInt *cid ); /* */ FT_END_HEADER #endif /* FTCID_H_ */ /* END */ freetype2/freetype/ftbdf.h 0000644 00000015211 15146341150 0011532 0 ustar 00 /***************************************************************************/ /* */ /* ftbdf.h */ /* */ /* FreeType API for accessing BDF-specific strings (specification). */ /* */ /* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTBDF_H_ #define FTBDF_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* bdf_fonts */ /* */ /* <Title> */ /* BDF and PCF Files */ /* */ /* <Abstract> */ /* BDF and PCF specific API. */ /* */ /* <Description> */ /* This section contains the declaration of functions specific to BDF */ /* and PCF fonts. */ /* */ /*************************************************************************/ /********************************************************************** * * @enum: * BDF_PropertyType * * @description: * A list of BDF property types. * * @values: * BDF_PROPERTY_TYPE_NONE :: * Value~0 is used to indicate a missing property. * * BDF_PROPERTY_TYPE_ATOM :: * Property is a string atom. * * BDF_PROPERTY_TYPE_INTEGER :: * Property is a 32-bit signed integer. * * BDF_PROPERTY_TYPE_CARDINAL :: * Property is a 32-bit unsigned integer. */ typedef enum BDF_PropertyType_ { BDF_PROPERTY_TYPE_NONE = 0, BDF_PROPERTY_TYPE_ATOM = 1, BDF_PROPERTY_TYPE_INTEGER = 2, BDF_PROPERTY_TYPE_CARDINAL = 3 } BDF_PropertyType; /********************************************************************** * * @type: * BDF_Property * * @description: * A handle to a @BDF_PropertyRec structure to model a given * BDF/PCF property. */ typedef struct BDF_PropertyRec_* BDF_Property; /********************************************************************** * * @struct: * BDF_PropertyRec * * @description: * This structure models a given BDF/PCF property. * * @fields: * type :: * The property type. * * u.atom :: * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. May be * NULL, indicating an empty string. * * u.integer :: * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. * * u.cardinal :: * An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL. */ typedef struct BDF_PropertyRec_ { BDF_PropertyType type; union { const char* atom; FT_Int32 integer; FT_UInt32 cardinal; } u; } BDF_PropertyRec; /********************************************************************** * * @function: * FT_Get_BDF_Charset_ID * * @description: * Retrieve a BDF font character set identity, according to * the BDF specification. * * @input: * face :: * A handle to the input face. * * @output: * acharset_encoding :: * Charset encoding, as a C~string, owned by the face. * * acharset_registry :: * Charset registry, as a C~string, owned by the face. * * @return: * FreeType error code. 0~means success. * * @note: * This function only works with BDF faces, returning an error otherwise. */ FT_EXPORT( FT_Error ) FT_Get_BDF_Charset_ID( FT_Face face, const char* *acharset_encoding, const char* *acharset_registry ); /********************************************************************** * * @function: * FT_Get_BDF_Property * * @description: * Retrieve a BDF property from a BDF or PCF font file. * * @input: * face :: A handle to the input face. * * name :: The property name. * * @output: * aproperty :: The property. * * @return: * FreeType error code. 0~means success. * * @note: * This function works with BDF _and_ PCF fonts. It returns an error * otherwise. It also returns an error if the property is not in the * font. * * A `property' is a either key-value pair within the STARTPROPERTIES * ... ENDPROPERTIES block of a BDF font or a key-value pair from the * `info->props' array within a `FontRec' structure of a PCF font. * * Integer properties are always stored as `signed' within PCF fonts; * consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value * for BDF fonts only. * * In case of error, `aproperty->type' is always set to * @BDF_PROPERTY_TYPE_NONE. */ FT_EXPORT( FT_Error ) FT_Get_BDF_Property( FT_Face face, const char* prop_name, BDF_PropertyRec *aproperty ); /* */ FT_END_HEADER #endif /* FTBDF_H_ */ /* END */ freetype2/freetype/ftoutln.h 0000644 00000105630 15146341150 0012145 0 ustar 00 /***************************************************************************/ /* */ /* ftoutln.h */ /* */ /* Support for the FT_Outline type used to store glyph shapes of */ /* most scalable font formats (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTOUTLN_H_ #define FTOUTLN_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* outline_processing */ /* */ /* <Title> */ /* Outline Processing */ /* */ /* <Abstract> */ /* Functions to create, transform, and render vectorial glyph images. */ /* */ /* <Description> */ /* This section contains routines used to create and destroy scalable */ /* glyph images known as `outlines'. These can also be measured, */ /* transformed, and converted into bitmaps and pixmaps. */ /* */ /* <Order> */ /* FT_Outline */ /* FT_Outline_New */ /* FT_Outline_Done */ /* FT_Outline_Copy */ /* FT_Outline_Translate */ /* FT_Outline_Transform */ /* FT_Outline_Embolden */ /* FT_Outline_EmboldenXY */ /* FT_Outline_Reverse */ /* FT_Outline_Check */ /* */ /* FT_Outline_Get_CBox */ /* FT_Outline_Get_BBox */ /* */ /* FT_Outline_Get_Bitmap */ /* FT_Outline_Render */ /* FT_Outline_Decompose */ /* FT_Outline_Funcs */ /* FT_Outline_MoveToFunc */ /* FT_Outline_LineToFunc */ /* FT_Outline_ConicToFunc */ /* FT_Outline_CubicToFunc */ /* */ /* FT_Orientation */ /* FT_Outline_Get_Orientation */ /* */ /* FT_OUTLINE_XXX */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Decompose */ /* */ /* <Description> */ /* Walk over an outline's structure to decompose it into individual */ /* segments and Bezier arcs. This function also emits `move to' */ /* operations to indicate the start of new contours in the outline. */ /* */ /* <Input> */ /* outline :: A pointer to the source target. */ /* */ /* func_interface :: A table of `emitters', i.e., function pointers */ /* called during decomposition to indicate path */ /* operations. */ /* */ /* <InOut> */ /* user :: A typeless pointer that is passed to each */ /* emitter during the decomposition. It can be */ /* used to store the state during the */ /* decomposition. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* A contour that contains a single point only is represented by a */ /* `move to' operation followed by `line to' to the same point. In */ /* most cases, it is best to filter this out before using the */ /* outline for stroking purposes (otherwise it would result in a */ /* visible dot when round caps are used). */ /* */ /* Similarly, the function returns success for an empty outline also */ /* (doing nothing, this is, not calling any emitter); if necessary, */ /* you should filter this out, too. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Decompose( FT_Outline* outline, const FT_Outline_Funcs* func_interface, void* user ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_New */ /* */ /* <Description> */ /* Create a new outline of a given size. */ /* */ /* <Input> */ /* library :: A handle to the library object from where the */ /* outline is allocated. Note however that the new */ /* outline will *not* necessarily be *freed*, when */ /* destroying the library, by @FT_Done_FreeType. */ /* */ /* numPoints :: The maximum number of points within the outline. */ /* Must be smaller than or equal to 0xFFFF (65535). */ /* */ /* numContours :: The maximum number of contours within the outline. */ /* This value must be in the range 0 to `numPoints'. */ /* */ /* <Output> */ /* anoutline :: A handle to the new outline. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The reason why this function takes a `library' parameter is simply */ /* to use the library's memory allocator. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_New( FT_Library library, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline ); FT_EXPORT( FT_Error ) FT_Outline_New_Internal( FT_Memory memory, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Done */ /* */ /* <Description> */ /* Destroy an outline created with @FT_Outline_New. */ /* */ /* <Input> */ /* library :: A handle of the library object used to allocate the */ /* outline. */ /* */ /* outline :: A pointer to the outline object to be discarded. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* If the outline's `owner' field is not set, only the outline */ /* descriptor will be released. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Done( FT_Library library, FT_Outline* outline ); FT_EXPORT( FT_Error ) FT_Outline_Done_Internal( FT_Memory memory, FT_Outline* outline ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Check */ /* */ /* <Description> */ /* Check the contents of an outline descriptor. */ /* */ /* <Input> */ /* outline :: A handle to a source outline. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* An empty outline, or an outline with a single point only is also */ /* valid. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Check( FT_Outline* outline ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Get_CBox */ /* */ /* <Description> */ /* Return an outline's `control box'. The control box encloses all */ /* the outline's points, including Bezier control points. Though it */ /* coincides with the exact bounding box for most glyphs, it can be */ /* slightly larger in some situations (like when rotating an outline */ /* that contains Bezier outside arcs). */ /* */ /* Computing the control box is very fast, while getting the bounding */ /* box can take much more time as it needs to walk over all segments */ /* and arcs in the outline. To get the latter, you can use the */ /* `ftbbox' component, which is dedicated to this single task. */ /* */ /* <Input> */ /* outline :: A pointer to the source outline descriptor. */ /* */ /* <Output> */ /* acbox :: The outline's control box. */ /* */ /* <Note> */ /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ /* */ FT_EXPORT( void ) FT_Outline_Get_CBox( const FT_Outline* outline, FT_BBox *acbox ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Translate */ /* */ /* <Description> */ /* Apply a simple translation to the points of an outline. */ /* */ /* <InOut> */ /* outline :: A pointer to the target outline descriptor. */ /* */ /* <Input> */ /* xOffset :: The horizontal offset. */ /* */ /* yOffset :: The vertical offset. */ /* */ FT_EXPORT( void ) FT_Outline_Translate( const FT_Outline* outline, FT_Pos xOffset, FT_Pos yOffset ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Copy */ /* */ /* <Description> */ /* Copy an outline into another one. Both objects must have the */ /* same sizes (number of points & number of contours) when this */ /* function is called. */ /* */ /* <Input> */ /* source :: A handle to the source outline. */ /* */ /* <Output> */ /* target :: A handle to the target outline. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Copy( const FT_Outline* source, FT_Outline *target ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Transform */ /* */ /* <Description> */ /* Apply a simple 2x2 matrix to all of an outline's points. Useful */ /* for applying rotations, slanting, flipping, etc. */ /* */ /* <InOut> */ /* outline :: A pointer to the target outline descriptor. */ /* */ /* <Input> */ /* matrix :: A pointer to the transformation matrix. */ /* */ /* <Note> */ /* You can use @FT_Outline_Translate if you need to translate the */ /* outline's points. */ /* */ FT_EXPORT( void ) FT_Outline_Transform( const FT_Outline* outline, const FT_Matrix* matrix ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Embolden */ /* */ /* <Description> */ /* Embolden an outline. The new outline will be at most 4~times */ /* `strength' pixels wider and higher. You may think of the left and */ /* bottom borders as unchanged. */ /* */ /* Negative `strength' values to reduce the outline thickness are */ /* possible also. */ /* */ /* <InOut> */ /* outline :: A handle to the target outline. */ /* */ /* <Input> */ /* strength :: How strong the glyph is emboldened. Expressed in */ /* 26.6 pixel format. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The used algorithm to increase or decrease the thickness of the */ /* glyph doesn't change the number of points; this means that certain */ /* situations like acute angles or intersections are sometimes */ /* handled incorrectly. */ /* */ /* If you need `better' metrics values you should call */ /* @FT_Outline_Get_CBox or @FT_Outline_Get_BBox. */ /* */ /* Example call: */ /* */ /* { */ /* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); */ /* if ( face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) */ /* FT_Outline_Embolden( &face->glyph->outline, strength ); */ /* } */ /* */ /* To get meaningful results, font scaling values must be set with */ /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Embolden( FT_Outline* outline, FT_Pos strength ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_EmboldenXY */ /* */ /* <Description> */ /* Embolden an outline. The new outline will be `xstrength' pixels */ /* wider and `ystrength' pixels higher. Otherwise, it is similar to */ /* @FT_Outline_Embolden, which uses the same strength in both */ /* directions. */ /* */ /* <Since> */ /* 2.4.10 */ /* */ FT_EXPORT( FT_Error ) FT_Outline_EmboldenXY( FT_Outline* outline, FT_Pos xstrength, FT_Pos ystrength ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Reverse */ /* */ /* <Description> */ /* Reverse the drawing direction of an outline. This is used to */ /* ensure consistent fill conventions for mirrored glyphs. */ /* */ /* <InOut> */ /* outline :: A pointer to the target outline descriptor. */ /* */ /* <Note> */ /* This function toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ /* the outline's `flags' field. */ /* */ /* It shouldn't be used by a normal client application, unless it */ /* knows what it is doing. */ /* */ FT_EXPORT( void ) FT_Outline_Reverse( FT_Outline* outline ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Get_Bitmap */ /* */ /* <Description> */ /* Render an outline within a bitmap. The outline's image is simply */ /* OR-ed to the target bitmap. */ /* */ /* <Input> */ /* library :: A handle to a FreeType library object. */ /* */ /* outline :: A pointer to the source outline descriptor. */ /* */ /* <InOut> */ /* abitmap :: A pointer to the target bitmap descriptor. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* This function does NOT CREATE the bitmap, it only renders an */ /* outline image within the one you pass to it! Consequently, the */ /* various fields in `abitmap' should be set accordingly. */ /* */ /* It will use the raster corresponding to the default glyph format. */ /* */ /* The value of the `num_grays' field in `abitmap' is ignored. If */ /* you select the gray-level rasterizer, and you want less than 256 */ /* gray levels, you have to use @FT_Outline_Render directly. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Get_Bitmap( FT_Library library, FT_Outline* outline, const FT_Bitmap *abitmap ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Render */ /* */ /* <Description> */ /* Render an outline within a bitmap using the current scan-convert. */ /* This function uses an @FT_Raster_Params structure as an argument, */ /* allowing advanced features like direct composition, translucency, */ /* etc. */ /* */ /* <Input> */ /* library :: A handle to a FreeType library object. */ /* */ /* outline :: A pointer to the source outline descriptor. */ /* */ /* <InOut> */ /* params :: A pointer to an @FT_Raster_Params structure used to */ /* describe the rendering operation. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* You should know what you are doing and how @FT_Raster_Params works */ /* to use this function. */ /* */ /* The field `params.source' will be set to `outline' before the scan */ /* converter is called, which means that the value you give to it is */ /* actually ignored. */ /* */ /* The gray-level rasterizer always uses 256 gray levels. If you */ /* want less gray levels, you have to provide your own span callback. */ /* See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the */ /* @FT_Raster_Params structure for more details. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Render( FT_Library library, FT_Outline* outline, FT_Raster_Params* params ); /************************************************************************** * * @enum: * FT_Orientation * * @description: * A list of values used to describe an outline's contour orientation. * * The TrueType and PostScript specifications use different conventions * to determine whether outline contours should be filled or unfilled. * * @values: * FT_ORIENTATION_TRUETYPE :: * According to the TrueType specification, clockwise contours must * be filled, and counter-clockwise ones must be unfilled. * * FT_ORIENTATION_POSTSCRIPT :: * According to the PostScript specification, counter-clockwise contours * must be filled, and clockwise ones must be unfilled. * * FT_ORIENTATION_FILL_RIGHT :: * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to * remember that in TrueType, everything that is to the right of * the drawing direction of a contour must be filled. * * FT_ORIENTATION_FILL_LEFT :: * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to * remember that in PostScript, everything that is to the left of * the drawing direction of a contour must be filled. * * FT_ORIENTATION_NONE :: * The orientation cannot be determined. That is, different parts of * the glyph have different orientation. * */ typedef enum FT_Orientation_ { FT_ORIENTATION_TRUETYPE = 0, FT_ORIENTATION_POSTSCRIPT = 1, FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE, FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT, FT_ORIENTATION_NONE } FT_Orientation; /************************************************************************** * * @function: * FT_Outline_Get_Orientation * * @description: * This function analyzes a glyph outline and tries to compute its * fill orientation (see @FT_Orientation). This is done by integrating * the total area covered by the outline. The positive integral * corresponds to the clockwise orientation and @FT_ORIENTATION_POSTSCRIPT * is returned. The negative integral corresponds to the counter-clockwise * orientation and @FT_ORIENTATION_TRUETYPE is returned. * * Note that this will return @FT_ORIENTATION_TRUETYPE for empty * outlines. * * @input: * outline :: * A handle to the source outline. * * @return: * The orientation. * */ FT_EXPORT( FT_Orientation ) FT_Outline_Get_Orientation( FT_Outline* outline ); /* */ FT_END_HEADER #endif /* FTOUTLN_H_ */ /* END */ /* Local Variables: */ /* coding: utf-8 */ /* End: */ freetype2/freetype/ftchapters.h 0000644 00000023161 15146341150 0012613 0 ustar 00 /***************************************************************************/ /* */ /* This file defines the structure of the FreeType reference. */ /* It is used by the python script that generates the HTML files. */ /* */ /***************************************************************************/ /***************************************************************************/ /* */ /* <Chapter> */ /* general_remarks */ /* */ /* <Title> */ /* General Remarks */ /* */ /* <Sections> */ /* header_inclusion */ /* user_allocation */ /* */ /***************************************************************************/ /***************************************************************************/ /* */ /* <Chapter> */ /* core_api */ /* */ /* <Title> */ /* Core API */ /* */ /* <Sections> */ /* version */ /* basic_types */ /* base_interface */ /* glyph_variants */ /* glyph_management */ /* mac_specific */ /* sizes_management */ /* header_file_macros */ /* */ /***************************************************************************/ /***************************************************************************/ /* */ /* <Chapter> */ /* format_specific */ /* */ /* <Title> */ /* Format-Specific API */ /* */ /* <Sections> */ /* multiple_masters */ /* truetype_tables */ /* type1_tables */ /* sfnt_names */ /* bdf_fonts */ /* cid_fonts */ /* pfr_fonts */ /* winfnt_fonts */ /* font_formats */ /* gasp_table */ /* */ /***************************************************************************/ /***************************************************************************/ /* */ /* <Chapter> */ /* module_specific */ /* */ /* <Title> */ /* Controlling FreeType Modules */ /* */ /* <Sections> */ /* auto_hinter */ /* cff_driver */ /* t1_cid_driver */ /* tt_driver */ /* pcf_driver */ /* properties */ /* parameter_tags */ /* */ /***************************************************************************/ /***************************************************************************/ /* */ /* <Chapter> */ /* cache_subsystem */ /* */ /* <Title> */ /* Cache Sub-System */ /* */ /* <Sections> */ /* cache_subsystem */ /* */ /***************************************************************************/ /***************************************************************************/ /* */ /* <Chapter> */ /* support_api */ /* */ /* <Title> */ /* Support API */ /* */ /* <Sections> */ /* computations */ /* list_processing */ /* outline_processing */ /* quick_advance */ /* bitmap_handling */ /* raster */ /* glyph_stroker */ /* system_interface */ /* module_management */ /* gzip */ /* lzw */ /* bzip2 */ /* lcd_filtering */ /* */ /***************************************************************************/ /***************************************************************************/ /* */ /* <Chapter> */ /* error_codes */ /* */ /* <Title> */ /* Error Codes */ /* */ /* <Sections> */ /* error_enumerations */ /* error_code_values */ /* */ /***************************************************************************/ freetype2/freetype/ftsynth.h 0000644 00000010033 15146341150 0012141 0 ustar 00 /***************************************************************************/ /* */ /* ftsynth.h */ /* */ /* FreeType synthesizing code for emboldening and slanting */ /* (specification). */ /* */ /* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /********* *********/ /********* WARNING, THIS IS ALPHA CODE! THIS API *********/ /********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/ /********* FREETYPE DEVELOPMENT TEAM *********/ /********* *********/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* Main reason for not lifting the functions in this module to a */ /* `standard' API is that the used parameters for emboldening and */ /* slanting are not configurable. Consider the functions as a */ /* code resource that should be copied into the application and */ /* adapted to the particular needs. */ #ifndef FTSYNTH_H_ #define FTSYNTH_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /* Embolden a glyph by a `reasonable' value (which is highly a matter of */ /* taste). This function is actually a convenience function, providing */ /* a wrapper for @FT_Outline_Embolden and @FT_Bitmap_Embolden. */ /* */ /* For emboldened outlines the height, width, and advance metrics are */ /* increased by the strength of the emboldening -- this even affects */ /* mono-width fonts! */ /* */ /* You can also call @FT_Outline_Get_CBox to get precise values. */ FT_EXPORT( void ) FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); /* Slant an outline glyph to the right by about 12 degrees. */ FT_EXPORT( void ) FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); /* */ FT_END_HEADER #endif /* FTSYNTH_H_ */ /* END */ freetype2/freetype/ttnameid.h 0000644 00000165056 15146341150 0012267 0 ustar 00 /***************************************************************************/ /* */ /* ttnameid.h */ /* */ /* TrueType name ID definitions (specification only). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef TTNAMEID_H_ #define TTNAMEID_H_ #include <ft2build.h> FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* truetype_tables */ /* */ /*************************************************************************/ /* */ /* Possible values for the `platform' identifier code in the name */ /* records of an SFNT `name' table. */ /* */ /*************************************************************************/ /*********************************************************************** * * @enum: * TT_PLATFORM_XXX * * @description: * A list of valid values for the `platform_id' identifier code in * @FT_CharMapRec and @FT_SfntName structures. * * @values: * TT_PLATFORM_APPLE_UNICODE :: * Used by Apple to indicate a Unicode character map and/or name entry. * See @TT_APPLE_ID_XXX for corresponding `encoding_id' values. Note * that name entries in this format are coded as big-endian UCS-2 * character codes _only_. * * TT_PLATFORM_MACINTOSH :: * Used by Apple to indicate a MacOS-specific charmap and/or name entry. * See @TT_MAC_ID_XXX for corresponding `encoding_id' values. Note that * most TrueType fonts contain an Apple roman charmap to be usable on * MacOS systems (even if they contain a Microsoft charmap as well). * * TT_PLATFORM_ISO :: * This value was used to specify ISO/IEC 10646 charmaps. It is however * now deprecated. See @TT_ISO_ID_XXX for a list of corresponding * `encoding_id' values. * * TT_PLATFORM_MICROSOFT :: * Used by Microsoft to indicate Windows-specific charmaps. See * @TT_MS_ID_XXX for a list of corresponding `encoding_id' values. * Note that most fonts contain a Unicode charmap using * (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS). * * TT_PLATFORM_CUSTOM :: * Used to indicate application-specific charmaps. * * TT_PLATFORM_ADOBE :: * This value isn't part of any font format specification, but is used * by FreeType to report Adobe-specific charmaps in an @FT_CharMapRec * structure. See @TT_ADOBE_ID_XXX. */ #define TT_PLATFORM_APPLE_UNICODE 0 #define TT_PLATFORM_MACINTOSH 1 #define TT_PLATFORM_ISO 2 /* deprecated */ #define TT_PLATFORM_MICROSOFT 3 #define TT_PLATFORM_CUSTOM 4 #define TT_PLATFORM_ADOBE 7 /* artificial */ /*********************************************************************** * * @enum: * TT_APPLE_ID_XXX * * @description: * A list of valid values for the `encoding_id' for * @TT_PLATFORM_APPLE_UNICODE charmaps and name entries. * * @values: * TT_APPLE_ID_DEFAULT :: * Unicode version 1.0. * * TT_APPLE_ID_UNICODE_1_1 :: * Unicode 1.1; specifies Hangul characters starting at U+34xx. * * TT_APPLE_ID_ISO_10646 :: * Deprecated (identical to preceding). * * TT_APPLE_ID_UNICODE_2_0 :: * Unicode 2.0 and beyond (UTF-16 BMP only). * * TT_APPLE_ID_UNICODE_32 :: * Unicode 3.1 and beyond, using UTF-32. * * TT_APPLE_ID_VARIANT_SELECTOR :: * From Adobe, not Apple. Not a normal cmap. Specifies variations * on a real cmap. * * TT_APPLE_ID_FULL_UNICODE :: * Used for fallback fonts that provide complete Unicode coverage with * a type~13 cmap. */ #define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ #define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ #define TT_APPLE_ID_ISO_10646 2 /* deprecated */ #define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ #define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ #define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ #define TT_APPLE_ID_FULL_UNICODE 6 /* used with type 13 cmaps */ /*********************************************************************** * * @enum: * TT_MAC_ID_XXX * * @description: * A list of valid values for the `encoding_id' for * @TT_PLATFORM_MACINTOSH charmaps and name entries. */ #define TT_MAC_ID_ROMAN 0 #define TT_MAC_ID_JAPANESE 1 #define TT_MAC_ID_TRADITIONAL_CHINESE 2 #define TT_MAC_ID_KOREAN 3 #define TT_MAC_ID_ARABIC 4 #define TT_MAC_ID_HEBREW 5 #define TT_MAC_ID_GREEK 6 #define TT_MAC_ID_RUSSIAN 7 #define TT_MAC_ID_RSYMBOL 8 #define TT_MAC_ID_DEVANAGARI 9 #define TT_MAC_ID_GURMUKHI 10 #define TT_MAC_ID_GUJARATI 11 #define TT_MAC_ID_ORIYA 12 #define TT_MAC_ID_BENGALI 13 #define TT_MAC_ID_TAMIL 14 #define TT_MAC_ID_TELUGU 15 #define TT_MAC_ID_KANNADA 16 #define TT_MAC_ID_MALAYALAM 17 #define TT_MAC_ID_SINHALESE 18 #define TT_MAC_ID_BURMESE 19 #define TT_MAC_ID_KHMER 20 #define TT_MAC_ID_THAI 21 #define TT_MAC_ID_LAOTIAN 22 #define TT_MAC_ID_GEORGIAN 23 #define TT_MAC_ID_ARMENIAN 24 #define TT_MAC_ID_MALDIVIAN 25 #define TT_MAC_ID_SIMPLIFIED_CHINESE 25 #define TT_MAC_ID_TIBETAN 26 #define TT_MAC_ID_MONGOLIAN 27 #define TT_MAC_ID_GEEZ 28 #define TT_MAC_ID_SLAVIC 29 #define TT_MAC_ID_VIETNAMESE 30 #define TT_MAC_ID_SINDHI 31 #define TT_MAC_ID_UNINTERP 32 /*********************************************************************** * * @enum: * TT_ISO_ID_XXX * * @description: * A list of valid values for the `encoding_id' for * @TT_PLATFORM_ISO charmaps and name entries. * * Their use is now deprecated. * * @values: * TT_ISO_ID_7BIT_ASCII :: * ASCII. * TT_ISO_ID_10646 :: * ISO/10646. * TT_ISO_ID_8859_1 :: * Also known as Latin-1. */ #define TT_ISO_ID_7BIT_ASCII 0 #define TT_ISO_ID_10646 1 #define TT_ISO_ID_8859_1 2 /*********************************************************************** * * @enum: * TT_MS_ID_XXX * * @description: * A list of valid values for the `encoding_id' for * @TT_PLATFORM_MICROSOFT charmaps and name entries. * * @values: * TT_MS_ID_SYMBOL_CS :: * Microsoft symbol encoding. See @FT_ENCODING_MS_SYMBOL. * * TT_MS_ID_UNICODE_CS :: * Microsoft WGL4 charmap, matching Unicode. See * @FT_ENCODING_UNICODE. * * TT_MS_ID_SJIS :: * Shift JIS Japanese encoding. See @FT_ENCODING_SJIS. * * TT_MS_ID_PRC :: * Chinese encodings as used in the People's Republic of China (PRC). * This means the encodings GB~2312 and its supersets GBK and * GB~18030. See @FT_ENCODING_PRC. * * TT_MS_ID_BIG_5 :: * Traditional Chinese as used in Taiwan and Hong Kong. See * @FT_ENCODING_BIG5. * * TT_MS_ID_WANSUNG :: * Korean Extended Wansung encoding. See @FT_ENCODING_WANSUNG. * * TT_MS_ID_JOHAB :: * Korean Johab encoding. See @FT_ENCODING_JOHAB. * * TT_MS_ID_UCS_4 :: * UCS-4 or UTF-32 charmaps. This has been added to the OpenType * specification version 1.4 (mid-2001). */ #define TT_MS_ID_SYMBOL_CS 0 #define TT_MS_ID_UNICODE_CS 1 #define TT_MS_ID_SJIS 2 #define TT_MS_ID_PRC 3 #define TT_MS_ID_BIG_5 4 #define TT_MS_ID_WANSUNG 5 #define TT_MS_ID_JOHAB 6 #define TT_MS_ID_UCS_4 10 /* this value is deprecated */ #define TT_MS_ID_GB2312 TT_MS_ID_PRC /*********************************************************************** * * @enum: * TT_ADOBE_ID_XXX * * @description: * A list of valid values for the `encoding_id' for * @TT_PLATFORM_ADOBE charmaps. This is a FreeType-specific extension! * * @values: * TT_ADOBE_ID_STANDARD :: * Adobe standard encoding. * TT_ADOBE_ID_EXPERT :: * Adobe expert encoding. * TT_ADOBE_ID_CUSTOM :: * Adobe custom encoding. * TT_ADOBE_ID_LATIN_1 :: * Adobe Latin~1 encoding. */ #define TT_ADOBE_ID_STANDARD 0 #define TT_ADOBE_ID_EXPERT 1 #define TT_ADOBE_ID_CUSTOM 2 #define TT_ADOBE_ID_LATIN_1 3 /*********************************************************************** * * @enum: * TT_MAC_LANGID_XXX * * @description: * Possible values of the language identifier field in the name records * of the SFNT `name' table if the `platform' identifier code is * @TT_PLATFORM_MACINTOSH. These values are also used as return values * for function @FT_Get_CMap_Language_ID. * * The canonical source for Apple's IDs is * * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html */ #define TT_MAC_LANGID_ENGLISH 0 #define TT_MAC_LANGID_FRENCH 1 #define TT_MAC_LANGID_GERMAN 2 #define TT_MAC_LANGID_ITALIAN 3 #define TT_MAC_LANGID_DUTCH 4 #define TT_MAC_LANGID_SWEDISH 5 #define TT_MAC_LANGID_SPANISH 6 #define TT_MAC_LANGID_DANISH 7 #define TT_MAC_LANGID_PORTUGUESE 8 #define TT_MAC_LANGID_NORWEGIAN 9 #define TT_MAC_LANGID_HEBREW 10 #define TT_MAC_LANGID_JAPANESE 11 #define TT_MAC_LANGID_ARABIC 12 #define TT_MAC_LANGID_FINNISH 13 #define TT_MAC_LANGID_GREEK 14 #define TT_MAC_LANGID_ICELANDIC 15 #define TT_MAC_LANGID_MALTESE 16 #define TT_MAC_LANGID_TURKISH 17 #define TT_MAC_LANGID_CROATIAN 18 #define TT_MAC_LANGID_CHINESE_TRADITIONAL 19 #define TT_MAC_LANGID_URDU 20 #define TT_MAC_LANGID_HINDI 21 #define TT_MAC_LANGID_THAI 22 #define TT_MAC_LANGID_KOREAN 23 #define TT_MAC_LANGID_LITHUANIAN 24 #define TT_MAC_LANGID_POLISH 25 #define TT_MAC_LANGID_HUNGARIAN 26 #define TT_MAC_LANGID_ESTONIAN 27 #define TT_MAC_LANGID_LETTISH 28 #define TT_MAC_LANGID_SAAMISK 29 #define TT_MAC_LANGID_FAEROESE 30 #define TT_MAC_LANGID_FARSI 31 #define TT_MAC_LANGID_RUSSIAN 32 #define TT_MAC_LANGID_CHINESE_SIMPLIFIED 33 #define TT_MAC_LANGID_FLEMISH 34 #define TT_MAC_LANGID_IRISH 35 #define TT_MAC_LANGID_ALBANIAN 36 #define TT_MAC_LANGID_ROMANIAN 37 #define TT_MAC_LANGID_CZECH 38 #define TT_MAC_LANGID_SLOVAK 39 #define TT_MAC_LANGID_SLOVENIAN 40 #define TT_MAC_LANGID_YIDDISH 41 #define TT_MAC_LANGID_SERBIAN 42 #define TT_MAC_LANGID_MACEDONIAN 43 #define TT_MAC_LANGID_BULGARIAN 44 #define TT_MAC_LANGID_UKRAINIAN 45 #define TT_MAC_LANGID_BYELORUSSIAN 46 #define TT_MAC_LANGID_UZBEK 47 #define TT_MAC_LANGID_KAZAKH 48 #define TT_MAC_LANGID_AZERBAIJANI 49 #define TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT 49 #define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT 50 #define TT_MAC_LANGID_ARMENIAN 51 #define TT_MAC_LANGID_GEORGIAN 52 #define TT_MAC_LANGID_MOLDAVIAN 53 #define TT_MAC_LANGID_KIRGHIZ 54 #define TT_MAC_LANGID_TAJIKI 55 #define TT_MAC_LANGID_TURKMEN 56 #define TT_MAC_LANGID_MONGOLIAN 57 #define TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT 57 #define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT 58 #define TT_MAC_LANGID_PASHTO 59 #define TT_MAC_LANGID_KURDISH 60 #define TT_MAC_LANGID_KASHMIRI 61 #define TT_MAC_LANGID_SINDHI 62 #define TT_MAC_LANGID_TIBETAN 63 #define TT_MAC_LANGID_NEPALI 64 #define TT_MAC_LANGID_SANSKRIT 65 #define TT_MAC_LANGID_MARATHI 66 #define TT_MAC_LANGID_BENGALI 67 #define TT_MAC_LANGID_ASSAMESE 68 #define TT_MAC_LANGID_GUJARATI 69 #define TT_MAC_LANGID_PUNJABI 70 #define TT_MAC_LANGID_ORIYA 71 #define TT_MAC_LANGID_MALAYALAM 72 #define TT_MAC_LANGID_KANNADA 73 #define TT_MAC_LANGID_TAMIL 74 #define TT_MAC_LANGID_TELUGU 75 #define TT_MAC_LANGID_SINHALESE 76 #define TT_MAC_LANGID_BURMESE 77 #define TT_MAC_LANGID_KHMER 78 #define TT_MAC_LANGID_LAO 79 #define TT_MAC_LANGID_VIETNAMESE 80 #define TT_MAC_LANGID_INDONESIAN 81 #define TT_MAC_LANGID_TAGALOG 82 #define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT 83 #define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT 84 #define TT_MAC_LANGID_AMHARIC 85 #define TT_MAC_LANGID_TIGRINYA 86 #define TT_MAC_LANGID_GALLA 87 #define TT_MAC_LANGID_SOMALI 88 #define TT_MAC_LANGID_SWAHILI 89 #define TT_MAC_LANGID_RUANDA 90 #define TT_MAC_LANGID_RUNDI 91 #define TT_MAC_LANGID_CHEWA 92 #define TT_MAC_LANGID_MALAGASY 93 #define TT_MAC_LANGID_ESPERANTO 94 #define TT_MAC_LANGID_WELSH 128 #define TT_MAC_LANGID_BASQUE 129 #define TT_MAC_LANGID_CATALAN 130 #define TT_MAC_LANGID_LATIN 131 #define TT_MAC_LANGID_QUECHUA 132 #define TT_MAC_LANGID_GUARANI 133 #define TT_MAC_LANGID_AYMARA 134 #define TT_MAC_LANGID_TATAR 135 #define TT_MAC_LANGID_UIGHUR 136 #define TT_MAC_LANGID_DZONGKHA 137 #define TT_MAC_LANGID_JAVANESE 138 #define TT_MAC_LANGID_SUNDANESE 139 /* The following codes are new as of 2000-03-10 */ #define TT_MAC_LANGID_GALICIAN 140 #define TT_MAC_LANGID_AFRIKAANS 141 #define TT_MAC_LANGID_BRETON 142 #define TT_MAC_LANGID_INUKTITUT 143 #define TT_MAC_LANGID_SCOTTISH_GAELIC 144 #define TT_MAC_LANGID_MANX_GAELIC 145 #define TT_MAC_LANGID_IRISH_GAELIC 146 #define TT_MAC_LANGID_TONGAN 147 #define TT_MAC_LANGID_GREEK_POLYTONIC 148 #define TT_MAC_LANGID_GREELANDIC 149 #define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 /*********************************************************************** * * @enum: * TT_MS_LANGID_XXX * * @description: * Possible values of the language identifier field in the name records * of the SFNT `name' table if the `platform' identifier code is * @TT_PLATFORM_MICROSOFT. These values are also used as return values * for function @FT_Get_CMap_Language_ID. * * The canonical source for Microsoft's IDs is * * https://www.microsoft.com/globaldev/reference/lcid-all.mspx , * * however, we only provide macros for language identifiers present in * the OpenType specification: Microsoft has abandoned the concept of * LCIDs (language code identifiers), and format~1 of the `name' table * provides a better mechanism for languages not covered here. * * More legacy values not listed in the reference can be found in the * @FT_TRUETYPE_IDS_H header file. */ #define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 #define TT_MS_LANGID_ARABIC_IRAQ 0x0801 #define TT_MS_LANGID_ARABIC_EGYPT 0x0C01 #define TT_MS_LANGID_ARABIC_LIBYA 0x1001 #define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 #define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 #define TT_MS_LANGID_ARABIC_TUNISIA 0x1C01 #define TT_MS_LANGID_ARABIC_OMAN 0x2001 #define TT_MS_LANGID_ARABIC_YEMEN 0x2401 #define TT_MS_LANGID_ARABIC_SYRIA 0x2801 #define TT_MS_LANGID_ARABIC_JORDAN 0x2C01 #define TT_MS_LANGID_ARABIC_LEBANON 0x3001 #define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 #define TT_MS_LANGID_ARABIC_UAE 0x3801 #define TT_MS_LANGID_ARABIC_BAHRAIN 0x3C01 #define TT_MS_LANGID_ARABIC_QATAR 0x4001 #define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 #define TT_MS_LANGID_CATALAN_CATALAN 0x0403 #define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 #define TT_MS_LANGID_CHINESE_PRC 0x0804 #define TT_MS_LANGID_CHINESE_HONG_KONG 0x0C04 #define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 #define TT_MS_LANGID_CHINESE_MACAO 0x1404 #define TT_MS_LANGID_CZECH_CZECH_REPUBLIC 0x0405 #define TT_MS_LANGID_DANISH_DENMARK 0x0406 #define TT_MS_LANGID_GERMAN_GERMANY 0x0407 #define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 #define TT_MS_LANGID_GERMAN_AUSTRIA 0x0C07 #define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 #define TT_MS_LANGID_GERMAN_LIECHTENSTEIN 0x1407 #define TT_MS_LANGID_GREEK_GREECE 0x0408 #define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 #define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 #define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0C09 #define TT_MS_LANGID_ENGLISH_CANADA 0x1009 #define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 #define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 #define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1C09 #define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 #define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 #define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 #define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2C09 #define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 #define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 #define TT_MS_LANGID_ENGLISH_INDIA 0x4009 #define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 #define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 #define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040A #define TT_MS_LANGID_SPANISH_MEXICO 0x080A #define TT_MS_LANGID_SPANISH_SPAIN_MODERN_SORT 0x0C0A #define TT_MS_LANGID_SPANISH_GUATEMALA 0x100A #define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140A #define TT_MS_LANGID_SPANISH_PANAMA 0x180A #define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1C0A #define TT_MS_LANGID_SPANISH_VENEZUELA 0x200A #define TT_MS_LANGID_SPANISH_COLOMBIA 0x240A #define TT_MS_LANGID_SPANISH_PERU 0x280A #define TT_MS_LANGID_SPANISH_ARGENTINA 0x2C0A #define TT_MS_LANGID_SPANISH_ECUADOR 0x300A #define TT_MS_LANGID_SPANISH_CHILE 0x340A #define TT_MS_LANGID_SPANISH_URUGUAY 0x380A #define TT_MS_LANGID_SPANISH_PARAGUAY 0x3C0A #define TT_MS_LANGID_SPANISH_BOLIVIA 0x400A #define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440A #define TT_MS_LANGID_SPANISH_HONDURAS 0x480A #define TT_MS_LANGID_SPANISH_NICARAGUA 0x4C0A #define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500A #define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540A #define TT_MS_LANGID_FINNISH_FINLAND 0x040B #define TT_MS_LANGID_FRENCH_FRANCE 0x040C #define TT_MS_LANGID_FRENCH_BELGIUM 0x080C #define TT_MS_LANGID_FRENCH_CANADA 0x0C0C #define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100C #define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140C #define TT_MS_LANGID_FRENCH_MONACO 0x180C #define TT_MS_LANGID_HEBREW_ISRAEL 0x040D #define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040E #define TT_MS_LANGID_ICELANDIC_ICELAND 0x040F #define TT_MS_LANGID_ITALIAN_ITALY 0x0410 #define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 #define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 #define TT_MS_LANGID_KOREAN_KOREA 0x0412 #define TT_MS_LANGID_DUTCH_NETHERLANDS 0x0413 #define TT_MS_LANGID_DUTCH_BELGIUM 0x0813 #define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL 0x0414 #define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK 0x0814 #define TT_MS_LANGID_POLISH_POLAND 0x0415 #define TT_MS_LANGID_PORTUGUESE_BRAZIL 0x0416 #define TT_MS_LANGID_PORTUGUESE_PORTUGAL 0x0816 #define TT_MS_LANGID_ROMANSH_SWITZERLAND 0x0417 #define TT_MS_LANGID_ROMANIAN_ROMANIA 0x0418 #define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 #define TT_MS_LANGID_CROATIAN_CROATIA 0x041A #define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081A #define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0C1A #define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101A #define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141A #define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181A #define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x1C1A #define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZ_CYRILLIC 0x201A #define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041B #define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041C #define TT_MS_LANGID_SWEDISH_SWEDEN 0x041D #define TT_MS_LANGID_SWEDISH_FINLAND 0x081D #define TT_MS_LANGID_THAI_THAILAND 0x041E #define TT_MS_LANGID_TURKISH_TURKEY 0x041F #define TT_MS_LANGID_URDU_PAKISTAN 0x0420 #define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 #define TT_MS_LANGID_UKRAINIAN_UKRAINE 0x0422 #define TT_MS_LANGID_BELARUSIAN_BELARUS 0x0423 #define TT_MS_LANGID_SLOVENIAN_SLOVENIA 0x0424 #define TT_MS_LANGID_ESTONIAN_ESTONIA 0x0425 #define TT_MS_LANGID_LATVIAN_LATVIA 0x0426 #define TT_MS_LANGID_LITHUANIAN_LITHUANIA 0x0427 #define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 #define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042A #define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042B #define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042C #define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082C #define TT_MS_LANGID_BASQUE_BASQUE 0x042D #define TT_MS_LANGID_UPPER_SORBIAN_GERMANY 0x042E #define TT_MS_LANGID_LOWER_SORBIAN_GERMANY 0x082E #define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042F #define TT_MS_LANGID_SETSWANA_SOUTH_AFRICA 0x0432 #define TT_MS_LANGID_ISIXHOSA_SOUTH_AFRICA 0x0434 #define TT_MS_LANGID_ISIZULU_SOUTH_AFRICA 0x0435 #define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA 0x0436 #define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 #define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 #define TT_MS_LANGID_HINDI_INDIA 0x0439 #define TT_MS_LANGID_MALTESE_MALTA 0x043A #define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043B #define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083B #define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3B #define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103B #define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143B #define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183B #define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3B #define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203B #define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243B #define TT_MS_LANGID_IRISH_IRELAND 0x083C #define TT_MS_LANGID_MALAY_MALAYSIA 0x043E #define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083E #define TT_MS_LANGID_KAZAKH_KAZAKHSTAN 0x043F #define TT_MS_LANGID_KYRGYZ_KYRGYZSTAN /* Cyrillic*/ 0x0440 #define TT_MS_LANGID_KISWAHILI_KENYA 0x0441 #define TT_MS_LANGID_TURKMEN_TURKMENISTAN 0x0442 #define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 #define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC 0x0843 #define TT_MS_LANGID_TATAR_RUSSIA 0x0444 #define TT_MS_LANGID_BENGALI_INDIA 0x0445 #define TT_MS_LANGID_BENGALI_BANGLADESH 0x0845 #define TT_MS_LANGID_PUNJABI_INDIA 0x0446 #define TT_MS_LANGID_GUJARATI_INDIA 0x0447 #define TT_MS_LANGID_ODIA_INDIA 0x0448 #define TT_MS_LANGID_TAMIL_INDIA 0x0449 #define TT_MS_LANGID_TELUGU_INDIA 0x044A #define TT_MS_LANGID_KANNADA_INDIA 0x044B #define TT_MS_LANGID_MALAYALAM_INDIA 0x044C #define TT_MS_LANGID_ASSAMESE_INDIA 0x044D #define TT_MS_LANGID_MARATHI_INDIA 0x044E #define TT_MS_LANGID_SANSKRIT_INDIA 0x044F #define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 #define TT_MS_LANGID_MONGOLIAN_PRC 0x0850 #define TT_MS_LANGID_TIBETAN_PRC 0x0451 #define TT_MS_LANGID_WELSH_UNITED_KINGDOM 0x0452 #define TT_MS_LANGID_KHMER_CAMBODIA 0x0453 #define TT_MS_LANGID_LAO_LAOS 0x0454 #define TT_MS_LANGID_GALICIAN_GALICIAN 0x0456 #define TT_MS_LANGID_KONKANI_INDIA 0x0457 #define TT_MS_LANGID_SYRIAC_SYRIA 0x045A #define TT_MS_LANGID_SINHALA_SRI_LANKA 0x045B #define TT_MS_LANGID_INUKTITUT_CANADA 0x045D #define TT_MS_LANGID_INUKTITUT_CANADA_LATIN 0x085D #define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045E #define TT_MS_LANGID_TAMAZIGHT_ALGERIA 0x085F #define TT_MS_LANGID_NEPALI_NEPAL 0x0461 #define TT_MS_LANGID_FRISIAN_NETHERLANDS 0x0462 #define TT_MS_LANGID_PASHTO_AFGHANISTAN 0x0463 #define TT_MS_LANGID_FILIPINO_PHILIPPINES 0x0464 #define TT_MS_LANGID_DHIVEHI_MALDIVES 0x0465 #define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 #define TT_MS_LANGID_YORUBA_NIGERIA 0x046A #define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046B #define TT_MS_LANGID_QUECHUA_ECUADOR 0x086B #define TT_MS_LANGID_QUECHUA_PERU 0x0C6B #define TT_MS_LANGID_SESOTHO_SA_LEBOA_SOUTH_AFRICA 0x046C #define TT_MS_LANGID_BASHKIR_RUSSIA 0x046D #define TT_MS_LANGID_LUXEMBOURGISH_LUXEMBOURG 0x046E #define TT_MS_LANGID_GREENLANDIC_GREENLAND 0x046F #define TT_MS_LANGID_IGBO_NIGERIA 0x0470 #define TT_MS_LANGID_YI_PRC 0x0478 #define TT_MS_LANGID_MAPUDUNGUN_CHILE 0x047A #define TT_MS_LANGID_MOHAWK_MOHAWK 0x047C #define TT_MS_LANGID_BRETON_FRANCE 0x047E #define TT_MS_LANGID_UIGHUR_PRC 0x0480 #define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 #define TT_MS_LANGID_OCCITAN_FRANCE 0x0482 #define TT_MS_LANGID_CORSICAN_FRANCE 0x0483 #define TT_MS_LANGID_ALSATIAN_FRANCE 0x0484 #define TT_MS_LANGID_YAKUT_RUSSIA 0x0485 #define TT_MS_LANGID_KICHE_GUATEMALA 0x0486 #define TT_MS_LANGID_KINYARWANDA_RWANDA 0x0487 #define TT_MS_LANGID_WOLOF_SENEGAL 0x0488 #define TT_MS_LANGID_DARI_AFGHANISTAN 0x048C /* */ /* legacy macro definitions not present in OpenType 1.8.1 */ #define TT_MS_LANGID_ARABIC_GENERAL 0x0001 #define TT_MS_LANGID_CATALAN_SPAIN \ TT_MS_LANGID_CATALAN_CATALAN #define TT_MS_LANGID_CHINESE_GENERAL 0x0004 #define TT_MS_LANGID_CHINESE_MACAU \ TT_MS_LANGID_CHINESE_MACAO #define TT_MS_LANGID_GERMAN_LIECHTENSTEI \ TT_MS_LANGID_GERMAN_LIECHTENSTEIN #define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 #define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 #define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3C09 #define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT \ TT_MS_LANGID_SPANISH_SPAIN_MODERN_SORT #define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40AU #define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1C0C #define TT_MS_LANGID_FRENCH_REUNION 0x200C #define TT_MS_LANGID_FRENCH_CONGO 0x240C /* which was formerly: */ #define TT_MS_LANGID_FRENCH_ZAIRE \ TT_MS_LANGID_FRENCH_CONGO #define TT_MS_LANGID_FRENCH_SENEGAL 0x280C #define TT_MS_LANGID_FRENCH_CAMEROON 0x2C0C #define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300C #define TT_MS_LANGID_FRENCH_MALI 0x340C #define TT_MS_LANGID_FRENCH_MOROCCO 0x380C #define TT_MS_LANGID_FRENCH_HAITI 0x3C0C #define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40CU #define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA \ TT_MS_LANGID_KOREAN_KOREA #define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 #define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND \ TT_MS_LANGID_ROMANSH_SWITZERLAND #define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 #define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 #define TT_MS_LANGID_URDU_INDIA 0x0820 #define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 #define TT_MS_LANGID_SLOVENE_SLOVENIA \ TT_MS_LANGID_SLOVENIAN_SLOVENIA #define TT_MS_LANGID_FARSI_IRAN 0x0429 #define TT_MS_LANGID_BASQUE_SPAIN \ TT_MS_LANGID_BASQUE_BASQUE #define TT_MS_LANGID_SORBIAN_GERMANY \ TT_MS_LANGID_UPPER_SORBIAN_GERMANY #define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 #define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 #define TT_MS_LANGID_TSWANA_SOUTH_AFRICA \ TT_MS_LANGID_SETSWANA_SOUTH_AFRICA #define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 #define TT_MS_LANGID_XHOSA_SOUTH_AFRICA \ TT_MS_LANGID_ISIXHOSA_SOUTH_AFRICA #define TT_MS_LANGID_ZULU_SOUTH_AFRICA \ TT_MS_LANGID_ISIZULU_SOUTH_AFRICA #define TT_MS_LANGID_SAAMI_LAPONIA 0x043B /* the next two values are incorrectly inverted */ #define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C #define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C #define TT_MS_LANGID_YIDDISH_GERMANY 0x043D #define TT_MS_LANGID_KAZAK_KAZAKSTAN \ TT_MS_LANGID_KAZAKH_KAZAKHSTAN #define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ TT_MS_LANGID_KYRGYZ_KYRGYZSTAN #define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN \ TT_MS_LANGID_KYRGYZ_KYRGYZSTAN #define TT_MS_LANGID_SWAHILI_KENYA \ TT_MS_LANGID_KISWAHILI_KENYA #define TT_MS_LANGID_TATAR_TATARSTAN \ TT_MS_LANGID_TATAR_RUSSIA #define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN 0x0846 #define TT_MS_LANGID_ORIYA_INDIA \ TT_MS_LANGID_ODIA_INDIA #define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN \ TT_MS_LANGID_MONGOLIAN_PRC #define TT_MS_LANGID_TIBETAN_CHINA \ TT_MS_LANGID_TIBETAN_PRC #define TT_MS_LANGID_DZONGHKA_BHUTAN 0x0851 #define TT_MS_LANGID_TIBETAN_BHUTAN \ TT_MS_LANGID_DZONGHKA_BHUTAN #define TT_MS_LANGID_WELSH_WALES \ TT_MS_LANGID_WELSH_UNITED_KINGDOM #define TT_MS_LANGID_BURMESE_MYANMAR 0x0455 #define TT_MS_LANGID_GALICIAN_SPAIN \ TT_MS_LANGID_GALICIAN_GALICIAN #define TT_MS_LANGID_MANIPURI_INDIA /* Bengali */ 0x0458 #define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 #define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 #define TT_MS_LANGID_SINHALESE_SRI_LANKA \ TT_MS_LANGID_SINHALA_SRI_LANKA #define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045C #define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045F #define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN \ TT_MS_LANGID_TAMAZIGHT_ALGERIA #define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 #define TT_MS_LANGID_KASHMIRI_SASIA 0x0860 #define TT_MS_LANGID_KASHMIRI_INDIA \ TT_MS_LANGID_KASHMIRI_SASIA #define TT_MS_LANGID_NEPALI_INDIA 0x0861 #define TT_MS_LANGID_DIVEHI_MALDIVES \ TT_MS_LANGID_DHIVEHI_MALDIVES #define TT_MS_LANGID_EDO_NIGERIA 0x0466 #define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 #define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 #define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA \ TT_MS_LANGID_SESOTHO_SA_LEBOA_SOUTH_AFRICA #define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ TT_MS_LANGID_SESOTHO_SA_LEBOA_SOUTH_AFRICA #define TT_MS_LANGID_KANURI_NIGERIA 0x0471 #define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 #define TT_MS_LANGID_TIGRIGNA_ETHIOPIA 0x0473 #define TT_MS_LANGID_TIGRIGNA_ERYTHREA 0x0873 #define TT_MS_LANGID_TIGRIGNA_ERYTREA \ TT_MS_LANGID_TIGRIGNA_ERYTHREA #define TT_MS_LANGID_GUARANI_PARAGUAY 0x0474 #define TT_MS_LANGID_HAWAIIAN_UNITED_STATES 0x0475 #define TT_MS_LANGID_LATIN 0x0476 #define TT_MS_LANGID_SOMALI_SOMALIA 0x0477 #define TT_MS_LANGID_YI_CHINA \ TT_MS_LANGID_YI_PRC #define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 #define TT_MS_LANGID_UIGHUR_CHINA \ TT_MS_LANGID_UIGHUR_PRC /*********************************************************************** * * @enum: * TT_NAME_ID_XXX * * @description: * Possible values of the `name' identifier field in the name records of * an SFNT `name' table. These values are platform independent. */ #define TT_NAME_ID_COPYRIGHT 0 #define TT_NAME_ID_FONT_FAMILY 1 #define TT_NAME_ID_FONT_SUBFAMILY 2 #define TT_NAME_ID_UNIQUE_ID 3 #define TT_NAME_ID_FULL_NAME 4 #define TT_NAME_ID_VERSION_STRING 5 #define TT_NAME_ID_PS_NAME 6 #define TT_NAME_ID_TRADEMARK 7 /* the following values are from the OpenType spec */ #define TT_NAME_ID_MANUFACTURER 8 #define TT_NAME_ID_DESIGNER 9 #define TT_NAME_ID_DESCRIPTION 10 #define TT_NAME_ID_VENDOR_URL 11 #define TT_NAME_ID_DESIGNER_URL 12 #define TT_NAME_ID_LICENSE 13 #define TT_NAME_ID_LICENSE_URL 14 /* number 15 is reserved */ #define TT_NAME_ID_TYPOGRAPHIC_FAMILY 16 #define TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY 17 #define TT_NAME_ID_MAC_FULL_NAME 18 /* The following code is new as of 2000-01-21 */ #define TT_NAME_ID_SAMPLE_TEXT 19 /* This is new in OpenType 1.3 */ #define TT_NAME_ID_CID_FINDFONT_NAME 20 /* This is new in OpenType 1.5 */ #define TT_NAME_ID_WWS_FAMILY 21 #define TT_NAME_ID_WWS_SUBFAMILY 22 /* This is new in OpenType 1.7 */ #define TT_NAME_ID_LIGHT_BACKGROUND 23 #define TT_NAME_ID_DARK_BACKGROUND 24 /* This is new in OpenType 1.8 */ #define TT_NAME_ID_VARIATIONS_PREFIX 25 /* these two values are deprecated */ #define TT_NAME_ID_PREFERRED_FAMILY TT_NAME_ID_TYPOGRAPHIC_FAMILY #define TT_NAME_ID_PREFERRED_SUBFAMILY TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY /*********************************************************************** * * @enum: * TT_UCR_XXX * * @description: * Possible bit mask values for the `ulUnicodeRangeX' fields in an SFNT * `OS/2' table. */ /* ulUnicodeRange1 */ /* --------------- */ /* Bit 0 Basic Latin */ #define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ /* Bit 1 C1 Controls and Latin-1 Supplement */ #define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+0080-U+00FF */ /* Bit 2 Latin Extended-A */ #define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ /* Bit 3 Latin Extended-B */ #define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ /* Bit 4 IPA Extensions */ /* Phonetic Extensions */ /* Phonetic Extensions Supplement */ #define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ /* U+1D00-U+1D7F */ /* U+1D80-U+1DBF */ /* Bit 5 Spacing Modifier Letters */ /* Modifier Tone Letters */ #define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ /* U+A700-U+A71F */ /* Bit 6 Combining Diacritical Marks */ /* Combining Diacritical Marks Supplement */ #define TT_UCR_COMBINING_DIACRITICAL_MARKS (1L << 6) /* U+0300-U+036F */ /* U+1DC0-U+1DFF */ /* Bit 7 Greek and Coptic */ #define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ /* Bit 8 Coptic */ #define TT_UCR_COPTIC (1L << 8) /* U+2C80-U+2CFF */ /* Bit 9 Cyrillic */ /* Cyrillic Supplement */ /* Cyrillic Extended-A */ /* Cyrillic Extended-B */ #define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ /* U+0500-U+052F */ /* U+2DE0-U+2DFF */ /* U+A640-U+A69F */ /* Bit 10 Armenian */ #define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ /* Bit 11 Hebrew */ #define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ /* Bit 12 Vai */ #define TT_UCR_VAI (1L << 12) /* U+A500-U+A63F */ /* Bit 13 Arabic */ /* Arabic Supplement */ #define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ /* U+0750-U+077F */ /* Bit 14 NKo */ #define TT_UCR_NKO (1L << 14) /* U+07C0-U+07FF */ /* Bit 15 Devanagari */ #define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ /* Bit 16 Bengali */ #define TT_UCR_BENGALI (1L << 16) /* U+0980-U+09FF */ /* Bit 17 Gurmukhi */ #define TT_UCR_GURMUKHI (1L << 17) /* U+0A00-U+0A7F */ /* Bit 18 Gujarati */ #define TT_UCR_GUJARATI (1L << 18) /* U+0A80-U+0AFF */ /* Bit 19 Oriya */ #define TT_UCR_ORIYA (1L << 19) /* U+0B00-U+0B7F */ /* Bit 20 Tamil */ #define TT_UCR_TAMIL (1L << 20) /* U+0B80-U+0BFF */ /* Bit 21 Telugu */ #define TT_UCR_TELUGU (1L << 21) /* U+0C00-U+0C7F */ /* Bit 22 Kannada */ #define TT_UCR_KANNADA (1L << 22) /* U+0C80-U+0CFF */ /* Bit 23 Malayalam */ #define TT_UCR_MALAYALAM (1L << 23) /* U+0D00-U+0D7F */ /* Bit 24 Thai */ #define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ /* Bit 25 Lao */ #define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ /* Bit 26 Georgian */ /* Georgian Supplement */ #define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ /* U+2D00-U+2D2F */ /* Bit 27 Balinese */ #define TT_UCR_BALINESE (1L << 27) /* U+1B00-U+1B7F */ /* Bit 28 Hangul Jamo */ #define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ /* Bit 29 Latin Extended Additional */ /* Latin Extended-C */ /* Latin Extended-D */ #define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ /* U+2C60-U+2C7F */ /* U+A720-U+A7FF */ /* Bit 30 Greek Extended */ #define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ /* Bit 31 General Punctuation */ /* Supplemental Punctuation */ #define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ /* U+2E00-U+2E7F */ /* ulUnicodeRange2 */ /* --------------- */ /* Bit 32 Superscripts And Subscripts */ #define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ /* Bit 33 Currency Symbols */ #define TT_UCR_CURRENCY_SYMBOLS (1L << 1) /* U+20A0-U+20CF */ /* Bit 34 Combining Diacritical Marks For Symbols */ #define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ (1L << 2) /* U+20D0-U+20FF */ /* Bit 35 Letterlike Symbols */ #define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ /* Bit 36 Number Forms */ #define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ /* Bit 37 Arrows */ /* Supplemental Arrows-A */ /* Supplemental Arrows-B */ /* Miscellaneous Symbols and Arrows */ #define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ /* U+27F0-U+27FF */ /* U+2900-U+297F */ /* U+2B00-U+2BFF */ /* Bit 38 Mathematical Operators */ /* Supplemental Mathematical Operators */ /* Miscellaneous Mathematical Symbols-A */ /* Miscellaneous Mathematical Symbols-B */ #define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ /* U+2A00-U+2AFF */ /* U+27C0-U+27EF */ /* U+2980-U+29FF */ /* Bit 39 Miscellaneous Technical */ #define TT_UCR_MISCELLANEOUS_TECHNICAL (1L << 7) /* U+2300-U+23FF */ /* Bit 40 Control Pictures */ #define TT_UCR_CONTROL_PICTURES (1L << 8) /* U+2400-U+243F */ /* Bit 41 Optical Character Recognition */ #define TT_UCR_OCR (1L << 9) /* U+2440-U+245F */ /* Bit 42 Enclosed Alphanumerics */ #define TT_UCR_ENCLOSED_ALPHANUMERICS (1L << 10) /* U+2460-U+24FF */ /* Bit 43 Box Drawing */ #define TT_UCR_BOX_DRAWING (1L << 11) /* U+2500-U+257F */ /* Bit 44 Block Elements */ #define TT_UCR_BLOCK_ELEMENTS (1L << 12) /* U+2580-U+259F */ /* Bit 45 Geometric Shapes */ #define TT_UCR_GEOMETRIC_SHAPES (1L << 13) /* U+25A0-U+25FF */ /* Bit 46 Miscellaneous Symbols */ #define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ /* Bit 47 Dingbats */ #define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ /* Bit 48 CJK Symbols and Punctuation */ #define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ /* Bit 49 Hiragana */ #define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ /* Bit 50 Katakana */ /* Katakana Phonetic Extensions */ #define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ /* U+31F0-U+31FF */ /* Bit 51 Bopomofo */ /* Bopomofo Extended */ #define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ /* U+31A0-U+31BF */ /* Bit 52 Hangul Compatibility Jamo */ #define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ /* Bit 53 Phags-Pa */ #define TT_UCR_CJK_MISC (1L << 21) /* U+A840-U+A87F */ #define TT_UCR_KANBUN TT_UCR_CJK_MISC /* deprecated */ #define TT_UCR_PHAGSPA /* Bit 54 Enclosed CJK Letters and Months */ #define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ /* Bit 55 CJK Compatibility */ #define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ /* Bit 56 Hangul Syllables */ #define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ /* Bit 57 High Surrogates */ /* High Private Use Surrogates */ /* Low Surrogates */ /* According to OpenType specs v.1.3+, */ /* setting bit 57 implies that there is */ /* at least one codepoint beyond the */ /* Basic Multilingual Plane that is */ /* supported by this font. So it really */ /* means >= U+10000. */ #define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ /* U+DB80-U+DBFF */ /* U+DC00-U+DFFF */ #define TT_UCR_NON_PLANE_0 TT_UCR_SURROGATES /* Bit 58 Phoenician */ #define TT_UCR_PHOENICIAN (1L << 26) /*U+10900-U+1091F*/ /* Bit 59 CJK Unified Ideographs */ /* CJK Radicals Supplement */ /* Kangxi Radicals */ /* Ideographic Description Characters */ /* CJK Unified Ideographs Extension A */ /* CJK Unified Ideographs Extension B */ /* Kanbun */ #define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ /* U+2E80-U+2EFF */ /* U+2F00-U+2FDF */ /* U+2FF0-U+2FFF */ /* U+3400-U+4DB5 */ /*U+20000-U+2A6DF*/ /* U+3190-U+319F */ /* Bit 60 Private Use */ #define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ /* Bit 61 CJK Strokes */ /* CJK Compatibility Ideographs */ /* CJK Compatibility Ideographs Supplement */ #define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+31C0-U+31EF */ /* U+F900-U+FAFF */ /*U+2F800-U+2FA1F*/ /* Bit 62 Alphabetic Presentation Forms */ #define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ /* Bit 63 Arabic Presentation Forms-A */ #define TT_UCR_ARABIC_PRESENTATION_FORMS_A (1L << 31) /* U+FB50-U+FDFF */ /* ulUnicodeRange3 */ /* --------------- */ /* Bit 64 Combining Half Marks */ #define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ /* Bit 65 Vertical forms */ /* CJK Compatibility Forms */ #define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE10-U+FE1F */ /* U+FE30-U+FE4F */ /* Bit 66 Small Form Variants */ #define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ /* Bit 67 Arabic Presentation Forms-B */ #define TT_UCR_ARABIC_PRESENTATION_FORMS_B (1L << 3) /* U+FE70-U+FEFE */ /* Bit 68 Halfwidth and Fullwidth Forms */ #define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) /* U+FF00-U+FFEF */ /* Bit 69 Specials */ #define TT_UCR_SPECIALS (1L << 5) /* U+FFF0-U+FFFD */ /* Bit 70 Tibetan */ #define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FFF */ /* Bit 71 Syriac */ #define TT_UCR_SYRIAC (1L << 7) /* U+0700-U+074F */ /* Bit 72 Thaana */ #define TT_UCR_THAANA (1L << 8) /* U+0780-U+07BF */ /* Bit 73 Sinhala */ #define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ /* Bit 74 Myanmar */ #define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ /* Bit 75 Ethiopic */ /* Ethiopic Supplement */ /* Ethiopic Extended */ #define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+137F */ /* U+1380-U+139F */ /* U+2D80-U+2DDF */ /* Bit 76 Cherokee */ #define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ /* Bit 77 Unified Canadian Aboriginal Syllabics */ #define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) /* U+1400-U+167F */ /* Bit 78 Ogham */ #define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ /* Bit 79 Runic */ #define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ /* Bit 80 Khmer */ /* Khmer Symbols */ #define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ /* U+19E0-U+19FF */ /* Bit 81 Mongolian */ #define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ /* Bit 82 Braille Patterns */ #define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ /* Bit 83 Yi Syllables */ /* Yi Radicals */ #define TT_UCR_YI (1L << 19) /* U+A000-U+A48F */ /* U+A490-U+A4CF */ /* Bit 84 Tagalog */ /* Hanunoo */ /* Buhid */ /* Tagbanwa */ #define TT_UCR_PHILIPPINE (1L << 20) /* U+1700-U+171F */ /* U+1720-U+173F */ /* U+1740-U+175F */ /* U+1760-U+177F */ /* Bit 85 Old Italic */ #define TT_UCR_OLD_ITALIC (1L << 21) /*U+10300-U+1032F*/ /* Bit 86 Gothic */ #define TT_UCR_GOTHIC (1L << 22) /*U+10330-U+1034F*/ /* Bit 87 Deseret */ #define TT_UCR_DESERET (1L << 23) /*U+10400-U+1044F*/ /* Bit 88 Byzantine Musical Symbols */ /* Musical Symbols */ /* Ancient Greek Musical Notation */ #define TT_UCR_MUSICAL_SYMBOLS (1L << 24) /*U+1D000-U+1D0FF*/ /*U+1D100-U+1D1FF*/ /*U+1D200-U+1D24F*/ /* Bit 89 Mathematical Alphanumeric Symbols */ #define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) /*U+1D400-U+1D7FF*/ /* Bit 90 Private Use (plane 15) */ /* Private Use (plane 16) */ #define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) /*U+F0000-U+FFFFD*/ /*U+100000-U+10FFFD*/ /* Bit 91 Variation Selectors */ /* Variation Selectors Supplement */ #define TT_UCR_VARIATION_SELECTORS (1L << 27) /* U+FE00-U+FE0F */ /*U+E0100-U+E01EF*/ /* Bit 92 Tags */ #define TT_UCR_TAGS (1L << 28) /*U+E0000-U+E007F*/ /* Bit 93 Limbu */ #define TT_UCR_LIMBU (1L << 29) /* U+1900-U+194F */ /* Bit 94 Tai Le */ #define TT_UCR_TAI_LE (1L << 30) /* U+1950-U+197F */ /* Bit 95 New Tai Lue */ #define TT_UCR_NEW_TAI_LUE (1L << 31) /* U+1980-U+19DF */ /* ulUnicodeRange4 */ /* --------------- */ /* Bit 96 Buginese */ #define TT_UCR_BUGINESE (1L << 0) /* U+1A00-U+1A1F */ /* Bit 97 Glagolitic */ #define TT_UCR_GLAGOLITIC (1L << 1) /* U+2C00-U+2C5F */ /* Bit 98 Tifinagh */ #define TT_UCR_TIFINAGH (1L << 2) /* U+2D30-U+2D7F */ /* Bit 99 Yijing Hexagram Symbols */ #define TT_UCR_YIJING (1L << 3) /* U+4DC0-U+4DFF */ /* Bit 100 Syloti Nagri */ #define TT_UCR_SYLOTI_NAGRI (1L << 4) /* U+A800-U+A82F */ /* Bit 101 Linear B Syllabary */ /* Linear B Ideograms */ /* Aegean Numbers */ #define TT_UCR_LINEAR_B (1L << 5) /*U+10000-U+1007F*/ /*U+10080-U+100FF*/ /*U+10100-U+1013F*/ /* Bit 102 Ancient Greek Numbers */ #define TT_UCR_ANCIENT_GREEK_NUMBERS (1L << 6) /*U+10140-U+1018F*/ /* Bit 103 Ugaritic */ #define TT_UCR_UGARITIC (1L << 7) /*U+10380-U+1039F*/ /* Bit 104 Old Persian */ #define TT_UCR_OLD_PERSIAN (1L << 8) /*U+103A0-U+103DF*/ /* Bit 105 Shavian */ #define TT_UCR_SHAVIAN (1L << 9) /*U+10450-U+1047F*/ /* Bit 106 Osmanya */ #define TT_UCR_OSMANYA (1L << 10) /*U+10480-U+104AF*/ /* Bit 107 Cypriot Syllabary */ #define TT_UCR_CYPRIOT_SYLLABARY (1L << 11) /*U+10800-U+1083F*/ /* Bit 108 Kharoshthi */ #define TT_UCR_KHAROSHTHI (1L << 12) /*U+10A00-U+10A5F*/ /* Bit 109 Tai Xuan Jing Symbols */ #define TT_UCR_TAI_XUAN_JING (1L << 13) /*U+1D300-U+1D35F*/ /* Bit 110 Cuneiform */ /* Cuneiform Numbers and Punctuation */ #define TT_UCR_CUNEIFORM (1L << 14) /*U+12000-U+123FF*/ /*U+12400-U+1247F*/ /* Bit 111 Counting Rod Numerals */ #define TT_UCR_COUNTING_ROD_NUMERALS (1L << 15) /*U+1D360-U+1D37F*/ /* Bit 112 Sundanese */ #define TT_UCR_SUNDANESE (1L << 16) /* U+1B80-U+1BBF */ /* Bit 113 Lepcha */ #define TT_UCR_LEPCHA (1L << 17) /* U+1C00-U+1C4F */ /* Bit 114 Ol Chiki */ #define TT_UCR_OL_CHIKI (1L << 18) /* U+1C50-U+1C7F */ /* Bit 115 Saurashtra */ #define TT_UCR_SAURASHTRA (1L << 19) /* U+A880-U+A8DF */ /* Bit 116 Kayah Li */ #define TT_UCR_KAYAH_LI (1L << 20) /* U+A900-U+A92F */ /* Bit 117 Rejang */ #define TT_UCR_REJANG (1L << 21) /* U+A930-U+A95F */ /* Bit 118 Cham */ #define TT_UCR_CHAM (1L << 22) /* U+AA00-U+AA5F */ /* Bit 119 Ancient Symbols */ #define TT_UCR_ANCIENT_SYMBOLS (1L << 23) /*U+10190-U+101CF*/ /* Bit 120 Phaistos Disc */ #define TT_UCR_PHAISTOS_DISC (1L << 24) /*U+101D0-U+101FF*/ /* Bit 121 Carian */ /* Lycian */ /* Lydian */ #define TT_UCR_OLD_ANATOLIAN (1L << 25) /*U+102A0-U+102DF*/ /*U+10280-U+1029F*/ /*U+10920-U+1093F*/ /* Bit 122 Domino Tiles */ /* Mahjong Tiles */ #define TT_UCR_GAME_TILES (1L << 26) /*U+1F030-U+1F09F*/ /*U+1F000-U+1F02F*/ /* Bit 123-127 Reserved for process-internal usage */ /* */ /* for backward compatibility with older FreeType versions */ #define TT_UCR_ARABIC_PRESENTATION_A \ TT_UCR_ARABIC_PRESENTATION_FORMS_A #define TT_UCR_ARABIC_PRESENTATION_B \ TT_UCR_ARABIC_PRESENTATION_FORMS_B #define TT_UCR_COMBINING_DIACRITICS \ TT_UCR_COMBINING_DIACRITICAL_MARKS #define TT_UCR_COMBINING_DIACRITICS_SYMB \ TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB FT_END_HEADER #endif /* TTNAMEID_H_ */ /* END */ freetype2/freetype/ftgasp.h 0000644 00000011326 15146341150 0011734 0 ustar 00 /***************************************************************************/ /* */ /* ftgasp.h */ /* */ /* Access of TrueType's `gasp' table (specification). */ /* */ /* Copyright 2007-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTGASP_H_ #define FTGASP_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************** * * @section: * gasp_table * * @title: * Gasp Table * * @abstract: * Retrieving TrueType `gasp' table entries. * * @description: * The function @FT_Get_Gasp can be used to query a TrueType or OpenType * font for specific entries in its `gasp' table, if any. This is * mainly useful when implementing native TrueType hinting with the * bytecode interpreter to duplicate the Windows text rendering results. */ /************************************************************************* * * @enum: * FT_GASP_XXX * * @description: * A list of values and/or bit-flags returned by the @FT_Get_Gasp * function. * * @values: * FT_GASP_NO_TABLE :: * This special value means that there is no GASP table in this face. * It is up to the client to decide what to do. * * FT_GASP_DO_GRIDFIT :: * Grid-fitting and hinting should be performed at the specified ppem. * This *really* means TrueType bytecode interpretation. If this bit * is not set, no hinting gets applied. * * FT_GASP_DO_GRAY :: * Anti-aliased rendering should be performed at the specified ppem. * If not set, do monochrome rendering. * * FT_GASP_SYMMETRIC_SMOOTHING :: * If set, smoothing along multiple axes must be used with ClearType. * * FT_GASP_SYMMETRIC_GRIDFIT :: * Grid-fitting must be used with ClearType's symmetric smoothing. * * @note: * The bit-flags `FT_GASP_DO_GRIDFIT' and `FT_GASP_DO_GRAY' are to be * used for standard font rasterization only. Independently of that, * `FT_GASP_SYMMETRIC_SMOOTHING' and `FT_GASP_SYMMETRIC_GRIDFIT' are to * be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT' and * `FT_GASP_DO_GRAY' are consequently ignored). * * `ClearType' is Microsoft's implementation of LCD rendering, partly * protected by patents. * * @since: * 2.3.0 */ #define FT_GASP_NO_TABLE -1 #define FT_GASP_DO_GRIDFIT 0x01 #define FT_GASP_DO_GRAY 0x02 #define FT_GASP_SYMMETRIC_GRIDFIT 0x04 #define FT_GASP_SYMMETRIC_SMOOTHING 0x08 /************************************************************************* * * @func: * FT_Get_Gasp * * @description: * For a TrueType or OpenType font file, return the rasterizer behaviour * flags from the font's `gasp' table corresponding to a given * character pixel size. * * @input: * face :: The source face handle. * * ppem :: The vertical character pixel size. * * @return: * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no * `gasp' table in the face. * * @note: * If you want to use the MM functionality of OpenType variation fonts * (i.e., using @FT_Set_Var_Design_Coordinates and friends), call this * function *after* setting an instance since the return values can * change. * * @since: * 2.3.0 */ FT_EXPORT( FT_Int ) FT_Get_Gasp( FT_Face face, FT_UInt ppem ); /* */ FT_END_HEADER #endif /* FTGASP_H_ */ /* END */ freetype2/freetype/ftwinfnt.h 0000644 00000024242 15146341150 0012310 0 ustar 00 /***************************************************************************/ /* */ /* ftwinfnt.h */ /* */ /* FreeType API for accessing Windows fnt-specific data. */ /* */ /* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTWINFNT_H_ #define FTWINFNT_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* winfnt_fonts */ /* */ /* <Title> */ /* Window FNT Files */ /* */ /* <Abstract> */ /* Windows FNT specific API. */ /* */ /* <Description> */ /* This section contains the declaration of Windows FNT specific */ /* functions. */ /* */ /*************************************************************************/ /************************************************************************* * * @enum: * FT_WinFNT_ID_XXX * * @description: * A list of valid values for the `charset' byte in * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX * encodings (except for cp1361) can be found at * ftp://ftp.unicode.org/Public in the MAPPINGS/VENDORS/MICSFT/WINDOWS * subdirectory. cp1361 is roughly a superset of * MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. * * @values: * FT_WinFNT_ID_DEFAULT :: * This is used for font enumeration and font creation as a * `don't care' value. Valid font files don't contain this value. * When querying for information about the character set of the font * that is currently selected into a specified device context, this * return value (of the related Windows API) simply denotes failure. * * FT_WinFNT_ID_SYMBOL :: * There is no known mapping table available. * * FT_WinFNT_ID_MAC :: * Mac Roman encoding. * * FT_WinFNT_ID_OEM :: * From Michael Poettgen <michael@poettgen.de>: * * The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM * is used for the charset of vector fonts, like `modern.fon', * `roman.fon', and `script.fon' on Windows. * * The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value * specifies a character set that is operating-system dependent. * * The `IFIMETRICS' documentation from the `Windows Driver * Development Kit' says: This font supports an OEM-specific * character set. The OEM character set is system dependent. * * In general OEM, as opposed to ANSI (i.e., cp1252), denotes the * second default codepage that most international versions of * Windows have. It is one of the OEM codepages from * * https://msdn.microsoft.com/en-us/goglobal/bb964655, * * and is used for the `DOS boxes', to support legacy applications. * A German Windows version for example usually uses ANSI codepage * 1252 and OEM codepage 850. * * FT_WinFNT_ID_CP874 :: * A superset of Thai TIS 620 and ISO 8859-11. * * FT_WinFNT_ID_CP932 :: * A superset of Japanese Shift-JIS (with minor deviations). * * FT_WinFNT_ID_CP936 :: * A superset of simplified Chinese GB 2312-1980 (with different * ordering and minor deviations). * * FT_WinFNT_ID_CP949 :: * A superset of Korean Hangul KS~C 5601-1987 (with different * ordering and minor deviations). * * FT_WinFNT_ID_CP950 :: * A superset of traditional Chinese Big~5 ETen (with different * ordering and minor deviations). * * FT_WinFNT_ID_CP1250 :: * A superset of East European ISO 8859-2 (with slightly different * ordering). * * FT_WinFNT_ID_CP1251 :: * A superset of Russian ISO 8859-5 (with different ordering). * * FT_WinFNT_ID_CP1252 :: * ANSI encoding. A superset of ISO 8859-1. * * FT_WinFNT_ID_CP1253 :: * A superset of Greek ISO 8859-7 (with minor modifications). * * FT_WinFNT_ID_CP1254 :: * A superset of Turkish ISO 8859-9. * * FT_WinFNT_ID_CP1255 :: * A superset of Hebrew ISO 8859-8 (with some modifications). * * FT_WinFNT_ID_CP1256 :: * A superset of Arabic ISO 8859-6 (with different ordering). * * FT_WinFNT_ID_CP1257 :: * A superset of Baltic ISO 8859-13 (with some deviations). * * FT_WinFNT_ID_CP1258 :: * For Vietnamese. This encoding doesn't cover all necessary * characters. * * FT_WinFNT_ID_CP1361 :: * Korean (Johab). */ #define FT_WinFNT_ID_CP1252 0 #define FT_WinFNT_ID_DEFAULT 1 #define FT_WinFNT_ID_SYMBOL 2 #define FT_WinFNT_ID_MAC 77 #define FT_WinFNT_ID_CP932 128 #define FT_WinFNT_ID_CP949 129 #define FT_WinFNT_ID_CP1361 130 #define FT_WinFNT_ID_CP936 134 #define FT_WinFNT_ID_CP950 136 #define FT_WinFNT_ID_CP1253 161 #define FT_WinFNT_ID_CP1254 162 #define FT_WinFNT_ID_CP1258 163 #define FT_WinFNT_ID_CP1255 177 #define FT_WinFNT_ID_CP1256 178 #define FT_WinFNT_ID_CP1257 186 #define FT_WinFNT_ID_CP1251 204 #define FT_WinFNT_ID_CP874 222 #define FT_WinFNT_ID_CP1250 238 #define FT_WinFNT_ID_OEM 255 /*************************************************************************/ /* */ /* <Struct> */ /* FT_WinFNT_HeaderRec */ /* */ /* <Description> */ /* Windows FNT Header info. */ /* */ typedef struct FT_WinFNT_HeaderRec_ { FT_UShort version; FT_ULong file_size; FT_Byte copyright[60]; FT_UShort file_type; FT_UShort nominal_point_size; FT_UShort vertical_resolution; FT_UShort horizontal_resolution; FT_UShort ascent; FT_UShort internal_leading; FT_UShort external_leading; FT_Byte italic; FT_Byte underline; FT_Byte strike_out; FT_UShort weight; FT_Byte charset; FT_UShort pixel_width; FT_UShort pixel_height; FT_Byte pitch_and_family; FT_UShort avg_width; FT_UShort max_width; FT_Byte first_char; FT_Byte last_char; FT_Byte default_char; FT_Byte break_char; FT_UShort bytes_per_row; FT_ULong device_offset; FT_ULong face_name_offset; FT_ULong bits_pointer; FT_ULong bits_offset; FT_Byte reserved; FT_ULong flags; FT_UShort A_space; FT_UShort B_space; FT_UShort C_space; FT_UShort color_table_offset; FT_ULong reserved1[4]; } FT_WinFNT_HeaderRec; /*************************************************************************/ /* */ /* <Struct> */ /* FT_WinFNT_Header */ /* */ /* <Description> */ /* A handle to an @FT_WinFNT_HeaderRec structure. */ /* */ typedef struct FT_WinFNT_HeaderRec_* FT_WinFNT_Header; /********************************************************************** * * @function: * FT_Get_WinFNT_Header * * @description: * Retrieve a Windows FNT font info header. * * @input: * face :: A handle to the input face. * * @output: * aheader :: The WinFNT header. * * @return: * FreeType error code. 0~means success. * * @note: * This function only works with Windows FNT faces, returning an error * otherwise. */ FT_EXPORT( FT_Error ) FT_Get_WinFNT_Header( FT_Face face, FT_WinFNT_HeaderRec *aheader ); /* */ FT_END_HEADER #endif /* FTWINFNT_H_ */ /* END */ /* Local Variables: */ /* coding: utf-8 */ /* End: */ freetype2/freetype/ftsizes.h 0000644 00000022520 15146341150 0012135 0 ustar 00 /***************************************************************************/ /* */ /* ftsizes.h */ /* */ /* FreeType size objects management (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* Typical application would normally not need to use these functions. */ /* However, they have been placed in a public API for the rare cases */ /* where they are needed. */ /* */ /*************************************************************************/ #ifndef FTSIZES_H_ #define FTSIZES_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* sizes_management */ /* */ /* <Title> */ /* Size Management */ /* */ /* <Abstract> */ /* Managing multiple sizes per face. */ /* */ /* <Description> */ /* When creating a new face object (e.g., with @FT_New_Face), an */ /* @FT_Size object is automatically created and used to store all */ /* pixel-size dependent information, available in the `face->size' */ /* field. */ /* */ /* It is however possible to create more sizes for a given face, */ /* mostly in order to manage several character pixel sizes of the */ /* same font family and style. See @FT_New_Size and @FT_Done_Size. */ /* */ /* Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only */ /* modify the contents of the current `active' size; you thus need */ /* to use @FT_Activate_Size to change it. */ /* */ /* 99% of applications won't need the functions provided here, */ /* especially if they use the caching sub-system, so be cautious */ /* when using these. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_New_Size */ /* */ /* <Description> */ /* Create a new size object from a given face object. */ /* */ /* <Input> */ /* face :: A handle to a parent face object. */ /* */ /* <Output> */ /* asize :: A handle to a new size object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* You need to call @FT_Activate_Size in order to select the new size */ /* for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size, */ /* @FT_Load_Glyph, @FT_Load_Char, etc. */ /* */ FT_EXPORT( FT_Error ) FT_New_Size( FT_Face face, FT_Size* size ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Done_Size */ /* */ /* <Description> */ /* Discard a given size object. Note that @FT_Done_Face */ /* automatically discards all size objects allocated with */ /* @FT_New_Size. */ /* */ /* <Input> */ /* size :: A handle to a target size object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_Size( FT_Size size ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Activate_Size */ /* */ /* <Description> */ /* Even though it is possible to create several size objects for a */ /* given face (see @FT_New_Size for details), functions like */ /* @FT_Load_Glyph or @FT_Load_Char only use the one that has been */ /* activated last to determine the `current character pixel size'. */ /* */ /* This function can be used to `activate' a previously created size */ /* object. */ /* */ /* <Input> */ /* size :: A handle to a target size object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* If `face' is the size's parent face object, this function changes */ /* the value of `face->size' to the input size handle. */ /* */ FT_EXPORT( FT_Error ) FT_Activate_Size( FT_Size size ); /* */ FT_END_HEADER #endif /* FTSIZES_H_ */ /* END */ freetype2/freetype/ftpfr.h 0000644 00000014206 15146341150 0011571 0 ustar 00 /***************************************************************************/ /* */ /* ftpfr.h */ /* */ /* FreeType API for accessing PFR-specific data (specification only). */ /* */ /* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTPFR_H_ #define FTPFR_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* pfr_fonts */ /* */ /* <Title> */ /* PFR Fonts */ /* */ /* <Abstract> */ /* PFR/TrueDoc specific API. */ /* */ /* <Description> */ /* This section contains the declaration of PFR-specific functions. */ /* */ /*************************************************************************/ /********************************************************************** * * @function: * FT_Get_PFR_Metrics * * @description: * Return the outline and metrics resolutions of a given PFR face. * * @input: * face :: Handle to the input face. It can be a non-PFR face. * * @output: * aoutline_resolution :: * Outline resolution. This is equivalent to `face->units_per_EM' * for non-PFR fonts. Optional (parameter can be NULL). * * ametrics_resolution :: * Metrics resolution. This is equivalent to `outline_resolution' * for non-PFR fonts. Optional (parameter can be NULL). * * ametrics_x_scale :: * A 16.16 fixed-point number used to scale distance expressed * in metrics units to device subpixels. This is equivalent to * `face->size->x_scale', but for metrics only. Optional (parameter * can be NULL). * * ametrics_y_scale :: * Same as `ametrics_x_scale' but for the vertical direction. * optional (parameter can be NULL). * * @return: * FreeType error code. 0~means success. * * @note: * If the input face is not a PFR, this function will return an error. * However, in all cases, it will return valid values. */ FT_EXPORT( FT_Error ) FT_Get_PFR_Metrics( FT_Face face, FT_UInt *aoutline_resolution, FT_UInt *ametrics_resolution, FT_Fixed *ametrics_x_scale, FT_Fixed *ametrics_y_scale ); /********************************************************************** * * @function: * FT_Get_PFR_Kerning * * @description: * Return the kerning pair corresponding to two glyphs in a PFR face. * The distance is expressed in metrics units, unlike the result of * @FT_Get_Kerning. * * @input: * face :: A handle to the input face. * * left :: Index of the left glyph. * * right :: Index of the right glyph. * * @output: * avector :: A kerning vector. * * @return: * FreeType error code. 0~means success. * * @note: * This function always return distances in original PFR metrics * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED * mode, which always returns distances converted to outline units. * * You can use the value of the `x_scale' and `y_scale' parameters * returned by @FT_Get_PFR_Metrics to scale these to device subpixels. */ FT_EXPORT( FT_Error ) FT_Get_PFR_Kerning( FT_Face face, FT_UInt left, FT_UInt right, FT_Vector *avector ); /********************************************************************** * * @function: * FT_Get_PFR_Advance * * @description: * Return a given glyph advance, expressed in original metrics units, * from a PFR font. * * @input: * face :: A handle to the input face. * * gindex :: The glyph index. * * @output: * aadvance :: The glyph advance in metrics units. * * @return: * FreeType error code. 0~means success. * * @note: * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics * to convert the advance to device subpixels (i.e., 1/64th of pixels). */ FT_EXPORT( FT_Error ) FT_Get_PFR_Advance( FT_Face face, FT_UInt gindex, FT_Pos *aadvance ); /* */ FT_END_HEADER #endif /* FTPFR_H_ */ /* END */ freetype2/freetype/ftotval.h 0000644 00000016645 15146341150 0012140 0 ustar 00 /***************************************************************************/ /* */ /* ftotval.h */ /* */ /* FreeType API for validating OpenType tables (specification). */ /* */ /* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /***************************************************************************/ /* */ /* */ /* Warning: This module might be moved to a different library in the */ /* future to avoid a tight dependency between FreeType and the */ /* OpenType specification. */ /* */ /* */ /***************************************************************************/ #ifndef FTOTVAL_H_ #define FTOTVAL_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* ot_validation */ /* */ /* <Title> */ /* OpenType Validation */ /* */ /* <Abstract> */ /* An API to validate OpenType tables. */ /* */ /* <Description> */ /* This section contains the declaration of functions to validate */ /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ /* */ /* <Order> */ /* FT_OpenType_Validate */ /* FT_OpenType_Free */ /* */ /* FT_VALIDATE_OTXXX */ /* */ /*************************************************************************/ /********************************************************************** * * @enum: * FT_VALIDATE_OTXXX * * @description: * A list of bit-field constants used with @FT_OpenType_Validate to * indicate which OpenType tables should be validated. * * @values: * FT_VALIDATE_BASE :: * Validate BASE table. * * FT_VALIDATE_GDEF :: * Validate GDEF table. * * FT_VALIDATE_GPOS :: * Validate GPOS table. * * FT_VALIDATE_GSUB :: * Validate GSUB table. * * FT_VALIDATE_JSTF :: * Validate JSTF table. * * FT_VALIDATE_MATH :: * Validate MATH table. * * FT_VALIDATE_OT :: * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). * */ #define FT_VALIDATE_BASE 0x0100 #define FT_VALIDATE_GDEF 0x0200 #define FT_VALIDATE_GPOS 0x0400 #define FT_VALIDATE_GSUB 0x0800 #define FT_VALIDATE_JSTF 0x1000 #define FT_VALIDATE_MATH 0x2000 #define FT_VALIDATE_OT ( FT_VALIDATE_BASE | \ FT_VALIDATE_GDEF | \ FT_VALIDATE_GPOS | \ FT_VALIDATE_GSUB | \ FT_VALIDATE_JSTF | \ FT_VALIDATE_MATH ) /********************************************************************** * * @function: * FT_OpenType_Validate * * @description: * Validate various OpenType tables to assure that all offsets and * indices are valid. The idea is that a higher-level library that * actually does the text layout can access those tables without * error checking (which can be quite time consuming). * * @input: * face :: * A handle to the input face. * * validation_flags :: * A bit field that specifies the tables to be validated. See * @FT_VALIDATE_OTXXX for possible values. * * @output: * BASE_table :: * A pointer to the BASE table. * * GDEF_table :: * A pointer to the GDEF table. * * GPOS_table :: * A pointer to the GPOS table. * * GSUB_table :: * A pointer to the GSUB table. * * JSTF_table :: * A pointer to the JSTF table. * * @return: * FreeType error code. 0~means success. * * @note: * This function only works with OpenType fonts, returning an error * otherwise. * * After use, the application should deallocate the five tables with * @FT_OpenType_Free. A NULL value indicates that the table either * doesn't exist in the font, or the application hasn't asked for * validation. */ FT_EXPORT( FT_Error ) FT_OpenType_Validate( FT_Face face, FT_UInt validation_flags, FT_Bytes *BASE_table, FT_Bytes *GDEF_table, FT_Bytes *GPOS_table, FT_Bytes *GSUB_table, FT_Bytes *JSTF_table ); /********************************************************************** * * @function: * FT_OpenType_Free * * @description: * Free the buffer allocated by OpenType validator. * * @input: * face :: * A handle to the input face. * * table :: * The pointer to the buffer that is allocated by * @FT_OpenType_Validate. * * @note: * This function must be used to free the buffer allocated by * @FT_OpenType_Validate only. */ FT_EXPORT( void ) FT_OpenType_Free( FT_Face face, FT_Bytes table ); /* */ FT_END_HEADER #endif /* FTOTVAL_H_ */ /* END */ freetype2/freetype/fttypes.h 0000644 00000105543 15146341150 0012153 0 ustar 00 /***************************************************************************/ /* */ /* fttypes.h */ /* */ /* FreeType simple types definitions (specification only). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTTYPES_H_ #define FTTYPES_H_ #include <ft2build.h> #include FT_CONFIG_CONFIG_H #include FT_SYSTEM_H #include FT_IMAGE_H #include <stddef.h> FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* basic_types */ /* */ /* <Title> */ /* Basic Data Types */ /* */ /* <Abstract> */ /* The basic data types defined by the library. */ /* */ /* <Description> */ /* This section contains the basic data types defined by FreeType~2, */ /* ranging from simple scalar types to bitmap descriptors. More */ /* font-specific structures are defined in a different section. */ /* */ /* <Order> */ /* FT_Byte */ /* FT_Bytes */ /* FT_Char */ /* FT_Int */ /* FT_UInt */ /* FT_Int16 */ /* FT_UInt16 */ /* FT_Int32 */ /* FT_UInt32 */ /* FT_Int64 */ /* FT_UInt64 */ /* FT_Short */ /* FT_UShort */ /* FT_Long */ /* FT_ULong */ /* FT_Bool */ /* FT_Offset */ /* FT_PtrDist */ /* FT_String */ /* FT_Tag */ /* FT_Error */ /* FT_Fixed */ /* FT_Pointer */ /* FT_Pos */ /* FT_Vector */ /* FT_BBox */ /* FT_Matrix */ /* FT_FWord */ /* FT_UFWord */ /* FT_F2Dot14 */ /* FT_UnitVector */ /* FT_F26Dot6 */ /* FT_Data */ /* */ /* FT_MAKE_TAG */ /* */ /* FT_Generic */ /* FT_Generic_Finalizer */ /* */ /* FT_Bitmap */ /* FT_Pixel_Mode */ /* FT_Palette_Mode */ /* FT_Glyph_Format */ /* FT_IMAGE_TAG */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Type> */ /* FT_Bool */ /* */ /* <Description> */ /* A typedef of unsigned char, used for simple booleans. As usual, */ /* values 1 and~0 represent true and false, respectively. */ /* */ typedef unsigned char FT_Bool; /*************************************************************************/ /* */ /* <Type> */ /* FT_FWord */ /* */ /* <Description> */ /* A signed 16-bit integer used to store a distance in original font */ /* units. */ /* */ typedef signed short FT_FWord; /* distance in FUnits */ /*************************************************************************/ /* */ /* <Type> */ /* FT_UFWord */ /* */ /* <Description> */ /* An unsigned 16-bit integer used to store a distance in original */ /* font units. */ /* */ typedef unsigned short FT_UFWord; /* unsigned distance */ /*************************************************************************/ /* */ /* <Type> */ /* FT_Char */ /* */ /* <Description> */ /* A simple typedef for the _signed_ char type. */ /* */ typedef signed char FT_Char; /*************************************************************************/ /* */ /* <Type> */ /* FT_Byte */ /* */ /* <Description> */ /* A simple typedef for the _unsigned_ char type. */ /* */ typedef unsigned char FT_Byte; /*************************************************************************/ /* */ /* <Type> */ /* FT_Bytes */ /* */ /* <Description> */ /* A typedef for constant memory areas. */ /* */ typedef const FT_Byte* FT_Bytes; /*************************************************************************/ /* */ /* <Type> */ /* FT_Tag */ /* */ /* <Description> */ /* A typedef for 32-bit tags (as used in the SFNT format). */ /* */ typedef FT_UInt32 FT_Tag; /*************************************************************************/ /* */ /* <Type> */ /* FT_String */ /* */ /* <Description> */ /* A simple typedef for the char type, usually used for strings. */ /* */ typedef char FT_String; /*************************************************************************/ /* */ /* <Type> */ /* FT_Short */ /* */ /* <Description> */ /* A typedef for signed short. */ /* */ typedef signed short FT_Short; /*************************************************************************/ /* */ /* <Type> */ /* FT_UShort */ /* */ /* <Description> */ /* A typedef for unsigned short. */ /* */ typedef unsigned short FT_UShort; /*************************************************************************/ /* */ /* <Type> */ /* FT_Int */ /* */ /* <Description> */ /* A typedef for the int type. */ /* */ typedef signed int FT_Int; /*************************************************************************/ /* */ /* <Type> */ /* FT_UInt */ /* */ /* <Description> */ /* A typedef for the unsigned int type. */ /* */ typedef unsigned int FT_UInt; /*************************************************************************/ /* */ /* <Type> */ /* FT_Long */ /* */ /* <Description> */ /* A typedef for signed long. */ /* */ typedef signed long FT_Long; /*************************************************************************/ /* */ /* <Type> */ /* FT_ULong */ /* */ /* <Description> */ /* A typedef for unsigned long. */ /* */ typedef unsigned long FT_ULong; /*************************************************************************/ /* */ /* <Type> */ /* FT_F2Dot14 */ /* */ /* <Description> */ /* A signed 2.14 fixed-point type used for unit vectors. */ /* */ typedef signed short FT_F2Dot14; /*************************************************************************/ /* */ /* <Type> */ /* FT_F26Dot6 */ /* */ /* <Description> */ /* A signed 26.6 fixed-point type used for vectorial pixel */ /* coordinates. */ /* */ typedef signed long FT_F26Dot6; /*************************************************************************/ /* */ /* <Type> */ /* FT_Fixed */ /* */ /* <Description> */ /* This type is used to store 16.16 fixed-point values, like scaling */ /* values or matrix coefficients. */ /* */ typedef signed long FT_Fixed; /*************************************************************************/ /* */ /* <Type> */ /* FT_Error */ /* */ /* <Description> */ /* The FreeType error code type. A value of~0 is always interpreted */ /* as a successful operation. */ /* */ typedef int FT_Error; /*************************************************************************/ /* */ /* <Type> */ /* FT_Pointer */ /* */ /* <Description> */ /* A simple typedef for a typeless pointer. */ /* */ typedef void* FT_Pointer; /*************************************************************************/ /* */ /* <Type> */ /* FT_Offset */ /* */ /* <Description> */ /* This is equivalent to the ANSI~C `size_t' type, i.e., the largest */ /* _unsigned_ integer type used to express a file size or position, */ /* or a memory block size. */ /* */ typedef size_t FT_Offset; /*************************************************************************/ /* */ /* <Type> */ /* FT_PtrDist */ /* */ /* <Description> */ /* This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the */ /* largest _signed_ integer type used to express the distance */ /* between two pointers. */ /* */ typedef ft_ptrdiff_t FT_PtrDist; /*************************************************************************/ /* */ /* <Struct> */ /* FT_UnitVector */ /* */ /* <Description> */ /* A simple structure used to store a 2D vector unit vector. Uses */ /* FT_F2Dot14 types. */ /* */ /* <Fields> */ /* x :: Horizontal coordinate. */ /* */ /* y :: Vertical coordinate. */ /* */ typedef struct FT_UnitVector_ { FT_F2Dot14 x; FT_F2Dot14 y; } FT_UnitVector; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Matrix */ /* */ /* <Description> */ /* A simple structure used to store a 2x2 matrix. Coefficients are */ /* in 16.16 fixed-point format. The computation performed is: */ /* */ /* { */ /* x' = x*xx + y*xy */ /* y' = x*yx + y*yy */ /* } */ /* */ /* <Fields> */ /* xx :: Matrix coefficient. */ /* */ /* xy :: Matrix coefficient. */ /* */ /* yx :: Matrix coefficient. */ /* */ /* yy :: Matrix coefficient. */ /* */ typedef struct FT_Matrix_ { FT_Fixed xx, xy; FT_Fixed yx, yy; } FT_Matrix; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Data */ /* */ /* <Description> */ /* Read-only binary data represented as a pointer and a length. */ /* */ /* <Fields> */ /* pointer :: The data. */ /* */ /* length :: The length of the data in bytes. */ /* */ typedef struct FT_Data_ { const FT_Byte* pointer; FT_Int length; } FT_Data; /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Generic_Finalizer */ /* */ /* <Description> */ /* Describe a function used to destroy the `client' data of any */ /* FreeType object. See the description of the @FT_Generic type for */ /* details of usage. */ /* */ /* <Input> */ /* The address of the FreeType object that is under finalization. */ /* Its client data is accessed through its `generic' field. */ /* */ typedef void (*FT_Generic_Finalizer)( void* object ); /*************************************************************************/ /* */ /* <Struct> */ /* FT_Generic */ /* */ /* <Description> */ /* Client applications often need to associate their own data to a */ /* variety of FreeType core objects. For example, a text layout API */ /* might want to associate a glyph cache to a given size object. */ /* */ /* Some FreeType object contains a `generic' field, of type */ /* FT_Generic, which usage is left to client applications and font */ /* servers. */ /* */ /* It can be used to store a pointer to client-specific data, as well */ /* as the address of a `finalizer' function, which will be called by */ /* FreeType when the object is destroyed (for example, the previous */ /* client example would put the address of the glyph cache destructor */ /* in the `finalizer' field). */ /* */ /* <Fields> */ /* data :: A typeless pointer to any client-specified data. This */ /* field is completely ignored by the FreeType library. */ /* */ /* finalizer :: A pointer to a `generic finalizer' function, which */ /* will be called when the object is destroyed. If this */ /* field is set to NULL, no code will be called. */ /* */ typedef struct FT_Generic_ { void* data; FT_Generic_Finalizer finalizer; } FT_Generic; /*************************************************************************/ /* */ /* <Macro> */ /* FT_MAKE_TAG */ /* */ /* <Description> */ /* This macro converts four-letter tags that are used to label */ /* TrueType tables into an unsigned long, to be used within FreeType. */ /* */ /* <Note> */ /* The produced values *must* be 32-bit integers. Don't redefine */ /* this macro. */ /* */ #define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ (FT_Tag) \ ( ( (FT_ULong)_x1 << 24 ) | \ ( (FT_ULong)_x2 << 16 ) | \ ( (FT_ULong)_x3 << 8 ) | \ (FT_ULong)_x4 ) /*************************************************************************/ /*************************************************************************/ /* */ /* L I S T M A N A G E M E N T */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* <Section> */ /* list_processing */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Type> */ /* FT_ListNode */ /* */ /* <Description> */ /* Many elements and objects in FreeType are listed through an */ /* @FT_List record (see @FT_ListRec). As its name suggests, an */ /* FT_ListNode is a handle to a single list element. */ /* */ typedef struct FT_ListNodeRec_* FT_ListNode; /*************************************************************************/ /* */ /* <Type> */ /* FT_List */ /* */ /* <Description> */ /* A handle to a list record (see @FT_ListRec). */ /* */ typedef struct FT_ListRec_* FT_List; /*************************************************************************/ /* */ /* <Struct> */ /* FT_ListNodeRec */ /* */ /* <Description> */ /* A structure used to hold a single list element. */ /* */ /* <Fields> */ /* prev :: The previous element in the list. NULL if first. */ /* */ /* next :: The next element in the list. NULL if last. */ /* */ /* data :: A typeless pointer to the listed object. */ /* */ typedef struct FT_ListNodeRec_ { FT_ListNode prev; FT_ListNode next; void* data; } FT_ListNodeRec; /*************************************************************************/ /* */ /* <Struct> */ /* FT_ListRec */ /* */ /* <Description> */ /* A structure used to hold a simple doubly-linked list. These are */ /* used in many parts of FreeType. */ /* */ /* <Fields> */ /* head :: The head (first element) of doubly-linked list. */ /* */ /* tail :: The tail (last element) of doubly-linked list. */ /* */ typedef struct FT_ListRec_ { FT_ListNode head; FT_ListNode tail; } FT_ListRec; /* */ #define FT_IS_EMPTY( list ) ( (list).head == 0 ) #define FT_BOOL( x ) ( (FT_Bool)( x ) ) /* concatenate C tokens */ #define FT_ERR_XCAT( x, y ) x ## y #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) /* see `ftmoderr.h' for descriptions of the following macros */ #define FT_ERR( e ) FT_ERR_CAT( FT_ERR_PREFIX, e ) #define FT_ERROR_BASE( x ) ( (x) & 0xFF ) #define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U ) #define FT_ERR_EQ( x, e ) \ ( FT_ERROR_BASE( x ) == FT_ERROR_BASE( FT_ERR( e ) ) ) #define FT_ERR_NEQ( x, e ) \ ( FT_ERROR_BASE( x ) != FT_ERROR_BASE( FT_ERR( e ) ) ) FT_END_HEADER #endif /* FTTYPES_H_ */ /* END */ freetype2/freetype/ftfntfmt.h 0000644 00000011560 15146341150 0012300 0 ustar 00 /***************************************************************************/ /* */ /* ftfntfmt.h */ /* */ /* Support functions for font formats. */ /* */ /* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTFNTFMT_H_ #define FTFNTFMT_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* font_formats */ /* */ /* <Title> */ /* Font Formats */ /* */ /* <Abstract> */ /* Getting the font format. */ /* */ /* <Description> */ /* The single function in this section can be used to get the font */ /* format. Note that this information is not needed normally; */ /* however, there are special cases (like in PDF devices) where it is */ /* important to differentiate, in spite of FreeType's uniform API. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Font_Format */ /* */ /* <Description> */ /* Return a string describing the format of a given face. Possible */ /* values are `TrueType', `Type~1', `BDF', `PCF', `Type~42', */ /* `CID~Type~1', `CFF', `PFR', and `Windows~FNT'. */ /* */ /* The return value is suitable to be used as an X11 FONT_PROPERTY. */ /* */ /* <Input> */ /* face :: */ /* Input face handle. */ /* */ /* <Return> */ /* Font format string. NULL in case of error. */ /* */ /* <Note> */ /* A deprecated name for the same function is */ /* `FT_Get_X11_Font_Format'. */ /* */ FT_EXPORT( const char* ) FT_Get_Font_Format( FT_Face face ); /* deprecated */ FT_EXPORT( const char* ) FT_Get_X11_Font_Format( FT_Face face ); /* */ FT_END_HEADER #endif /* FTFNTFMT_H_ */ /* END */ freetype2/freetype/tttags.h 0000644 00000013003 15146341150 0011750 0 ustar 00 /***************************************************************************/ /* */ /* tttags.h */ /* */ /* Tags for TrueType and OpenType tables (specification only). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef TTAGS_H_ #define TTAGS_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER #define TTAG_avar FT_MAKE_TAG( 'a', 'v', 'a', 'r' ) #define TTAG_BASE FT_MAKE_TAG( 'B', 'A', 'S', 'E' ) #define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) #define TTAG_BDF FT_MAKE_TAG( 'B', 'D', 'F', ' ' ) #define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' ) #define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) #define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' ) #define TTAG_CBDT FT_MAKE_TAG( 'C', 'B', 'D', 'T' ) #define TTAG_CBLC FT_MAKE_TAG( 'C', 'B', 'L', 'C' ) #define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) #define TTAG_CFF2 FT_MAKE_TAG( 'C', 'F', 'F', '2' ) #define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) #define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) #define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) #define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) #define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) #define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) #define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) #define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) #define TTAG_feat FT_MAKE_TAG( 'f', 'e', 'a', 't' ) #define TTAG_FOND FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) #define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) #define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) #define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) #define TTAG_GDEF FT_MAKE_TAG( 'G', 'D', 'E', 'F' ) #define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) #define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) #define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) #define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) #define TTAG_HVAR FT_MAKE_TAG( 'H', 'V', 'A', 'R' ) #define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) #define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) #define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) #define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) #define TTAG_JSTF FT_MAKE_TAG( 'J', 'S', 'T', 'F' ) #define TTAG_just FT_MAKE_TAG( 'j', 'u', 's', 't' ) #define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) #define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' ) #define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) #define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) #define TTAG_LWFN FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) #define TTAG_MATH FT_MAKE_TAG( 'M', 'A', 'T', 'H' ) #define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) #define TTAG_META FT_MAKE_TAG( 'M', 'E', 'T', 'A' ) #define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) #define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) #define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' ) #define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' ) #define TTAG_MVAR FT_MAKE_TAG( 'M', 'V', 'A', 'R' ) #define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) #define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' ) #define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) #define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) #define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) #define TTAG_POST FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) #define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) #define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) #define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) #define TTAG_sbix FT_MAKE_TAG( 's', 'b', 'i', 'x' ) #define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) #define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) #define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) #define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) #define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) #define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) #define TTAG_TYP1 FT_MAKE_TAG( 'T', 'Y', 'P', '1' ) #define TTAG_typ1 FT_MAKE_TAG( 't', 'y', 'p', '1' ) #define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) #define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) #define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) #define TTAG_VVAR FT_MAKE_TAG( 'V', 'V', 'A', 'R' ) #define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' ) /* used by "Keyboard.dfont" on legacy Mac OS X */ #define TTAG_0xA5kbd FT_MAKE_TAG( 0xA5, 'k', 'b', 'd' ) /* used by "LastResort.dfont" on legacy Mac OS X */ #define TTAG_0xA5lst FT_MAKE_TAG( 0xA5, 'l', 's', 't' ) FT_END_HEADER #endif /* TTAGS_H_ */ /* END */ freetype2/freetype/ftmac.h 0000644 00000041361 15146341150 0011544 0 ustar 00 /***************************************************************************/ /* */ /* ftmac.h */ /* */ /* Additional Mac-specific API. */ /* */ /* Copyright 1996-2018 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /***************************************************************************/ /* */ /* NOTE: Include this file after FT_FREETYPE_H and after any */ /* Mac-specific headers (because this header uses Mac types such as */ /* Handle, FSSpec, FSRef, etc.) */ /* */ /***************************************************************************/ #ifndef FTMAC_H_ #define FTMAC_H_ #include <ft2build.h> FT_BEGIN_HEADER /* gcc-3.1 and later can warn about functions tagged as deprecated */ #ifndef FT_DEPRECATED_ATTRIBUTE #if defined( __GNUC__ ) && \ ( ( __GNUC__ >= 4 ) || \ ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 1 ) ) ) #define FT_DEPRECATED_ATTRIBUTE __attribute__(( deprecated )) #else #define FT_DEPRECATED_ATTRIBUTE #endif #endif /*************************************************************************/ /* */ /* <Section> */ /* mac_specific */ /* */ /* <Title> */ /* Mac Specific Interface */ /* */ /* <Abstract> */ /* Only available on the Macintosh. */ /* */ /* <Description> */ /* The following definitions are only available if FreeType is */ /* compiled on a Macintosh. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_New_Face_From_FOND */ /* */ /* <Description> */ /* Create a new face object from a FOND resource. */ /* */ /* <InOut> */ /* library :: A handle to the library resource. */ /* */ /* <Input> */ /* fond :: A FOND resource. */ /* */ /* face_index :: Only supported for the -1 `sanity check' special */ /* case. */ /* */ /* <Output> */ /* aface :: A handle to a new face object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Notes> */ /* This function can be used to create @FT_Face objects from fonts */ /* that are installed in the system as follows. */ /* */ /* { */ /* fond = GetResource( 'FOND', fontName ); */ /* error = FT_New_Face_From_FOND( library, fond, 0, &face ); */ /* } */ /* */ FT_EXPORT( FT_Error ) FT_New_Face_From_FOND( FT_Library library, Handle fond, FT_Long face_index, FT_Face *aface ) FT_DEPRECATED_ATTRIBUTE; /*************************************************************************/ /* */ /* <Function> */ /* FT_GetFile_From_Mac_Name */ /* */ /* <Description> */ /* Return an FSSpec for the disk file containing the named font. */ /* */ /* <Input> */ /* fontName :: Mac OS name of the font (e.g., Times New Roman */ /* Bold). */ /* */ /* <Output> */ /* pathSpec :: FSSpec to the file. For passing to */ /* @FT_New_Face_From_FSSpec. */ /* */ /* face_index :: Index of the face. For passing to */ /* @FT_New_Face_From_FSSpec. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, FSSpec* pathSpec, FT_Long* face_index ) FT_DEPRECATED_ATTRIBUTE; /*************************************************************************/ /* */ /* <Function> */ /* FT_GetFile_From_Mac_ATS_Name */ /* */ /* <Description> */ /* Return an FSSpec for the disk file containing the named font. */ /* */ /* <Input> */ /* fontName :: Mac OS name of the font in ATS framework. */ /* */ /* <Output> */ /* pathSpec :: FSSpec to the file. For passing to */ /* @FT_New_Face_From_FSSpec. */ /* */ /* face_index :: Index of the face. For passing to */ /* @FT_New_Face_From_FSSpec. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_GetFile_From_Mac_ATS_Name( const char* fontName, FSSpec* pathSpec, FT_Long* face_index ) FT_DEPRECATED_ATTRIBUTE; /*************************************************************************/ /* */ /* <Function> */ /* FT_GetFilePath_From_Mac_ATS_Name */ /* */ /* <Description> */ /* Return a pathname of the disk file and face index for given font */ /* name that is handled by ATS framework. */ /* */ /* <Input> */ /* fontName :: Mac OS name of the font in ATS framework. */ /* */ /* <Output> */ /* path :: Buffer to store pathname of the file. For passing */ /* to @FT_New_Face. The client must allocate this */ /* buffer before calling this function. */ /* */ /* maxPathSize :: Lengths of the buffer `path' that client allocated. */ /* */ /* face_index :: Index of the face. For passing to @FT_New_Face. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, UInt8* path, UInt32 maxPathSize, FT_Long* face_index ) FT_DEPRECATED_ATTRIBUTE; /*************************************************************************/ /* */ /* <Function> */ /* FT_New_Face_From_FSSpec */ /* */ /* <Description> */ /* Create a new face object from a given resource and typeface index */ /* using an FSSpec to the font file. */ /* */ /* <InOut> */ /* library :: A handle to the library resource. */ /* */ /* <Input> */ /* spec :: FSSpec to the font file. */ /* */ /* face_index :: The index of the face within the resource. The */ /* first face has index~0. */ /* <Output> */ /* aface :: A handle to a new face object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ /* it accepts an FSSpec instead of a path. */ /* */ FT_EXPORT( FT_Error ) FT_New_Face_From_FSSpec( FT_Library library, const FSSpec *spec, FT_Long face_index, FT_Face *aface ) FT_DEPRECATED_ATTRIBUTE; /*************************************************************************/ /* */ /* <Function> */ /* FT_New_Face_From_FSRef */ /* */ /* <Description> */ /* Create a new face object from a given resource and typeface index */ /* using an FSRef to the font file. */ /* */ /* <InOut> */ /* library :: A handle to the library resource. */ /* */ /* <Input> */ /* spec :: FSRef to the font file. */ /* */ /* face_index :: The index of the face within the resource. The */ /* first face has index~0. */ /* <Output> */ /* aface :: A handle to a new face object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* @FT_New_Face_From_FSRef is identical to @FT_New_Face except */ /* it accepts an FSRef instead of a path. */ /* */ FT_EXPORT( FT_Error ) FT_New_Face_From_FSRef( FT_Library library, const FSRef *ref, FT_Long face_index, FT_Face *aface ) FT_DEPRECATED_ATTRIBUTE; /* */ FT_END_HEADER #endif /* FTMAC_H_ */ /* END */ freetype2/freetype/ftbbox.h 0000644 00000012162 15146341150 0011733 0 ustar 00 /***************************************************************************/ /* */ /* ftbbox.h */ /* */ /* FreeType exact bbox computation (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This component has a _single_ role: to compute exact outline bounding */ /* boxes. */ /* */ /* It is separated from the rest of the engine for various technical */ /* reasons. It may well be integrated in `ftoutln' later. */ /* */ /*************************************************************************/ #ifndef FTBBOX_H_ #define FTBBOX_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* outline_processing */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_Outline_Get_BBox */ /* */ /* <Description> */ /* Compute the exact bounding box of an outline. This is slower */ /* than computing the control box. However, it uses an advanced */ /* algorithm that returns _very_ quickly when the two boxes */ /* coincide. Otherwise, the outline Bezier arcs are traversed to */ /* extract their extrema. */ /* */ /* <Input> */ /* outline :: A pointer to the source outline. */ /* */ /* <Output> */ /* abbox :: The outline's exact bounding box. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* If the font is tricky and the glyph has been loaded with */ /* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get */ /* reasonable values for the BBox it is necessary to load the glyph */ /* at a large ppem value (so that the hinting instructions can */ /* properly shift and scale the subglyphs), then extracting the BBox, */ /* which can be eventually converted back to font units. */ /* */ FT_EXPORT( FT_Error ) FT_Outline_Get_BBox( FT_Outline* outline, FT_BBox *abbox ); /* */ FT_END_HEADER #endif /* FTBBOX_H_ */ /* END */ /* Local Variables: */ /* coding: utf-8 */ /* End: */ freetype2/freetype/ftlist.h 0000644 00000040562 15146341150 0011761 0 ustar 00 /***************************************************************************/ /* */ /* ftlist.h */ /* */ /* Generic list support for FreeType (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This file implements functions relative to list processing. Its */ /* data structures are defined in `freetype.h'. */ /* */ /*************************************************************************/ #ifndef FTLIST_H_ #define FTLIST_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* list_processing */ /* */ /* <Title> */ /* List Processing */ /* */ /* <Abstract> */ /* Simple management of lists. */ /* */ /* <Description> */ /* This section contains various definitions related to list */ /* processing using doubly-linked nodes. */ /* */ /* <Order> */ /* FT_List */ /* FT_ListNode */ /* FT_ListRec */ /* FT_ListNodeRec */ /* */ /* FT_List_Add */ /* FT_List_Insert */ /* FT_List_Find */ /* FT_List_Remove */ /* FT_List_Up */ /* FT_List_Iterate */ /* FT_List_Iterator */ /* FT_List_Finalize */ /* FT_List_Destructor */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Find */ /* */ /* <Description> */ /* Find the list node for a given listed object. */ /* */ /* <Input> */ /* list :: A pointer to the parent list. */ /* data :: The address of the listed object. */ /* */ /* <Return> */ /* List node. NULL if it wasn't found. */ /* */ FT_EXPORT( FT_ListNode ) FT_List_Find( FT_List list, void* data ); /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Add */ /* */ /* <Description> */ /* Append an element to the end of a list. */ /* */ /* <InOut> */ /* list :: A pointer to the parent list. */ /* node :: The node to append. */ /* */ FT_EXPORT( void ) FT_List_Add( FT_List list, FT_ListNode node ); /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Insert */ /* */ /* <Description> */ /* Insert an element at the head of a list. */ /* */ /* <InOut> */ /* list :: A pointer to parent list. */ /* node :: The node to insert. */ /* */ FT_EXPORT( void ) FT_List_Insert( FT_List list, FT_ListNode node ); /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Remove */ /* */ /* <Description> */ /* Remove a node from a list. This function doesn't check whether */ /* the node is in the list! */ /* */ /* <Input> */ /* node :: The node to remove. */ /* */ /* <InOut> */ /* list :: A pointer to the parent list. */ /* */ FT_EXPORT( void ) FT_List_Remove( FT_List list, FT_ListNode node ); /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Up */ /* */ /* <Description> */ /* Move a node to the head/top of a list. Used to maintain LRU */ /* lists. */ /* */ /* <InOut> */ /* list :: A pointer to the parent list. */ /* node :: The node to move. */ /* */ FT_EXPORT( void ) FT_List_Up( FT_List list, FT_ListNode node ); /*************************************************************************/ /* */ /* <FuncType> */ /* FT_List_Iterator */ /* */ /* <Description> */ /* An FT_List iterator function that is called during a list parse */ /* by @FT_List_Iterate. */ /* */ /* <Input> */ /* node :: The current iteration list node. */ /* */ /* user :: A typeless pointer passed to @FT_List_Iterate. */ /* Can be used to point to the iteration's state. */ /* */ typedef FT_Error (*FT_List_Iterator)( FT_ListNode node, void* user ); /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Iterate */ /* */ /* <Description> */ /* Parse a list and calls a given iterator function on each element. */ /* Note that parsing is stopped as soon as one of the iterator calls */ /* returns a non-zero value. */ /* */ /* <Input> */ /* list :: A handle to the list. */ /* iterator :: An iterator function, called on each node of the list. */ /* user :: A user-supplied field that is passed as the second */ /* argument to the iterator. */ /* */ /* <Return> */ /* The result (a FreeType error code) of the last iterator call. */ /* */ FT_EXPORT( FT_Error ) FT_List_Iterate( FT_List list, FT_List_Iterator iterator, void* user ); /*************************************************************************/ /* */ /* <FuncType> */ /* FT_List_Destructor */ /* */ /* <Description> */ /* An @FT_List iterator function that is called during a list */ /* finalization by @FT_List_Finalize to destroy all elements in a */ /* given list. */ /* */ /* <Input> */ /* system :: The current system object. */ /* */ /* data :: The current object to destroy. */ /* */ /* user :: A typeless pointer passed to @FT_List_Iterate. It can */ /* be used to point to the iteration's state. */ /* */ typedef void (*FT_List_Destructor)( FT_Memory memory, void* data, void* user ); /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Finalize */ /* */ /* <Description> */ /* Destroy all elements in the list as well as the list itself. */ /* */ /* <Input> */ /* list :: A handle to the list. */ /* */ /* destroy :: A list destructor that will be applied to each element */ /* of the list. Set this to NULL if not needed. */ /* */ /* memory :: The current memory object that handles deallocation. */ /* */ /* user :: A user-supplied field that is passed as the last */ /* argument to the destructor. */ /* */ /* <Note> */ /* This function expects that all nodes added by @FT_List_Add or */ /* @FT_List_Insert have been dynamically allocated. */ /* */ FT_EXPORT( void ) FT_List_Finalize( FT_List list, FT_List_Destructor destroy, FT_Memory memory, void* user ); /* */ FT_END_HEADER #endif /* FTLIST_H_ */ /* END */ freetype2/freetype/ftsystem.h 0000644 00000024472 15146341150 0012334 0 ustar 00 /***************************************************************************/ /* */ /* ftsystem.h */ /* */ /* FreeType low-level system interface definition (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTSYSTEM_H_ #define FTSYSTEM_H_ #include <ft2build.h> FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* system_interface */ /* */ /* <Title> */ /* System Interface */ /* */ /* <Abstract> */ /* How FreeType manages memory and i/o. */ /* */ /* <Description> */ /* This section contains various definitions related to memory */ /* management and i/o access. You need to understand this */ /* information if you want to use a custom memory manager or you own */ /* i/o streams. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* M E M O R Y M A N A G E M E N T */ /* */ /*************************************************************************/ /************************************************************************* * * @type: * FT_Memory * * @description: * A handle to a given memory manager object, defined with an * @FT_MemoryRec structure. * */ typedef struct FT_MemoryRec_* FT_Memory; /************************************************************************* * * @functype: * FT_Alloc_Func * * @description: * A function used to allocate `size' bytes from `memory'. * * @input: * memory :: * A handle to the source memory manager. * * size :: * The size in bytes to allocate. * * @return: * Address of new memory block. 0~in case of failure. * */ typedef void* (*FT_Alloc_Func)( FT_Memory memory, long size ); /************************************************************************* * * @functype: * FT_Free_Func * * @description: * A function used to release a given block of memory. * * @input: * memory :: * A handle to the source memory manager. * * block :: * The address of the target memory block. * */ typedef void (*FT_Free_Func)( FT_Memory memory, void* block ); /************************************************************************* * * @functype: * FT_Realloc_Func * * @description: * A function used to re-allocate a given block of memory. * * @input: * memory :: * A handle to the source memory manager. * * cur_size :: * The block's current size in bytes. * * new_size :: * The block's requested new size. * * block :: * The block's current address. * * @return: * New block address. 0~in case of memory shortage. * * @note: * In case of error, the old block must still be available. * */ typedef void* (*FT_Realloc_Func)( FT_Memory memory, long cur_size, long new_size, void* block ); /************************************************************************* * * @struct: * FT_MemoryRec * * @description: * A structure used to describe a given memory manager to FreeType~2. * * @fields: * user :: * A generic typeless pointer for user data. * * alloc :: * A pointer type to an allocation function. * * free :: * A pointer type to an memory freeing function. * * realloc :: * A pointer type to a reallocation function. * */ struct FT_MemoryRec_ { void* user; FT_Alloc_Func alloc; FT_Free_Func free; FT_Realloc_Func realloc; }; /*************************************************************************/ /* */ /* I / O M A N A G E M E N T */ /* */ /*************************************************************************/ /************************************************************************* * * @type: * FT_Stream * * @description: * A handle to an input stream. * * @also: * See @FT_StreamRec for the publicly accessible fields of a given * stream object. * */ typedef struct FT_StreamRec_* FT_Stream; /************************************************************************* * * @struct: * FT_StreamDesc * * @description: * A union type used to store either a long or a pointer. This is used * to store a file descriptor or a `FILE*' in an input stream. * */ typedef union FT_StreamDesc_ { long value; void* pointer; } FT_StreamDesc; /************************************************************************* * * @functype: * FT_Stream_IoFunc * * @description: * A function used to seek and read data from a given input stream. * * @input: * stream :: * A handle to the source stream. * * offset :: * The offset of read in stream (always from start). * * buffer :: * The address of the read buffer. * * count :: * The number of bytes to read from the stream. * * @return: * The number of bytes effectively read by the stream. * * @note: * This function might be called to perform a seek or skip operation * with a `count' of~0. A non-zero return value then indicates an * error. * */ typedef unsigned long (*FT_Stream_IoFunc)( FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count ); /************************************************************************* * * @functype: * FT_Stream_CloseFunc * * @description: * A function used to close a given input stream. * * @input: * stream :: * A handle to the target stream. * */ typedef void (*FT_Stream_CloseFunc)( FT_Stream stream ); /************************************************************************* * * @struct: * FT_StreamRec * * @description: * A structure used to describe an input stream. * * @input: * base :: * For memory-based streams, this is the address of the first stream * byte in memory. This field should always be set to NULL for * disk-based streams. * * size :: * The stream size in bytes. * * In case of compressed streams where the size is unknown before * actually doing the decompression, the value is set to 0x7FFFFFFF. * (Note that this size value can occur for normal streams also; it is * thus just a hint.) * * pos :: * The current position within the stream. * * descriptor :: * This field is a union that can hold an integer or a pointer. It is * used by stream implementations to store file descriptors or `FILE*' * pointers. * * pathname :: * This field is completely ignored by FreeType. However, it is often * useful during debugging to use it to store the stream's filename * (where available). * * read :: * The stream's input function. * * close :: * The stream's close function. * * memory :: * The memory manager to use to preload frames. This is set * internally by FreeType and shouldn't be touched by stream * implementations. * * cursor :: * This field is set and used internally by FreeType when parsing * frames. * * limit :: * This field is set and used internally by FreeType when parsing * frames. * */ typedef struct FT_StreamRec_ { unsigned char* base; unsigned long size; unsigned long pos; FT_StreamDesc descriptor; FT_StreamDesc pathname; FT_Stream_IoFunc read; FT_Stream_CloseFunc close; FT_Memory memory; unsigned char* cursor; unsigned char* limit; } FT_StreamRec; /* */ FT_END_HEADER #endif /* FTSYSTEM_H_ */ /* END */ freetype2/freetype/fterrdef.h 0000644 00000034330 15146341150 0012251 0 ustar 00 /***************************************************************************/ /* */ /* fterrdef.h */ /* */ /* FreeType error codes (specification). */ /* */ /* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* <Section> */ /* error_code_values */ /* */ /* <Title> */ /* Error Code Values */ /* */ /* <Abstract> */ /* All possible error codes returned by FreeType functions. */ /* */ /* <Description> */ /* The list below is taken verbatim from the file `fterrdef.h' */ /* (loaded automatically by including `FT_FREETYPE_H'). The first */ /* argument of the `FT_ERROR_DEF_' macro is the error label; by */ /* default, the prefix `FT_Err_' gets added so that you get error */ /* names like `FT_Err_Cannot_Open_Resource'. The second argument is */ /* the error code, and the last argument an error string, which is not */ /* used by FreeType. */ /* */ /* Within your application you should *only* use error names and */ /* *never* its numeric values! The latter might (and actually do) */ /* change in forthcoming FreeType versions. */ /* */ /* Macro `FT_NOERRORDEF_' defines `FT_Err_Ok', which is always zero. */ /* See the `Error Enumerations' subsection how to automatically */ /* generate a list of error strings. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Enum> */ /* FT_Err_XXX */ /* */ /*************************************************************************/ /* generic errors */ FT_NOERRORDEF_( Ok, 0x00, "no error" ) FT_ERRORDEF_( Cannot_Open_Resource, 0x01, "cannot open resource" ) FT_ERRORDEF_( Unknown_File_Format, 0x02, "unknown file format" ) FT_ERRORDEF_( Invalid_File_Format, 0x03, "broken file" ) FT_ERRORDEF_( Invalid_Version, 0x04, "invalid FreeType version" ) FT_ERRORDEF_( Lower_Module_Version, 0x05, "module version is too low" ) FT_ERRORDEF_( Invalid_Argument, 0x06, "invalid argument" ) FT_ERRORDEF_( Unimplemented_Feature, 0x07, "unimplemented feature" ) FT_ERRORDEF_( Invalid_Table, 0x08, "broken table" ) FT_ERRORDEF_( Invalid_Offset, 0x09, "broken offset within table" ) FT_ERRORDEF_( Array_Too_Large, 0x0A, "array allocation size too large" ) FT_ERRORDEF_( Missing_Module, 0x0B, "missing module" ) FT_ERRORDEF_( Missing_Property, 0x0C, "missing property" ) /* glyph/character errors */ FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, "invalid glyph index" ) FT_ERRORDEF_( Invalid_Character_Code, 0x11, "invalid character code" ) FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, "unsupported glyph image format" ) FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, "cannot render this glyph format" ) FT_ERRORDEF_( Invalid_Outline, 0x14, "invalid outline" ) FT_ERRORDEF_( Invalid_Composite, 0x15, "invalid composite glyph" ) FT_ERRORDEF_( Too_Many_Hints, 0x16, "too many hints" ) FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, "invalid pixel size" ) /* handle errors */ FT_ERRORDEF_( Invalid_Handle, 0x20, "invalid object handle" ) FT_ERRORDEF_( Invalid_Library_Handle, 0x21, "invalid library handle" ) FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, "invalid module handle" ) FT_ERRORDEF_( Invalid_Face_Handle, 0x23, "invalid face handle" ) FT_ERRORDEF_( Invalid_Size_Handle, 0x24, "invalid size handle" ) FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, "invalid glyph slot handle" ) FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, "invalid charmap handle" ) FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, "invalid cache manager handle" ) FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, "invalid stream handle" ) /* driver errors */ FT_ERRORDEF_( Too_Many_Drivers, 0x30, "too many modules" ) FT_ERRORDEF_( Too_Many_Extensions, 0x31, "too many extensions" ) /* memory errors */ FT_ERRORDEF_( Out_Of_Memory, 0x40, "out of memory" ) FT_ERRORDEF_( Unlisted_Object, 0x41, "unlisted object" ) /* stream errors */ FT_ERRORDEF_( Cannot_Open_Stream, 0x51, "cannot open stream" ) FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, "invalid stream seek" ) FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, "invalid stream skip" ) FT_ERRORDEF_( Invalid_Stream_Read, 0x54, "invalid stream read" ) FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, "invalid stream operation" ) FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, "invalid frame operation" ) FT_ERRORDEF_( Nested_Frame_Access, 0x57, "nested frame access" ) FT_ERRORDEF_( Invalid_Frame_Read, 0x58, "invalid frame read" ) /* raster errors */ FT_ERRORDEF_( Raster_Uninitialized, 0x60, "raster uninitialized" ) FT_ERRORDEF_( Raster_Corrupted, 0x61, "raster corrupted" ) FT_ERRORDEF_( Raster_Overflow, 0x62, "raster overflow" ) FT_ERRORDEF_( Raster_Negative_Height, 0x63, "negative height while rastering" ) /* cache errors */ FT_ERRORDEF_( Too_Many_Caches, 0x70, "too many registered caches" ) /* TrueType and SFNT errors */ FT_ERRORDEF_( Invalid_Opcode, 0x80, "invalid opcode" ) FT_ERRORDEF_( Too_Few_Arguments, 0x81, "too few arguments" ) FT_ERRORDEF_( Stack_Overflow, 0x82, "stack overflow" ) FT_ERRORDEF_( Code_Overflow, 0x83, "code overflow" ) FT_ERRORDEF_( Bad_Argument, 0x84, "bad argument" ) FT_ERRORDEF_( Divide_By_Zero, 0x85, "division by zero" ) FT_ERRORDEF_( Invalid_Reference, 0x86, "invalid reference" ) FT_ERRORDEF_( Debug_OpCode, 0x87, "found debug opcode" ) FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, "found ENDF opcode in execution stream" ) FT_ERRORDEF_( Nested_DEFS, 0x89, "nested DEFS" ) FT_ERRORDEF_( Invalid_CodeRange, 0x8A, "invalid code range" ) FT_ERRORDEF_( Execution_Too_Long, 0x8B, "execution context too long" ) FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, "too many function definitions" ) FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, "too many instruction definitions" ) FT_ERRORDEF_( Table_Missing, 0x8E, "SFNT font table missing" ) FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, "horizontal header (hhea) table missing" ) FT_ERRORDEF_( Locations_Missing, 0x90, "locations (loca) table missing" ) FT_ERRORDEF_( Name_Table_Missing, 0x91, "name table missing" ) FT_ERRORDEF_( CMap_Table_Missing, 0x92, "character map (cmap) table missing" ) FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, "horizontal metrics (hmtx) table missing" ) FT_ERRORDEF_( Post_Table_Missing, 0x94, "PostScript (post) table missing" ) FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, "invalid horizontal metrics" ) FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, "invalid character map (cmap) format" ) FT_ERRORDEF_( Invalid_PPem, 0x97, "invalid ppem value" ) FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, "invalid vertical metrics" ) FT_ERRORDEF_( Could_Not_Find_Context, 0x99, "could not find context" ) FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, "invalid PostScript (post) table format" ) FT_ERRORDEF_( Invalid_Post_Table, 0x9B, "invalid PostScript (post) table" ) FT_ERRORDEF_( DEF_In_Glyf_Bytecode, 0x9C, "found FDEF or IDEF opcode in glyf bytecode" ) FT_ERRORDEF_( Missing_Bitmap, 0x9D, "missing bitmap in strike" ) /* CFF, CID, and Type 1 errors */ FT_ERRORDEF_( Syntax_Error, 0xA0, "opcode syntax error" ) FT_ERRORDEF_( Stack_Underflow, 0xA1, "argument stack underflow" ) FT_ERRORDEF_( Ignore, 0xA2, "ignore" ) FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, "no Unicode glyph name found" ) FT_ERRORDEF_( Glyph_Too_Big, 0xA4, "glyph too big for hinting" ) /* BDF errors */ FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, "`STARTFONT' field missing" ) FT_ERRORDEF_( Missing_Font_Field, 0xB1, "`FONT' field missing" ) FT_ERRORDEF_( Missing_Size_Field, 0xB2, "`SIZE' field missing" ) FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3, "`FONTBOUNDINGBOX' field missing" ) FT_ERRORDEF_( Missing_Chars_Field, 0xB4, "`CHARS' field missing" ) FT_ERRORDEF_( Missing_Startchar_Field, 0xB5, "`STARTCHAR' field missing" ) FT_ERRORDEF_( Missing_Encoding_Field, 0xB6, "`ENCODING' field missing" ) FT_ERRORDEF_( Missing_Bbx_Field, 0xB7, "`BBX' field missing" ) FT_ERRORDEF_( Bbx_Too_Big, 0xB8, "`BBX' too big" ) FT_ERRORDEF_( Corrupted_Font_Header, 0xB9, "Font header corrupted or missing fields" ) FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA, "Font glyphs corrupted or missing fields" ) /* */ /* END */ freetype2/freetype/ftgzip.h 0000644 00000013023 15146341150 0011747 0 ustar 00 /***************************************************************************/ /* */ /* ftgzip.h */ /* */ /* Gzip-compressed stream support. */ /* */ /* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTGZIP_H_ #define FTGZIP_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* gzip */ /* */ /* <Title> */ /* GZIP Streams */ /* */ /* <Abstract> */ /* Using gzip-compressed font files. */ /* */ /* <Description> */ /* This section contains the declaration of Gzip-specific functions. */ /* */ /*************************************************************************/ /************************************************************************ * * @function: * FT_Stream_OpenGzip * * @description: * Open a new stream to parse gzip-compressed font files. This is * mainly used to support the compressed `*.pcf.gz' fonts that come * with XFree86. * * @input: * stream :: * The target embedding stream. * * source :: * The source stream. * * @return: * FreeType error code. 0~means success. * * @note: * The source stream must be opened _before_ calling this function. * * Calling the internal function `FT_Stream_Close' on the new stream will * *not* call `FT_Stream_Close' on the source stream. None of the stream * objects will be released to the heap. * * The stream implementation is very basic and resets the decompression * process each time seeking backwards is needed within the stream. * * In certain builds of the library, gzip compression recognition is * automatically handled when calling @FT_New_Face or @FT_Open_Face. * This means that if no font driver is capable of handling the raw * compressed file, the library will try to open a gzipped stream from * it and re-open the face with it. * * This function may return `FT_Err_Unimplemented_Feature' if your build * of FreeType was not compiled with zlib support. */ FT_EXPORT( FT_Error ) FT_Stream_OpenGzip( FT_Stream stream, FT_Stream source ); /************************************************************************ * * @function: * FT_Gzip_Uncompress * * @description: * Decompress a zipped input buffer into an output buffer. This function * is modeled after zlib's `uncompress' function. * * @input: * memory :: * A FreeType memory handle. * * input :: * The input buffer. * * input_len :: * The length of the input buffer. * * @output: * output:: * The output buffer. * * @inout: * output_len :: * Before calling the function, this is the total size of the output * buffer, which must be large enough to hold the entire uncompressed * data (so the size of the uncompressed data must be known in * advance). After calling the function, `output_len' is the size of * the used data in `output'. * * @return: * FreeType error code. 0~means success. * * @note: * This function may return `FT_Err_Unimplemented_Feature' if your build * of FreeType was not compiled with zlib support. * * @since: * 2.5.1 */ FT_EXPORT( FT_Error ) FT_Gzip_Uncompress( FT_Memory memory, FT_Byte* output, FT_ULong* output_len, const FT_Byte* input, FT_ULong input_len ); /* */ FT_END_HEADER #endif /* FTGZIP_H_ */ /* END */ freetype2/freetype/ftmm.h 0000644 00000120573 15146341150 0011420 0 ustar 00 /***************************************************************************/ /* */ /* ftmm.h */ /* */ /* FreeType Multiple Master font interface (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTMM_H_ #define FTMM_H_ #include <ft2build.h> #include FT_TYPE1_TABLES_H FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* multiple_masters */ /* */ /* <Title> */ /* Multiple Masters */ /* */ /* <Abstract> */ /* How to manage Multiple Masters fonts. */ /* */ /* <Description> */ /* The following types and functions are used to manage Multiple */ /* Master fonts, i.e., the selection of specific design instances by */ /* setting design axis coordinates. */ /* */ /* Besides Adobe MM fonts, the interface supports Apple's TrueType GX */ /* and OpenType variation fonts. Some of the routines only work with */ /* Adobe MM fonts, others will work with all three types. They are */ /* similar enough that a consistent interface makes sense. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Struct> */ /* FT_MM_Axis */ /* */ /* <Description> */ /* A structure to model a given axis in design space for Multiple */ /* Masters fonts. */ /* */ /* This structure can't be used for TrueType GX or OpenType variation */ /* fonts. */ /* */ /* <Fields> */ /* name :: The axis's name. */ /* */ /* minimum :: The axis's minimum design coordinate. */ /* */ /* maximum :: The axis's maximum design coordinate. */ /* */ typedef struct FT_MM_Axis_ { FT_String* name; FT_Long minimum; FT_Long maximum; } FT_MM_Axis; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Multi_Master */ /* */ /* <Description> */ /* A structure to model the axes and space of a Multiple Masters */ /* font. */ /* */ /* This structure can't be used for TrueType GX or OpenType variation */ /* fonts. */ /* */ /* <Fields> */ /* num_axis :: Number of axes. Cannot exceed~4. */ /* */ /* num_designs :: Number of designs; should be normally 2^num_axis */ /* even though the Type~1 specification strangely */ /* allows for intermediate designs to be present. */ /* This number cannot exceed~16. */ /* */ /* axis :: A table of axis descriptors. */ /* */ typedef struct FT_Multi_Master_ { FT_UInt num_axis; FT_UInt num_designs; FT_MM_Axis axis[T1_MAX_MM_AXIS]; } FT_Multi_Master; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Var_Axis */ /* */ /* <Description> */ /* A structure to model a given axis in design space for Multiple */ /* Masters, TrueType GX, and OpenType variation fonts. */ /* */ /* <Fields> */ /* name :: The axis's name. */ /* Not always meaningful for TrueType GX or OpenType */ /* variation fonts. */ /* */ /* minimum :: The axis's minimum design coordinate. */ /* */ /* def :: The axis's default design coordinate. */ /* FreeType computes meaningful default values for Adobe */ /* MM fonts. */ /* */ /* maximum :: The axis's maximum design coordinate. */ /* */ /* tag :: The axis's tag (the equivalent to `name' for TrueType */ /* GX and OpenType variation fonts). FreeType provides */ /* default values for Adobe MM fonts if possible. */ /* */ /* strid :: The axis name entry in the font's `name' table. This */ /* is another (and often better) version of the `name' */ /* field for TrueType GX or OpenType variation fonts. Not */ /* meaningful for Adobe MM fonts. */ /* */ /* <Note> */ /* The fields `minimum', `def', and `maximum' are 16.16 fractional */ /* values for TrueType GX and OpenType variation fonts. For Adobe MM */ /* fonts, the values are integers. */ /* */ typedef struct FT_Var_Axis_ { FT_String* name; FT_Fixed minimum; FT_Fixed def; FT_Fixed maximum; FT_ULong tag; FT_UInt strid; } FT_Var_Axis; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Var_Named_Style */ /* */ /* <Description> */ /* A structure to model a named instance in a TrueType GX or OpenType */ /* variation font. */ /* */ /* This structure can't be used for Adobe MM fonts. */ /* */ /* <Fields> */ /* coords :: The design coordinates for this instance. */ /* This is an array with one entry for each axis. */ /* */ /* strid :: The entry in `name' table identifying this instance. */ /* */ /* psid :: The entry in `name' table identifying a PostScript name */ /* for this instance. Value 0xFFFF indicates a missing */ /* entry. */ /* */ typedef struct FT_Var_Named_Style_ { FT_Fixed* coords; FT_UInt strid; FT_UInt psid; /* since 2.7.1 */ } FT_Var_Named_Style; /*************************************************************************/ /* */ /* <Struct> */ /* FT_MM_Var */ /* */ /* <Description> */ /* A structure to model the axes and space of an Adobe MM, TrueType */ /* GX, or OpenType variation font. */ /* */ /* Some fields are specific to one format and not to the others. */ /* */ /* <Fields> */ /* num_axis :: The number of axes. The maximum value is~4 for */ /* Adobe MM fonts; no limit in TrueType GX or */ /* OpenType variation fonts. */ /* */ /* num_designs :: The number of designs; should be normally */ /* 2^num_axis for Adobe MM fonts. Not meaningful */ /* for TrueType GX or OpenType variation fonts */ /* (where every glyph could have a different */ /* number of designs). */ /* */ /* num_namedstyles :: The number of named styles; a `named style' is */ /* a tuple of design coordinates that has a string */ /* ID (in the `name' table) associated with it. */ /* The font can tell the user that, for example, */ /* [Weight=1.5,Width=1.1] is `Bold'. Another name */ /* for `named style' is `named instance'. */ /* */ /* For Adobe Multiple Masters fonts, this value is */ /* always zero because the format does not support */ /* named styles. */ /* */ /* axis :: An axis descriptor table. */ /* TrueType GX and OpenType variation fonts */ /* contain slightly more data than Adobe MM fonts. */ /* Memory management of this pointer is done */ /* internally by FreeType. */ /* */ /* namedstyle :: A named style (instance) table. */ /* Only meaningful for TrueType GX and OpenType */ /* variation fonts. Memory management of this */ /* pointer is done internally by FreeType. */ /* */ typedef struct FT_MM_Var_ { FT_UInt num_axis; FT_UInt num_designs; FT_UInt num_namedstyles; FT_Var_Axis* axis; FT_Var_Named_Style* namedstyle; } FT_MM_Var; /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Multi_Master */ /* */ /* <Description> */ /* Retrieve a variation descriptor of a given Adobe MM font. */ /* */ /* This function can't be used with TrueType GX or OpenType variation */ /* fonts. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* <Output> */ /* amaster :: The Multiple Masters descriptor. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Multi_Master( FT_Face face, FT_Multi_Master *amaster ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_MM_Var */ /* */ /* <Description> */ /* Retrieve a variation descriptor for a given font. */ /* */ /* This function works with all supported variation formats. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* <Output> */ /* amaster :: The variation descriptor. */ /* Allocates a data structure, which the user must */ /* deallocate with a call to @FT_Done_MM_Var after use. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Get_MM_Var( FT_Face face, FT_MM_Var* *amaster ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Done_MM_Var */ /* */ /* <Description> */ /* Free the memory allocated by @FT_Get_MM_Var. */ /* */ /* <Input> */ /* library :: A handle of the face's parent library object that was */ /* used in the call to @FT_Get_MM_Var to create `amaster'. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_MM_Var( FT_Library library, FT_MM_Var *amaster ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_MM_Design_Coordinates */ /* */ /* <Description> */ /* For Adobe MM fonts, choose an interpolated font design through */ /* design coordinates. */ /* */ /* This function can't be used with TrueType GX or OpenType variation */ /* fonts. */ /* */ /* <InOut> */ /* face :: A handle to the source face. */ /* */ /* <Input> */ /* num_coords :: The number of available design coordinates. If it */ /* is larger than the number of axes, ignore the excess */ /* values. If it is smaller than the number of axes, */ /* use default values for the remaining axes. */ /* */ /* coords :: An array of design coordinates. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* [Since 2.8.1] To reset all axes to the default values, call the */ /* function with `num_coords' set to zero and `coords' set to NULL. */ /* */ /* [Since 2.9] If `num_coords' is larger than zero, this function */ /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */ /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */ /* is zero, this bit flag gets unset. */ /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Design_Coordinates( FT_Face face, FT_UInt num_coords, FT_Long* coords ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Var_Design_Coordinates */ /* */ /* <Description> */ /* Choose an interpolated font design through design coordinates. */ /* */ /* This function works with all supported variation formats. */ /* */ /* <InOut> */ /* face :: A handle to the source face. */ /* */ /* <Input> */ /* num_coords :: The number of available design coordinates. If it */ /* is larger than the number of axes, ignore the excess */ /* values. If it is smaller than the number of axes, */ /* use default values for the remaining axes. */ /* */ /* coords :: An array of design coordinates. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* [Since 2.8.1] To reset all axes to the default values, call the */ /* function with `num_coords' set to zero and `coords' set to NULL. */ /* [Since 2.9] `Default values' means the currently selected named */ /* instance (or the base font if no named instance is selected). */ /* */ /* [Since 2.9] If `num_coords' is larger than zero, this function */ /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */ /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */ /* is zero, this bit flag gets unset. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Var_Design_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Var_Design_Coordinates */ /* */ /* <Description> */ /* Get the design coordinates of the currently selected interpolated */ /* font. */ /* */ /* This function works with all supported variation formats. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* num_coords :: The number of design coordinates to retrieve. If it */ /* is larger than the number of axes, set the excess */ /* values to~0. */ /* */ /* <Output> */ /* coords :: The design coordinates array. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Since> */ /* 2.7.1 */ /* */ FT_EXPORT( FT_Error ) FT_Get_Var_Design_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_MM_Blend_Coordinates */ /* */ /* <Description> */ /* Choose an interpolated font design through normalized blend */ /* coordinates. */ /* */ /* This function works with all supported variation formats. */ /* */ /* <InOut> */ /* face :: A handle to the source face. */ /* */ /* <Input> */ /* num_coords :: The number of available design coordinates. If it */ /* is larger than the number of axes, ignore the excess */ /* values. If it is smaller than the number of axes, */ /* use default values for the remaining axes. */ /* */ /* coords :: The design coordinates array (each element must be */ /* between 0 and 1.0 for Adobe MM fonts, and between */ /* -1.0 and 1.0 for TrueType GX and OpenType variation */ /* fonts). */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* [Since 2.8.1] To reset all axes to the default values, call the */ /* function with `num_coords' set to zero and `coords' set to NULL. */ /* [Since 2.9] `Default values' means the currently selected named */ /* instance (or the base font if no named instance is selected). */ /* */ /* [Since 2.9] If `num_coords' is larger than zero, this function */ /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */ /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */ /* is zero, this bit flag gets unset. */ /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_MM_Blend_Coordinates */ /* */ /* <Description> */ /* Get the normalized blend coordinates of the currently selected */ /* interpolated font. */ /* */ /* This function works with all supported variation formats. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* num_coords :: The number of normalized blend coordinates to */ /* retrieve. If it is larger than the number of axes, */ /* set the excess values to~0.5 for Adobe MM fonts, and */ /* to~0 for TrueType GX and OpenType variation fonts. */ /* */ /* <Output> */ /* coords :: The normalized blend coordinates array. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Since> */ /* 2.7.1 */ /* */ FT_EXPORT( FT_Error ) FT_Get_MM_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Var_Blend_Coordinates */ /* */ /* <Description> */ /* This is another name of @FT_Set_MM_Blend_Coordinates. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Var_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Var_Blend_Coordinates */ /* */ /* <Description> */ /* This is another name of @FT_Get_MM_Blend_Coordinates. */ /* */ /* <Since> */ /* 2.7.1 */ /* */ FT_EXPORT( FT_Error ) FT_Get_Var_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); /*************************************************************************/ /* */ /* <Enum> */ /* FT_VAR_AXIS_FLAG_XXX */ /* */ /* <Description> */ /* A list of bit flags used in the return value of */ /* @FT_Get_Var_Axis_Flags. */ /* */ /* <Values> */ /* FT_VAR_AXIS_FLAG_HIDDEN :: */ /* The variation axis should not be exposed to user interfaces. */ /* */ /* <Since> */ /* 2.8.1 */ /* */ #define FT_VAR_AXIS_FLAG_HIDDEN 1 /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Var_Axis_Flags */ /* */ /* <Description> */ /* Get the `flags' field of an OpenType Variation Axis Record. */ /* */ /* Not meaningful for Adobe MM fonts (`*flags' is always zero). */ /* */ /* <Input> */ /* master :: The variation descriptor. */ /* */ /* axis_index :: The index of the requested variation axis. */ /* */ /* <Output> */ /* flags :: The `flags' field. See @FT_VAR_AXIS_FLAG_XXX for */ /* possible values. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Since> */ /* 2.8.1 */ /* */ FT_EXPORT( FT_Error ) FT_Get_Var_Axis_Flags( FT_MM_Var* master, FT_UInt axis_index, FT_UInt* flags ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Named_Instance */ /* */ /* <Description> */ /* Set or change the current named instance. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* instance_index :: The index of the requested instance, starting */ /* with value 1. If set to value 0, FreeType */ /* switches to font access without a named */ /* instance. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The function uses the value of `instance_index' to set bits 16-30 */ /* of the face's `face_index' field. It also resets any variation */ /* applied to the font, and the @FT_FACE_FLAG_VARIATION bit of the */ /* face's `face_flags' field gets reset to zero (i.e., */ /* @FT_IS_VARIATION will return false). */ /* */ /* For Adobe MM fonts (which don't have named instances) this */ /* function simply resets the current face to the default instance. */ /* */ /* <Since> */ /* 2.9 */ /* */ FT_EXPORT( FT_Error ) FT_Set_Named_Instance( FT_Face face, FT_UInt instance_index ); /* */ FT_END_HEADER #endif /* FTMM_H_ */ /* END */ freetype2/freetype/ftlzw.h 0000644 00000010230 15146341150 0011607 0 ustar 00 /***************************************************************************/ /* */ /* ftlzw.h */ /* */ /* LZW-compressed stream support. */ /* */ /* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTLZW_H_ #define FTLZW_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* lzw */ /* */ /* <Title> */ /* LZW Streams */ /* */ /* <Abstract> */ /* Using LZW-compressed font files. */ /* */ /* <Description> */ /* This section contains the declaration of LZW-specific functions. */ /* */ /*************************************************************************/ /************************************************************************ * * @function: * FT_Stream_OpenLZW * * @description: * Open a new stream to parse LZW-compressed font files. This is * mainly used to support the compressed `*.pcf.Z' fonts that come * with XFree86. * * @input: * stream :: The target embedding stream. * * source :: The source stream. * * @return: * FreeType error code. 0~means success. * * @note: * The source stream must be opened _before_ calling this function. * * Calling the internal function `FT_Stream_Close' on the new stream will * *not* call `FT_Stream_Close' on the source stream. None of the stream * objects will be released to the heap. * * The stream implementation is very basic and resets the decompression * process each time seeking backwards is needed within the stream * * In certain builds of the library, LZW compression recognition is * automatically handled when calling @FT_New_Face or @FT_Open_Face. * This means that if no font driver is capable of handling the raw * compressed file, the library will try to open a LZW stream from it * and re-open the face with it. * * This function may return `FT_Err_Unimplemented_Feature' if your build * of FreeType was not compiled with LZW support. */ FT_EXPORT( FT_Error ) FT_Stream_OpenLZW( FT_Stream stream, FT_Stream source ); /* */ FT_END_HEADER #endif /* FTLZW_H_ */ /* END */ freetype2/freetype/ftsnames.h 0000644 00000036562 15146341150 0012301 0 ustar 00 /***************************************************************************/ /* */ /* ftsnames.h */ /* */ /* Simple interface to access SFNT `name' tables (which are used */ /* to hold font names, copyright info, notices, etc.) (specification). */ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTSNAMES_H_ #define FTSNAMES_H_ #include <ft2build.h> #include FT_FREETYPE_H #include FT_PARAMETER_TAGS_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* sfnt_names */ /* */ /* <Title> */ /* SFNT Names */ /* */ /* <Abstract> */ /* Access the names embedded in TrueType and OpenType files. */ /* */ /* <Description> */ /* The TrueType and OpenType specifications allow the inclusion of */ /* a special names table (`name') in font files. This table contains */ /* textual (and internationalized) information regarding the font, */ /* like family name, copyright, version, etc. */ /* */ /* The definitions below are used to access them if available. */ /* */ /* Note that this has nothing to do with glyph names! */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Struct> */ /* FT_SfntName */ /* */ /* <Description> */ /* A structure used to model an SFNT `name' table entry. */ /* */ /* <Fields> */ /* platform_id :: The platform ID for `string'. */ /* See @TT_PLATFORM_XXX for possible values. */ /* */ /* encoding_id :: The encoding ID for `string'. */ /* See @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, */ /* @TT_ISO_ID_XXX, @TT_MS_ID_XXX, and @TT_ADOBE_ID_XXX */ /* for possible values. */ /* */ /* language_id :: The language ID for `string'. */ /* See @TT_MAC_LANGID_XXX and @TT_MS_LANGID_XXX for */ /* possible values. */ /* */ /* Registered OpenType values for `language_id' are */ /* always smaller than 0x8000; values equal or larger */ /* than 0x8000 usually indicate a language tag string */ /* (introduced in OpenType version 1.6). Use function */ /* @FT_Get_Sfnt_LangTag with `language_id' as its */ /* argument to retrieve the associated language tag. */ /* */ /* name_id :: An identifier for `string'. */ /* See @TT_NAME_ID_XXX for possible values. */ /* */ /* string :: The `name' string. Note that its format differs */ /* depending on the (platform,encoding) pair, being */ /* either a string of bytes (without a terminating */ /* NULL byte) or containing UTF-16BE entities. */ /* */ /* string_len :: The length of `string' in bytes. */ /* */ /* <Note> */ /* Please refer to the TrueType or OpenType specification for more */ /* details. */ /* */ typedef struct FT_SfntName_ { FT_UShort platform_id; FT_UShort encoding_id; FT_UShort language_id; FT_UShort name_id; FT_Byte* string; /* this string is *not* null-terminated! */ FT_UInt string_len; /* in bytes */ } FT_SfntName; /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Sfnt_Name_Count */ /* */ /* <Description> */ /* Retrieve the number of name strings in the SFNT `name' table. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* <Return> */ /* The number of strings in the `name' table. */ /* */ FT_EXPORT( FT_UInt ) FT_Get_Sfnt_Name_Count( FT_Face face ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Sfnt_Name */ /* */ /* <Description> */ /* Retrieve a string of the SFNT `name' table for a given index. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* idx :: The index of the `name' string. */ /* */ /* <Output> */ /* aname :: The indexed @FT_SfntName structure. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The `string' array returned in the `aname' structure is not */ /* null-terminated. Note that you don't have to deallocate `string' */ /* by yourself; FreeType takes care of it if you call @FT_Done_Face. */ /* */ /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ /* `name' table entries, then do a loop until you get the right */ /* platform, encoding, and name ID. */ /* */ /* `name' table format~1 entries can use language tags also, see */ /* @FT_Get_Sfnt_LangTag. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Sfnt_Name( FT_Face face, FT_UInt idx, FT_SfntName *aname ); /*************************************************************************/ /* */ /* <Struct> */ /* FT_SfntLangTag */ /* */ /* <Description> */ /* A structure to model a language tag entry from an SFNT `name' */ /* table. */ /* */ /* <Fields> */ /* string :: The language tag string, encoded in UTF-16BE */ /* (without trailing NULL bytes). */ /* */ /* string_len :: The length of `string' in *bytes*. */ /* */ /* <Note> */ /* Please refer to the TrueType or OpenType specification for more */ /* details. */ /* */ /* <Since> */ /* 2.8 */ /* */ typedef struct FT_SfntLangTag_ { FT_Byte* string; /* this string is *not* null-terminated! */ FT_UInt string_len; /* in bytes */ } FT_SfntLangTag; /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Sfnt_LangTag */ /* */ /* <Description> */ /* Retrieve the language tag associated with a language ID of an SFNT */ /* `name' table entry. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* langID :: The language ID, as returned by @FT_Get_Sfnt_Name. */ /* This is always a value larger than 0x8000. */ /* */ /* <Output> */ /* alangTag :: The language tag associated with the `name' table */ /* entry's language ID. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The `string' array returned in the `alangTag' structure is not */ /* null-terminated. Note that you don't have to deallocate `string' */ /* by yourself; FreeType takes care of it if you call @FT_Done_Face. */ /* */ /* Only `name' table format~1 supports language tags. For format~0 */ /* tables, this function always returns FT_Err_Invalid_Table. For */ /* invalid format~1 language ID values, FT_Err_Invalid_Argument is */ /* returned. */ /* */ /* <Since> */ /* 2.8 */ /* */ FT_EXPORT( FT_Error ) FT_Get_Sfnt_LangTag( FT_Face face, FT_UInt langID, FT_SfntLangTag *alangTag ); /* */ FT_END_HEADER #endif /* FTSNAMES_H_ */ /* END */ freetype2/freetype/ftmodapi.h 0000644 00000112171 15146341150 0012253 0 ustar 00 /***************************************************************************/ /* */ /* ftmodapi.h */ /* */ /* FreeType modules public interface (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTMODAPI_H_ #define FTMODAPI_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* module_management */ /* */ /* <Title> */ /* Module Management */ /* */ /* <Abstract> */ /* How to add, upgrade, remove, and control modules from FreeType. */ /* */ /* <Description> */ /* The definitions below are used to manage modules within FreeType. */ /* Modules can be added, upgraded, and removed at runtime. */ /* Additionally, some module properties can be controlled also. */ /* */ /* Here is a list of possible values of the `module_name' field in */ /* the @FT_Module_Class structure. */ /* */ /* { */ /* autofitter */ /* bdf */ /* cff */ /* gxvalid */ /* otvalid */ /* pcf */ /* pfr */ /* psaux */ /* pshinter */ /* psnames */ /* raster1 */ /* sfnt */ /* smooth, smooth-lcd, smooth-lcdv */ /* truetype */ /* type1 */ /* type42 */ /* t1cid */ /* winfonts */ /* } */ /* */ /* Note that the FreeType Cache sub-system is not a FreeType module. */ /* */ /* <Order> */ /* FT_Module */ /* FT_Module_Constructor */ /* FT_Module_Destructor */ /* FT_Module_Requester */ /* FT_Module_Class */ /* */ /* FT_Add_Module */ /* FT_Get_Module */ /* FT_Remove_Module */ /* FT_Add_Default_Modules */ /* */ /* FT_Property_Set */ /* FT_Property_Get */ /* FT_Set_Default_Properties */ /* */ /* FT_New_Library */ /* FT_Done_Library */ /* FT_Reference_Library */ /* */ /* FT_Renderer */ /* FT_Renderer_Class */ /* */ /* FT_Get_Renderer */ /* FT_Set_Renderer */ /* */ /* FT_Set_Debug_Hook */ /* */ /*************************************************************************/ /* module bit flags */ #define FT_MODULE_FONT_DRIVER 1 /* this module is a font driver */ #define FT_MODULE_RENDERER 2 /* this module is a renderer */ #define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ #define FT_MODULE_STYLER 8 /* this module is a styler */ #define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ /* scalable fonts */ #define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ /* support vector outlines */ #define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ /* own hinter */ #define FT_MODULE_DRIVER_HINTS_LIGHTLY 0x800 /* the driver's hinter */ /* produces LIGHT hints */ /* deprecated values */ #define ft_module_font_driver FT_MODULE_FONT_DRIVER #define ft_module_renderer FT_MODULE_RENDERER #define ft_module_hinter FT_MODULE_HINTER #define ft_module_styler FT_MODULE_STYLER #define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE #define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES #define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER #define ft_module_driver_hints_lightly FT_MODULE_DRIVER_HINTS_LIGHTLY typedef FT_Pointer FT_Module_Interface; /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Module_Constructor */ /* */ /* <Description> */ /* A function used to initialize (not create) a new module object. */ /* */ /* <Input> */ /* module :: The module to initialize. */ /* */ typedef FT_Error (*FT_Module_Constructor)( FT_Module module ); /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Module_Destructor */ /* */ /* <Description> */ /* A function used to finalize (not destroy) a given module object. */ /* */ /* <Input> */ /* module :: The module to finalize. */ /* */ typedef void (*FT_Module_Destructor)( FT_Module module ); /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Module_Requester */ /* */ /* <Description> */ /* A function used to query a given module for a specific interface. */ /* */ /* <Input> */ /* module :: The module to be searched. */ /* */ /* name :: The name of the interface in the module. */ /* */ typedef FT_Module_Interface (*FT_Module_Requester)( FT_Module module, const char* name ); /*************************************************************************/ /* */ /* <Struct> */ /* FT_Module_Class */ /* */ /* <Description> */ /* The module class descriptor. */ /* */ /* <Fields> */ /* module_flags :: Bit flags describing the module. */ /* */ /* module_size :: The size of one module object/instance in */ /* bytes. */ /* */ /* module_name :: The name of the module. */ /* */ /* module_version :: The version, as a 16.16 fixed number */ /* (major.minor). */ /* */ /* module_requires :: The version of FreeType this module requires, */ /* as a 16.16 fixed number (major.minor). Starts */ /* at version 2.0, i.e., 0x20000. */ /* */ /* module_init :: The initializing function. */ /* */ /* module_done :: The finalizing function. */ /* */ /* get_interface :: The interface requesting function. */ /* */ typedef struct FT_Module_Class_ { FT_ULong module_flags; FT_Long module_size; const FT_String* module_name; FT_Fixed module_version; FT_Fixed module_requires; const void* module_interface; FT_Module_Constructor module_init; FT_Module_Destructor module_done; FT_Module_Requester get_interface; } FT_Module_Class; /*************************************************************************/ /* */ /* <Function> */ /* FT_Add_Module */ /* */ /* <Description> */ /* Add a new module to a given library instance. */ /* */ /* <InOut> */ /* library :: A handle to the library object. */ /* */ /* <Input> */ /* clazz :: A pointer to class descriptor for the module. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* An error will be returned if a module already exists by that name, */ /* or if the module requires a version of FreeType that is too great. */ /* */ FT_EXPORT( FT_Error ) FT_Add_Module( FT_Library library, const FT_Module_Class* clazz ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Module */ /* */ /* <Description> */ /* Find a module by its name. */ /* */ /* <Input> */ /* library :: A handle to the library object. */ /* */ /* module_name :: The module's name (as an ASCII string). */ /* */ /* <Return> */ /* A module handle. 0~if none was found. */ /* */ /* <Note> */ /* FreeType's internal modules aren't documented very well, and you */ /* should look up the source code for details. */ /* */ FT_EXPORT( FT_Module ) FT_Get_Module( FT_Library library, const char* module_name ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Remove_Module */ /* */ /* <Description> */ /* Remove a given module from a library instance. */ /* */ /* <InOut> */ /* library :: A handle to a library object. */ /* */ /* <Input> */ /* module :: A handle to a module object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The module object is destroyed by the function in case of success. */ /* */ FT_EXPORT( FT_Error ) FT_Remove_Module( FT_Library library, FT_Module module ); /********************************************************************** * * @function: * FT_Property_Set * * @description: * Set a property for a given module. * * @input: * library :: * A handle to the library the module is part of. * * module_name :: * The module name. * * property_name :: * The property name. Properties are described in section * @properties. * * Note that only a few modules have properties. * * value :: * A generic pointer to a variable or structure that gives the new * value of the property. The exact definition of `value' is * dependent on the property; see section @properties. * * @return: * FreeType error code. 0~means success. * * @note: * If `module_name' isn't a valid module name, or `property_name' * doesn't specify a valid property, or if `value' doesn't represent a * valid value for the given property, an error is returned. * * The following example sets property `bar' (a simple integer) in * module `foo' to value~1. * * { * FT_UInt bar; * * * bar = 1; * FT_Property_Set( library, "foo", "bar", &bar ); * } * * Note that the FreeType Cache sub-system doesn't recognize module * property changes. To avoid glyph lookup confusion within the cache * you should call @FTC_Manager_Reset to completely flush the cache if * a module property gets changed after @FTC_Manager_New has been * called. * * It is not possible to set properties of the FreeType Cache * sub-system itself with FT_Property_Set; use @FTC_Property_Set * instead. * * @since: * 2.4.11 * */ FT_EXPORT( FT_Error ) FT_Property_Set( FT_Library library, const FT_String* module_name, const FT_String* property_name, const void* value ); /********************************************************************** * * @function: * FT_Property_Get * * @description: * Get a module's property value. * * @input: * library :: * A handle to the library the module is part of. * * module_name :: * The module name. * * property_name :: * The property name. Properties are described in section * @properties. * * @inout: * value :: * A generic pointer to a variable or structure that gives the * value of the property. The exact definition of `value' is * dependent on the property; see section @properties. * * @return: * FreeType error code. 0~means success. * * @note: * If `module_name' isn't a valid module name, or `property_name' * doesn't specify a valid property, or if `value' doesn't represent a * valid value for the given property, an error is returned. * * The following example gets property `baz' (a range) in module `foo'. * * { * typedef range_ * { * FT_Int32 min; * FT_Int32 max; * * } range; * * range baz; * * * FT_Property_Get( library, "foo", "baz", &baz ); * } * * It is not possible to retrieve properties of the FreeType Cache * sub-system with FT_Property_Get; use @FTC_Property_Get instead. * * @since: * 2.4.11 * */ FT_EXPORT( FT_Error ) FT_Property_Get( FT_Library library, const FT_String* module_name, const FT_String* property_name, void* value ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Default_Properties */ /* */ /* <Description> */ /* If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is */ /* set, this function reads the `FREETYPE_PROPERTIES' environment */ /* variable to control driver properties. See section @properties */ /* for more. */ /* */ /* If the compilation option is not set, this function does nothing. */ /* */ /* `FREETYPE_PROPERTIES' has the following syntax form (broken here */ /* into multiple lines for better readability). */ /* */ /* { */ /* <optional whitespace> */ /* <module-name1> ':' */ /* <property-name1> '=' <property-value1> */ /* <whitespace> */ /* <module-name2> ':' */ /* <property-name2> '=' <property-value2> */ /* ... */ /* } */ /* */ /* Example: */ /* */ /* { */ /* FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ */ /* cff:no-stem-darkening=1 \ */ /* autofitter:warping=1 */ /* } */ /* */ /* <InOut> */ /* library :: A handle to a new library object. */ /* */ /* <Since> */ /* 2.8 */ /* */ FT_EXPORT( void ) FT_Set_Default_Properties( FT_Library library ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Reference_Library */ /* */ /* <Description> */ /* A counter gets initialized to~1 at the time an @FT_Library */ /* structure is created. This function increments the counter. */ /* @FT_Done_Library then only destroys a library if the counter is~1, */ /* otherwise it simply decrements the counter. */ /* */ /* This function helps in managing life-cycles of structures that */ /* reference @FT_Library objects. */ /* */ /* <Input> */ /* library :: A handle to a target library object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Since> */ /* 2.4.2 */ /* */ FT_EXPORT( FT_Error ) FT_Reference_Library( FT_Library library ); /*************************************************************************/ /* */ /* <Function> */ /* FT_New_Library */ /* */ /* <Description> */ /* This function is used to create a new FreeType library instance */ /* from a given memory object. It is thus possible to use libraries */ /* with distinct memory allocators within the same program. Note, */ /* however, that the used @FT_Memory structure is expected to remain */ /* valid for the life of the @FT_Library object. */ /* */ /* Normally, you would call this function (followed by a call to */ /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module, */ /* and a call to @FT_Set_Default_Properties) instead of */ /* @FT_Init_FreeType to initialize the FreeType library. */ /* */ /* Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a */ /* library instance. */ /* */ /* <Input> */ /* memory :: A handle to the original memory object. */ /* */ /* <Output> */ /* alibrary :: A pointer to handle of a new library object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* See the discussion of reference counters in the description of */ /* @FT_Reference_Library. */ /* */ FT_EXPORT( FT_Error ) FT_New_Library( FT_Memory memory, FT_Library *alibrary ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Done_Library */ /* */ /* <Description> */ /* Discard a given library object. This closes all drivers and */ /* discards all resource objects. */ /* */ /* <Input> */ /* library :: A handle to the target library. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* See the discussion of reference counters in the description of */ /* @FT_Reference_Library. */ /* */ FT_EXPORT( FT_Error ) FT_Done_Library( FT_Library library ); /* */ typedef void (*FT_DebugHook_Func)( void* arg ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Debug_Hook */ /* */ /* <Description> */ /* Set a debug hook function for debugging the interpreter of a font */ /* format. */ /* */ /* <InOut> */ /* library :: A handle to the library object. */ /* */ /* <Input> */ /* hook_index :: The index of the debug hook. You should use the */ /* values defined in `ftobjs.h', e.g., */ /* `FT_DEBUG_HOOK_TRUETYPE'. */ /* */ /* debug_hook :: The function used to debug the interpreter. */ /* */ /* <Note> */ /* Currently, four debug hook slots are available, but only two (for */ /* the TrueType and the Type~1 interpreter) are defined. */ /* */ /* Since the internal headers of FreeType are no longer installed, */ /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ /* This is a bug and will be fixed in a forthcoming release. */ /* */ FT_EXPORT( void ) FT_Set_Debug_Hook( FT_Library library, FT_UInt hook_index, FT_DebugHook_Func debug_hook ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Add_Default_Modules */ /* */ /* <Description> */ /* Add the set of default drivers to a given library object. */ /* This is only useful when you create a library object with */ /* @FT_New_Library (usually to plug a custom memory manager). */ /* */ /* <InOut> */ /* library :: A handle to a new library object. */ /* */ FT_EXPORT( void ) FT_Add_Default_Modules( FT_Library library ); /************************************************************************** * * @section: * truetype_engine * * @title: * The TrueType Engine * * @abstract: * TrueType bytecode support. * * @description: * This section contains a function used to query the level of TrueType * bytecode support compiled in this version of the library. * */ /************************************************************************** * * @enum: * FT_TrueTypeEngineType * * @description: * A list of values describing which kind of TrueType bytecode * engine is implemented in a given FT_Library instance. It is used * by the @FT_Get_TrueType_Engine_Type function. * * @values: * FT_TRUETYPE_ENGINE_TYPE_NONE :: * The library doesn't implement any kind of bytecode interpreter. * * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: * Deprecated and removed. * * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: * The library implements a bytecode interpreter that covers * the full instruction set of the TrueType virtual machine (this * was governed by patents until May 2010, hence the name). * * @since: * 2.2 * */ typedef enum FT_TrueTypeEngineType_ { FT_TRUETYPE_ENGINE_TYPE_NONE = 0, FT_TRUETYPE_ENGINE_TYPE_UNPATENTED, FT_TRUETYPE_ENGINE_TYPE_PATENTED } FT_TrueTypeEngineType; /************************************************************************** * * @func: * FT_Get_TrueType_Engine_Type * * @description: * Return an @FT_TrueTypeEngineType value to indicate which level of * the TrueType virtual machine a given library instance supports. * * @input: * library :: * A library instance. * * @return: * A value indicating which level is supported. * * @since: * 2.2 * */ FT_EXPORT( FT_TrueTypeEngineType ) FT_Get_TrueType_Engine_Type( FT_Library library ); /* */ FT_END_HEADER #endif /* FTMODAPI_H_ */ /* END */ freetype2/freetype/ftbzip2.h 0000644 00000010313 15146341150 0012023 0 ustar 00 /***************************************************************************/ /* */ /* ftbzip2.h */ /* */ /* Bzip2-compressed stream support. */ /* */ /* Copyright 2010-2018 by */ /* Joel Klinghed. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTBZIP2_H_ #define FTBZIP2_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* bzip2 */ /* */ /* <Title> */ /* BZIP2 Streams */ /* */ /* <Abstract> */ /* Using bzip2-compressed font files. */ /* */ /* <Description> */ /* This section contains the declaration of Bzip2-specific functions. */ /* */ /*************************************************************************/ /************************************************************************ * * @function: * FT_Stream_OpenBzip2 * * @description: * Open a new stream to parse bzip2-compressed font files. This is * mainly used to support the compressed `*.pcf.bz2' fonts that come * with XFree86. * * @input: * stream :: * The target embedding stream. * * source :: * The source stream. * * @return: * FreeType error code. 0~means success. * * @note: * The source stream must be opened _before_ calling this function. * * Calling the internal function `FT_Stream_Close' on the new stream will * *not* call `FT_Stream_Close' on the source stream. None of the stream * objects will be released to the heap. * * The stream implementation is very basic and resets the decompression * process each time seeking backwards is needed within the stream. * * In certain builds of the library, bzip2 compression recognition is * automatically handled when calling @FT_New_Face or @FT_Open_Face. * This means that if no font driver is capable of handling the raw * compressed file, the library will try to open a bzip2 compressed stream * from it and re-open the face with it. * * This function may return `FT_Err_Unimplemented_Feature' if your build * of FreeType was not compiled with bzip2 support. */ FT_EXPORT( FT_Error ) FT_Stream_OpenBzip2( FT_Stream stream, FT_Stream source ); /* */ FT_END_HEADER #endif /* FTBZIP2_H_ */ /* END */ freetype2/freetype/ftincrem.h 0000644 00000025460 15146341150 0012263 0 ustar 00 /***************************************************************************/ /* */ /* ftincrem.h */ /* */ /* FreeType incremental loading (specification). */ /* */ /* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTINCREM_H_ #define FTINCREM_H_ #include <ft2build.h> #include FT_FREETYPE_H #include FT_PARAMETER_TAGS_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************** * * @section: * incremental * * @title: * Incremental Loading * * @abstract: * Custom Glyph Loading. * * @description: * This section contains various functions used to perform so-called * `incremental' glyph loading. This is a mode where all glyphs loaded * from a given @FT_Face are provided by the client application. * * Apart from that, all other tables are loaded normally from the font * file. This mode is useful when FreeType is used within another * engine, e.g., a PostScript Imaging Processor. * * To enable this mode, you must use @FT_Open_Face, passing an * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an * @FT_Incremental_Interface value. See the comments for * @FT_Incremental_InterfaceRec for an example. * */ /*************************************************************************** * * @type: * FT_Incremental * * @description: * An opaque type describing a user-provided object used to implement * `incremental' glyph loading within FreeType. This is used to support * embedded fonts in certain environments (e.g., PostScript interpreters), * where the glyph data isn't in the font file, or must be overridden by * different values. * * @note: * It is up to client applications to create and implement @FT_Incremental * objects, as long as they provide implementations for the methods * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc * and @FT_Incremental_GetGlyphMetricsFunc. * * See the description of @FT_Incremental_InterfaceRec to understand how * to use incremental objects with FreeType. * */ typedef struct FT_IncrementalRec_* FT_Incremental; /*************************************************************************** * * @struct: * FT_Incremental_MetricsRec * * @description: * A small structure used to contain the basic glyph metrics returned * by the @FT_Incremental_GetGlyphMetricsFunc method. * * @fields: * bearing_x :: * Left bearing, in font units. * * bearing_y :: * Top bearing, in font units. * * advance :: * Horizontal component of glyph advance, in font units. * * advance_v :: * Vertical component of glyph advance, in font units. * * @note: * These correspond to horizontal or vertical metrics depending on the * value of the `vertical' argument to the function * @FT_Incremental_GetGlyphMetricsFunc. * */ typedef struct FT_Incremental_MetricsRec_ { FT_Long bearing_x; FT_Long bearing_y; FT_Long advance; FT_Long advance_v; /* since 2.3.12 */ } FT_Incremental_MetricsRec; /*************************************************************************** * * @struct: * FT_Incremental_Metrics * * @description: * A handle to an @FT_Incremental_MetricsRec structure. * */ typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics; /*************************************************************************** * * @type: * FT_Incremental_GetGlyphDataFunc * * @description: * A function called by FreeType to access a given glyph's data bytes * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is * enabled. * * Note that the format of the glyph's data bytes depends on the font * file format. For TrueType, it must correspond to the raw bytes within * the `glyf' table. For PostScript formats, it must correspond to the * *unencrypted* charstring bytes, without any `lenIV' header. It is * undefined for any other format. * * @input: * incremental :: * Handle to an opaque @FT_Incremental handle provided by the client * application. * * glyph_index :: * Index of relevant glyph. * * @output: * adata :: * A structure describing the returned glyph data bytes (which will be * accessed as a read-only byte block). * * @return: * FreeType error code. 0~means success. * * @note: * If this function returns successfully the method * @FT_Incremental_FreeGlyphDataFunc will be called later to release * the data bytes. * * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for * compound glyphs. * */ typedef FT_Error (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, FT_UInt glyph_index, FT_Data* adata ); /*************************************************************************** * * @type: * FT_Incremental_FreeGlyphDataFunc * * @description: * A function used to release the glyph data bytes returned by a * successful call to @FT_Incremental_GetGlyphDataFunc. * * @input: * incremental :: * A handle to an opaque @FT_Incremental handle provided by the client * application. * * data :: * A structure describing the glyph data bytes (which will be accessed * as a read-only byte block). * */ typedef void (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, FT_Data* data ); /*************************************************************************** * * @type: * FT_Incremental_GetGlyphMetricsFunc * * @description: * A function used to retrieve the basic metrics of a given glyph index * before accessing its data. This is necessary because, in certain * formats like TrueType, the metrics are stored in a different place from * the glyph images proper. * * @input: * incremental :: * A handle to an opaque @FT_Incremental handle provided by the client * application. * * glyph_index :: * Index of relevant glyph. * * vertical :: * If true, return vertical metrics. * * ametrics :: * This parameter is used for both input and output. * The original glyph metrics, if any, in font units. If metrics are * not available all the values must be set to zero. * * @output: * ametrics :: * The replacement glyph metrics in font units. * */ typedef FT_Error (*FT_Incremental_GetGlyphMetricsFunc) ( FT_Incremental incremental, FT_UInt glyph_index, FT_Bool vertical, FT_Incremental_MetricsRec *ametrics ); /************************************************************************** * * @struct: * FT_Incremental_FuncsRec * * @description: * A table of functions for accessing fonts that load data * incrementally. Used in @FT_Incremental_InterfaceRec. * * @fields: * get_glyph_data :: * The function to get glyph data. Must not be null. * * free_glyph_data :: * The function to release glyph data. Must not be null. * * get_glyph_metrics :: * The function to get glyph metrics. May be null if the font does * not provide overriding glyph metrics. * */ typedef struct FT_Incremental_FuncsRec_ { FT_Incremental_GetGlyphDataFunc get_glyph_data; FT_Incremental_FreeGlyphDataFunc free_glyph_data; FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics; } FT_Incremental_FuncsRec; /*************************************************************************** * * @struct: * FT_Incremental_InterfaceRec * * @description: * A structure to be used with @FT_Open_Face to indicate that the user * wants to support incremental glyph loading. You should use it with * @FT_PARAM_TAG_INCREMENTAL as in the following example: * * { * FT_Incremental_InterfaceRec inc_int; * FT_Parameter parameter; * FT_Open_Args open_args; * * * // set up incremental descriptor * inc_int.funcs = my_funcs; * inc_int.object = my_object; * * // set up optional parameter * parameter.tag = FT_PARAM_TAG_INCREMENTAL; * parameter.data = &inc_int; * * // set up FT_Open_Args structure * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; * open_args.pathname = my_font_pathname; * open_args.num_params = 1; * open_args.params = ¶meter; // we use one optional argument * * // open the font * error = FT_Open_Face( library, &open_args, index, &face ); * ... * } * */ typedef struct FT_Incremental_InterfaceRec_ { const FT_Incremental_FuncsRec* funcs; FT_Incremental object; } FT_Incremental_InterfaceRec; /*************************************************************************** * * @type: * FT_Incremental_Interface * * @description: * A pointer to an @FT_Incremental_InterfaceRec structure. * */ typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface; /* */ FT_END_HEADER #endif /* FTINCREM_H_ */ /* END */ freetype2/freetype/fterrors.h 0000644 00000026151 15146341150 0012320 0 ustar 00 /***************************************************************************/ /* */ /* fterrors.h */ /* */ /* FreeType error code handling (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* <Section> */ /* error_enumerations */ /* */ /* <Title> */ /* Error Enumerations */ /* */ /* <Abstract> */ /* How to handle errors and error strings. */ /* */ /* <Description> */ /* The header file `fterrors.h' (which is automatically included by */ /* `freetype.h' defines the handling of FreeType's enumeration */ /* constants. It can also be used to generate error message strings */ /* with a small macro trick explained below. */ /* */ /* *Error* *Formats* */ /* */ /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ /* defined in `ftoption.h' in order to make the higher byte indicate */ /* the module where the error has happened (this is not compatible */ /* with standard builds of FreeType~2, however). See the file */ /* `ftmoderr.h' for more details. */ /* */ /* *Error* *Message* *Strings* */ /* */ /* Error definitions are set up with special macros that allow client */ /* applications to build a table of error message strings. The */ /* strings are not included in a normal build of FreeType~2 to save */ /* space (most client applications do not use them). */ /* */ /* To do so, you have to define the following macros before including */ /* this file. */ /* */ /* { */ /* FT_ERROR_START_LIST */ /* } */ /* */ /* This macro is called before anything else to define the start of */ /* the error list. It is followed by several FT_ERROR_DEF calls. */ /* */ /* { */ /* FT_ERROR_DEF( e, v, s ) */ /* } */ /* */ /* This macro is called to define one single error. `e' is the error */ /* code identifier (e.g., `Invalid_Argument'), `v' is the error's */ /* numerical value, and `s' is the corresponding error string. */ /* */ /* { */ /* FT_ERROR_END_LIST */ /* } */ /* */ /* This macro ends the list. */ /* */ /* Additionally, you have to undefine `FTERRORS_H_' before #including */ /* this file. */ /* */ /* Here is a simple example. */ /* */ /* { */ /* #undef FTERRORS_H_ */ /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ /* #define FT_ERROR_START_LIST { */ /* #define FT_ERROR_END_LIST { 0, NULL } }; */ /* */ /* const struct */ /* { */ /* int err_code; */ /* const char* err_msg; */ /* } ft_errors[] = */ /* */ /* #include FT_ERRORS_H */ /* } */ /* */ /* Note that `FT_Err_Ok' is _not_ defined with `FT_ERRORDEF' but with */ /* `FT_NOERRORDEF'; it is always zero. */ /* */ /*************************************************************************/ /* */ /* In previous FreeType versions we used `__FTERRORS_H__'. However, */ /* using two successive underscores in a non-system symbol name */ /* violates the C (and C++) standard, so it was changed to the */ /* current form. In spite of this, we have to make */ /* */ /* #undefine __FTERRORS_H__ */ /* */ /* work for backward compatibility. */ /* */ #if !( defined( FTERRORS_H_ ) && defined ( __FTERRORS_H__ ) ) #define FTERRORS_H_ #define __FTERRORS_H__ /* include module base error codes */ #include FT_MODULE_ERRORS_H /*******************************************************************/ /*******************************************************************/ /***** *****/ /***** SETUP MACROS *****/ /***** *****/ /*******************************************************************/ /*******************************************************************/ #undef FT_NEED_EXTERN_C /* FT_ERR_PREFIX is used as a prefix for error identifiers. */ /* By default, we use `FT_Err_'. */ /* */ #ifndef FT_ERR_PREFIX #define FT_ERR_PREFIX FT_Err_ #endif /* FT_ERR_BASE is used as the base for module-specific errors. */ /* */ #ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS #ifndef FT_ERR_BASE #define FT_ERR_BASE FT_Mod_Err_Base #endif #else #undef FT_ERR_BASE #define FT_ERR_BASE 0 #endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */ /* If FT_ERRORDEF is not defined, we need to define a simple */ /* enumeration type. */ /* */ #ifndef FT_ERRORDEF #define FT_ERRORDEF( e, v, s ) e = v, #define FT_ERROR_START_LIST enum { #define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) }; #ifdef __cplusplus #define FT_NEED_EXTERN_C extern "C" { #endif #endif /* !FT_ERRORDEF */ /* this macro is used to define an error */ #define FT_ERRORDEF_( e, v, s ) \ FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) /* this is only used for <module>_Err_Ok, which must be 0! */ #define FT_NOERRORDEF_( e, v, s ) \ FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) #ifdef FT_ERROR_START_LIST FT_ERROR_START_LIST #endif /* now include the error codes */ #include FT_ERROR_DEFINITIONS_H #ifdef FT_ERROR_END_LIST FT_ERROR_END_LIST #endif /*******************************************************************/ /*******************************************************************/ /***** *****/ /***** SIMPLE CLEANUP *****/ /***** *****/ /*******************************************************************/ /*******************************************************************/ #ifdef FT_NEED_EXTERN_C } #endif #undef FT_ERROR_START_LIST #undef FT_ERROR_END_LIST #undef FT_ERRORDEF #undef FT_ERRORDEF_ #undef FT_NOERRORDEF_ #undef FT_NEED_EXTERN_C #undef FT_ERR_BASE /* FT_ERR_PREFIX is needed internally */ #ifndef FT2_BUILD_LIBRARY #undef FT_ERR_PREFIX #endif #endif /* !(FTERRORS_H_ && __FTERRORS_H__) */ /* END */ freetype2/freetype/freetype.h 0000644 00001076164 15146341150 0012307 0 ustar 00 /***************************************************************************/ /* */ /* freetype.h */ /* */ /* FreeType high-level API and common types (specification only). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FREETYPE_H_ #define FREETYPE_H_ #ifndef FT_FREETYPE_H #error "`ft2build.h' hasn't been included yet!" #error "Please always use macros to include FreeType header files." #error "Example:" #error " #include <ft2build.h>" #error " #include FT_FREETYPE_H" #endif #include <ft2build.h> #include FT_CONFIG_CONFIG_H #include FT_TYPES_H #include FT_ERRORS_H FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* header_inclusion */ /* */ /* <Title> */ /* FreeType's header inclusion scheme */ /* */ /* <Abstract> */ /* How client applications should include FreeType header files. */ /* */ /* <Description> */ /* To be as flexible as possible (and for historical reasons), */ /* FreeType uses a very special inclusion scheme to load header */ /* files, for example */ /* */ /* { */ /* #include <ft2build.h> */ /* */ /* #include FT_FREETYPE_H */ /* #include FT_OUTLINE_H */ /* } */ /* */ /* A compiler and its preprocessor only needs an include path to find */ /* the file `ft2build.h'; the exact locations and names of the other */ /* FreeType header files are hidden by preprocessor macro names, */ /* loaded by `ft2build.h'. The API documentation always gives the */ /* header macro name needed for a particular function. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Section> */ /* user_allocation */ /* */ /* <Title> */ /* User allocation */ /* */ /* <Abstract> */ /* How client applications should allocate FreeType data structures. */ /* */ /* <Description> */ /* FreeType assumes that structures allocated by the user and passed */ /* as arguments are zeroed out except for the actual data. In other */ /* words, it is recommended to use `calloc' (or variants of it) */ /* instead of `malloc' for allocation. */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* B A S I C T Y P E S */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* <Section> */ /* base_interface */ /* */ /* <Title> */ /* Base Interface */ /* */ /* <Abstract> */ /* The FreeType~2 base font interface. */ /* */ /* <Description> */ /* This section describes the most important public high-level API */ /* functions of FreeType~2. */ /* */ /* <Order> */ /* FT_Library */ /* FT_Face */ /* FT_Size */ /* FT_GlyphSlot */ /* FT_CharMap */ /* FT_Encoding */ /* FT_ENC_TAG */ /* */ /* FT_FaceRec */ /* */ /* FT_FACE_FLAG_SCALABLE */ /* FT_FACE_FLAG_FIXED_SIZES */ /* FT_FACE_FLAG_FIXED_WIDTH */ /* FT_FACE_FLAG_HORIZONTAL */ /* FT_FACE_FLAG_VERTICAL */ /* FT_FACE_FLAG_COLOR */ /* FT_FACE_FLAG_SFNT */ /* FT_FACE_FLAG_CID_KEYED */ /* FT_FACE_FLAG_TRICKY */ /* FT_FACE_FLAG_KERNING */ /* FT_FACE_FLAG_MULTIPLE_MASTERS */ /* FT_FACE_FLAG_VARIATION */ /* FT_FACE_FLAG_GLYPH_NAMES */ /* FT_FACE_FLAG_EXTERNAL_STREAM */ /* FT_FACE_FLAG_HINTER */ /* */ /* FT_HAS_HORIZONTAL */ /* FT_HAS_VERTICAL */ /* FT_HAS_KERNING */ /* FT_HAS_FIXED_SIZES */ /* FT_HAS_GLYPH_NAMES */ /* FT_HAS_COLOR */ /* FT_HAS_MULTIPLE_MASTERS */ /* */ /* FT_IS_SFNT */ /* FT_IS_SCALABLE */ /* FT_IS_FIXED_WIDTH */ /* FT_IS_CID_KEYED */ /* FT_IS_TRICKY */ /* FT_IS_NAMED_INSTANCE */ /* FT_IS_VARIATION */ /* */ /* FT_STYLE_FLAG_BOLD */ /* FT_STYLE_FLAG_ITALIC */ /* */ /* FT_SizeRec */ /* FT_Size_Metrics */ /* */ /* FT_GlyphSlotRec */ /* FT_Glyph_Metrics */ /* FT_SubGlyph */ /* */ /* FT_Bitmap_Size */ /* */ /* FT_Init_FreeType */ /* FT_Done_FreeType */ /* */ /* FT_New_Face */ /* FT_Done_Face */ /* FT_Reference_Face */ /* FT_New_Memory_Face */ /* FT_Face_Properties */ /* FT_Open_Face */ /* FT_Open_Args */ /* FT_Parameter */ /* FT_Attach_File */ /* FT_Attach_Stream */ /* */ /* FT_Set_Char_Size */ /* FT_Set_Pixel_Sizes */ /* FT_Request_Size */ /* FT_Select_Size */ /* FT_Size_Request_Type */ /* FT_Size_RequestRec */ /* FT_Size_Request */ /* FT_Set_Transform */ /* FT_Load_Glyph */ /* FT_Get_Char_Index */ /* FT_Get_First_Char */ /* FT_Get_Next_Char */ /* FT_Get_Name_Index */ /* FT_Load_Char */ /* */ /* FT_OPEN_MEMORY */ /* FT_OPEN_STREAM */ /* FT_OPEN_PATHNAME */ /* FT_OPEN_DRIVER */ /* FT_OPEN_PARAMS */ /* */ /* FT_LOAD_DEFAULT */ /* FT_LOAD_RENDER */ /* FT_LOAD_MONOCHROME */ /* FT_LOAD_LINEAR_DESIGN */ /* FT_LOAD_NO_SCALE */ /* FT_LOAD_NO_HINTING */ /* FT_LOAD_NO_BITMAP */ /* FT_LOAD_NO_AUTOHINT */ /* FT_LOAD_COLOR */ /* */ /* FT_LOAD_VERTICAL_LAYOUT */ /* FT_LOAD_IGNORE_TRANSFORM */ /* FT_LOAD_FORCE_AUTOHINT */ /* FT_LOAD_NO_RECURSE */ /* FT_LOAD_PEDANTIC */ /* */ /* FT_LOAD_TARGET_NORMAL */ /* FT_LOAD_TARGET_LIGHT */ /* FT_LOAD_TARGET_MONO */ /* FT_LOAD_TARGET_LCD */ /* FT_LOAD_TARGET_LCD_V */ /* */ /* FT_LOAD_TARGET_MODE */ /* */ /* FT_Render_Glyph */ /* FT_Render_Mode */ /* FT_Get_Kerning */ /* FT_Kerning_Mode */ /* FT_Get_Track_Kerning */ /* FT_Get_Glyph_Name */ /* FT_Get_Postscript_Name */ /* */ /* FT_CharMapRec */ /* FT_Select_Charmap */ /* FT_Set_Charmap */ /* FT_Get_Charmap_Index */ /* */ /* FT_Get_FSType_Flags */ /* FT_Get_SubGlyph_Info */ /* */ /* FT_Face_Internal */ /* FT_Size_Internal */ /* FT_Slot_Internal */ /* */ /* FT_FACE_FLAG_XXX */ /* FT_STYLE_FLAG_XXX */ /* FT_OPEN_XXX */ /* FT_LOAD_XXX */ /* FT_LOAD_TARGET_XXX */ /* FT_SUBGLYPH_FLAG_XXX */ /* FT_FSTYPE_XXX */ /* */ /* FT_HAS_FAST_GLYPHS */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Struct> */ /* FT_Glyph_Metrics */ /* */ /* <Description> */ /* A structure to model the metrics of a single glyph. The values */ /* are expressed in 26.6 fractional pixel format; if the flag */ /* @FT_LOAD_NO_SCALE has been used while loading the glyph, values */ /* are expressed in font units instead. */ /* */ /* <Fields> */ /* width :: */ /* The glyph's width. */ /* */ /* height :: */ /* The glyph's height. */ /* */ /* horiBearingX :: */ /* Left side bearing for horizontal layout. */ /* */ /* horiBearingY :: */ /* Top side bearing for horizontal layout. */ /* */ /* horiAdvance :: */ /* Advance width for horizontal layout. */ /* */ /* vertBearingX :: */ /* Left side bearing for vertical layout. */ /* */ /* vertBearingY :: */ /* Top side bearing for vertical layout. Larger positive values */ /* mean further below the vertical glyph origin. */ /* */ /* vertAdvance :: */ /* Advance height for vertical layout. Positive values mean the */ /* glyph has a positive advance downward. */ /* */ /* <Note> */ /* If not disabled with @FT_LOAD_NO_HINTING, the values represent */ /* dimensions of the hinted glyph (in case hinting is applicable). */ /* */ /* Stroking a glyph with an outside border does not increase */ /* `horiAdvance' or `vertAdvance'; you have to manually adjust these */ /* values to account for the added width and height. */ /* */ /* FreeType doesn't use the `VORG' table data for CFF fonts because */ /* it doesn't have an interface to quickly retrieve the glyph height. */ /* The y~coordinate of the vertical origin can be simply computed as */ /* `vertBearingY + height' after loading a glyph. */ /* */ typedef struct FT_Glyph_Metrics_ { FT_Pos width; FT_Pos height; FT_Pos horiBearingX; FT_Pos horiBearingY; FT_Pos horiAdvance; FT_Pos vertBearingX; FT_Pos vertBearingY; FT_Pos vertAdvance; } FT_Glyph_Metrics; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Bitmap_Size */ /* */ /* <Description> */ /* This structure models the metrics of a bitmap strike (i.e., a set */ /* of glyphs for a given point size and resolution) in a bitmap font. */ /* It is used for the `available_sizes' field of @FT_Face. */ /* */ /* <Fields> */ /* height :: The vertical distance, in pixels, between two */ /* consecutive baselines. It is always positive. */ /* */ /* width :: The average width, in pixels, of all glyphs in the */ /* strike. */ /* */ /* size :: The nominal size of the strike in 26.6 fractional */ /* points. This field is not very useful. */ /* */ /* x_ppem :: The horizontal ppem (nominal width) in 26.6 fractional */ /* pixels. */ /* */ /* y_ppem :: The vertical ppem (nominal height) in 26.6 fractional */ /* pixels. */ /* */ /* <Note> */ /* Windows FNT: */ /* The nominal size given in a FNT font is not reliable. If the */ /* driver finds it incorrect, it sets `size' to some calculated */ /* values, and `x_ppem' and `y_ppem' to the pixel width and height */ /* given in the font, respectively. */ /* */ /* TrueType embedded bitmaps: */ /* `size', `width', and `height' values are not contained in the */ /* bitmap strike itself. They are computed from the global font */ /* parameters. */ /* */ typedef struct FT_Bitmap_Size_ { FT_Short height; FT_Short width; FT_Pos size; FT_Pos x_ppem; FT_Pos y_ppem; } FT_Bitmap_Size; /*************************************************************************/ /*************************************************************************/ /* */ /* O B J E C T C L A S S E S */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* <Type> */ /* FT_Library */ /* */ /* <Description> */ /* A handle to a FreeType library instance. Each `library' is */ /* completely independent from the others; it is the `root' of a set */ /* of objects like fonts, faces, sizes, etc. */ /* */ /* It also embeds a memory manager (see @FT_Memory), as well as a */ /* scan-line converter object (see @FT_Raster). */ /* */ /* In multi-threaded applications it is easiest to use one */ /* `FT_Library' object per thread. In case this is too cumbersome, */ /* a single `FT_Library' object across threads is possible also */ /* (since FreeType version 2.5.6), as long as a mutex lock is used */ /* around @FT_New_Face and @FT_Done_Face. */ /* */ /* <Note> */ /* Library objects are normally created by @FT_Init_FreeType, and */ /* destroyed with @FT_Done_FreeType. If you need reference-counting */ /* (cf. @FT_Reference_Library), use @FT_New_Library and */ /* @FT_Done_Library. */ /* */ typedef struct FT_LibraryRec_ *FT_Library; /*************************************************************************/ /* */ /* <Section> */ /* module_management */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Type> */ /* FT_Module */ /* */ /* <Description> */ /* A handle to a given FreeType module object. A module can be a */ /* font driver, a renderer, or anything else that provides services */ /* to the former. */ /* */ typedef struct FT_ModuleRec_* FT_Module; /*************************************************************************/ /* */ /* <Type> */ /* FT_Driver */ /* */ /* <Description> */ /* A handle to a given FreeType font driver object. A font driver */ /* is a module capable of creating faces from font files. */ /* */ typedef struct FT_DriverRec_* FT_Driver; /*************************************************************************/ /* */ /* <Type> */ /* FT_Renderer */ /* */ /* <Description> */ /* A handle to a given FreeType renderer. A renderer is a module in */ /* charge of converting a glyph's outline image to a bitmap. It */ /* supports a single glyph image format, and one or more target */ /* surface depths. */ /* */ typedef struct FT_RendererRec_* FT_Renderer; /*************************************************************************/ /* */ /* <Section> */ /* base_interface */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Type> */ /* FT_Face */ /* */ /* <Description> */ /* A handle to a typographic face object. A face object models a */ /* given typeface, in a given style. */ /* */ /* <Note> */ /* A face object also owns a single @FT_GlyphSlot object, as well */ /* as one or more @FT_Size objects. */ /* */ /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ /* a given filepath or a custom input stream. */ /* */ /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ /* */ /* An `FT_Face' object can only be safely used from one thread at a */ /* time. Similarly, creation and destruction of `FT_Face' with the */ /* same @FT_Library object can only be done from one thread at a */ /* time. On the other hand, functions like @FT_Load_Glyph and its */ /* siblings are thread-safe and do not need the lock to be held as */ /* long as the same `FT_Face' object is not used from multiple */ /* threads at the same time. */ /* */ /* <Also> */ /* See @FT_FaceRec for the publicly accessible fields of a given face */ /* object. */ /* */ typedef struct FT_FaceRec_* FT_Face; /*************************************************************************/ /* */ /* <Type> */ /* FT_Size */ /* */ /* <Description> */ /* A handle to an object that models a face scaled to a given */ /* character size. */ /* */ /* <Note> */ /* An @FT_Face has one _active_ @FT_Size object that is used by */ /* functions like @FT_Load_Glyph to determine the scaling */ /* transformation that in turn is used to load and hint glyphs and */ /* metrics. */ /* */ /* You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, */ /* @FT_Request_Size or even @FT_Select_Size to change the content */ /* (i.e., the scaling values) of the active @FT_Size. */ /* */ /* You can use @FT_New_Size to create additional size objects for a */ /* given @FT_Face, but they won't be used by other functions until */ /* you activate it through @FT_Activate_Size. Only one size can be */ /* activated at any given time per face. */ /* */ /* <Also> */ /* See @FT_SizeRec for the publicly accessible fields of a given size */ /* object. */ /* */ typedef struct FT_SizeRec_* FT_Size; /*************************************************************************/ /* */ /* <Type> */ /* FT_GlyphSlot */ /* */ /* <Description> */ /* A handle to a given `glyph slot'. A slot is a container that can */ /* hold any of the glyphs contained in its parent face. */ /* */ /* In other words, each time you call @FT_Load_Glyph or */ /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ /* i.e., the glyph's metrics, its image (bitmap or outline), and */ /* other control information. */ /* */ /* <Also> */ /* See @FT_GlyphSlotRec for the publicly accessible glyph fields. */ /* */ typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; /*************************************************************************/ /* */ /* <Type> */ /* FT_CharMap */ /* */ /* <Description> */ /* A handle to a character map (usually abbreviated to `charmap'). A */ /* charmap is used to translate character codes in a given encoding */ /* into glyph indexes for its parent's face. Some font formats may */ /* provide several charmaps per font. */ /* */ /* Each face object owns zero or more charmaps, but only one of them */ /* can be `active', providing the data used by @FT_Get_Char_Index or */ /* @FT_Load_Char. */ /* */ /* The list of available charmaps in a face is available through the */ /* `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec. */ /* */ /* The currently active charmap is available as `face->charmap'. */ /* You should call @FT_Set_Charmap to change it. */ /* */ /* <Note> */ /* When a new face is created (either through @FT_New_Face or */ /* @FT_Open_Face), the library looks for a Unicode charmap within */ /* the list and automatically activates it. If there is no Unicode */ /* charmap, FreeType doesn't set an `active' charmap. */ /* */ /* <Also> */ /* See @FT_CharMapRec for the publicly accessible fields of a given */ /* character map. */ /* */ typedef struct FT_CharMapRec_* FT_CharMap; /*************************************************************************/ /* */ /* <Macro> */ /* FT_ENC_TAG */ /* */ /* <Description> */ /* This macro converts four-letter tags into an unsigned long. It is */ /* used to define `encoding' identifiers (see @FT_Encoding). */ /* */ /* <Note> */ /* Since many 16-bit compilers don't like 32-bit enumerations, you */ /* should redefine this macro in case of problems to something like */ /* this: */ /* */ /* { */ /* #define FT_ENC_TAG( value, a, b, c, d ) value */ /* } */ /* */ /* to get a simple enumeration without assigning special numbers. */ /* */ #ifndef FT_ENC_TAG #define FT_ENC_TAG( value, a, b, c, d ) \ value = ( ( (FT_UInt32)(a) << 24 ) | \ ( (FT_UInt32)(b) << 16 ) | \ ( (FT_UInt32)(c) << 8 ) | \ (FT_UInt32)(d) ) #endif /* FT_ENC_TAG */ /*************************************************************************/ /* */ /* <Enum> */ /* FT_Encoding */ /* */ /* <Description> */ /* An enumeration to specify character sets supported by charmaps. */ /* Used in the @FT_Select_Charmap API function. */ /* */ /* <Note> */ /* Despite the name, this enumeration lists specific character */ /* repertories (i.e., charsets), and not text encoding methods (e.g., */ /* UTF-8, UTF-16, etc.). */ /* */ /* Other encodings might be defined in the future. */ /* */ /* <Values> */ /* FT_ENCODING_NONE :: */ /* The encoding value~0 is reserved. */ /* */ /* FT_ENCODING_UNICODE :: */ /* The Unicode character set. This value covers all versions of */ /* the Unicode repertoire, including ASCII and Latin-1. Most fonts */ /* include a Unicode charmap, but not all of them. */ /* */ /* For example, if you want to access Unicode value U+1F028 (and */ /* the font contains it), use value 0x1F028 as the input value for */ /* @FT_Get_Char_Index. */ /* */ /* FT_ENCODING_MS_SYMBOL :: */ /* Microsoft Symbol encoding, used to encode mathematical symbols */ /* and wingdings. For more information, see */ /* `https://www.microsoft.com/typography/otspec/recom.htm', */ /* `http://www.kostis.net/charsets/symbol.htm', and */ /* `http://www.kostis.net/charsets/wingding.htm'. */ /* */ /* This encoding uses character codes from the PUA (Private Unicode */ /* Area) in the range U+F020-U+F0FF. */ /* */ /* FT_ENCODING_SJIS :: */ /* Shift JIS encoding for Japanese. More info at */ /* `https://en.wikipedia.org/wiki/Shift_JIS'. See note on */ /* multi-byte encodings below. */ /* */ /* FT_ENCODING_PRC :: */ /* Corresponds to encoding systems mainly for Simplified Chinese as */ /* used in People's Republic of China (PRC). The encoding layout */ /* is based on GB~2312 and its supersets GBK and GB~18030. */ /* */ /* FT_ENCODING_BIG5 :: */ /* Corresponds to an encoding system for Traditional Chinese as */ /* used in Taiwan and Hong Kong. */ /* */ /* FT_ENCODING_WANSUNG :: */ /* Corresponds to the Korean encoding system known as Extended */ /* Wansung (MS Windows code page 949). */ /* For more information see */ /* `https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit949.txt'. */ /* */ /* FT_ENCODING_JOHAB :: */ /* The Korean standard character set (KS~C 5601-1992), which */ /* corresponds to MS Windows code page 1361. This character set */ /* includes all possible Hangul character combinations. */ /* */ /* FT_ENCODING_ADOBE_LATIN_1 :: */ /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ /* PostScript font. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_ADOBE_STANDARD :: */ /* Adobe Standard encoding, as found in Type~1, CFF, and */ /* OpenType/CFF fonts. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_ADOBE_EXPERT :: */ /* Adobe Expert encoding, as found in Type~1, CFF, and OpenType/CFF */ /* fonts. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_ADOBE_CUSTOM :: */ /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ /* OpenType/CFF fonts. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_APPLE_ROMAN :: */ /* Apple roman encoding. Many TrueType and OpenType fonts contain */ /* a charmap for this 8-bit encoding, since older versions of Mac */ /* OS are able to use it. */ /* */ /* FT_ENCODING_OLD_LATIN_2 :: */ /* This value is deprecated and was neither used nor reported by */ /* FreeType. Don't use or test for it. */ /* */ /* FT_ENCODING_MS_SJIS :: */ /* Same as FT_ENCODING_SJIS. Deprecated. */ /* */ /* FT_ENCODING_MS_GB2312 :: */ /* Same as FT_ENCODING_PRC. Deprecated. */ /* */ /* FT_ENCODING_MS_BIG5 :: */ /* Same as FT_ENCODING_BIG5. Deprecated. */ /* */ /* FT_ENCODING_MS_WANSUNG :: */ /* Same as FT_ENCODING_WANSUNG. Deprecated. */ /* */ /* FT_ENCODING_MS_JOHAB :: */ /* Same as FT_ENCODING_JOHAB. Deprecated. */ /* */ /* <Note> */ /* By default, FreeType enables a Unicode charmap and tags it with */ /* FT_ENCODING_UNICODE when it is either provided or can be generated */ /* from PostScript glyph name dictionaries in the font file. */ /* All other encodings are considered legacy and tagged only if */ /* explicitly defined in the font file. Otherwise, FT_ENCODING_NONE */ /* is used. */ /* */ /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out */ /* which encoding is really present. If, for example, the */ /* `cs_registry' field is `KOI8' and the `cs_encoding' field is `R', */ /* the font is encoded in KOI8-R. */ /* */ /* FT_ENCODING_NONE is always set (with a single exception) by the */ /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ /* which encoding is really present. For example, */ /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ /* Russian). */ /* */ /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ /* and `encoding_id' is not `TT_MAC_ID_ROMAN' (otherwise it is set to */ /* FT_ENCODING_APPLE_ROMAN). */ /* */ /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ /* @FT_Get_CMap_Language_ID to query the Mac language ID that may */ /* be needed to be able to distinguish Apple encoding variants. See */ /* */ /* https://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt */ /* */ /* to get an idea how to do that. Basically, if the language ID */ /* is~0, don't use it, otherwise subtract 1 from the language ID. */ /* Then examine `encoding_id'. If, for example, `encoding_id' is */ /* `TT_MAC_ID_ROMAN' and the language ID (minus~1) is */ /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ /* `TT_MAC_ID_ARABIC' with `TT_MAC_LANGID_FARSI' means the Farsi */ /* variant the Arabic encoding. */ /* */ typedef enum FT_Encoding_ { FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ), FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ), FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ), FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ), FT_ENC_TAG( FT_ENCODING_PRC, 'g', 'b', ' ', ' ' ), FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ), FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ), FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ), /* for backward compatibility */ FT_ENCODING_GB2312 = FT_ENCODING_PRC, FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS, FT_ENCODING_MS_GB2312 = FT_ENCODING_PRC, FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5, FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG, FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB, FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ), FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ), FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM, 'A', 'D', 'B', 'C' ), FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1, 'l', 'a', 't', '1' ), FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ), FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' ) } FT_Encoding; /* these constants are deprecated; use the corresponding `FT_Encoding' */ /* values instead */ #define ft_encoding_none FT_ENCODING_NONE #define ft_encoding_unicode FT_ENCODING_UNICODE #define ft_encoding_symbol FT_ENCODING_MS_SYMBOL #define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 #define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 #define ft_encoding_sjis FT_ENCODING_SJIS #define ft_encoding_gb2312 FT_ENCODING_PRC #define ft_encoding_big5 FT_ENCODING_BIG5 #define ft_encoding_wansung FT_ENCODING_WANSUNG #define ft_encoding_johab FT_ENCODING_JOHAB #define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD #define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT #define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM #define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN /*************************************************************************/ /* */ /* <Struct> */ /* FT_CharMapRec */ /* */ /* <Description> */ /* The base charmap structure. */ /* */ /* <Fields> */ /* face :: A handle to the parent face object. */ /* */ /* encoding :: An @FT_Encoding tag identifying the charmap. Use */ /* this with @FT_Select_Charmap. */ /* */ /* platform_id :: An ID number describing the platform for the */ /* following encoding ID. This comes directly from */ /* the TrueType specification and gets emulated for */ /* other formats. */ /* */ /* encoding_id :: A platform specific encoding number. This also */ /* comes from the TrueType specification and gets */ /* emulated similarly. */ /* */ typedef struct FT_CharMapRec_ { FT_Face face; FT_Encoding encoding; FT_UShort platform_id; FT_UShort encoding_id; } FT_CharMapRec; /*************************************************************************/ /*************************************************************************/ /* */ /* B A S E O B J E C T C L A S S E S */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* <Type> */ /* FT_Face_Internal */ /* */ /* <Description> */ /* An opaque handle to an `FT_Face_InternalRec' structure that models */ /* the private data of a given @FT_Face object. */ /* */ /* This structure might change between releases of FreeType~2 and is */ /* not generally available to client applications. */ /* */ typedef struct FT_Face_InternalRec_* FT_Face_Internal; /*************************************************************************/ /* */ /* <Struct> */ /* FT_FaceRec */ /* */ /* <Description> */ /* FreeType root face class structure. A face object models a */ /* typeface in a font file. */ /* */ /* <Fields> */ /* num_faces :: The number of faces in the font file. Some */ /* font formats can have multiple faces in */ /* a single font file. */ /* */ /* face_index :: This field holds two different values. */ /* Bits 0-15 are the index of the face in the */ /* font file (starting with value~0). They */ /* are set to~0 if there is only one face in */ /* the font file. */ /* */ /* [Since 2.6.1] Bits 16-30 are relevant to GX */ /* and OpenType variation fonts only, holding */ /* the named instance index for the current */ /* face index (starting with value~1; value~0 */ /* indicates font access without a named */ /* instance). For non-variation fonts, bits */ /* 16-30 are ignored. If we have the third */ /* named instance of face~4, say, `face_index' */ /* is set to 0x00030004. */ /* */ /* Bit 31 is always zero (this is, */ /* `face_index' is always a positive value). */ /* */ /* [Since 2.9] Changing the design coordinates */ /* with @FT_Set_Var_Design_Coordinates or */ /* @FT_Set_Var_Blend_Coordinates does not */ /* influence the named instance index value */ /* (only @FT_Set_Named_Instance does that). */ /* */ /* face_flags :: A set of bit flags that give important */ /* information about the face; see */ /* @FT_FACE_FLAG_XXX for the details. */ /* */ /* style_flags :: The lower 16~bits contain a set of bit */ /* flags indicating the style of the face; see */ /* @FT_STYLE_FLAG_XXX for the details. */ /* */ /* [Since 2.6.1] Bits 16-30 hold the number */ /* of named instances available for the */ /* current face if we have a GX or OpenType */ /* variation (sub)font. Bit 31 is always zero */ /* (this is, `style_flags' is always a */ /* positive value). Note that a variation */ /* font has always at least one named */ /* instance, namely the default instance. */ /* */ /* num_glyphs :: The number of glyphs in the face. If the */ /* face is scalable and has sbits (see */ /* `num_fixed_sizes'), it is set to the number */ /* of outline glyphs. */ /* */ /* For CID-keyed fonts (not in an SFNT */ /* wrapper) this value gives the highest CID */ /* used in the font. */ /* */ /* family_name :: The face's family name. This is an ASCII */ /* string, usually in English, that describes */ /* the typeface's family (like `Times New */ /* Roman', `Bodoni', `Garamond', etc). This */ /* is a least common denominator used to list */ /* fonts. Some formats (TrueType & OpenType) */ /* provide localized and Unicode versions of */ /* this string. Applications should use the */ /* format specific interface to access them. */ /* Can be NULL (e.g., in fonts embedded in a */ /* PDF file). */ /* */ /* In case the font doesn't provide a specific */ /* family name entry, FreeType tries to */ /* synthesize one, deriving it from other name */ /* entries. */ /* */ /* style_name :: The face's style name. This is an ASCII */ /* string, usually in English, that describes */ /* the typeface's style (like `Italic', */ /* `Bold', `Condensed', etc). Not all font */ /* formats provide a style name, so this field */ /* is optional, and can be set to NULL. As */ /* for `family_name', some formats provide */ /* localized and Unicode versions of this */ /* string. Applications should use the format */ /* specific interface to access them. */ /* */ /* num_fixed_sizes :: The number of bitmap strikes in the face. */ /* Even if the face is scalable, there might */ /* still be bitmap strikes, which are called */ /* `sbits' in that case. */ /* */ /* available_sizes :: An array of @FT_Bitmap_Size for all bitmap */ /* strikes in the face. It is set to NULL if */ /* there is no bitmap strike. */ /* */ /* Note that FreeType tries to sanitize the */ /* strike data since they are sometimes sloppy */ /* or incorrect, but this can easily fail. */ /* */ /* num_charmaps :: The number of charmaps in the face. */ /* */ /* charmaps :: An array of the charmaps of the face. */ /* */ /* generic :: A field reserved for client uses. See the */ /* @FT_Generic type description. */ /* */ /* bbox :: The font bounding box. Coordinates are */ /* expressed in font units (see */ /* `units_per_EM'). The box is large enough */ /* to contain any glyph from the font. Thus, */ /* `bbox.yMax' can be seen as the `maximum */ /* ascender', and `bbox.yMin' as the `minimum */ /* descender'. Only relevant for scalable */ /* formats. */ /* */ /* Note that the bounding box might be off by */ /* (at least) one pixel for hinted fonts. See */ /* @FT_Size_Metrics for further discussion. */ /* */ /* units_per_EM :: The number of font units per EM square for */ /* this face. This is typically 2048 for */ /* TrueType fonts, and 1000 for Type~1 fonts. */ /* Only relevant for scalable formats. */ /* */ /* ascender :: The typographic ascender of the face, */ /* expressed in font units. For font formats */ /* not having this information, it is set to */ /* `bbox.yMax'. Only relevant for scalable */ /* formats. */ /* */ /* descender :: The typographic descender of the face, */ /* expressed in font units. For font formats */ /* not having this information, it is set to */ /* `bbox.yMin'. Note that this field is */ /* negative for values below the baseline. */ /* Only relevant for scalable formats. */ /* */ /* height :: This value is the vertical distance */ /* between two consecutive baselines, */ /* expressed in font units. It is always */ /* positive. Only relevant for scalable */ /* formats. */ /* */ /* If you want the global glyph height, use */ /* `ascender - descender'. */ /* */ /* max_advance_width :: The maximum advance width, in font units, */ /* for all glyphs in this face. This can be */ /* used to make word wrapping computations */ /* faster. Only relevant for scalable */ /* formats. */ /* */ /* max_advance_height :: The maximum advance height, in font units, */ /* for all glyphs in this face. This is only */ /* relevant for vertical layouts, and is set */ /* to `height' for fonts that do not provide */ /* vertical metrics. Only relevant for */ /* scalable formats. */ /* */ /* underline_position :: The position, in font units, of the */ /* underline line for this face. It is the */ /* center of the underlining stem. Only */ /* relevant for scalable formats. */ /* */ /* underline_thickness :: The thickness, in font units, of the */ /* underline for this face. Only relevant for */ /* scalable formats. */ /* */ /* glyph :: The face's associated glyph slot(s). */ /* */ /* size :: The current active size for this face. */ /* */ /* charmap :: The current active charmap for this face. */ /* */ /* <Note> */ /* Fields may be changed after a call to @FT_Attach_File or */ /* @FT_Attach_Stream. */ /* */ /* For an OpenType variation font, the values of the following fields */ /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ /* friends) if the font contains an `MVAR' table: `ascender', */ /* `descender', `height', `underline_position', and */ /* `underline_thickness'. */ /* */ /* Especially for TrueType fonts see also the documentation for */ /* @FT_Size_Metrics. */ /* */ typedef struct FT_FaceRec_ { FT_Long num_faces; FT_Long face_index; FT_Long face_flags; FT_Long style_flags; FT_Long num_glyphs; FT_String* family_name; FT_String* style_name; FT_Int num_fixed_sizes; FT_Bitmap_Size* available_sizes; FT_Int num_charmaps; FT_CharMap* charmaps; FT_Generic generic; /*# The following member variables (down to `underline_thickness') */ /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */ /*# for bitmap fonts. */ FT_BBox bbox; FT_UShort units_per_EM; FT_Short ascender; FT_Short descender; FT_Short height; FT_Short max_advance_width; FT_Short max_advance_height; FT_Short underline_position; FT_Short underline_thickness; FT_GlyphSlot glyph; FT_Size size; FT_CharMap charmap; /*@private begin */ FT_Driver driver; FT_Memory memory; FT_Stream stream; FT_ListRec sizes_list; FT_Generic autohint; /* face-specific auto-hinter data */ void* extensions; /* unused */ FT_Face_Internal internal; /*@private end */ } FT_FaceRec; /*************************************************************************/ /* */ /* <Enum> */ /* FT_FACE_FLAG_XXX */ /* */ /* <Description> */ /* A list of bit flags used in the `face_flags' field of the */ /* @FT_FaceRec structure. They inform client applications of */ /* properties of the corresponding face. */ /* */ /* <Values> */ /* FT_FACE_FLAG_SCALABLE :: */ /* The face contains outline glyphs. Note that a face can contain */ /* bitmap strikes also, i.e., a face can have both this flag and */ /* @FT_FACE_FLAG_FIXED_SIZES set. */ /* */ /* FT_FACE_FLAG_FIXED_SIZES :: */ /* The face contains bitmap strikes. See also the */ /* `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec. */ /* */ /* FT_FACE_FLAG_FIXED_WIDTH :: */ /* The face contains fixed-width characters (like Courier, Lucida, */ /* MonoType, etc.). */ /* */ /* FT_FACE_FLAG_SFNT :: */ /* The face uses the SFNT storage scheme. For now, this means */ /* TrueType and OpenType. */ /* */ /* FT_FACE_FLAG_HORIZONTAL :: */ /* The face contains horizontal glyph metrics. This should be set */ /* for all common formats. */ /* */ /* FT_FACE_FLAG_VERTICAL :: */ /* The face contains vertical glyph metrics. This is only */ /* available in some formats, not all of them. */ /* */ /* FT_FACE_FLAG_KERNING :: */ /* The face contains kerning information. If set, the kerning */ /* distance can be retrieved using the function @FT_Get_Kerning. */ /* Otherwise the function always return the vector (0,0). Note */ /* that FreeType doesn't handle kerning data from the SFNT `GPOS' */ /* table (as present in many OpenType fonts). */ /* */ /* FT_FACE_FLAG_FAST_GLYPHS :: */ /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ /* */ /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ /* The face contains multiple masters and is capable of */ /* interpolating between them. Supported formats are Adobe MM, */ /* TrueType GX, and OpenType variation fonts. */ /* */ /* See section @multiple_masters for API details. */ /* */ /* FT_FACE_FLAG_GLYPH_NAMES :: */ /* The face contains glyph names, which can be retrieved using */ /* @FT_Get_Glyph_Name. Note that some TrueType fonts contain */ /* broken glyph name tables. Use the function */ /* @FT_Has_PS_Glyph_Names when needed. */ /* */ /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ /* Used internally by FreeType to indicate that a face's stream was */ /* provided by the client application and should not be destroyed */ /* when @FT_Done_Face is called. Don't read or test this flag. */ /* */ /* FT_FACE_FLAG_HINTER :: */ /* The font driver has a hinting machine of its own. For example, */ /* with TrueType fonts, it makes sense to use data from the SFNT */ /* `gasp' table only if the native TrueType hinting engine (with */ /* the bytecode interpreter) is available and active. */ /* */ /* FT_FACE_FLAG_CID_KEYED :: */ /* The face is CID-keyed. In that case, the face is not accessed */ /* by glyph indices but by CID values. For subsetted CID-keyed */ /* fonts this has the consequence that not all index values are a */ /* valid argument to @FT_Load_Glyph. Only the CID values for which */ /* corresponding glyphs in the subsetted font exist make */ /* `FT_Load_Glyph' return successfully; in all other cases you get */ /* an `FT_Err_Invalid_Argument' error. */ /* */ /* Note that CID-keyed fonts that are in an SFNT wrapper (this is, */ /* all OpenType/CFF fonts) don't have this flag set since the */ /* glyphs are accessed in the normal way (using contiguous */ /* indices); the `CID-ness' isn't visible to the application. */ /* */ /* FT_FACE_FLAG_TRICKY :: */ /* The face is `tricky', this is, it always needs the font format's */ /* native hinting engine to get a reasonable result. A typical */ /* example is the old Chinese font `mingli.ttf' (but not */ /* `mingliu.ttc') that uses TrueType bytecode instructions to move */ /* and scale all of its subglyphs. */ /* */ /* It is not possible to auto-hint such fonts using */ /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ /* @FT_LOAD_NO_HINTING. You have to set both @FT_LOAD_NO_HINTING */ /* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */ /* probably never want this except for demonstration purposes. */ /* */ /* Currently, there are about a dozen TrueType fonts in the list of */ /* tricky fonts; they are hard-coded in file `ttobjs.c'. */ /* */ /* FT_FACE_FLAG_COLOR :: */ /* [Since 2.5.1] The face has color glyph tables. To access color */ /* glyphs use @FT_LOAD_COLOR. */ /* */ /* FT_FACE_FLAG_VARIATION :: */ /* [Since 2.9] Set if the current face (or named instance) has been */ /* altered with @FT_Set_MM_Design_Coordinates, */ /* @FT_Set_Var_Design_Coordinates, or */ /* @FT_Set_Var_Blend_Coordinates. This flag is unset by a call to */ /* @FT_Set_Named_Instance. */ /* */ #define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) #define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) #define FT_FACE_FLAG_SFNT ( 1L << 3 ) #define FT_FACE_FLAG_HORIZONTAL ( 1L << 4 ) #define FT_FACE_FLAG_VERTICAL ( 1L << 5 ) #define FT_FACE_FLAG_KERNING ( 1L << 6 ) #define FT_FACE_FLAG_FAST_GLYPHS ( 1L << 7 ) #define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 ) #define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) #define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) #define FT_FACE_FLAG_HINTER ( 1L << 11 ) #define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) #define FT_FACE_FLAG_TRICKY ( 1L << 13 ) #define FT_FACE_FLAG_COLOR ( 1L << 14 ) #define FT_FACE_FLAG_VARIATION ( 1L << 15 ) /************************************************************************* * * @macro: * FT_HAS_HORIZONTAL( face ) * * @description: * A macro that returns true whenever a face object contains * horizontal metrics (this is true for all font formats though). * * @also: * @FT_HAS_VERTICAL can be used to check for vertical metrics. * */ #define FT_HAS_HORIZONTAL( face ) \ ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL ) /************************************************************************* * * @macro: * FT_HAS_VERTICAL( face ) * * @description: * A macro that returns true whenever a face object contains real * vertical metrics (and not only synthesized ones). * */ #define FT_HAS_VERTICAL( face ) \ ( (face)->face_flags & FT_FACE_FLAG_VERTICAL ) /************************************************************************* * * @macro: * FT_HAS_KERNING( face ) * * @description: * A macro that returns true whenever a face object contains kerning * data that can be accessed with @FT_Get_Kerning. * */ #define FT_HAS_KERNING( face ) \ ( (face)->face_flags & FT_FACE_FLAG_KERNING ) /************************************************************************* * * @macro: * FT_IS_SCALABLE( face ) * * @description: * A macro that returns true whenever a face object contains a scalable * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, * and PFR font formats). * */ #define FT_IS_SCALABLE( face ) \ ( (face)->face_flags & FT_FACE_FLAG_SCALABLE ) /************************************************************************* * * @macro: * FT_IS_SFNT( face ) * * @description: * A macro that returns true whenever a face object contains a font * whose format is based on the SFNT storage scheme. This usually * means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded * bitmap fonts. * * If this macro is true, all functions defined in @FT_SFNT_NAMES_H and * @FT_TRUETYPE_TABLES_H are available. * */ #define FT_IS_SFNT( face ) \ ( (face)->face_flags & FT_FACE_FLAG_SFNT ) /************************************************************************* * * @macro: * FT_IS_FIXED_WIDTH( face ) * * @description: * A macro that returns true whenever a face object contains a font face * that contains fixed-width (or `monospace', `fixed-pitch', etc.) * glyphs. * */ #define FT_IS_FIXED_WIDTH( face ) \ ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) /************************************************************************* * * @macro: * FT_HAS_FIXED_SIZES( face ) * * @description: * A macro that returns true whenever a face object contains some * embedded bitmaps. See the `available_sizes' field of the * @FT_FaceRec structure. * */ #define FT_HAS_FIXED_SIZES( face ) \ ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES ) /************************************************************************* * * @macro: * FT_HAS_FAST_GLYPHS( face ) * * @description: * Deprecated. * */ #define FT_HAS_FAST_GLYPHS( face ) 0 /************************************************************************* * * @macro: * FT_HAS_GLYPH_NAMES( face ) * * @description: * A macro that returns true whenever a face object contains some glyph * names that can be accessed through @FT_Get_Glyph_Name. * */ #define FT_HAS_GLYPH_NAMES( face ) \ ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) /************************************************************************* * * @macro: * FT_HAS_MULTIPLE_MASTERS( face ) * * @description: * A macro that returns true whenever a face object contains some * multiple masters. The functions provided by @FT_MULTIPLE_MASTERS_H * are then available to choose the exact design you want. * */ #define FT_HAS_MULTIPLE_MASTERS( face ) \ ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) /************************************************************************* * * @macro: * FT_IS_NAMED_INSTANCE( face ) * * @description: * A macro that returns true whenever a face object is a named instance * of a GX or OpenType variation font. * * [Since 2.9] Changing the design coordinates with * @FT_Set_Var_Design_Coordinates or @FT_Set_Var_Blend_Coordinates does * not influence the return value of this macro (only * @FT_Set_Named_Instance does that). * * @since: * 2.7 * */ #define FT_IS_NAMED_INSTANCE( face ) \ ( (face)->face_index & 0x7FFF0000L ) /************************************************************************* * * @macro: * FT_IS_VARIATION( face ) * * @description: * A macro that returns true whenever a face object has been altered * by @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates, or * @FT_Set_Var_Blend_Coordinates. * * @since: * 2.9 * */ #define FT_IS_VARIATION( face ) \ ( (face)->face_flags & FT_FACE_FLAG_VARIATION ) /************************************************************************* * * @macro: * FT_IS_CID_KEYED( face ) * * @description: * A macro that returns true whenever a face object contains a CID-keyed * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more * details. * * If this macro is true, all functions defined in @FT_CID_H are * available. * */ #define FT_IS_CID_KEYED( face ) \ ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED ) /************************************************************************* * * @macro: * FT_IS_TRICKY( face ) * * @description: * A macro that returns true whenever a face represents a `tricky' font. * See the discussion of @FT_FACE_FLAG_TRICKY for more details. * */ #define FT_IS_TRICKY( face ) \ ( (face)->face_flags & FT_FACE_FLAG_TRICKY ) /************************************************************************* * * @macro: * FT_HAS_COLOR( face ) * * @description: * A macro that returns true whenever a face object contains * tables for color glyphs. * * @since: * 2.5.1 * */ #define FT_HAS_COLOR( face ) \ ( (face)->face_flags & FT_FACE_FLAG_COLOR ) /*************************************************************************/ /* */ /* <Const> */ /* FT_STYLE_FLAG_XXX */ /* */ /* <Description> */ /* A list of bit flags to indicate the style of a given face. These */ /* are used in the `style_flags' field of @FT_FaceRec. */ /* */ /* <Values> */ /* FT_STYLE_FLAG_ITALIC :: */ /* The face style is italic or oblique. */ /* */ /* FT_STYLE_FLAG_BOLD :: */ /* The face is bold. */ /* */ /* <Note> */ /* The style information as provided by FreeType is very basic. More */ /* details are beyond the scope and should be done on a higher level */ /* (for example, by analyzing various fields of the `OS/2' table in */ /* SFNT based fonts). */ /* */ #define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) #define FT_STYLE_FLAG_BOLD ( 1 << 1 ) /*************************************************************************/ /* */ /* <Type> */ /* FT_Size_Internal */ /* */ /* <Description> */ /* An opaque handle to an `FT_Size_InternalRec' structure, used to */ /* model private data of a given @FT_Size object. */ /* */ typedef struct FT_Size_InternalRec_* FT_Size_Internal; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Size_Metrics */ /* */ /* <Description> */ /* The size metrics structure gives the metrics of a size object. */ /* */ /* <Fields> */ /* x_ppem :: The width of the scaled EM square in pixels, hence */ /* the term `ppem' (pixels per EM). It is also */ /* referred to as `nominal width'. */ /* */ /* y_ppem :: The height of the scaled EM square in pixels, */ /* hence the term `ppem' (pixels per EM). It is also */ /* referred to as `nominal height'. */ /* */ /* x_scale :: A 16.16 fractional scaling value to convert */ /* horizontal metrics from font units to 26.6 */ /* fractional pixels. Only relevant for scalable */ /* font formats. */ /* */ /* y_scale :: A 16.16 fractional scaling value to convert */ /* vertical metrics from font units to 26.6 */ /* fractional pixels. Only relevant for scalable */ /* font formats. */ /* */ /* ascender :: The ascender in 26.6 fractional pixels, rounded up */ /* to an integer value. See @FT_FaceRec for the */ /* details. */ /* */ /* descender :: The descender in 26.6 fractional pixels, rounded */ /* down to an integer value. See @FT_FaceRec for the */ /* details. */ /* */ /* height :: The height in 26.6 fractional pixels, rounded to */ /* an integer value. See @FT_FaceRec for the */ /* details. */ /* */ /* max_advance :: The maximum advance width in 26.6 fractional */ /* pixels, rounded to an integer value. See */ /* @FT_FaceRec for the details. */ /* */ /* <Note> */ /* The scaling values, if relevant, are determined first during a */ /* size changing operation. The remaining fields are then set by the */ /* driver. For scalable formats, they are usually set to scaled */ /* values of the corresponding fields in @FT_FaceRec. Some values */ /* like ascender or descender are rounded for historical reasons; */ /* more precise values (for outline fonts) can be derived by scaling */ /* the corresponding @FT_FaceRec values manually, with code similar */ /* to the following. */ /* */ /* { */ /* scaled_ascender = FT_MulFix( face->ascender, */ /* size_metrics->y_scale ); */ /* } */ /* */ /* Note that due to glyph hinting and the selected rendering mode */ /* these values are usually not exact; consequently, they must be */ /* treated as unreliable with an error margin of at least one pixel! */ /* */ /* Indeed, the only way to get the exact metrics is to render _all_ */ /* glyphs. As this would be a definite performance hit, it is up to */ /* client applications to perform such computations. */ /* */ /* The `FT_Size_Metrics' structure is valid for bitmap fonts also. */ /* */ /* */ /* *TrueType* *fonts* *with* *native* *bytecode* *hinting* */ /* */ /* All applications that handle TrueType fonts with native hinting */ /* must be aware that TTFs expect different rounding of vertical font */ /* dimensions. The application has to cater for this, especially if */ /* it wants to rely on a TTF's vertical data (for example, to */ /* properly align box characters vertically). */ /* */ /* Only the application knows _in_ _advance_ that it is going to use */ /* native hinting for TTFs! FreeType, on the other hand, selects the */ /* hinting mode not at the time of creating an @FT_Size object but */ /* much later, namely while calling @FT_Load_Glyph. */ /* */ /* Here is some pseudo code that illustrates a possible solution. */ /* */ /* { */ /* font_format = FT_Get_Font_Format( face ); */ /* */ /* if ( !strcmp( font_format, "TrueType" ) && */ /* do_native_bytecode_hinting ) */ /* { */ /* ascender = ROUND( FT_MulFix( face->ascender, */ /* size_metrics->y_scale ) ); */ /* descender = ROUND( FT_MulFix( face->descender, */ /* size_metrics->y_scale ) ); */ /* } */ /* else */ /* { */ /* ascender = size_metrics->ascender; */ /* descender = size_metrics->descender; */ /* } */ /* */ /* height = size_metrics->height; */ /* max_advance = size_metrics->max_advance; */ /* } */ /* */ typedef struct FT_Size_Metrics_ { FT_UShort x_ppem; /* horizontal pixels per EM */ FT_UShort y_ppem; /* vertical pixels per EM */ FT_Fixed x_scale; /* scaling values used to convert font */ FT_Fixed y_scale; /* units to 26.6 fractional pixels */ FT_Pos ascender; /* ascender in 26.6 frac. pixels */ FT_Pos descender; /* descender in 26.6 frac. pixels */ FT_Pos height; /* text height in 26.6 frac. pixels */ FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */ } FT_Size_Metrics; /*************************************************************************/ /* */ /* <Struct> */ /* FT_SizeRec */ /* */ /* <Description> */ /* FreeType root size class structure. A size object models a face */ /* object at a given size. */ /* */ /* <Fields> */ /* face :: Handle to the parent face object. */ /* */ /* generic :: A typeless pointer, unused by the FreeType library or */ /* any of its drivers. It can be used by client */ /* applications to link their own data to each size */ /* object. */ /* */ /* metrics :: Metrics for this size object. This field is read-only. */ /* */ typedef struct FT_SizeRec_ { FT_Face face; /* parent face object */ FT_Generic generic; /* generic pointer for client uses */ FT_Size_Metrics metrics; /* size metrics */ FT_Size_Internal internal; } FT_SizeRec; /*************************************************************************/ /* */ /* <Struct> */ /* FT_SubGlyph */ /* */ /* <Description> */ /* The subglyph structure is an internal object used to describe */ /* subglyphs (for example, in the case of composites). */ /* */ /* <Note> */ /* The subglyph implementation is not part of the high-level API, */ /* hence the forward structure declaration. */ /* */ /* You can however retrieve subglyph information with */ /* @FT_Get_SubGlyph_Info. */ /* */ typedef struct FT_SubGlyphRec_* FT_SubGlyph; /*************************************************************************/ /* */ /* <Type> */ /* FT_Slot_Internal */ /* */ /* <Description> */ /* An opaque handle to an `FT_Slot_InternalRec' structure, used to */ /* model private data of a given @FT_GlyphSlot object. */ /* */ typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; /*************************************************************************/ /* */ /* <Struct> */ /* FT_GlyphSlotRec */ /* */ /* <Description> */ /* FreeType root glyph slot class structure. A glyph slot is a */ /* container where individual glyphs can be loaded, be they in */ /* outline or bitmap format. */ /* */ /* <Fields> */ /* library :: A handle to the FreeType library instance */ /* this slot belongs to. */ /* */ /* face :: A handle to the parent face object. */ /* */ /* next :: In some cases (like some font tools), several */ /* glyph slots per face object can be a good */ /* thing. As this is rare, the glyph slots are */ /* listed through a direct, single-linked list */ /* using its `next' field. */ /* */ /* generic :: A typeless pointer unused by the FreeType */ /* library or any of its drivers. It can be */ /* used by client applications to link their own */ /* data to each glyph slot object. */ /* */ /* metrics :: The metrics of the last loaded glyph in the */ /* slot. The returned values depend on the last */ /* load flags (see the @FT_Load_Glyph API */ /* function) and can be expressed either in 26.6 */ /* fractional pixels or font units. */ /* */ /* Note that even when the glyph image is */ /* transformed, the metrics are not. */ /* */ /* linearHoriAdvance :: The advance width of the unhinted glyph. */ /* Its value is expressed in 16.16 fractional */ /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ /* when loading the glyph. This field can be */ /* important to perform correct WYSIWYG layout. */ /* Only relevant for outline glyphs. */ /* */ /* linearVertAdvance :: The advance height of the unhinted glyph. */ /* Its value is expressed in 16.16 fractional */ /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ /* when loading the glyph. This field can be */ /* important to perform correct WYSIWYG layout. */ /* Only relevant for outline glyphs. */ /* */ /* advance :: This shorthand is, depending on */ /* @FT_LOAD_IGNORE_TRANSFORM, the transformed */ /* (hinted) advance width for the glyph, in 26.6 */ /* fractional pixel format. As specified with */ /* @FT_LOAD_VERTICAL_LAYOUT, it uses either the */ /* `horiAdvance' or the `vertAdvance' value of */ /* `metrics' field. */ /* */ /* format :: This field indicates the format of the image */ /* contained in the glyph slot. Typically */ /* @FT_GLYPH_FORMAT_BITMAP, */ /* @FT_GLYPH_FORMAT_OUTLINE, or */ /* @FT_GLYPH_FORMAT_COMPOSITE, but other values */ /* are possible. */ /* */ /* bitmap :: This field is used as a bitmap descriptor. */ /* Note that the address and content of the */ /* bitmap buffer can change between calls of */ /* @FT_Load_Glyph and a few other functions. */ /* */ /* bitmap_left :: The bitmap's left bearing expressed in */ /* integer pixels. */ /* */ /* bitmap_top :: The bitmap's top bearing expressed in integer */ /* pixels. This is the distance from the */ /* baseline to the top-most glyph scanline, */ /* upwards y~coordinates being *positive*. */ /* */ /* outline :: The outline descriptor for the current glyph */ /* image if its format is */ /* @FT_GLYPH_FORMAT_OUTLINE. Once a glyph is */ /* loaded, `outline' can be transformed, */ /* distorted, emboldened, etc. However, it must */ /* not be freed. */ /* */ /* num_subglyphs :: The number of subglyphs in a composite glyph. */ /* This field is only valid for the composite */ /* glyph format that should normally only be */ /* loaded with the @FT_LOAD_NO_RECURSE flag. */ /* */ /* subglyphs :: An array of subglyph descriptors for */ /* composite glyphs. There are `num_subglyphs' */ /* elements in there. Currently internal to */ /* FreeType. */ /* */ /* control_data :: Certain font drivers can also return the */ /* control data for a given glyph image (e.g. */ /* TrueType bytecode, Type~1 charstrings, etc.). */ /* This field is a pointer to such data; it is */ /* currently internal to FreeType. */ /* */ /* control_len :: This is the length in bytes of the control */ /* data. Currently internal to FreeType. */ /* */ /* other :: Reserved. */ /* */ /* lsb_delta :: The difference between hinted and unhinted */ /* left side bearing while auto-hinting is */ /* active. Zero otherwise. */ /* */ /* rsb_delta :: The difference between hinted and unhinted */ /* right side bearing while auto-hinting is */ /* active. Zero otherwise. */ /* */ /* <Note> */ /* If @FT_Load_Glyph is called with default flags (see */ /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ /* its native format (e.g., an outline glyph for TrueType and Type~1 */ /* formats). [Since 2.9] The prospective bitmap metrics are */ /* calculated according to @FT_LOAD_TARGET_XXX and other flags even */ /* for the outline glyph, even if @FT_LOAD_RENDER is not set. */ /* */ /* This image can later be converted into a bitmap by calling */ /* @FT_Render_Glyph. This function searches the current renderer for */ /* the native image's format, then invokes it. */ /* */ /* The renderer is in charge of transforming the native image through */ /* the slot's face transformation fields, then converting it into a */ /* bitmap that is returned in `slot->bitmap'. */ /* */ /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ /* to specify the position of the bitmap relative to the current pen */ /* position (e.g., coordinates (0,0) on the baseline). Of course, */ /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ /* */ /* Here is a small pseudo code fragment that shows how to use */ /* `lsb_delta' and `rsb_delta' to do fractional positioning of */ /* glyphs: */ /* */ /* { */ /* FT_GlyphSlot slot = face->glyph; */ /* FT_Pos origin_x = 0; */ /* */ /* */ /* for all glyphs do */ /* <load glyph with `FT_Load_Glyph'> */ /* */ /* FT_Outline_Translate( slot->outline, origin_x & 63, 0 ); */ /* */ /* <save glyph image, or render glyph, or ...> */ /* */ /* <compute kern between current and next glyph */ /* and add it to `origin_x'> */ /* */ /* origin_x += slot->advance.x; */ /* origin_x += slot->rsb_delta - slot->lsb_delta; */ /* endfor */ /* } */ /* */ /* Here is another small pseudo code fragment that shows how to use */ /* `lsb_delta' and `rsb_delta' to improve integer positioning of */ /* glyphs: */ /* */ /* { */ /* FT_GlyphSlot slot = face->glyph; */ /* FT_Pos origin_x = 0; */ /* FT_Pos prev_rsb_delta = 0; */ /* */ /* */ /* for all glyphs do */ /* <compute kern between current and previous glyph */ /* and add it to `origin_x'> */ /* */ /* <load glyph with `FT_Load_Glyph'> */ /* */ /* if ( prev_rsb_delta - slot->lsb_delta > 32 ) */ /* origin_x -= 64; */ /* else if ( prev_rsb_delta - slot->lsb_delta < -31 ) */ /* origin_x += 64; */ /* */ /* prev_rsb_delta = slot->rsb_delta; */ /* */ /* <save glyph image, or render glyph, or ...> */ /* */ /* origin_x += slot->advance.x; */ /* endfor */ /* } */ /* */ /* If you use strong auto-hinting, you *must* apply these delta */ /* values! Otherwise you will experience far too large inter-glyph */ /* spacing at small rendering sizes in most cases. Note that it */ /* doesn't harm to use the above code for other hinting modes also, */ /* since the delta values are zero then. */ /* */ typedef struct FT_GlyphSlotRec_ { FT_Library library; FT_Face face; FT_GlyphSlot next; FT_UInt reserved; /* retained for binary compatibility */ FT_Generic generic; FT_Glyph_Metrics metrics; FT_Fixed linearHoriAdvance; FT_Fixed linearVertAdvance; FT_Vector advance; FT_Glyph_Format format; FT_Bitmap bitmap; FT_Int bitmap_left; FT_Int bitmap_top; FT_Outline outline; FT_UInt num_subglyphs; FT_SubGlyph subglyphs; void* control_data; long control_len; FT_Pos lsb_delta; FT_Pos rsb_delta; void* other; FT_Slot_Internal internal; } FT_GlyphSlotRec; /*************************************************************************/ /*************************************************************************/ /* */ /* F U N C T I O N S */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_Init_FreeType */ /* */ /* <Description> */ /* Initialize a new FreeType library object. The set of modules */ /* that are registered by this function is determined at build time. */ /* */ /* <Output> */ /* alibrary :: A handle to a new library object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* In case you want to provide your own memory allocating routines, */ /* use @FT_New_Library instead, followed by a call to */ /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module) */ /* and @FT_Set_Default_Properties. */ /* */ /* See the documentation of @FT_Library and @FT_Face for */ /* multi-threading issues. */ /* */ /* If you need reference-counting (cf. @FT_Reference_Library), use */ /* @FT_New_Library and @FT_Done_Library. */ /* */ /* If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is */ /* set, this function reads the `FREETYPE_PROPERTIES' environment */ /* variable to control driver properties. See section @properties */ /* for more. */ /* */ FT_EXPORT( FT_Error ) FT_Init_FreeType( FT_Library *alibrary ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Done_FreeType */ /* */ /* <Description> */ /* Destroy a given FreeType library object and all of its children, */ /* including resources, drivers, faces, sizes, etc. */ /* */ /* <Input> */ /* library :: A handle to the target library object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_FreeType( FT_Library library ); /*************************************************************************/ /* */ /* <Enum> */ /* FT_OPEN_XXX */ /* */ /* <Description> */ /* A list of bit field constants used within the `flags' field of the */ /* @FT_Open_Args structure. */ /* */ /* <Values> */ /* FT_OPEN_MEMORY :: This is a memory-based stream. */ /* */ /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ /* */ /* FT_OPEN_PATHNAME :: Create a new input stream from a C~path */ /* name. */ /* */ /* FT_OPEN_DRIVER :: Use the `driver' field. */ /* */ /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ /* */ /* <Note> */ /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ /* flags are mutually exclusive. */ /* */ #define FT_OPEN_MEMORY 0x1 #define FT_OPEN_STREAM 0x2 #define FT_OPEN_PATHNAME 0x4 #define FT_OPEN_DRIVER 0x8 #define FT_OPEN_PARAMS 0x10 /* these constants are deprecated; use the corresponding `FT_OPEN_XXX' */ /* values instead */ #define ft_open_memory FT_OPEN_MEMORY #define ft_open_stream FT_OPEN_STREAM #define ft_open_pathname FT_OPEN_PATHNAME #define ft_open_driver FT_OPEN_DRIVER #define ft_open_params FT_OPEN_PARAMS /*************************************************************************/ /* */ /* <Struct> */ /* FT_Parameter */ /* */ /* <Description> */ /* A simple structure to pass more or less generic parameters to */ /* @FT_Open_Face and @FT_Face_Properties. */ /* */ /* <Fields> */ /* tag :: A four-byte identification tag. */ /* */ /* data :: A pointer to the parameter data. */ /* */ /* <Note> */ /* The ID and function of parameters are driver-specific. See */ /* section @parameter_tags for more information. */ /* */ typedef struct FT_Parameter_ { FT_ULong tag; FT_Pointer data; } FT_Parameter; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Open_Args */ /* */ /* <Description> */ /* A structure to indicate how to open a new font file or stream. A */ /* pointer to such a structure can be used as a parameter for the */ /* functions @FT_Open_Face and @FT_Attach_Stream. */ /* */ /* <Fields> */ /* flags :: A set of bit flags indicating how to use the */ /* structure. */ /* */ /* memory_base :: The first byte of the file in memory. */ /* */ /* memory_size :: The size in bytes of the file in memory. */ /* */ /* pathname :: A pointer to an 8-bit file pathname. */ /* */ /* stream :: A handle to a source stream object. */ /* */ /* driver :: This field is exclusively used by @FT_Open_Face; */ /* it simply specifies the font driver to use for */ /* opening the face. If set to NULL, FreeType tries */ /* to load the face with each one of the drivers in */ /* its list. */ /* */ /* num_params :: The number of extra parameters. */ /* */ /* params :: Extra parameters passed to the font driver when */ /* opening a new face. */ /* */ /* <Note> */ /* The stream type is determined by the contents of `flags' that */ /* are tested in the following order by @FT_Open_Face: */ /* */ /* If the @FT_OPEN_MEMORY bit is set, assume that this is a */ /* memory file of `memory_size' bytes, located at `memory_address'. */ /* The data are not copied, and the client is responsible for */ /* releasing and destroying them _after_ the corresponding call to */ /* @FT_Done_Face. */ /* */ /* Otherwise, if the @FT_OPEN_STREAM bit is set, assume that a */ /* custom input stream `stream' is used. */ /* */ /* Otherwise, if the @FT_OPEN_PATHNAME bit is set, assume that this */ /* is a normal file and use `pathname' to open it. */ /* */ /* If the @FT_OPEN_DRIVER bit is set, @FT_Open_Face only tries to */ /* open the file with the driver whose handler is in `driver'. */ /* */ /* If the @FT_OPEN_PARAMS bit is set, the parameters given by */ /* `num_params' and `params' is used. They are ignored otherwise. */ /* */ /* Ideally, both the `pathname' and `params' fields should be tagged */ /* as `const'; this is missing for API backward compatibility. In */ /* other words, applications should treat them as read-only. */ /* */ typedef struct FT_Open_Args_ { FT_UInt flags; const FT_Byte* memory_base; FT_Long memory_size; FT_String* pathname; FT_Stream stream; FT_Module driver; FT_Int num_params; FT_Parameter* params; } FT_Open_Args; /*************************************************************************/ /* */ /* <Function> */ /* FT_New_Face */ /* */ /* <Description> */ /* Call @FT_Open_Face to open a font by its pathname. */ /* */ /* <InOut> */ /* library :: A handle to the library resource. */ /* */ /* <Input> */ /* pathname :: A path to the font file. */ /* */ /* face_index :: See @FT_Open_Face for a detailed description of this */ /* parameter. */ /* */ /* <Output> */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* Use @FT_Done_Face to destroy the created @FT_Face object (along */ /* with its slot and sizes). */ /* */ FT_EXPORT( FT_Error ) FT_New_Face( FT_Library library, const char* filepathname, FT_Long face_index, FT_Face *aface ); /*************************************************************************/ /* */ /* <Function> */ /* FT_New_Memory_Face */ /* */ /* <Description> */ /* Call @FT_Open_Face to open a font that has been loaded into */ /* memory. */ /* */ /* <InOut> */ /* library :: A handle to the library resource. */ /* */ /* <Input> */ /* file_base :: A pointer to the beginning of the font data. */ /* */ /* file_size :: The size of the memory chunk used by the font data. */ /* */ /* face_index :: See @FT_Open_Face for a detailed description of this */ /* parameter. */ /* */ /* <Output> */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* You must not deallocate the memory before calling @FT_Done_Face. */ /* */ FT_EXPORT( FT_Error ) FT_New_Memory_Face( FT_Library library, const FT_Byte* file_base, FT_Long file_size, FT_Long face_index, FT_Face *aface ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Open_Face */ /* */ /* <Description> */ /* Create a face object from a given resource described by */ /* @FT_Open_Args. */ /* */ /* <InOut> */ /* library :: A handle to the library resource. */ /* */ /* <Input> */ /* args :: A pointer to an `FT_Open_Args' structure that must */ /* be filled by the caller. */ /* */ /* face_index :: This field holds two different values. Bits 0-15 */ /* are the index of the face in the font file (starting */ /* with value~0). Set it to~0 if there is only one */ /* face in the font file. */ /* */ /* [Since 2.6.1] Bits 16-30 are relevant to GX and */ /* OpenType variation fonts only, specifying the named */ /* instance index for the current face index (starting */ /* with value~1; value~0 makes FreeType ignore named */ /* instances). For non-variation fonts, bits 16-30 are */ /* ignored. Assuming that you want to access the third */ /* named instance in face~4, `face_index' should be set */ /* to 0x00030004. If you want to access face~4 without */ /* variation handling, simply set `face_index' to */ /* value~4. */ /* */ /* `FT_Open_Face' and its siblings can be used to */ /* quickly check whether the font format of a given */ /* font resource is supported by FreeType. In general, */ /* if the `face_index' argument is negative, the */ /* function's return value is~0 if the font format is */ /* recognized, or non-zero otherwise. The function */ /* allocates a more or less empty face handle in */ /* `*aface' (if `aface' isn't NULL); the only two */ /* useful fields in this special case are */ /* `face->num_faces' and `face->style_flags'. For any */ /* negative value of `face_index', `face->num_faces' */ /* gives the number of faces within the font file. For */ /* the negative value `-(N+1)' (with `N' a non-negative */ /* 16-bit value), bits 16-30 in `face->style_flags' */ /* give the number of named instances in face `N' if we */ /* have a variation font (or zero otherwise). After */ /* examination, the returned @FT_Face structure should */ /* be deallocated with a call to @FT_Done_Face. */ /* */ /* <Output> */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* Unlike FreeType 1.x, this function automatically creates a glyph */ /* slot for the face object that can be accessed directly through */ /* `face->glyph'. */ /* */ /* Each new face object created with this function also owns a */ /* default @FT_Size object, accessible as `face->size'. */ /* */ /* One @FT_Library instance can have multiple face objects, this is, */ /* @FT_Open_Face and its siblings can be called multiple times using */ /* the same `library' argument. */ /* */ /* See the discussion of reference counters in the description of */ /* @FT_Reference_Face. */ /* */ /* To loop over all faces, use code similar to the following snippet */ /* (omitting the error handling). */ /* */ /* { */ /* ... */ /* FT_Face face; */ /* FT_Long i, num_faces; */ /* */ /* */ /* error = FT_Open_Face( library, args, -1, &face ); */ /* if ( error ) { ... } */ /* */ /* num_faces = face->num_faces; */ /* FT_Done_Face( face ); */ /* */ /* for ( i = 0; i < num_faces; i++ ) */ /* { */ /* ... */ /* error = FT_Open_Face( library, args, i, &face ); */ /* ... */ /* FT_Done_Face( face ); */ /* ... */ /* } */ /* } */ /* */ /* To loop over all valid values for `face_index', use something */ /* similar to the following snippet, again without error handling. */ /* The code accesses all faces immediately (thus only a single call */ /* of `FT_Open_Face' within the do-loop), with and without named */ /* instances. */ /* */ /* { */ /* ... */ /* FT_Face face; */ /* */ /* FT_Long num_faces = 0; */ /* FT_Long num_instances = 0; */ /* */ /* FT_Long face_idx = 0; */ /* FT_Long instance_idx = 0; */ /* */ /* */ /* do */ /* { */ /* FT_Long id = ( instance_idx << 16 ) + face_idx; */ /* */ /* */ /* error = FT_Open_Face( library, args, id, &face ); */ /* if ( error ) { ... } */ /* */ /* num_faces = face->num_faces; */ /* num_instances = face->style_flags >> 16; */ /* */ /* ... */ /* */ /* FT_Done_Face( face ); */ /* */ /* if ( instance_idx < num_instances ) */ /* instance_idx++; */ /* else */ /* { */ /* face_idx++; */ /* instance_idx = 0; */ /* } */ /* */ /* } while ( face_idx < num_faces ) */ /* } */ /* */ FT_EXPORT( FT_Error ) FT_Open_Face( FT_Library library, const FT_Open_Args* args, FT_Long face_index, FT_Face *aface ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Attach_File */ /* */ /* <Description> */ /* Call @FT_Attach_Stream to attach a file. */ /* */ /* <InOut> */ /* face :: The target face object. */ /* */ /* <Input> */ /* filepathname :: The pathname. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FT_Attach_File( FT_Face face, const char* filepathname ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Attach_Stream */ /* */ /* <Description> */ /* `Attach' data to a face object. Normally, this is used to read */ /* additional information for the face object. For example, you can */ /* attach an AFM file that comes with a Type~1 font to get the */ /* kerning values and other metrics. */ /* */ /* <InOut> */ /* face :: The target face object. */ /* */ /* <Input> */ /* parameters :: A pointer to @FT_Open_Args that must be filled by */ /* the caller. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The meaning of the `attach' (i.e., what really happens when the */ /* new file is read) is not fixed by FreeType itself. It really */ /* depends on the font format (and thus the font driver). */ /* */ /* Client applications are expected to know what they are doing */ /* when invoking this function. Most drivers simply do not implement */ /* file or stream attachments. */ /* */ FT_EXPORT( FT_Error ) FT_Attach_Stream( FT_Face face, FT_Open_Args* parameters ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Reference_Face */ /* */ /* <Description> */ /* A counter gets initialized to~1 at the time an @FT_Face structure */ /* is created. This function increments the counter. @FT_Done_Face */ /* then only destroys a face if the counter is~1, otherwise it simply */ /* decrements the counter. */ /* */ /* This function helps in managing life-cycles of structures that */ /* reference @FT_Face objects. */ /* */ /* <Input> */ /* face :: A handle to a target face object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Since> */ /* 2.4.2 */ /* */ FT_EXPORT( FT_Error ) FT_Reference_Face( FT_Face face ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Done_Face */ /* */ /* <Description> */ /* Discard a given face object, as well as all of its child slots and */ /* sizes. */ /* */ /* <Input> */ /* face :: A handle to a target face object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* See the discussion of reference counters in the description of */ /* @FT_Reference_Face. */ /* */ FT_EXPORT( FT_Error ) FT_Done_Face( FT_Face face ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Select_Size */ /* */ /* <Description> */ /* Select a bitmap strike. To be more precise, this function sets */ /* the scaling factors of the active @FT_Size object in a face so */ /* that bitmaps from this particular strike are taken by */ /* @FT_Load_Glyph and friends. */ /* */ /* <InOut> */ /* face :: A handle to a target face object. */ /* */ /* <Input> */ /* strike_index :: The index of the bitmap strike in the */ /* `available_sizes' field of @FT_FaceRec structure. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* For bitmaps embedded in outline fonts it is common that only a */ /* subset of the available glyphs at a given ppem value is available. */ /* FreeType silently uses outlines if there is no bitmap for a given */ /* glyph index. */ /* */ /* For GX and OpenType variation fonts, a bitmap strike makes sense */ /* only if the default instance is active (this is, no glyph */ /* variation takes place); otherwise, FreeType simply ignores bitmap */ /* strikes. The same is true for all named instances that are */ /* different from the default instance. */ /* */ /* Don't use this function if you are using the FreeType cache API. */ /* */ FT_EXPORT( FT_Error ) FT_Select_Size( FT_Face face, FT_Int strike_index ); /*************************************************************************/ /* */ /* <Enum> */ /* FT_Size_Request_Type */ /* */ /* <Description> */ /* An enumeration type that lists the supported size request types, */ /* i.e., what input size (in font units) maps to the requested output */ /* size (in pixels, as computed from the arguments of */ /* @FT_Size_Request). */ /* */ /* <Values> */ /* FT_SIZE_REQUEST_TYPE_NOMINAL :: */ /* The nominal size. The `units_per_EM' field of @FT_FaceRec is */ /* used to determine both scaling values. */ /* */ /* This is the standard scaling found in most applications. In */ /* particular, use this size request type for TrueType fonts if */ /* they provide optical scaling or something similar. Note, */ /* however, that `units_per_EM' is a rather abstract value which */ /* bears no relation to the actual size of the glyphs in a font. */ /* */ /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ /* The real dimension. The sum of the `ascender' and (minus of) */ /* the `descender' fields of @FT_FaceRec is used to determine both */ /* scaling values. */ /* */ /* FT_SIZE_REQUEST_TYPE_BBOX :: */ /* The font bounding box. The width and height of the `bbox' field */ /* of @FT_FaceRec are used to determine the horizontal and vertical */ /* scaling value, respectively. */ /* */ /* FT_SIZE_REQUEST_TYPE_CELL :: */ /* The `max_advance_width' field of @FT_FaceRec is used to */ /* determine the horizontal scaling value; the vertical scaling */ /* value is determined the same way as */ /* @FT_SIZE_REQUEST_TYPE_REAL_DIM does. Finally, both scaling */ /* values are set to the smaller one. This type is useful if you */ /* want to specify the font size for, say, a window of a given */ /* dimension and 80x24 cells. */ /* */ /* FT_SIZE_REQUEST_TYPE_SCALES :: */ /* Specify the scaling values directly. */ /* */ /* <Note> */ /* The above descriptions only apply to scalable formats. For bitmap */ /* formats, the behaviour is up to the driver. */ /* */ /* See the note section of @FT_Size_Metrics if you wonder how size */ /* requesting relates to scaling values. */ /* */ typedef enum FT_Size_Request_Type_ { FT_SIZE_REQUEST_TYPE_NOMINAL, FT_SIZE_REQUEST_TYPE_REAL_DIM, FT_SIZE_REQUEST_TYPE_BBOX, FT_SIZE_REQUEST_TYPE_CELL, FT_SIZE_REQUEST_TYPE_SCALES, FT_SIZE_REQUEST_TYPE_MAX } FT_Size_Request_Type; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Size_RequestRec */ /* */ /* <Description> */ /* A structure to model a size request. */ /* */ /* <Fields> */ /* type :: See @FT_Size_Request_Type. */ /* */ /* width :: The desired width, given as a 26.6 fractional */ /* point value (with 72pt = 1in). */ /* */ /* height :: The desired height, given as a 26.6 fractional */ /* point value (with 72pt = 1in). */ /* */ /* horiResolution :: The horizontal resolution (dpi, i.e., pixels per */ /* inch). If set to zero, `width' is treated as a */ /* 26.6 fractional *pixel* value, which gets */ /* internally rounded to an integer. */ /* */ /* vertResolution :: The vertical resolution (dpi, i.e., pixels per */ /* inch). If set to zero, `height' is treated as a */ /* 26.6 fractional *pixel* value, which gets */ /* internally rounded to an integer. */ /* */ /* <Note> */ /* If `width' is zero, the horizontal scaling value is set equal */ /* to the vertical scaling value, and vice versa. */ /* */ /* If `type' is FT_SIZE_REQUEST_TYPE_SCALES, `width' and `height' are */ /* interpreted directly as 16.16 fractional scaling values, without */ /* any further modification, and both `horiResolution' and */ /* `vertResolution' are ignored. */ /* */ typedef struct FT_Size_RequestRec_ { FT_Size_Request_Type type; FT_Long width; FT_Long height; FT_UInt horiResolution; FT_UInt vertResolution; } FT_Size_RequestRec; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Size_Request */ /* */ /* <Description> */ /* A handle to a size request structure. */ /* */ typedef struct FT_Size_RequestRec_ *FT_Size_Request; /*************************************************************************/ /* */ /* <Function> */ /* FT_Request_Size */ /* */ /* <Description> */ /* Resize the scale of the active @FT_Size object in a face. */ /* */ /* <InOut> */ /* face :: A handle to a target face object. */ /* */ /* <Input> */ /* req :: A pointer to a @FT_Size_RequestRec. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* Although drivers may select the bitmap strike matching the */ /* request, you should not rely on this if you intend to select a */ /* particular bitmap strike. Use @FT_Select_Size instead in that */ /* case. */ /* */ /* The relation between the requested size and the resulting glyph */ /* size is dependent entirely on how the size is defined in the */ /* source face. The font designer chooses the final size of each */ /* glyph relative to this size. For more information refer to */ /* `https://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'. */ /* */ /* Contrary to @FT_Set_Char_Size, this function doesn't have special */ /* code to normalize zero-valued widths, heights, or resolutions */ /* (which lead to errors in most cases). */ /* */ /* Don't use this function if you are using the FreeType cache API. */ /* */ FT_EXPORT( FT_Error ) FT_Request_Size( FT_Face face, FT_Size_Request req ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Char_Size */ /* */ /* <Description> */ /* Call @FT_Request_Size to request the nominal size (in points). */ /* */ /* <InOut> */ /* face :: A handle to a target face object. */ /* */ /* <Input> */ /* char_width :: The nominal width, in 26.6 fractional points. */ /* */ /* char_height :: The nominal height, in 26.6 fractional points. */ /* */ /* horz_resolution :: The horizontal resolution in dpi. */ /* */ /* vert_resolution :: The vertical resolution in dpi. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* While this function allows fractional points as input values, the */ /* resulting ppem value for the given resolution is always rounded to */ /* the nearest integer. */ /* */ /* If either the character width or height is zero, it is set equal */ /* to the other value. */ /* */ /* If either the horizontal or vertical resolution is zero, it is set */ /* equal to the other value. */ /* */ /* A character width or height smaller than 1pt is set to 1pt; if */ /* both resolution values are zero, they are set to 72dpi. */ /* */ /* Don't use this function if you are using the FreeType cache API. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Char_Size( FT_Face face, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Pixel_Sizes */ /* */ /* <Description> */ /* Call @FT_Request_Size to request the nominal size (in pixels). */ /* */ /* <InOut> */ /* face :: A handle to the target face object. */ /* */ /* <Input> */ /* pixel_width :: The nominal width, in pixels. */ /* */ /* pixel_height :: The nominal height, in pixels. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* You should not rely on the resulting glyphs matching or being */ /* constrained to this pixel size. Refer to @FT_Request_Size to */ /* understand how requested sizes relate to actual sizes. */ /* */ /* Don't use this function if you are using the FreeType cache API. */ /* */ FT_EXPORT( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Load_Glyph */ /* */ /* <Description> */ /* Load a glyph into the glyph slot of a face object. */ /* */ /* <InOut> */ /* face :: A handle to the target face object where the glyph */ /* is loaded. */ /* */ /* <Input> */ /* glyph_index :: The index of the glyph in the font file. For */ /* CID-keyed fonts (either in PS or in CFF format) */ /* this argument specifies the CID value. */ /* */ /* load_flags :: A flag indicating what to load for this glyph. The */ /* @FT_LOAD_XXX constants can be used to control the */ /* glyph loading process (e.g., whether the outline */ /* should be scaled, whether to load bitmaps or not, */ /* whether to hint the outline, etc). */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The loaded glyph may be transformed. See @FT_Set_Transform for */ /* the details. */ /* */ /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ /* returned for invalid CID values (this is, for CID values that */ /* don't have a corresponding glyph in the font). See the discussion */ /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ /* */ /* If you receive `FT_Err_Glyph_Too_Big', try getting the glyph */ /* outline at EM size, then scale it manually and fill it as a */ /* graphics operation. */ /* */ FT_EXPORT( FT_Error ) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Load_Char */ /* */ /* <Description> */ /* Load a glyph into the glyph slot of a face object, accessed by its */ /* character code. */ /* */ /* <InOut> */ /* face :: A handle to a target face object where the glyph */ /* is loaded. */ /* */ /* <Input> */ /* char_code :: The glyph's character code, according to the */ /* current charmap used in the face. */ /* */ /* load_flags :: A flag indicating what to load for this glyph. The */ /* @FT_LOAD_XXX constants can be used to control the */ /* glyph loading process (e.g., whether the outline */ /* should be scaled, whether to load bitmaps or not, */ /* whether to hint the outline, etc). */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ /* */ /* Many fonts contain glyphs that can't be loaded by this function */ /* since its glyph indices are not listed in any of the font's */ /* charmaps. */ /* */ /* If no active cmap is set up (i.e., `face->charmap' is zero), the */ /* call to @FT_Get_Char_Index is omitted, and the function behaves */ /* identically to @FT_Load_Glyph. */ /* */ FT_EXPORT( FT_Error ) FT_Load_Char( FT_Face face, FT_ULong char_code, FT_Int32 load_flags ); /************************************************************************* * * @enum: * FT_LOAD_XXX * * @description: * A list of bit field constants for @FT_Load_Glyph to indicate what * kind of operations to perform during glyph loading. * * @values: * FT_LOAD_DEFAULT :: * Corresponding to~0, this value is used as the default glyph load * operation. In this case, the following happens: * * 1. FreeType looks for a bitmap for the glyph corresponding to the * face's current size. If one is found, the function returns. * The bitmap data can be accessed from the glyph slot (see note * below). * * 2. If no embedded bitmap is searched for or found, FreeType looks * for a scalable outline. If one is found, it is loaded from * the font file, scaled to device pixels, then `hinted' to the * pixel grid in order to optimize it. The outline data can be * accessed from the glyph slot (see note below). * * Note that by default the glyph loader doesn't render outlines into * bitmaps. The following flags are used to modify this default * behaviour to more specific and useful cases. * * FT_LOAD_NO_SCALE :: * Don't scale the loaded outline glyph but keep it in font units. * * This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and * unsets @FT_LOAD_RENDER. * * If the font is `tricky' (see @FT_FACE_FLAG_TRICKY for more), using * FT_LOAD_NO_SCALE usually yields meaningless outlines because the * subglyphs must be scaled and positioned with hinting instructions. * This can be solved by loading the font without FT_LOAD_NO_SCALE and * setting the character size to `font->units_per_EM'. * * FT_LOAD_NO_HINTING :: * Disable hinting. This generally generates `blurrier' bitmap glyphs * when the glyph are rendered in any of the anti-aliased modes. See * also the note below. * * This flag is implied by @FT_LOAD_NO_SCALE. * * FT_LOAD_RENDER :: * Call @FT_Render_Glyph after the glyph is loaded. By default, the * glyph is rendered in @FT_RENDER_MODE_NORMAL mode. This can be * overridden by @FT_LOAD_TARGET_XXX or @FT_LOAD_MONOCHROME. * * This flag is unset by @FT_LOAD_NO_SCALE. * * FT_LOAD_NO_BITMAP :: * Ignore bitmap strikes when loading. Bitmap-only fonts ignore this * flag. * * @FT_LOAD_NO_SCALE always sets this flag. * * FT_LOAD_VERTICAL_LAYOUT :: * Load the glyph for vertical text layout. In particular, the * `advance' value in the @FT_GlyphSlotRec structure is set to the * `vertAdvance' value of the `metrics' field. * * In case @FT_HAS_VERTICAL doesn't return true, you shouldn't use * this flag currently. Reason is that in this case vertical metrics * get synthesized, and those values are not always consistent across * various font formats. * * FT_LOAD_FORCE_AUTOHINT :: * Prefer the auto-hinter over the font's native hinter. See also * the note below. * * FT_LOAD_PEDANTIC :: * Make the font driver perform pedantic verifications during glyph * loading. This is mostly used to detect broken glyphs in fonts. * By default, FreeType tries to handle broken fonts also. * * In particular, errors from the TrueType bytecode engine are not * passed to the application if this flag is not set; this might * result in partially hinted or distorted glyphs in case a glyph's * bytecode is buggy. * * FT_LOAD_NO_RECURSE :: * Don't load composite glyphs recursively. Instead, the font * driver should set the `num_subglyph' and `subglyphs' values of * the glyph slot accordingly, and set `glyph->format' to * @FT_GLYPH_FORMAT_COMPOSITE. The description of subglyphs can * then be accessed with @FT_Get_SubGlyph_Info. * * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. * * FT_LOAD_IGNORE_TRANSFORM :: * Ignore the transform matrix set by @FT_Set_Transform. * * FT_LOAD_MONOCHROME :: * This flag is used with @FT_LOAD_RENDER to indicate that you want to * render an outline glyph to a 1-bit monochrome bitmap glyph, with * 8~pixels packed into each byte of the bitmap data. * * Note that this has no effect on the hinting algorithm used. You * should rather use @FT_LOAD_TARGET_MONO so that the * monochrome-optimized hinting algorithm is used. * * FT_LOAD_LINEAR_DESIGN :: * Keep `linearHoriAdvance' and `linearVertAdvance' fields of * @FT_GlyphSlotRec in font units. See @FT_GlyphSlotRec for * details. * * FT_LOAD_NO_AUTOHINT :: * Disable the auto-hinter. See also the note below. * * FT_LOAD_COLOR :: * [Since 2.5] Load embedded color bitmap images. The resulting color * bitmaps, if available, will have the @FT_PIXEL_MODE_BGRA format. * If the flag is not set and color bitmaps are found, they are * converted to 256-level gray bitmaps transparently, using the * @FT_PIXEL_MODE_GRAY format. * * FT_LOAD_COMPUTE_METRICS :: * [Since 2.6.1] Compute glyph metrics from the glyph data, without * the use of bundled metrics tables (for example, the `hdmx' table in * TrueType fonts). This flag is mainly used by font validating or * font editing applications, which need to ignore, verify, or edit * those tables. * * Currently, this flag is only implemented for TrueType fonts. * * FT_LOAD_BITMAP_METRICS_ONLY :: * [Since 2.7.1] Request loading of the metrics and bitmap image * information of a (possibly embedded) bitmap glyph without * allocating or copying the bitmap image data itself. No effect if * the target glyph is not a bitmap image. * * This flag unsets @FT_LOAD_RENDER. * * FT_LOAD_CROP_BITMAP :: * Ignored. Deprecated. * * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: * Ignored. Deprecated. * * @note: * By default, hinting is enabled and the font's native hinter (see * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can * disable hinting by setting @FT_LOAD_NO_HINTING or change the * precedence by setting @FT_LOAD_FORCE_AUTOHINT. You can also set * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be * used at all. * * See the description of @FT_FACE_FLAG_TRICKY for a special exception * (affecting only a handful of Asian fonts). * * Besides deciding which hinter to use, you can also decide which * hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details. * * Note that the auto-hinter needs a valid Unicode cmap (either a native * one or synthesized by FreeType) for producing correct results. If a * font provides an incorrect mapping (for example, assigning the * character code U+005A, LATIN CAPITAL LETTER Z, to a glyph depicting a * mathematical integral sign), the auto-hinter might produce useless * results. * */ #define FT_LOAD_DEFAULT 0x0 #define FT_LOAD_NO_SCALE ( 1L << 0 ) #define FT_LOAD_NO_HINTING ( 1L << 1 ) #define FT_LOAD_RENDER ( 1L << 2 ) #define FT_LOAD_NO_BITMAP ( 1L << 3 ) #define FT_LOAD_VERTICAL_LAYOUT ( 1L << 4 ) #define FT_LOAD_FORCE_AUTOHINT ( 1L << 5 ) #define FT_LOAD_CROP_BITMAP ( 1L << 6 ) #define FT_LOAD_PEDANTIC ( 1L << 7 ) #define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ( 1L << 9 ) #define FT_LOAD_NO_RECURSE ( 1L << 10 ) #define FT_LOAD_IGNORE_TRANSFORM ( 1L << 11 ) #define FT_LOAD_MONOCHROME ( 1L << 12 ) #define FT_LOAD_LINEAR_DESIGN ( 1L << 13 ) #define FT_LOAD_NO_AUTOHINT ( 1L << 15 ) /* Bits 16-19 are used by `FT_LOAD_TARGET_' */ #define FT_LOAD_COLOR ( 1L << 20 ) #define FT_LOAD_COMPUTE_METRICS ( 1L << 21 ) #define FT_LOAD_BITMAP_METRICS_ONLY ( 1L << 22 ) /* */ /* used internally only by certain font drivers */ #define FT_LOAD_ADVANCE_ONLY ( 1L << 8 ) #define FT_LOAD_SBITS_ONLY ( 1L << 14 ) /************************************************************************** * * @enum: * FT_LOAD_TARGET_XXX * * @description: * A list of values to select a specific hinting algorithm for the * hinter. You should OR one of these values to your `load_flags' * when calling @FT_Load_Glyph. * * Note that a font's native hinters may ignore the hinting algorithm * you have specified (e.g., the TrueType bytecode interpreter). You * can set @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is * used. * * @values: * FT_LOAD_TARGET_NORMAL :: * The default hinting algorithm, optimized for standard gray-level * rendering. For monochrome output, use @FT_LOAD_TARGET_MONO * instead. * * FT_LOAD_TARGET_LIGHT :: * A lighter hinting algorithm for gray-level modes. Many generated * glyphs are fuzzier but better resemble their original shape. This * is achieved by snapping glyphs to the pixel grid only vertically * (Y-axis), as is done by FreeType's new CFF engine or Microsoft's * ClearType font renderer. This preserves inter-glyph spacing in * horizontal text. The snapping is done either by the native font * driver, if the driver itself and the font support it, or by the * auto-hinter. * * Advance widths are rounded to integer values; however, using the * `lsb_delta' and `rsb_delta' fields of @FT_GlyphSlotRec, it is * possible to get fractional advance widths for subpixel positioning * (which is recommended to use). * * If configuration option AF_CONFIG_OPTION_TT_SIZE_METRICS is active, * TrueType-like metrics are used to make this mode behave similarly * as in unpatched FreeType versions between 2.4.6 and 2.7.1 * (inclusive). * * FT_LOAD_TARGET_MONO :: * Strong hinting algorithm that should only be used for monochrome * output. The result is probably unpleasant if the glyph is rendered * in non-monochrome modes. * * FT_LOAD_TARGET_LCD :: * A variant of @FT_LOAD_TARGET_LIGHT optimized for horizontally * decimated LCD displays. * * FT_LOAD_TARGET_LCD_V :: * A variant of @FT_LOAD_TARGET_NORMAL optimized for vertically * decimated LCD displays. * * @note: * You should use only _one_ of the FT_LOAD_TARGET_XXX values in your * `load_flags'. They can't be ORed. * * If @FT_LOAD_RENDER is also set, the glyph is rendered in the * corresponding mode (i.e., the mode that matches the used algorithm * best). An exception is FT_LOAD_TARGET_MONO since it implies * @FT_LOAD_MONOCHROME. * * You can use a hinting algorithm that doesn't correspond to the same * rendering mode. As an example, it is possible to use the `light' * hinting algorithm and have the results rendered in horizontal LCD * pixel mode, with code like * * { * FT_Load_Glyph( face, glyph_index, * load_flags | FT_LOAD_TARGET_LIGHT ); * * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); * } * * In general, you should stick with one rendering mode. For example, * switching between @FT_LOAD_TARGET_NORMAL and @FT_LOAD_TARGET_MONO * enforces a lot of recomputation for TrueType fonts, which is slow. * Another reason is caching: Selecting a different mode usually causes * changes in both the outlines and the rasterized bitmaps; it is thus * necessary to empty the cache after a mode switch to avoid false hits. * */ #define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) #define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) #define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) #define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) #define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) #define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) /************************************************************************** * * @macro: * FT_LOAD_TARGET_MODE * * @description: * Return the @FT_Render_Mode corresponding to a given * @FT_LOAD_TARGET_XXX value. * */ #define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Transform */ /* */ /* <Description> */ /* Set the transformation that is applied to glyph images when they */ /* are loaded into a glyph slot through @FT_Load_Glyph. */ /* */ /* <InOut> */ /* face :: A handle to the source face object. */ /* */ /* <Input> */ /* matrix :: A pointer to the transformation's 2x2 matrix. Use NULL */ /* for the identity matrix. */ /* delta :: A pointer to the translation vector. Use NULL for the */ /* null vector. */ /* */ /* <Note> */ /* The transformation is only applied to scalable image formats after */ /* the glyph has been loaded. It means that hinting is unaltered by */ /* the transformation and is performed on the character size given in */ /* the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes. */ /* */ /* Note that this also transforms the `face.glyph.advance' field, but */ /* *not* the values in `face.glyph.metrics'. */ /* */ FT_EXPORT( void ) FT_Set_Transform( FT_Face face, FT_Matrix* matrix, FT_Vector* delta ); /*************************************************************************/ /* */ /* <Enum> */ /* FT_Render_Mode */ /* */ /* <Description> */ /* Render modes supported by FreeType~2. Each mode corresponds to a */ /* specific type of scanline conversion performed on the outline. */ /* */ /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ /* field in the @FT_GlyphSlotRec structure gives the format of the */ /* returned bitmap. */ /* */ /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity, */ /* indicating pixel coverage. Use linear alpha blending and gamma */ /* correction to correctly render non-monochrome glyph bitmaps onto a */ /* surface; see @FT_Render_Glyph. */ /* */ /* <Values> */ /* FT_RENDER_MODE_NORMAL :: */ /* Default render mode; it corresponds to 8-bit anti-aliased */ /* bitmaps. */ /* */ /* FT_RENDER_MODE_LIGHT :: */ /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ /* defined as a separate value because render modes are also used */ /* indirectly to define hinting algorithm selectors. See */ /* @FT_LOAD_TARGET_XXX for details. */ /* */ /* FT_RENDER_MODE_MONO :: */ /* This mode corresponds to 1-bit bitmaps (with 2~levels of */ /* opacity). */ /* */ /* FT_RENDER_MODE_LCD :: */ /* This mode corresponds to horizontal RGB and BGR subpixel */ /* displays like LCD screens. It produces 8-bit bitmaps that are */ /* 3~times the width of the original glyph outline in pixels, and */ /* which use the @FT_PIXEL_MODE_LCD mode. */ /* */ /* FT_RENDER_MODE_LCD_V :: */ /* This mode corresponds to vertical RGB and BGR subpixel displays */ /* (like PDA screens, rotated LCD displays, etc.). It produces */ /* 8-bit bitmaps that are 3~times the height of the original */ /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ /* */ /* <Note> */ /* Should you define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your */ /* `ftoption.h', which enables patented ClearType-style rendering, */ /* the LCD-optimized glyph bitmaps should be filtered to reduce color */ /* fringes inherent to this technology. You can either set up LCD */ /* filtering with @FT_Library_SetLcdFilter or @FT_Face_Properties, */ /* or do the filtering yourself. The default FreeType LCD rendering */ /* technology does not require filtering. */ /* */ /* The selected render mode only affects vector glyphs of a font. */ /* Embedded bitmaps often have a different pixel mode like */ /* @FT_PIXEL_MODE_MONO. You can use @FT_Bitmap_Convert to transform */ /* them into 8-bit pixmaps. */ /* */ typedef enum FT_Render_Mode_ { FT_RENDER_MODE_NORMAL = 0, FT_RENDER_MODE_LIGHT, FT_RENDER_MODE_MONO, FT_RENDER_MODE_LCD, FT_RENDER_MODE_LCD_V, FT_RENDER_MODE_MAX } FT_Render_Mode; /* these constants are deprecated; use the corresponding */ /* `FT_Render_Mode' values instead */ #define ft_render_mode_normal FT_RENDER_MODE_NORMAL #define ft_render_mode_mono FT_RENDER_MODE_MONO /*************************************************************************/ /* */ /* <Function> */ /* FT_Render_Glyph */ /* */ /* <Description> */ /* Convert a given glyph image to a bitmap. It does so by inspecting */ /* the glyph image format, finding the relevant renderer, and */ /* invoking it. */ /* */ /* <InOut> */ /* slot :: A handle to the glyph slot containing the image to */ /* convert. */ /* */ /* <Input> */ /* render_mode :: The render mode used to render the glyph image into */ /* a bitmap. See @FT_Render_Mode for a list of */ /* possible values. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* To get meaningful results, font scaling values must be set with */ /* functions like @FT_Set_Char_Size before calling `FT_Render_Glyph'. */ /* */ /* When FreeType outputs a bitmap of a glyph, it really outputs an */ /* alpha coverage map. If a pixel is completely covered by a */ /* filled-in outline, the bitmap contains 0xFF at that pixel, meaning */ /* that 0xFF/0xFF fraction of that pixel is covered, meaning the */ /* pixel is 100% black (or 0% bright). If a pixel is only 50% */ /* covered (value 0x80), the pixel is made 50% black (50% bright or a */ /* middle shade of grey). 0% covered means 0% black (100% bright or */ /* white). */ /* */ /* On high-DPI screens like on smartphones and tablets, the pixels */ /* are so small that their chance of being completely covered and */ /* therefore completely black are fairly good. On the low-DPI */ /* screens, however, the situation is different. The pixels are too */ /* large for most of the details of a glyph and shades of gray are */ /* the norm rather than the exception. */ /* */ /* This is relevant because all our screens have a second problem: */ /* they are not linear. 1~+~1 is not~2. Twice the value does not */ /* result in twice the brightness. When a pixel is only 50% covered, */ /* the coverage map says 50% black, and this translates to a pixel */ /* value of 128 when you use 8~bits per channel (0-255). However, */ /* this does not translate to 50% brightness for that pixel on our */ /* sRGB and gamma~2.2 screens. Due to their non-linearity, they */ /* dwell longer in the darks and only a pixel value of about 186 */ /* results in 50% brightness -- 128 ends up too dark on both bright */ /* and dark backgrounds. The net result is that dark text looks */ /* burnt-out, pixely and blotchy on bright background, bright text */ /* too frail on dark backgrounds, and colored text on colored */ /* background (for example, red on green) seems to have dark halos or */ /* `dirt' around it. The situation is especially ugly for diagonal */ /* stems like in `w' glyph shapes where the quality of FreeType's */ /* anti-aliasing depends on the correct display of grays. On */ /* high-DPI screens where smaller, fully black pixels reign supreme, */ /* this doesn't matter, but on our low-DPI screens with all the gray */ /* shades, it does. 0% and 100% brightness are the same things in */ /* linear and non-linear space, just all the shades in-between */ /* aren't. */ /* */ /* The blending function for placing text over a background is */ /* */ /* { */ /* dst = alpha * src + (1 - alpha) * dst , */ /* } */ /* */ /* which is known as the OVER operator. */ /* */ /* To correctly composite an antialiased pixel of a glyph onto a */ /* surface, */ /* */ /* 1. take the foreground and background colors (e.g., in sRGB space) */ /* and apply gamma to get them in a linear space, */ /* */ /* 2. use OVER to blend the two linear colors using the glyph pixel */ /* as the alpha value (remember, the glyph bitmap is an alpha */ /* coverage bitmap), and */ /* */ /* 3. apply inverse gamma to the blended pixel and write it back to */ /* the image. */ /* */ /* Internal testing at Adobe found that a target inverse gamma of~1.8 */ /* for step~3 gives good results across a wide range of displays with */ /* an sRGB gamma curve or a similar one. */ /* */ /* This process can cost performance. There is an approximation that */ /* does not need to know about the background color; see */ /* https://bel.fi/alankila/lcd/ and */ /* https://bel.fi/alankila/lcd/alpcor.html for details. */ /* */ /* *ATTENTION*: Linear blending is even more important when dealing */ /* with subpixel-rendered glyphs to prevent color-fringing! A */ /* subpixel-rendered glyph must first be filtered with a filter that */ /* gives equal weight to the three color primaries and does not */ /* exceed a sum of 0x100, see section @lcd_filtering. Then the */ /* only difference to gray linear blending is that subpixel-rendered */ /* linear blending is done 3~times per pixel: red foreground subpixel */ /* to red background subpixel and so on for green and blue. */ /* */ FT_EXPORT( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, FT_Render_Mode render_mode ); /*************************************************************************/ /* */ /* <Enum> */ /* FT_Kerning_Mode */ /* */ /* <Description> */ /* An enumeration to specify the format of kerning values returned by */ /* @FT_Get_Kerning. */ /* */ /* <Values> */ /* FT_KERNING_DEFAULT :: Return grid-fitted kerning distances in */ /* 26.6 fractional pixels. */ /* */ /* FT_KERNING_UNFITTED :: Return un-grid-fitted kerning distances in */ /* 26.6 fractional pixels. */ /* */ /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ /* units. */ /* */ /* <Note> */ /* FT_KERNING_DEFAULT returns full pixel values; it also makes */ /* FreeType heuristically scale down kerning distances at small ppem */ /* values so that they don't become too big. */ /* */ /* Both FT_KERNING_DEFAULT and FT_KERNING_UNFITTED use the current */ /* horizontal scaling factor (as set e.g. with @FT_Set_Char_Size) to */ /* convert font units to pixels. */ /* */ typedef enum FT_Kerning_Mode_ { FT_KERNING_DEFAULT = 0, FT_KERNING_UNFITTED, FT_KERNING_UNSCALED } FT_Kerning_Mode; /* these constants are deprecated; use the corresponding */ /* `FT_Kerning_Mode' values instead */ #define ft_kerning_default FT_KERNING_DEFAULT #define ft_kerning_unfitted FT_KERNING_UNFITTED #define ft_kerning_unscaled FT_KERNING_UNSCALED /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Kerning */ /* */ /* <Description> */ /* Return the kerning vector between two glyphs of the same face. */ /* */ /* <Input> */ /* face :: A handle to a source face object. */ /* */ /* left_glyph :: The index of the left glyph in the kern pair. */ /* */ /* right_glyph :: The index of the right glyph in the kern pair. */ /* */ /* kern_mode :: See @FT_Kerning_Mode for more information. */ /* Determines the scale and dimension of the returned */ /* kerning vector. */ /* */ /* <Output> */ /* akerning :: The kerning vector. This is either in font units, */ /* fractional pixels (26.6 format), or pixels for */ /* scalable formats, and in pixels for fixed-sizes */ /* formats. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* Only horizontal layouts (left-to-right & right-to-left) are */ /* supported by this method. Other layouts, or more sophisticated */ /* kernings, are out of the scope of this API function -- they can be */ /* implemented through format-specific interfaces. */ /* */ /* Kerning for OpenType fonts implemented in a `GPOS' table is not */ /* supported; use @FT_HAS_KERNING to find out whether a font has data */ /* that can be extracted with `FT_Get_Kerning'. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Kerning( FT_Face face, FT_UInt left_glyph, FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Track_Kerning */ /* */ /* <Description> */ /* Return the track kerning for a given face object at a given size. */ /* */ /* <Input> */ /* face :: A handle to a source face object. */ /* */ /* point_size :: The point size in 16.16 fractional points. */ /* */ /* degree :: The degree of tightness. Increasingly negative */ /* values represent tighter track kerning, while */ /* increasingly positive values represent looser track */ /* kerning. Value zero means no track kerning. */ /* */ /* <Output> */ /* akerning :: The kerning in 16.16 fractional points, to be */ /* uniformly applied between all glyphs. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* Currently, only the Type~1 font driver supports track kerning, */ /* using data from AFM files (if attached with @FT_Attach_File or */ /* @FT_Attach_Stream). */ /* */ /* Only very few AFM files come with track kerning data; please refer */ /* to Adobe's AFM specification for more details. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Track_Kerning( FT_Face face, FT_Fixed point_size, FT_Int degree, FT_Fixed* akerning ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Glyph_Name */ /* */ /* <Description> */ /* Retrieve the ASCII name of a given glyph in a face. This only */ /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. */ /* */ /* <Input> */ /* face :: A handle to a source face object. */ /* */ /* glyph_index :: The glyph index. */ /* */ /* buffer_max :: The maximum number of bytes available in the */ /* buffer. */ /* */ /* <Output> */ /* buffer :: A pointer to a target buffer where the name is */ /* copied to. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* An error is returned if the face doesn't provide glyph names or if */ /* the glyph index is invalid. In all cases of failure, the first */ /* byte of `buffer' is set to~0 to indicate an empty name. */ /* */ /* The glyph name is truncated to fit within the buffer if it is too */ /* long. The returned string is always zero-terminated. */ /* */ /* Be aware that FreeType reorders glyph indices internally so that */ /* glyph index~0 always corresponds to the `missing glyph' (called */ /* `.notdef'). */ /* */ /* This function always returns an error if the config macro */ /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoption.h'. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph_Name( FT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Postscript_Name */ /* */ /* <Description> */ /* Retrieve the ASCII PostScript name of a given face, if available. */ /* This only works with PostScript, TrueType, and OpenType fonts. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ /* */ /* <Return> */ /* A pointer to the face's PostScript name. NULL if unavailable. */ /* */ /* <Note> */ /* The returned pointer is owned by the face and is destroyed with */ /* it. */ /* */ /* For variation fonts, this string changes if you select a different */ /* instance, and you have to call `FT_Get_PostScript_Name' again to */ /* retrieve it. FreeType follows Adobe TechNote #5902, `Generating */ /* PostScript Names for Fonts Using OpenType Font Variations'. */ /* */ /* https://download.macromedia.com/pub/developer/opentype/tech-notes/5902.AdobePSNameGeneration.html */ /* */ /* [Since 2.9] Special PostScript names for named instances are only */ /* returned if the named instance is set with @FT_Set_Named_Instance */ /* (and the font has corresponding entries in its `fvar' table). If */ /* @FT_IS_VARIATION returns true, the algorithmically derived */ /* PostScript name is provided, not looking up special entries for */ /* named instances. */ /* */ FT_EXPORT( const char* ) FT_Get_Postscript_Name( FT_Face face ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Select_Charmap */ /* */ /* <Description> */ /* Select a given charmap by its encoding tag (as listed in */ /* `freetype.h'). */ /* */ /* <InOut> */ /* face :: A handle to the source face object. */ /* */ /* <Input> */ /* encoding :: A handle to the selected encoding. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* This function returns an error if no charmap in the face */ /* corresponds to the encoding queried here. */ /* */ /* Because many fonts contain more than a single cmap for Unicode */ /* encoding, this function has some special code to select the one */ /* that covers Unicode best (`best' in the sense that a UCS-4 cmap is */ /* preferred to a UCS-2 cmap). It is thus preferable to */ /* @FT_Set_Charmap in this case. */ /* */ FT_EXPORT( FT_Error ) FT_Select_Charmap( FT_Face face, FT_Encoding encoding ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Charmap */ /* */ /* <Description> */ /* Select a given charmap for character code to glyph index mapping. */ /* */ /* <InOut> */ /* face :: A handle to the source face object. */ /* */ /* <Input> */ /* charmap :: A handle to the selected charmap. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* This function returns an error if the charmap is not part of */ /* the face (i.e., if it is not listed in the `face->charmaps' */ /* table). */ /* */ /* It also fails if an OpenType type~14 charmap is selected (which */ /* doesn't map character codes to glyph indices at all). */ /* */ FT_EXPORT( FT_Error ) FT_Set_Charmap( FT_Face face, FT_CharMap charmap ); /************************************************************************* * * @function: * FT_Get_Charmap_Index * * @description: * Retrieve index of a given charmap. * * @input: * charmap :: * A handle to a charmap. * * @return: * The index into the array of character maps within the face to which * `charmap' belongs. If an error occurs, -1 is returned. * */ FT_EXPORT( FT_Int ) FT_Get_Charmap_Index( FT_CharMap charmap ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Char_Index */ /* */ /* <Description> */ /* Return the glyph index of a given character code. This function */ /* uses the currently selected charmap to do the mapping. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ /* */ /* charcode :: The character code. */ /* */ /* <Return> */ /* The glyph index. 0~means `undefined character code'. */ /* */ /* <Note> */ /* If you use FreeType to manipulate the contents of font files */ /* directly, be aware that the glyph index returned by this function */ /* doesn't always correspond to the internal indices used within the */ /* file. This is done to ensure that value~0 always corresponds to */ /* the `missing glyph'. If the first glyph is not named `.notdef', */ /* then for Type~1 and Type~42 fonts, `.notdef' will be moved into */ /* the glyph ID~0 position, and whatever was there will be moved to */ /* the position `.notdef' had. For Type~1 fonts, if there is no */ /* `.notdef' glyph at all, then one will be created at index~0 and */ /* whatever was there will be moved to the last index -- Type~42 */ /* fonts are considered invalid under this condition. */ /* */ FT_EXPORT( FT_UInt ) FT_Get_Char_Index( FT_Face face, FT_ULong charcode ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_First_Char */ /* */ /* <Description> */ /* Return the first character code in the current charmap of a given */ /* face, together with its corresponding glyph index. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ /* */ /* <Output> */ /* agindex :: Glyph index of first character code. 0~if charmap is */ /* empty. */ /* */ /* <Return> */ /* The charmap's first character code. */ /* */ /* <Note> */ /* You should use this function together with @FT_Get_Next_Char to */ /* parse all character codes available in a given charmap. The code */ /* should look like this: */ /* */ /* { */ /* FT_ULong charcode; */ /* FT_UInt gindex; */ /* */ /* */ /* charcode = FT_Get_First_Char( face, &gindex ); */ /* while ( gindex != 0 ) */ /* { */ /* ... do something with (charcode,gindex) pair ... */ /* */ /* charcode = FT_Get_Next_Char( face, charcode, &gindex ); */ /* } */ /* } */ /* */ /* Be aware that character codes can have values up to 0xFFFFFFFF; */ /* this might happen for non-Unicode or malformed cmaps. However, */ /* even with regular Unicode encoding, so-called `last resort fonts' */ /* (using SFNT cmap format 13, see function @FT_Get_CMap_Format) */ /* normally have entries for all Unicode characters up to 0x1FFFFF, */ /* which can cause *a lot* of iterations. */ /* */ /* Note that `*agindex' is set to~0 if the charmap is empty. The */ /* result itself can be~0 in two cases: if the charmap is empty or */ /* if the value~0 is the first valid character code. */ /* */ FT_EXPORT( FT_ULong ) FT_Get_First_Char( FT_Face face, FT_UInt *agindex ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Next_Char */ /* */ /* <Description> */ /* Return the next character code in the current charmap of a given */ /* face following the value `char_code', as well as the corresponding */ /* glyph index. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ /* */ /* char_code :: The starting character code. */ /* */ /* <Output> */ /* agindex :: Glyph index of next character code. 0~if charmap */ /* is empty. */ /* */ /* <Return> */ /* The charmap's next character code. */ /* */ /* <Note> */ /* You should use this function with @FT_Get_First_Char to walk */ /* over all character codes available in a given charmap. See the */ /* note for that function for a simple code example. */ /* */ /* Note that `*agindex' is set to~0 when there are no more codes in */ /* the charmap. */ /* */ FT_EXPORT( FT_ULong ) FT_Get_Next_Char( FT_Face face, FT_ULong char_code, FT_UInt *agindex ); /************************************************************************* * * @function: * FT_Face_Properties * * @description: * Set or override certain (library or module-wide) properties on a * face-by-face basis. Useful for finer-grained control and avoiding * locks on shared structures (threads can modify their own faces as * they see fit). * * Contrary to @FT_Property_Set, this function uses @FT_Parameter so * that you can pass multiple properties to the target face in one call. * Note that only a subset of the available properties can be * controlled. * * * @FT_PARAM_TAG_STEM_DARKENING (stem darkening, corresponding to the * property `no-stem-darkening' provided by the `autofit', `cff', * `type1', and `t1cid' modules; see @no-stem-darkening). * * * @FT_PARAM_TAG_LCD_FILTER_WEIGHTS (LCD filter weights, corresponding * to function @FT_Library_SetLcdFilterWeights). * * * @FT_PARAM_TAG_RANDOM_SEED (seed value for the CFF, Type~1, and CID * `random' operator, corresponding to the `random-seed' property * provided by the `cff', `type1', and `t1cid' modules; see * @random-seed). * * Pass NULL as `data' in @FT_Parameter for a given tag to reset the * option and use the library or module default again. * * @input: * face :: * A handle to the source face object. * * num_properties :: * The number of properties that follow. * * properties :: * A handle to an @FT_Parameter array with `num_properties' elements. * * @return: * FreeType error code. 0~means success. * * @note: * Here an example that sets three properties. You must define * FT_CONFIG_OPTION_SUBPIXEL_RENDERING to make the LCD filter examples * work. * * { * FT_Parameter property1; * FT_Bool darken_stems = 1; * * FT_Parameter property2; * FT_LcdFiveTapFilter custom_weight = * { 0x11, 0x44, 0x56, 0x44, 0x11 }; * * FT_Parameter property3; * FT_Int32 random_seed = 314159265; * * FT_Parameter properties[3] = { property1, * property2, * property3 }; * * * property1.tag = FT_PARAM_TAG_STEM_DARKENING; * property1.data = &darken_stems; * * property2.tag = FT_PARAM_TAG_LCD_FILTER_WEIGHTS; * property2.data = custom_weight; * * property3.tag = FT_PARAM_TAG_RANDOM_SEED; * property3.data = &random_seed; * * FT_Face_Properties( face, 3, properties ); * } * * The next example resets a single property to its default value. * * { * FT_Parameter property; * * * property.tag = FT_PARAM_TAG_LCD_FILTER_WEIGHTS; * property.data = NULL; * * FT_Face_Properties( face, 1, &property ); * } * * @since: * 2.8 * */ FT_EXPORT( FT_Error ) FT_Face_Properties( FT_Face face, FT_UInt num_properties, FT_Parameter* properties ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Name_Index */ /* */ /* <Description> */ /* Return the glyph index of a given glyph name. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ /* */ /* glyph_name :: The glyph name. */ /* */ /* <Return> */ /* The glyph index. 0~means `undefined character code'. */ /* */ FT_EXPORT( FT_UInt ) FT_Get_Name_Index( FT_Face face, FT_String* glyph_name ); /************************************************************************* * * @macro: * FT_SUBGLYPH_FLAG_XXX * * @description: * A list of constants describing subglyphs. Please refer to the * `glyf' table description in the OpenType specification for the * meaning of the various flags (which get synthesized for * non-OpenType subglyphs). * * @values: * FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS :: * FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES :: * FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID :: * FT_SUBGLYPH_FLAG_SCALE :: * FT_SUBGLYPH_FLAG_XY_SCALE :: * FT_SUBGLYPH_FLAG_2X2 :: * FT_SUBGLYPH_FLAG_USE_MY_METRICS :: * */ #define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 #define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 #define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 #define FT_SUBGLYPH_FLAG_SCALE 8 #define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 #define FT_SUBGLYPH_FLAG_2X2 0x80 #define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 /************************************************************************* * * @func: * FT_Get_SubGlyph_Info * * @description: * Retrieve a description of a given subglyph. Only use it if * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE; an error is * returned otherwise. * * @input: * glyph :: * The source glyph slot. * * sub_index :: * The index of the subglyph. Must be less than * `glyph->num_subglyphs'. * * @output: * p_index :: * The glyph index of the subglyph. * * p_flags :: * The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX. * * p_arg1 :: * The subglyph's first argument (if any). * * p_arg2 :: * The subglyph's second argument (if any). * * p_transform :: * The subglyph transformation (if any). * * @return: * FreeType error code. 0~means success. * * @note: * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be * interpreted depending on the flags returned in `*p_flags'. See the * OpenType specification for details. * */ FT_EXPORT( FT_Error ) FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, FT_UInt sub_index, FT_Int *p_index, FT_UInt *p_flags, FT_Int *p_arg1, FT_Int *p_arg2, FT_Matrix *p_transform ); /*************************************************************************/ /* */ /* <Enum> */ /* FT_FSTYPE_XXX */ /* */ /* <Description> */ /* A list of bit flags used in the `fsType' field of the OS/2 table */ /* in a TrueType or OpenType font and the `FSType' entry in a */ /* PostScript font. These bit flags are returned by */ /* @FT_Get_FSType_Flags; they inform client applications of embedding */ /* and subsetting restrictions associated with a font. */ /* */ /* See */ /* https://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/FontPolicies.pdf */ /* for more details. */ /* */ /* <Values> */ /* FT_FSTYPE_INSTALLABLE_EMBEDDING :: */ /* Fonts with no fsType bit set may be embedded and permanently */ /* installed on the remote system by an application. */ /* */ /* FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING :: */ /* Fonts that have only this bit set must not be modified, embedded */ /* or exchanged in any manner without first obtaining permission of */ /* the font software copyright owner. */ /* */ /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ /* The font may be embedded and temporarily loaded on the remote */ /* system. Documents containing Preview & Print fonts must be */ /* opened `read-only'; no edits can be applied to the document. */ /* */ /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ /* The font may be embedded but must only be installed temporarily */ /* on other systems. In contrast to Preview & Print fonts, */ /* documents containing editable fonts may be opened for reading, */ /* editing is permitted, and changes may be saved. */ /* */ /* FT_FSTYPE_NO_SUBSETTING :: */ /* The font may not be subsetted prior to embedding. */ /* */ /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ /* Only bitmaps contained in the font may be embedded; no outline */ /* data may be embedded. If there are no bitmaps available in the */ /* font, then the font is unembeddable. */ /* */ /* <Note> */ /* The flags are ORed together, thus more than a single value can be */ /* returned. */ /* */ /* While the `fsType' flags can indicate that a font may be embedded, */ /* a license with the font vendor may be separately required to use */ /* the font in this way. */ /* */ #define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 #define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 #define FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING 0x0004 #define FT_FSTYPE_EDITABLE_EMBEDDING 0x0008 #define FT_FSTYPE_NO_SUBSETTING 0x0100 #define FT_FSTYPE_BITMAP_EMBEDDING_ONLY 0x0200 /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_FSType_Flags */ /* */ /* <Description> */ /* Return the `fsType' flags for a font. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ /* */ /* <Return> */ /* The `fsType' flags, see @FT_FSTYPE_XXX. */ /* */ /* <Note> */ /* Use this function rather than directly reading the `fs_type' field */ /* in the @PS_FontInfoRec structure, which is only guaranteed to */ /* return the correct results for Type~1 fonts. */ /* */ /* <Since> */ /* 2.3.8 */ /* */ FT_EXPORT( FT_UShort ) FT_Get_FSType_Flags( FT_Face face ); /*************************************************************************/ /* */ /* <Section> */ /* glyph_variants */ /* */ /* <Title> */ /* Unicode Variation Sequences */ /* */ /* <Abstract> */ /* The FreeType~2 interface to Unicode Variation Sequences (UVS), */ /* using the SFNT cmap format~14. */ /* */ /* <Description> */ /* Many characters, especially for CJK scripts, have variant forms. */ /* They are a sort of grey area somewhere between being totally */ /* irrelevant and semantically distinct; for this reason, the Unicode */ /* consortium decided to introduce Variation Sequences (VS), */ /* consisting of a Unicode base character and a variation selector */ /* instead of further extending the already huge number of */ /* characters. */ /* */ /* Unicode maintains two different sets, namely `Standardized */ /* Variation Sequences' and registered `Ideographic Variation */ /* Sequences' (IVS), collected in the `Ideographic Variation */ /* Database' (IVD). */ /* */ /* https://unicode.org/Public/UCD/latest/ucd/StandardizedVariants.txt */ /* https://unicode.org/reports/tr37/ */ /* https://unicode.org/ivd/ */ /* */ /* To date (January 2017), the character with the most ideographic */ /* variations is U+9089, having 32 such IVS. */ /* */ /* Three Mongolian Variation Selectors have the values U+180B-U+180D; */ /* 256 generic Variation Selectors are encoded in the ranges */ /* U+FE00-U+FE0F and U+E0100-U+E01EF. IVS currently use Variation */ /* Selectors from the range U+E0100-U+E01EF only. */ /* */ /* A VS consists of the base character value followed by a single */ /* Variation Selector. For example, to get the first variation of */ /* U+9089, you have to write the character sequence `U+9089 U+E0100'. */ /* */ /* Adobe and MS decided to support both standardized and ideographic */ /* VS with a new cmap subtable (format~14). It is an odd subtable */ /* because it is not a mapping of input code points to glyphs, but */ /* contains lists of all variations supported by the font. */ /* */ /* A variation may be either `default' or `non-default' for a given */ /* font. A default variation is the one you will get for that code */ /* point if you look it up in the standard Unicode cmap. A */ /* non-default variation is a different glyph. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_Face_GetCharVariantIndex */ /* */ /* <Description> */ /* Return the glyph index of a given character code as modified by */ /* the variation selector. */ /* */ /* <Input> */ /* face :: */ /* A handle to the source face object. */ /* */ /* charcode :: */ /* The character code point in Unicode. */ /* */ /* variantSelector :: */ /* The Unicode code point of the variation selector. */ /* */ /* <Return> */ /* The glyph index. 0~means either `undefined character code', or */ /* `undefined selector code', or `no variation selector cmap */ /* subtable', or `current CharMap is not Unicode'. */ /* */ /* <Note> */ /* If you use FreeType to manipulate the contents of font files */ /* directly, be aware that the glyph index returned by this function */ /* doesn't always correspond to the internal indices used within */ /* the file. This is done to ensure that value~0 always corresponds */ /* to the `missing glyph'. */ /* */ /* This function is only meaningful if */ /* a) the font has a variation selector cmap sub table, */ /* and */ /* b) the current charmap has a Unicode encoding. */ /* */ /* <Since> */ /* 2.3.6 */ /* */ FT_EXPORT( FT_UInt ) FT_Face_GetCharVariantIndex( FT_Face face, FT_ULong charcode, FT_ULong variantSelector ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Face_GetCharVariantIsDefault */ /* */ /* <Description> */ /* Check whether this variation of this Unicode character is the one */ /* to be found in the `cmap'. */ /* */ /* <Input> */ /* face :: */ /* A handle to the source face object. */ /* */ /* charcode :: */ /* The character codepoint in Unicode. */ /* */ /* variantSelector :: */ /* The Unicode codepoint of the variation selector. */ /* */ /* <Return> */ /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ /* variation selector cmap, or -1 if it is not a variation. */ /* */ /* <Note> */ /* This function is only meaningful if the font has a variation */ /* selector cmap subtable. */ /* */ /* <Since> */ /* 2.3.6 */ /* */ FT_EXPORT( FT_Int ) FT_Face_GetCharVariantIsDefault( FT_Face face, FT_ULong charcode, FT_ULong variantSelector ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Face_GetVariantSelectors */ /* */ /* <Description> */ /* Return a zero-terminated list of Unicode variation selectors found */ /* in the font. */ /* */ /* <Input> */ /* face :: */ /* A handle to the source face object. */ /* */ /* <Return> */ /* A pointer to an array of selector code points, or NULL if there is */ /* no valid variation selector cmap subtable. */ /* */ /* <Note> */ /* The last item in the array is~0; the array is owned by the */ /* @FT_Face object but can be overwritten or released on the next */ /* call to a FreeType function. */ /* */ /* <Since> */ /* 2.3.6 */ /* */ FT_EXPORT( FT_UInt32* ) FT_Face_GetVariantSelectors( FT_Face face ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Face_GetVariantsOfChar */ /* */ /* <Description> */ /* Return a zero-terminated list of Unicode variation selectors found */ /* for the specified character code. */ /* */ /* <Input> */ /* face :: */ /* A handle to the source face object. */ /* */ /* charcode :: */ /* The character codepoint in Unicode. */ /* */ /* <Return> */ /* A pointer to an array of variation selector code points that are */ /* active for the given character, or NULL if the corresponding list */ /* is empty. */ /* */ /* <Note> */ /* The last item in the array is~0; the array is owned by the */ /* @FT_Face object but can be overwritten or released on the next */ /* call to a FreeType function. */ /* */ /* <Since> */ /* 2.3.6 */ /* */ FT_EXPORT( FT_UInt32* ) FT_Face_GetVariantsOfChar( FT_Face face, FT_ULong charcode ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Face_GetCharsOfVariant */ /* */ /* <Description> */ /* Return a zero-terminated list of Unicode character codes found for */ /* the specified variation selector. */ /* */ /* <Input> */ /* face :: */ /* A handle to the source face object. */ /* */ /* variantSelector :: */ /* The variation selector code point in Unicode. */ /* */ /* <Return> */ /* A list of all the code points that are specified by this selector */ /* (both default and non-default codes are returned) or NULL if there */ /* is no valid cmap or the variation selector is invalid. */ /* */ /* <Note> */ /* The last item in the array is~0; the array is owned by the */ /* @FT_Face object but can be overwritten or released on the next */ /* call to a FreeType function. */ /* */ /* <Since> */ /* 2.3.6 */ /* */ FT_EXPORT( FT_UInt32* ) FT_Face_GetCharsOfVariant( FT_Face face, FT_ULong variantSelector ); /*************************************************************************/ /* */ /* <Section> */ /* computations */ /* */ /* <Title> */ /* Computations */ /* */ /* <Abstract> */ /* Crunching fixed numbers and vectors. */ /* */ /* <Description> */ /* This section contains various functions used to perform */ /* computations on 16.16 fixed-float numbers or 2d vectors. */ /* */ /* <Order> */ /* FT_MulDiv */ /* FT_MulFix */ /* FT_DivFix */ /* FT_RoundFix */ /* FT_CeilFix */ /* FT_FloorFix */ /* FT_Vector_Transform */ /* FT_Matrix_Multiply */ /* FT_Matrix_Invert */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_MulDiv */ /* */ /* <Description> */ /* Compute `(a*b)/c' with maximum accuracy, using a 64-bit */ /* intermediate integer whenever necessary. */ /* */ /* This function isn't necessarily as fast as some processor specific */ /* operations, but is at least completely portable. */ /* */ /* <Input> */ /* a :: The first multiplier. */ /* */ /* b :: The second multiplier. */ /* */ /* c :: The divisor. */ /* */ /* <Return> */ /* The result of `(a*b)/c'. This function never traps when trying to */ /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ /* on the signs of `a' and `b'. */ /* */ FT_EXPORT( FT_Long ) FT_MulDiv( FT_Long a, FT_Long b, FT_Long c ); /*************************************************************************/ /* */ /* <Function> */ /* FT_MulFix */ /* */ /* <Description> */ /* Compute `(a*b)/0x10000' with maximum accuracy. Its main use is to */ /* multiply a given value by a 16.16 fixed-point factor. */ /* */ /* <Input> */ /* a :: The first multiplier. */ /* */ /* b :: The second multiplier. Use a 16.16 factor here whenever */ /* possible (see note below). */ /* */ /* <Return> */ /* The result of `(a*b)/0x10000'. */ /* */ /* <Note> */ /* This function has been optimized for the case where the absolute */ /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ /* As this happens mainly when scaling from notional units to */ /* fractional pixels in FreeType, it resulted in noticeable speed */ /* improvements between versions 2.x and 1.x. */ /* */ /* As a conclusion, always try to place a 16.16 factor as the */ /* _second_ argument of this function; this can make a great */ /* difference. */ /* */ FT_EXPORT( FT_Long ) FT_MulFix( FT_Long a, FT_Long b ); /*************************************************************************/ /* */ /* <Function> */ /* FT_DivFix */ /* */ /* <Description> */ /* Compute `(a*0x10000)/b' with maximum accuracy. Its main use is to */ /* divide a given value by a 16.16 fixed-point factor. */ /* */ /* <Input> */ /* a :: The numerator. */ /* */ /* b :: The denominator. Use a 16.16 factor here. */ /* */ /* <Return> */ /* The result of `(a*0x10000)/b'. */ /* */ FT_EXPORT( FT_Long ) FT_DivFix( FT_Long a, FT_Long b ); /*************************************************************************/ /* */ /* <Function> */ /* FT_RoundFix */ /* */ /* <Description> */ /* Round a 16.16 fixed number. */ /* */ /* <Input> */ /* a :: The number to be rounded. */ /* */ /* <Return> */ /* `a' rounded to the nearest 16.16 fixed integer, halfway cases away */ /* from zero. */ /* */ /* <Note> */ /* The function uses wrap-around arithmetic. */ /* */ FT_EXPORT( FT_Fixed ) FT_RoundFix( FT_Fixed a ); /*************************************************************************/ /* */ /* <Function> */ /* FT_CeilFix */ /* */ /* <Description> */ /* Compute the smallest following integer of a 16.16 fixed number. */ /* */ /* <Input> */ /* a :: The number for which the ceiling function is to be computed. */ /* */ /* <Return> */ /* `a' rounded towards plus infinity. */ /* */ /* <Note> */ /* The function uses wrap-around arithmetic. */ /* */ FT_EXPORT( FT_Fixed ) FT_CeilFix( FT_Fixed a ); /*************************************************************************/ /* */ /* <Function> */ /* FT_FloorFix */ /* */ /* <Description> */ /* Compute the largest previous integer of a 16.16 fixed number. */ /* */ /* <Input> */ /* a :: The number for which the floor function is to be computed. */ /* */ /* <Return> */ /* `a' rounded towards minus infinity. */ /* */ FT_EXPORT( FT_Fixed ) FT_FloorFix( FT_Fixed a ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Vector_Transform */ /* */ /* <Description> */ /* Transform a single vector through a 2x2 matrix. */ /* */ /* <InOut> */ /* vector :: The target vector to transform. */ /* */ /* <Input> */ /* matrix :: A pointer to the source 2x2 matrix. */ /* */ /* <Note> */ /* The result is undefined if either `vector' or `matrix' is invalid. */ /* */ FT_EXPORT( void ) FT_Vector_Transform( FT_Vector* vec, const FT_Matrix* matrix ); /*************************************************************************/ /* */ /* <Section> */ /* version */ /* */ /* <Title> */ /* FreeType Version */ /* */ /* <Abstract> */ /* Functions and macros related to FreeType versions. */ /* */ /* <Description> */ /* Note that those functions and macros are of limited use because */ /* even a new release of FreeType with only documentation changes */ /* increases the version number. */ /* */ /* <Order> */ /* FT_Library_Version */ /* */ /* FREETYPE_MAJOR */ /* FREETYPE_MINOR */ /* FREETYPE_PATCH */ /* */ /* FT_Face_CheckTrueTypePatents */ /* FT_Face_SetUnpatentedHinting */ /* */ /* FREETYPE_XXX */ /* */ /*************************************************************************/ /************************************************************************* * * @enum: * FREETYPE_XXX * * @description: * These three macros identify the FreeType source code version. * Use @FT_Library_Version to access them at runtime. * * @values: * FREETYPE_MAJOR :: The major version number. * FREETYPE_MINOR :: The minor version number. * FREETYPE_PATCH :: The patch level. * * @note: * The version number of FreeType if built as a dynamic link library * with the `libtool' package is _not_ controlled by these three * macros. * */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 9 #define FREETYPE_PATCH 1 /*************************************************************************/ /* */ /* <Function> */ /* FT_Library_Version */ /* */ /* <Description> */ /* Return the version of the FreeType library being used. This is */ /* useful when dynamically linking to the library, since one cannot */ /* use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and */ /* @FREETYPE_PATCH. */ /* */ /* <Input> */ /* library :: A source library handle. */ /* */ /* <Output> */ /* amajor :: The major version number. */ /* */ /* aminor :: The minor version number. */ /* */ /* apatch :: The patch version number. */ /* */ /* <Note> */ /* The reason why this function takes a `library' argument is because */ /* certain programs implement library initialization in a custom way */ /* that doesn't use @FT_Init_FreeType. */ /* */ /* In such cases, the library version might not be available before */ /* the library object has been created. */ /* */ FT_EXPORT( void ) FT_Library_Version( FT_Library library, FT_Int *amajor, FT_Int *aminor, FT_Int *apatch ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Face_CheckTrueTypePatents */ /* */ /* <Description> */ /* Deprecated, does nothing. */ /* */ /* <Input> */ /* face :: A face handle. */ /* */ /* <Return> */ /* Always returns false. */ /* */ /* <Note> */ /* Since May 2010, TrueType hinting is no longer patented. */ /* */ /* <Since> */ /* 2.3.5 */ /* */ FT_EXPORT( FT_Bool ) FT_Face_CheckTrueTypePatents( FT_Face face ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Face_SetUnpatentedHinting */ /* */ /* <Description> */ /* Deprecated, does nothing. */ /* */ /* <Input> */ /* face :: A face handle. */ /* */ /* value :: New boolean setting. */ /* */ /* <Return> */ /* Always returns false. */ /* */ /* <Note> */ /* Since May 2010, TrueType hinting is no longer patented. */ /* */ /* <Since> */ /* 2.3.5 */ /* */ FT_EXPORT( FT_Bool ) FT_Face_SetUnpatentedHinting( FT_Face face, FT_Bool value ); /* */ FT_END_HEADER #endif /* FREETYPE_H_ */ /* END */ freetype2/freetype/t1tables.h 0000644 00000105310 15146341150 0012164 0 ustar 00 /***************************************************************************/ /* */ /* t1tables.h */ /* */ /* Basic Type 1/Type 2 tables definitions and interface (specification */ /* only). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef T1TABLES_H_ #define T1TABLES_H_ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* type1_tables */ /* */ /* <Title> */ /* Type 1 Tables */ /* */ /* <Abstract> */ /* Type~1 (PostScript) specific font tables. */ /* */ /* <Description> */ /* This section contains the definition of Type 1-specific tables, */ /* including structures related to other PostScript font formats. */ /* */ /* <Order> */ /* PS_FontInfoRec */ /* PS_FontInfo */ /* PS_PrivateRec */ /* PS_Private */ /* */ /* CID_FaceDictRec */ /* CID_FaceDict */ /* CID_FaceInfoRec */ /* CID_FaceInfo */ /* */ /* FT_Has_PS_Glyph_Names */ /* FT_Get_PS_Font_Info */ /* FT_Get_PS_Font_Private */ /* FT_Get_PS_Font_Value */ /* */ /* T1_Blend_Flags */ /* T1_EncodingType */ /* PS_Dict_Keys */ /* */ /*************************************************************************/ /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */ /* structures in order to support Multiple Master fonts. */ /*************************************************************************/ /* */ /* <Struct> */ /* PS_FontInfoRec */ /* */ /* <Description> */ /* A structure used to model a Type~1 or Type~2 FontInfo dictionary. */ /* Note that for Multiple Master fonts, each instance has its own */ /* FontInfo dictionary. */ /* */ typedef struct PS_FontInfoRec_ { FT_String* version; FT_String* notice; FT_String* full_name; FT_String* family_name; FT_String* weight; FT_Long italic_angle; FT_Bool is_fixed_pitch; FT_Short underline_position; FT_UShort underline_thickness; } PS_FontInfoRec; /*************************************************************************/ /* */ /* <Struct> */ /* PS_FontInfo */ /* */ /* <Description> */ /* A handle to a @PS_FontInfoRec structure. */ /* */ typedef struct PS_FontInfoRec_* PS_FontInfo; /*************************************************************************/ /* */ /* <Struct> */ /* T1_FontInfo */ /* */ /* <Description> */ /* This type is equivalent to @PS_FontInfoRec. It is deprecated but */ /* kept to maintain source compatibility between various versions of */ /* FreeType. */ /* */ typedef PS_FontInfoRec T1_FontInfo; /*************************************************************************/ /* */ /* <Struct> */ /* PS_PrivateRec */ /* */ /* <Description> */ /* A structure used to model a Type~1 or Type~2 private dictionary. */ /* Note that for Multiple Master fonts, each instance has its own */ /* Private dictionary. */ /* */ typedef struct PS_PrivateRec_ { FT_Int unique_id; FT_Int lenIV; FT_Byte num_blue_values; FT_Byte num_other_blues; FT_Byte num_family_blues; FT_Byte num_family_other_blues; FT_Short blue_values[14]; FT_Short other_blues[10]; FT_Short family_blues [14]; FT_Short family_other_blues[10]; FT_Fixed blue_scale; FT_Int blue_shift; FT_Int blue_fuzz; FT_UShort standard_width[1]; FT_UShort standard_height[1]; FT_Byte num_snap_widths; FT_Byte num_snap_heights; FT_Bool force_bold; FT_Bool round_stem_up; FT_Short snap_widths [13]; /* including std width */ FT_Short snap_heights[13]; /* including std height */ FT_Fixed expansion_factor; FT_Long language_group; FT_Long password; FT_Short min_feature[2]; } PS_PrivateRec; /*************************************************************************/ /* */ /* <Struct> */ /* PS_Private */ /* */ /* <Description> */ /* A handle to a @PS_PrivateRec structure. */ /* */ typedef struct PS_PrivateRec_* PS_Private; /*************************************************************************/ /* */ /* <Struct> */ /* T1_Private */ /* */ /* <Description> */ /* This type is equivalent to @PS_PrivateRec. It is deprecated but */ /* kept to maintain source compatibility between various versions of */ /* FreeType. */ /* */ typedef PS_PrivateRec T1_Private; /*************************************************************************/ /* */ /* <Enum> */ /* T1_Blend_Flags */ /* */ /* <Description> */ /* A set of flags used to indicate which fields are present in a */ /* given blend dictionary (font info or private). Used to support */ /* Multiple Masters fonts. */ /* */ /* <Values> */ /* T1_BLEND_UNDERLINE_POSITION :: */ /* T1_BLEND_UNDERLINE_THICKNESS :: */ /* T1_BLEND_ITALIC_ANGLE :: */ /* T1_BLEND_BLUE_VALUES :: */ /* T1_BLEND_OTHER_BLUES :: */ /* T1_BLEND_STANDARD_WIDTH :: */ /* T1_BLEND_STANDARD_HEIGHT :: */ /* T1_BLEND_STEM_SNAP_WIDTHS :: */ /* T1_BLEND_STEM_SNAP_HEIGHTS :: */ /* T1_BLEND_BLUE_SCALE :: */ /* T1_BLEND_BLUE_SHIFT :: */ /* T1_BLEND_FAMILY_BLUES :: */ /* T1_BLEND_FAMILY_OTHER_BLUES :: */ /* T1_BLEND_FORCE_BOLD :: */ /* */ typedef enum T1_Blend_Flags_ { /* required fields in a FontInfo blend dictionary */ T1_BLEND_UNDERLINE_POSITION = 0, T1_BLEND_UNDERLINE_THICKNESS, T1_BLEND_ITALIC_ANGLE, /* required fields in a Private blend dictionary */ T1_BLEND_BLUE_VALUES, T1_BLEND_OTHER_BLUES, T1_BLEND_STANDARD_WIDTH, T1_BLEND_STANDARD_HEIGHT, T1_BLEND_STEM_SNAP_WIDTHS, T1_BLEND_STEM_SNAP_HEIGHTS, T1_BLEND_BLUE_SCALE, T1_BLEND_BLUE_SHIFT, T1_BLEND_FAMILY_BLUES, T1_BLEND_FAMILY_OTHER_BLUES, T1_BLEND_FORCE_BOLD, T1_BLEND_MAX /* do not remove */ } T1_Blend_Flags; /* these constants are deprecated; use the corresponding */ /* `T1_Blend_Flags' values instead */ #define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION #define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS #define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE #define t1_blend_blue_values T1_BLEND_BLUE_VALUES #define t1_blend_other_blues T1_BLEND_OTHER_BLUES #define t1_blend_standard_widths T1_BLEND_STANDARD_WIDTH #define t1_blend_standard_height T1_BLEND_STANDARD_HEIGHT #define t1_blend_stem_snap_widths T1_BLEND_STEM_SNAP_WIDTHS #define t1_blend_stem_snap_heights T1_BLEND_STEM_SNAP_HEIGHTS #define t1_blend_blue_scale T1_BLEND_BLUE_SCALE #define t1_blend_blue_shift T1_BLEND_BLUE_SHIFT #define t1_blend_family_blues T1_BLEND_FAMILY_BLUES #define t1_blend_family_other_blues T1_BLEND_FAMILY_OTHER_BLUES #define t1_blend_force_bold T1_BLEND_FORCE_BOLD #define t1_blend_max T1_BLEND_MAX /* */ /* maximum number of Multiple Masters designs, as defined in the spec */ #define T1_MAX_MM_DESIGNS 16 /* maximum number of Multiple Masters axes, as defined in the spec */ #define T1_MAX_MM_AXIS 4 /* maximum number of elements in a design map */ #define T1_MAX_MM_MAP_POINTS 20 /* this structure is used to store the BlendDesignMap entry for an axis */ typedef struct PS_DesignMap_ { FT_Byte num_points; FT_Long* design_points; FT_Fixed* blend_points; } PS_DesignMapRec, *PS_DesignMap; /* backward compatible definition */ typedef PS_DesignMapRec T1_DesignMap; typedef struct PS_BlendRec_ { FT_UInt num_designs; FT_UInt num_axis; FT_String* axis_names[T1_MAX_MM_AXIS]; FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; FT_Fixed* weight_vector; FT_Fixed* default_weight_vector; PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; PS_Private privates [T1_MAX_MM_DESIGNS + 1]; FT_ULong blend_bitflags; FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; /* since 2.3.0 */ /* undocumented, optional: the default design instance; */ /* corresponds to default_weight_vector -- */ /* num_default_design_vector == 0 means it is not present */ /* in the font and associated metrics files */ FT_UInt default_design_vector[T1_MAX_MM_DESIGNS]; FT_UInt num_default_design_vector; } PS_BlendRec, *PS_Blend; /* backward compatible definition */ typedef PS_BlendRec T1_Blend; /*************************************************************************/ /* */ /* <Struct> */ /* CID_FaceDictRec */ /* */ /* <Description> */ /* A structure used to represent data in a CID top-level dictionary. */ /* */ typedef struct CID_FaceDictRec_ { PS_PrivateRec private_dict; FT_UInt len_buildchar; FT_Fixed forcebold_threshold; FT_Pos stroke_width; FT_Fixed expansion_factor; FT_Byte paint_type; FT_Byte font_type; FT_Matrix font_matrix; FT_Vector font_offset; FT_UInt num_subrs; FT_ULong subrmap_offset; FT_Int sd_bytes; } CID_FaceDictRec; /*************************************************************************/ /* */ /* <Struct> */ /* CID_FaceDict */ /* */ /* <Description> */ /* A handle to a @CID_FaceDictRec structure. */ /* */ typedef struct CID_FaceDictRec_* CID_FaceDict; /*************************************************************************/ /* */ /* <Struct> */ /* CID_FontDict */ /* */ /* <Description> */ /* This type is equivalent to @CID_FaceDictRec. It is deprecated but */ /* kept to maintain source compatibility between various versions of */ /* FreeType. */ /* */ typedef CID_FaceDictRec CID_FontDict; /*************************************************************************/ /* */ /* <Struct> */ /* CID_FaceInfoRec */ /* */ /* <Description> */ /* A structure used to represent CID Face information. */ /* */ typedef struct CID_FaceInfoRec_ { FT_String* cid_font_name; FT_Fixed cid_version; FT_Int cid_font_type; FT_String* registry; FT_String* ordering; FT_Int supplement; PS_FontInfoRec font_info; FT_BBox font_bbox; FT_ULong uid_base; FT_Int num_xuid; FT_ULong xuid[16]; FT_ULong cidmap_offset; FT_Int fd_bytes; FT_Int gd_bytes; FT_ULong cid_count; FT_Int num_dicts; CID_FaceDict font_dicts; FT_ULong data_offset; } CID_FaceInfoRec; /*************************************************************************/ /* */ /* <Struct> */ /* CID_FaceInfo */ /* */ /* <Description> */ /* A handle to a @CID_FaceInfoRec structure. */ /* */ typedef struct CID_FaceInfoRec_* CID_FaceInfo; /*************************************************************************/ /* */ /* <Struct> */ /* CID_Info */ /* */ /* <Description> */ /* This type is equivalent to @CID_FaceInfoRec. It is deprecated but */ /* kept to maintain source compatibility between various versions of */ /* FreeType. */ /* */ typedef CID_FaceInfoRec CID_Info; /************************************************************************ * * @function: * FT_Has_PS_Glyph_Names * * @description: * Return true if a given face provides reliable PostScript glyph * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, * except that certain fonts (mostly TrueType) contain incorrect * glyph name tables. * * When this function returns true, the caller is sure that the glyph * names returned by @FT_Get_Glyph_Name are reliable. * * @input: * face :: * face handle * * @return: * Boolean. True if glyph names are reliable. * */ FT_EXPORT( FT_Int ) FT_Has_PS_Glyph_Names( FT_Face face ); /************************************************************************ * * @function: * FT_Get_PS_Font_Info * * @description: * Retrieve the @PS_FontInfoRec structure corresponding to a given * PostScript font. * * @input: * face :: * PostScript face handle. * * @output: * afont_info :: * Output font info structure pointer. * * @return: * FreeType error code. 0~means success. * * @note: * String pointers within the @PS_FontInfoRec structure are owned by * the face and don't need to be freed by the caller. Missing entries * in the font's FontInfo dictionary are represented by NULL pointers. * * If the font's format is not PostScript-based, this function will * return the `FT_Err_Invalid_Argument' error code. * */ FT_EXPORT( FT_Error ) FT_Get_PS_Font_Info( FT_Face face, PS_FontInfo afont_info ); /************************************************************************ * * @function: * FT_Get_PS_Font_Private * * @description: * Retrieve the @PS_PrivateRec structure corresponding to a given * PostScript font. * * @input: * face :: * PostScript face handle. * * @output: * afont_private :: * Output private dictionary structure pointer. * * @return: * FreeType error code. 0~means success. * * @note: * The string pointers within the @PS_PrivateRec structure are owned by * the face and don't need to be freed by the caller. * * If the font's format is not PostScript-based, this function returns * the `FT_Err_Invalid_Argument' error code. * */ FT_EXPORT( FT_Error ) FT_Get_PS_Font_Private( FT_Face face, PS_Private afont_private ); /*************************************************************************/ /* */ /* <Enum> */ /* T1_EncodingType */ /* */ /* <Description> */ /* An enumeration describing the `Encoding' entry in a Type 1 */ /* dictionary. */ /* */ /* <Values> */ /* T1_ENCODING_TYPE_NONE :: */ /* T1_ENCODING_TYPE_ARRAY :: */ /* T1_ENCODING_TYPE_STANDARD :: */ /* T1_ENCODING_TYPE_ISOLATIN1 :: */ /* T1_ENCODING_TYPE_EXPERT :: */ /* */ /* <Since> */ /* 2.4.8 */ /* */ typedef enum T1_EncodingType_ { T1_ENCODING_TYPE_NONE = 0, T1_ENCODING_TYPE_ARRAY, T1_ENCODING_TYPE_STANDARD, T1_ENCODING_TYPE_ISOLATIN1, T1_ENCODING_TYPE_EXPERT } T1_EncodingType; /*************************************************************************/ /* */ /* <Enum> */ /* PS_Dict_Keys */ /* */ /* <Description> */ /* An enumeration used in calls to @FT_Get_PS_Font_Value to identify */ /* the Type~1 dictionary entry to retrieve. */ /* */ /* <Values> */ /* PS_DICT_FONT_TYPE :: */ /* PS_DICT_FONT_MATRIX :: */ /* PS_DICT_FONT_BBOX :: */ /* PS_DICT_PAINT_TYPE :: */ /* PS_DICT_FONT_NAME :: */ /* PS_DICT_UNIQUE_ID :: */ /* PS_DICT_NUM_CHAR_STRINGS :: */ /* PS_DICT_CHAR_STRING_KEY :: */ /* PS_DICT_CHAR_STRING :: */ /* PS_DICT_ENCODING_TYPE :: */ /* PS_DICT_ENCODING_ENTRY :: */ /* PS_DICT_NUM_SUBRS :: */ /* PS_DICT_SUBR :: */ /* PS_DICT_STD_HW :: */ /* PS_DICT_STD_VW :: */ /* PS_DICT_NUM_BLUE_VALUES :: */ /* PS_DICT_BLUE_VALUE :: */ /* PS_DICT_BLUE_FUZZ :: */ /* PS_DICT_NUM_OTHER_BLUES :: */ /* PS_DICT_OTHER_BLUE :: */ /* PS_DICT_NUM_FAMILY_BLUES :: */ /* PS_DICT_FAMILY_BLUE :: */ /* PS_DICT_NUM_FAMILY_OTHER_BLUES :: */ /* PS_DICT_FAMILY_OTHER_BLUE :: */ /* PS_DICT_BLUE_SCALE :: */ /* PS_DICT_BLUE_SHIFT :: */ /* PS_DICT_NUM_STEM_SNAP_H :: */ /* PS_DICT_STEM_SNAP_H :: */ /* PS_DICT_NUM_STEM_SNAP_V :: */ /* PS_DICT_STEM_SNAP_V :: */ /* PS_DICT_FORCE_BOLD :: */ /* PS_DICT_RND_STEM_UP :: */ /* PS_DICT_MIN_FEATURE :: */ /* PS_DICT_LEN_IV :: */ /* PS_DICT_PASSWORD :: */ /* PS_DICT_LANGUAGE_GROUP :: */ /* PS_DICT_VERSION :: */ /* PS_DICT_NOTICE :: */ /* PS_DICT_FULL_NAME :: */ /* PS_DICT_FAMILY_NAME :: */ /* PS_DICT_WEIGHT :: */ /* PS_DICT_IS_FIXED_PITCH :: */ /* PS_DICT_UNDERLINE_POSITION :: */ /* PS_DICT_UNDERLINE_THICKNESS :: */ /* PS_DICT_FS_TYPE :: */ /* PS_DICT_ITALIC_ANGLE :: */ /* */ /* <Since> */ /* 2.4.8 */ /* */ typedef enum PS_Dict_Keys_ { /* conventionally in the font dictionary */ PS_DICT_FONT_TYPE, /* FT_Byte */ PS_DICT_FONT_MATRIX, /* FT_Fixed */ PS_DICT_FONT_BBOX, /* FT_Fixed */ PS_DICT_PAINT_TYPE, /* FT_Byte */ PS_DICT_FONT_NAME, /* FT_String* */ PS_DICT_UNIQUE_ID, /* FT_Int */ PS_DICT_NUM_CHAR_STRINGS, /* FT_Int */ PS_DICT_CHAR_STRING_KEY, /* FT_String* */ PS_DICT_CHAR_STRING, /* FT_String* */ PS_DICT_ENCODING_TYPE, /* T1_EncodingType */ PS_DICT_ENCODING_ENTRY, /* FT_String* */ /* conventionally in the font Private dictionary */ PS_DICT_NUM_SUBRS, /* FT_Int */ PS_DICT_SUBR, /* FT_String* */ PS_DICT_STD_HW, /* FT_UShort */ PS_DICT_STD_VW, /* FT_UShort */ PS_DICT_NUM_BLUE_VALUES, /* FT_Byte */ PS_DICT_BLUE_VALUE, /* FT_Short */ PS_DICT_BLUE_FUZZ, /* FT_Int */ PS_DICT_NUM_OTHER_BLUES, /* FT_Byte */ PS_DICT_OTHER_BLUE, /* FT_Short */ PS_DICT_NUM_FAMILY_BLUES, /* FT_Byte */ PS_DICT_FAMILY_BLUE, /* FT_Short */ PS_DICT_NUM_FAMILY_OTHER_BLUES, /* FT_Byte */ PS_DICT_FAMILY_OTHER_BLUE, /* FT_Short */ PS_DICT_BLUE_SCALE, /* FT_Fixed */ PS_DICT_BLUE_SHIFT, /* FT_Int */ PS_DICT_NUM_STEM_SNAP_H, /* FT_Byte */ PS_DICT_STEM_SNAP_H, /* FT_Short */ PS_DICT_NUM_STEM_SNAP_V, /* FT_Byte */ PS_DICT_STEM_SNAP_V, /* FT_Short */ PS_DICT_FORCE_BOLD, /* FT_Bool */ PS_DICT_RND_STEM_UP, /* FT_Bool */ PS_DICT_MIN_FEATURE, /* FT_Short */ PS_DICT_LEN_IV, /* FT_Int */ PS_DICT_PASSWORD, /* FT_Long */ PS_DICT_LANGUAGE_GROUP, /* FT_Long */ /* conventionally in the font FontInfo dictionary */ PS_DICT_VERSION, /* FT_String* */ PS_DICT_NOTICE, /* FT_String* */ PS_DICT_FULL_NAME, /* FT_String* */ PS_DICT_FAMILY_NAME, /* FT_String* */ PS_DICT_WEIGHT, /* FT_String* */ PS_DICT_IS_FIXED_PITCH, /* FT_Bool */ PS_DICT_UNDERLINE_POSITION, /* FT_Short */ PS_DICT_UNDERLINE_THICKNESS, /* FT_UShort */ PS_DICT_FS_TYPE, /* FT_UShort */ PS_DICT_ITALIC_ANGLE, /* FT_Long */ PS_DICT_MAX = PS_DICT_ITALIC_ANGLE } PS_Dict_Keys; /************************************************************************ * * @function: * FT_Get_PS_Font_Value * * @description: * Retrieve the value for the supplied key from a PostScript font. * * @input: * face :: * PostScript face handle. * * key :: * An enumeration value representing the dictionary key to retrieve. * * idx :: * For array values, this specifies the index to be returned. * * value :: * A pointer to memory into which to write the value. * * valen_len :: * The size, in bytes, of the memory supplied for the value. * * @output: * value :: * The value matching the above key, if it exists. * * @return: * The amount of memory (in bytes) required to hold the requested * value (if it exists, -1 otherwise). * * @note: * The values returned are not pointers into the internal structures of * the face, but are `fresh' copies, so that the memory containing them * belongs to the calling application. This also enforces the * `read-only' nature of these values, i.e., this function cannot be * used to manipulate the face. * * `value' is a void pointer because the values returned can be of * various types. * * If either `value' is NULL or `value_len' is too small, just the * required memory size for the requested entry is returned. * * The `idx' parameter is used, not only to retrieve elements of, for * example, the FontMatrix or FontBBox, but also to retrieve name keys * from the CharStrings dictionary, and the charstrings themselves. It * is ignored for atomic values. * * PS_DICT_BLUE_SCALE returns a value that is scaled up by 1000. To * get the value as in the font stream, you need to divide by * 65536000.0 (to remove the FT_Fixed scale, and the x1000 scale). * * IMPORTANT: Only key/value pairs read by the FreeType interpreter can * be retrieved. So, for example, PostScript procedures such as NP, * ND, and RD are not available. Arbitrary keys are, obviously, not be * available either. * * If the font's format is not PostScript-based, this function returns * the `FT_Err_Invalid_Argument' error code. * * @since: * 2.4.8 * */ FT_EXPORT( FT_Long ) FT_Get_PS_Font_Value( FT_Face face, PS_Dict_Keys key, FT_UInt idx, void *value, FT_Long value_len ); /* */ FT_END_HEADER #endif /* T1TABLES_H_ */ /* END */ freetype2/freetype/ftcache.h 0000644 00000156403 15146341150 0012053 0 ustar 00 /***************************************************************************/ /* */ /* ftcache.h */ /* */ /* FreeType Cache subsystem (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #ifndef FTCACHE_H_ #define FTCACHE_H_ #include <ft2build.h> #include FT_GLYPH_H FT_BEGIN_HEADER /************************************************************************* * * <Section> * cache_subsystem * * <Title> * Cache Sub-System * * <Abstract> * How to cache face, size, and glyph data with FreeType~2. * * <Description> * This section describes the FreeType~2 cache sub-system, which is used * to limit the number of concurrently opened @FT_Face and @FT_Size * objects, as well as caching information like character maps and glyph * images while limiting their maximum memory usage. * * Note that all types and functions begin with the `FTC_' prefix. * * The cache is highly portable and thus doesn't know anything about the * fonts installed on your system, or how to access them. This implies * the following scheme: * * First, available or installed font faces are uniquely identified by * @FTC_FaceID values, provided to the cache by the client. Note that * the cache only stores and compares these values, and doesn't try to * interpret them in any way. * * Second, the cache calls, only when needed, a client-provided function * to convert an @FTC_FaceID into a new @FT_Face object. The latter is * then completely managed by the cache, including its termination * through @FT_Done_Face. To monitor termination of face objects, the * finalizer callback in the `generic' field of the @FT_Face object can * be used, which might also be used to store the @FTC_FaceID of the * face. * * Clients are free to map face IDs to anything else. The most simple * usage is to associate them to a (pathname,face_index) pair that is * used to call @FT_New_Face. However, more complex schemes are also * possible. * * Note that for the cache to work correctly, the face ID values must be * *persistent*, which means that the contents they point to should not * change at runtime, or that their value should not become invalid. * * If this is unavoidable (e.g., when a font is uninstalled at runtime), * you should call @FTC_Manager_RemoveFaceID as soon as possible, to let * the cache get rid of any references to the old @FTC_FaceID it may * keep internally. Failure to do so will lead to incorrect behaviour * or even crashes. * * To use the cache, start with calling @FTC_Manager_New to create a new * @FTC_Manager object, which models a single cache instance. You can * then look up @FT_Face and @FT_Size objects with * @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively. * * If you want to use the charmap caching, call @FTC_CMapCache_New, then * later use @FTC_CMapCache_Lookup to perform the equivalent of * @FT_Get_Char_Index, only much faster. * * If you want to use the @FT_Glyph caching, call @FTC_ImageCache, then * later use @FTC_ImageCache_Lookup to retrieve the corresponding * @FT_Glyph objects from the cache. * * If you need lots of small bitmaps, it is much more memory efficient * to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This * returns @FTC_SBitRec structures, which are used to store small * bitmaps directly. (A small bitmap is one whose metrics and * dimensions all fit into 8-bit integers). * * We hope to also provide a kerning cache in the near future. * * * <Order> * FTC_Manager * FTC_FaceID * FTC_Face_Requester * * FTC_Manager_New * FTC_Manager_Reset * FTC_Manager_Done * FTC_Manager_LookupFace * FTC_Manager_LookupSize * FTC_Manager_RemoveFaceID * * FTC_Node * FTC_Node_Unref * * FTC_ImageCache * FTC_ImageCache_New * FTC_ImageCache_Lookup * * FTC_SBit * FTC_SBitCache * FTC_SBitCache_New * FTC_SBitCache_Lookup * * FTC_CMapCache * FTC_CMapCache_New * FTC_CMapCache_Lookup * *************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** BASIC TYPE DEFINITIONS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /************************************************************************* * * @type: FTC_FaceID * * @description: * An opaque pointer type that is used to identity face objects. The * contents of such objects is application-dependent. * * These pointers are typically used to point to a user-defined * structure containing a font file path, and face index. * * @note: * Never use NULL as a valid @FTC_FaceID. * * Face IDs are passed by the client to the cache manager that calls, * when needed, the @FTC_Face_Requester to translate them into new * @FT_Face objects. * * If the content of a given face ID changes at runtime, or if the value * becomes invalid (e.g., when uninstalling a font), you should * immediately call @FTC_Manager_RemoveFaceID before any other cache * function. * * Failure to do so will result in incorrect behaviour or even * memory leaks and crashes. */ typedef FT_Pointer FTC_FaceID; /************************************************************************ * * @functype: * FTC_Face_Requester * * @description: * A callback function provided by client applications. It is used by * the cache manager to translate a given @FTC_FaceID into a new valid * @FT_Face object, on demand. * * <Input> * face_id :: * The face ID to resolve. * * library :: * A handle to a FreeType library object. * * req_data :: * Application-provided request data (see note below). * * <Output> * aface :: * A new @FT_Face handle. * * <Return> * FreeType error code. 0~means success. * * <Note> * The third parameter `req_data' is the same as the one passed by the * client when @FTC_Manager_New is called. * * The face requester should not perform funny things on the returned * face object, like creating a new @FT_Size for it, or setting a * transformation through @FT_Set_Transform! */ typedef FT_Error (*FTC_Face_Requester)( FTC_FaceID face_id, FT_Library library, FT_Pointer req_data, FT_Face* aface ); /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CACHE MANAGER OBJECT *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* <Type> */ /* FTC_Manager */ /* */ /* <Description> */ /* This object corresponds to one instance of the cache-subsystem. */ /* It is used to cache one or more @FT_Face objects, along with */ /* corresponding @FT_Size objects. */ /* */ /* The manager intentionally limits the total number of opened */ /* @FT_Face and @FT_Size objects to control memory usage. See the */ /* `max_faces' and `max_sizes' parameters of @FTC_Manager_New. */ /* */ /* The manager is also used to cache `nodes' of various types while */ /* limiting their total memory usage. */ /* */ /* All limitations are enforced by keeping lists of managed objects */ /* in most-recently-used order, and flushing old nodes to make room */ /* for new ones. */ /* */ typedef struct FTC_ManagerRec_* FTC_Manager; /*************************************************************************/ /* */ /* <Type> */ /* FTC_Node */ /* */ /* <Description> */ /* An opaque handle to a cache node object. Each cache node is */ /* reference-counted. A node with a count of~0 might be flushed */ /* out of a full cache whenever a lookup request is performed. */ /* */ /* If you look up nodes, you have the ability to `acquire' them, */ /* i.e., to increment their reference count. This will prevent the */ /* node from being flushed out of the cache until you explicitly */ /* `release' it (see @FTC_Node_Unref). */ /* */ /* See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup. */ /* */ typedef struct FTC_NodeRec_* FTC_Node; /*************************************************************************/ /* */ /* <Function> */ /* FTC_Manager_New */ /* */ /* <Description> */ /* Create a new cache manager. */ /* */ /* <Input> */ /* library :: The parent FreeType library handle to use. */ /* */ /* max_faces :: Maximum number of opened @FT_Face objects managed by */ /* this cache instance. Use~0 for defaults. */ /* */ /* max_sizes :: Maximum number of opened @FT_Size objects managed by */ /* this cache instance. Use~0 for defaults. */ /* */ /* max_bytes :: Maximum number of bytes to use for cached data nodes. */ /* Use~0 for defaults. Note that this value does not */ /* account for managed @FT_Face and @FT_Size objects. */ /* */ /* requester :: An application-provided callback used to translate */ /* face IDs into real @FT_Face objects. */ /* */ /* req_data :: A generic pointer that is passed to the requester */ /* each time it is called (see @FTC_Face_Requester). */ /* */ /* <Output> */ /* amanager :: A handle to a new manager object. 0~in case of */ /* failure. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FTC_Manager_New( FT_Library library, FT_UInt max_faces, FT_UInt max_sizes, FT_ULong max_bytes, FTC_Face_Requester requester, FT_Pointer req_data, FTC_Manager *amanager ); /*************************************************************************/ /* */ /* <Function> */ /* FTC_Manager_Reset */ /* */ /* <Description> */ /* Empty a given cache manager. This simply gets rid of all the */ /* currently cached @FT_Face and @FT_Size objects within the manager. */ /* */ /* <InOut> */ /* manager :: A handle to the manager. */ /* */ FT_EXPORT( void ) FTC_Manager_Reset( FTC_Manager manager ); /*************************************************************************/ /* */ /* <Function> */ /* FTC_Manager_Done */ /* */ /* <Description> */ /* Destroy a given manager after emptying it. */ /* */ /* <Input> */ /* manager :: A handle to the target cache manager object. */ /* */ FT_EXPORT( void ) FTC_Manager_Done( FTC_Manager manager ); /*************************************************************************/ /* */ /* <Function> */ /* FTC_Manager_LookupFace */ /* */ /* <Description> */ /* Retrieve the @FT_Face object that corresponds to a given face ID */ /* through a cache manager. */ /* */ /* <Input> */ /* manager :: A handle to the cache manager. */ /* */ /* face_id :: The ID of the face object. */ /* */ /* <Output> */ /* aface :: A handle to the face object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned @FT_Face object is always owned by the manager. You */ /* should never try to discard it yourself. */ /* */ /* The @FT_Face object doesn't necessarily have a current size object */ /* (i.e., face->size can be~0). If you need a specific `font size', */ /* use @FTC_Manager_LookupSize instead. */ /* */ /* Never change the face's transformation matrix (i.e., never call */ /* the @FT_Set_Transform function) on a returned face! If you need */ /* to transform glyphs, do it yourself after glyph loading. */ /* */ /* When you perform a lookup, out-of-memory errors are detected */ /* _within_ the lookup and force incremental flushes of the cache */ /* until enough memory is released for the lookup to succeed. */ /* */ /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ /* already been completely flushed, and still no memory was available */ /* for the operation. */ /* */ FT_EXPORT( FT_Error ) FTC_Manager_LookupFace( FTC_Manager manager, FTC_FaceID face_id, FT_Face *aface ); /*************************************************************************/ /* */ /* <Struct> */ /* FTC_ScalerRec */ /* */ /* <Description> */ /* A structure used to describe a given character size in either */ /* pixels or points to the cache manager. See */ /* @FTC_Manager_LookupSize. */ /* */ /* <Fields> */ /* face_id :: The source face ID. */ /* */ /* width :: The character width. */ /* */ /* height :: The character height. */ /* */ /* pixel :: A Boolean. If 1, the `width' and `height' fields are */ /* interpreted as integer pixel character sizes. */ /* Otherwise, they are expressed as 1/64th of points. */ /* */ /* x_res :: Only used when `pixel' is value~0 to indicate the */ /* horizontal resolution in dpi. */ /* */ /* y_res :: Only used when `pixel' is value~0 to indicate the */ /* vertical resolution in dpi. */ /* */ /* <Note> */ /* This type is mainly used to retrieve @FT_Size objects through the */ /* cache manager. */ /* */ typedef struct FTC_ScalerRec_ { FTC_FaceID face_id; FT_UInt width; FT_UInt height; FT_Int pixel; FT_UInt x_res; FT_UInt y_res; } FTC_ScalerRec; /*************************************************************************/ /* */ /* <Struct> */ /* FTC_Scaler */ /* */ /* <Description> */ /* A handle to an @FTC_ScalerRec structure. */ /* */ typedef struct FTC_ScalerRec_* FTC_Scaler; /*************************************************************************/ /* */ /* <Function> */ /* FTC_Manager_LookupSize */ /* */ /* <Description> */ /* Retrieve the @FT_Size object that corresponds to a given */ /* @FTC_ScalerRec pointer through a cache manager. */ /* */ /* <Input> */ /* manager :: A handle to the cache manager. */ /* */ /* scaler :: A scaler handle. */ /* */ /* <Output> */ /* asize :: A handle to the size object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned @FT_Size object is always owned by the manager. You */ /* should never try to discard it by yourself. */ /* */ /* You can access the parent @FT_Face object simply as `size->face' */ /* if you need it. Note that this object is also owned by the */ /* manager. */ /* */ /* <Note> */ /* When you perform a lookup, out-of-memory errors are detected */ /* _within_ the lookup and force incremental flushes of the cache */ /* until enough memory is released for the lookup to succeed. */ /* */ /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ /* already been completely flushed, and still no memory is available */ /* for the operation. */ /* */ FT_EXPORT( FT_Error ) FTC_Manager_LookupSize( FTC_Manager manager, FTC_Scaler scaler, FT_Size *asize ); /*************************************************************************/ /* */ /* <Function> */ /* FTC_Node_Unref */ /* */ /* <Description> */ /* Decrement a cache node's internal reference count. When the count */ /* reaches 0, it is not destroyed but becomes eligible for subsequent */ /* cache flushes. */ /* */ /* <Input> */ /* node :: The cache node handle. */ /* */ /* manager :: The cache manager handle. */ /* */ FT_EXPORT( void ) FTC_Node_Unref( FTC_Node node, FTC_Manager manager ); /************************************************************************* * * @function: * FTC_Manager_RemoveFaceID * * @description: * A special function used to indicate to the cache manager that * a given @FTC_FaceID is no longer valid, either because its * content changed, or because it was deallocated or uninstalled. * * @input: * manager :: * The cache manager handle. * * face_id :: * The @FTC_FaceID to be removed. * * @note: * This function flushes all nodes from the cache corresponding to this * `face_id', with the exception of nodes with a non-null reference * count. * * Such nodes are however modified internally so as to never appear * in later lookups with the same `face_id' value, and to be immediately * destroyed when released by all their users. * */ FT_EXPORT( void ) FTC_Manager_RemoveFaceID( FTC_Manager manager, FTC_FaceID face_id ); /************************************************************************* * * @type: * FTC_CMapCache * * @description: * An opaque handle used to model a charmap cache. This cache is to * hold character codes -> glyph indices mappings. * */ typedef struct FTC_CMapCacheRec_* FTC_CMapCache; /************************************************************************* * * @function: * FTC_CMapCache_New * * @description: * Create a new charmap cache. * * @input: * manager :: * A handle to the cache manager. * * @output: * acache :: * A new cache handle. NULL in case of error. * * @return: * FreeType error code. 0~means success. * * @note: * Like all other caches, this one will be destroyed with the cache * manager. * */ FT_EXPORT( FT_Error ) FTC_CMapCache_New( FTC_Manager manager, FTC_CMapCache *acache ); /************************************************************************ * * @function: * FTC_CMapCache_Lookup * * @description: * Translate a character code into a glyph index, using the charmap * cache. * * @input: * cache :: * A charmap cache handle. * * face_id :: * The source face ID. * * cmap_index :: * The index of the charmap in the source face. Any negative value * means to use the cache @FT_Face's default charmap. * * char_code :: * The character code (in the corresponding charmap). * * @return: * Glyph index. 0~means `no glyph'. * */ FT_EXPORT( FT_UInt ) FTC_CMapCache_Lookup( FTC_CMapCache cache, FTC_FaceID face_id, FT_Int cmap_index, FT_UInt32 char_code ); /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** IMAGE CACHE OBJECT *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /************************************************************************* * * @struct: * FTC_ImageTypeRec * * @description: * A structure used to model the type of images in a glyph cache. * * @fields: * face_id :: * The face ID. * * width :: * The width in pixels. * * height :: * The height in pixels. * * flags :: * The load flags, as in @FT_Load_Glyph. * */ typedef struct FTC_ImageTypeRec_ { FTC_FaceID face_id; FT_UInt width; FT_UInt height; FT_Int32 flags; } FTC_ImageTypeRec; /************************************************************************* * * @type: * FTC_ImageType * * @description: * A handle to an @FTC_ImageTypeRec structure. * */ typedef struct FTC_ImageTypeRec_* FTC_ImageType; /* */ #define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \ ( (d1)->face_id == (d2)->face_id && \ (d1)->width == (d2)->width && \ (d1)->flags == (d2)->flags ) /*************************************************************************/ /* */ /* <Type> */ /* FTC_ImageCache */ /* */ /* <Description> */ /* A handle to a glyph image cache object. They are designed to */ /* hold many distinct glyph images while not exceeding a certain */ /* memory threshold. */ /* */ typedef struct FTC_ImageCacheRec_* FTC_ImageCache; /*************************************************************************/ /* */ /* <Function> */ /* FTC_ImageCache_New */ /* */ /* <Description> */ /* Create a new glyph image cache. */ /* */ /* <Input> */ /* manager :: The parent manager for the image cache. */ /* */ /* <Output> */ /* acache :: A handle to the new glyph image cache object. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FTC_ImageCache_New( FTC_Manager manager, FTC_ImageCache *acache ); /*************************************************************************/ /* */ /* <Function> */ /* FTC_ImageCache_Lookup */ /* */ /* <Description> */ /* Retrieve a given glyph image from a glyph image cache. */ /* */ /* <Input> */ /* cache :: A handle to the source glyph image cache. */ /* */ /* type :: A pointer to a glyph image type descriptor. */ /* */ /* gindex :: The glyph index to retrieve. */ /* */ /* <Output> */ /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ /* anode :: Used to return the address of the corresponding cache */ /* node after incrementing its reference count (see note */ /* below). */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned glyph is owned and managed by the glyph image cache. */ /* Never try to transform or discard it manually! You can however */ /* create a copy with @FT_Glyph_Copy and modify the new one. */ /* */ /* If `anode' is _not_ NULL, it receives the address of the cache */ /* node containing the glyph image, after increasing its reference */ /* count. This ensures that the node (as well as the @FT_Glyph) will */ /* always be kept in the cache until you call @FTC_Node_Unref to */ /* `release' it. */ /* */ /* If `anode' is NULL, the cache node is left unchanged, which means */ /* that the @FT_Glyph could be flushed out of the cache on the next */ /* call to one of the caching sub-system APIs. Don't assume that it */ /* is persistent! */ /* */ FT_EXPORT( FT_Error ) FTC_ImageCache_Lookup( FTC_ImageCache cache, FTC_ImageType type, FT_UInt gindex, FT_Glyph *aglyph, FTC_Node *anode ); /*************************************************************************/ /* */ /* <Function> */ /* FTC_ImageCache_LookupScaler */ /* */ /* <Description> */ /* A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec */ /* to specify the face ID and its size. */ /* */ /* <Input> */ /* cache :: A handle to the source glyph image cache. */ /* */ /* scaler :: A pointer to a scaler descriptor. */ /* */ /* load_flags :: The corresponding load flags. */ /* */ /* gindex :: The glyph index to retrieve. */ /* */ /* <Output> */ /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ /* anode :: Used to return the address of the corresponding */ /* cache node after incrementing its reference count */ /* (see note below). */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The returned glyph is owned and managed by the glyph image cache. */ /* Never try to transform or discard it manually! You can however */ /* create a copy with @FT_Glyph_Copy and modify the new one. */ /* */ /* If `anode' is _not_ NULL, it receives the address of the cache */ /* node containing the glyph image, after increasing its reference */ /* count. This ensures that the node (as well as the @FT_Glyph) will */ /* always be kept in the cache until you call @FTC_Node_Unref to */ /* `release' it. */ /* */ /* If `anode' is NULL, the cache node is left unchanged, which means */ /* that the @FT_Glyph could be flushed out of the cache on the next */ /* call to one of the caching sub-system APIs. Don't assume that it */ /* is persistent! */ /* */ /* Calls to @FT_Set_Char_Size and friends have no effect on cached */ /* glyphs; you should always use the FreeType cache API instead. */ /* */ FT_EXPORT( FT_Error ) FTC_ImageCache_LookupScaler( FTC_ImageCache cache, FTC_Scaler scaler, FT_ULong load_flags, FT_UInt gindex, FT_Glyph *aglyph, FTC_Node *anode ); /*************************************************************************/ /* */ /* <Type> */ /* FTC_SBit */ /* */ /* <Description> */ /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ /* structure for details. */ /* */ typedef struct FTC_SBitRec_* FTC_SBit; /*************************************************************************/ /* */ /* <Struct> */ /* FTC_SBitRec */ /* */ /* <Description> */ /* A very compact structure used to describe a small glyph bitmap. */ /* */ /* <Fields> */ /* width :: The bitmap width in pixels. */ /* */ /* height :: The bitmap height in pixels. */ /* */ /* left :: The horizontal distance from the pen position to the */ /* left bitmap border (a.k.a. `left side bearing', or */ /* `lsb'). */ /* */ /* top :: The vertical distance from the pen position (on the */ /* baseline) to the upper bitmap border (a.k.a. `top */ /* side bearing'). The distance is positive for upwards */ /* y~coordinates. */ /* */ /* format :: The format of the glyph bitmap (monochrome or gray). */ /* */ /* max_grays :: Maximum gray level value (in the range 1 to~255). */ /* */ /* pitch :: The number of bytes per bitmap line. May be positive */ /* or negative. */ /* */ /* xadvance :: The horizontal advance width in pixels. */ /* */ /* yadvance :: The vertical advance height in pixels. */ /* */ /* buffer :: A pointer to the bitmap pixels. */ /* */ typedef struct FTC_SBitRec_ { FT_Byte width; FT_Byte height; FT_Char left; FT_Char top; FT_Byte format; FT_Byte max_grays; FT_Short pitch; FT_Char xadvance; FT_Char yadvance; FT_Byte* buffer; } FTC_SBitRec; /*************************************************************************/ /* */ /* <Type> */ /* FTC_SBitCache */ /* */ /* <Description> */ /* A handle to a small bitmap cache. These are special cache objects */ /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ /* much more efficient way than the traditional glyph image cache */ /* implemented by @FTC_ImageCache. */ /* */ typedef struct FTC_SBitCacheRec_* FTC_SBitCache; /*************************************************************************/ /* */ /* <Function> */ /* FTC_SBitCache_New */ /* */ /* <Description> */ /* Create a new cache to store small glyph bitmaps. */ /* */ /* <Input> */ /* manager :: A handle to the source cache manager. */ /* */ /* <Output> */ /* acache :: A handle to the new sbit cache. NULL in case of error. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ FT_EXPORT( FT_Error ) FTC_SBitCache_New( FTC_Manager manager, FTC_SBitCache *acache ); /*************************************************************************/ /* */ /* <Function> */ /* FTC_SBitCache_Lookup */ /* */ /* <Description> */ /* Look up a given small glyph bitmap in a given sbit cache and */ /* `lock' it to prevent its flushing from the cache until needed. */ /* */ /* <Input> */ /* cache :: A handle to the source sbit cache. */ /* */ /* type :: A pointer to the glyph image type descriptor. */ /* */ /* gindex :: The glyph index. */ /* */ /* <Output> */ /* sbit :: A handle to a small bitmap descriptor. */ /* */ /* anode :: Used to return the address of the corresponding cache */ /* node after incrementing its reference count (see note */ /* below). */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The small bitmap descriptor and its bit buffer are owned by the */ /* cache and should never be freed by the application. They might */ /* as well disappear from memory on the next cache lookup, so don't */ /* treat them as persistent data. */ /* */ /* The descriptor's `buffer' field is set to~0 to indicate a missing */ /* glyph bitmap. */ /* */ /* If `anode' is _not_ NULL, it receives the address of the cache */ /* node containing the bitmap, after increasing its reference count. */ /* This ensures that the node (as well as the image) will always be */ /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ /* */ /* If `anode' is NULL, the cache node is left unchanged, which means */ /* that the bitmap could be flushed out of the cache on the next */ /* call to one of the caching sub-system APIs. Don't assume that it */ /* is persistent! */ /* */ FT_EXPORT( FT_Error ) FTC_SBitCache_Lookup( FTC_SBitCache cache, FTC_ImageType type, FT_UInt gindex, FTC_SBit *sbit, FTC_Node *anode ); /*************************************************************************/ /* */ /* <Function> */ /* FTC_SBitCache_LookupScaler */ /* */ /* <Description> */ /* A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec */ /* to specify the face ID and its size. */ /* */ /* <Input> */ /* cache :: A handle to the source sbit cache. */ /* */ /* scaler :: A pointer to the scaler descriptor. */ /* */ /* load_flags :: The corresponding load flags. */ /* */ /* gindex :: The glyph index. */ /* */ /* <Output> */ /* sbit :: A handle to a small bitmap descriptor. */ /* */ /* anode :: Used to return the address of the corresponding */ /* cache node after incrementing its reference count */ /* (see note below). */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ /* <Note> */ /* The small bitmap descriptor and its bit buffer are owned by the */ /* cache and should never be freed by the application. They might */ /* as well disappear from memory on the next cache lookup, so don't */ /* treat them as persistent data. */ /* */ /* The descriptor's `buffer' field is set to~0 to indicate a missing */ /* glyph bitmap. */ /* */ /* If `anode' is _not_ NULL, it receives the address of the cache */ /* node containing the bitmap, after increasing its reference count. */ /* This ensures that the node (as well as the image) will always be */ /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ /* */ /* If `anode' is NULL, the cache node is left unchanged, which means */ /* that the bitmap could be flushed out of the cache on the next */ /* call to one of the caching sub-system APIs. Don't assume that it */ /* is persistent! */ /* */ FT_EXPORT( FT_Error ) FTC_SBitCache_LookupScaler( FTC_SBitCache cache, FTC_Scaler scaler, FT_ULong load_flags, FT_UInt gindex, FTC_SBit *sbit, FTC_Node *anode ); /* */ FT_END_HEADER #endif /* FTCACHE_H_ */ /* END */ freetype2/freetype/ftmoderr.h 0000644 00000024261 15146341150 0012274 0 ustar 00 /***************************************************************************/ /* */ /* ftmoderr.h */ /* */ /* FreeType module error offsets (specification). */ /* */ /* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This file is used to define the FreeType module error codes. */ /* */ /* If the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in `ftoption.h' is */ /* set, the lower byte of an error value identifies the error code as */ /* usual. In addition, the higher byte identifies the module. For */ /* example, the error `FT_Err_Invalid_File_Format' has value 0x0003, the */ /* error `TT_Err_Invalid_File_Format' has value 0x1303, the error */ /* `T1_Err_Invalid_File_Format' has value 0x1403, etc. */ /* */ /* Note that `FT_Err_Ok', `TT_Err_Ok', etc. are always equal to zero, */ /* including the high byte. */ /* */ /* If FT_CONFIG_OPTION_USE_MODULE_ERRORS isn't set, the higher byte of */ /* an error value is set to zero. */ /* */ /* To hide the various `XXX_Err_' prefixes in the source code, FreeType */ /* provides some macros in `fttypes.h'. */ /* */ /* FT_ERR( err ) */ /* Add current error module prefix (as defined with the */ /* `FT_ERR_PREFIX' macro) to `err'. For example, in the BDF module */ /* the line */ /* */ /* error = FT_ERR( Invalid_Outline ); */ /* */ /* expands to */ /* */ /* error = BDF_Err_Invalid_Outline; */ /* */ /* For simplicity, you can always use `FT_Err_Ok' directly instead */ /* of `FT_ERR( Ok )'. */ /* */ /* FT_ERR_EQ( errcode, err ) */ /* FT_ERR_NEQ( errcode, err ) */ /* Compare error code `errcode' with the error `err' for equality */ /* and inequality, respectively. Example: */ /* */ /* if ( FT_ERR_EQ( error, Invalid_Outline ) ) */ /* ... */ /* */ /* Using this macro you don't have to think about error prefixes. */ /* Of course, if module errors are not active, the above example is */ /* the same as */ /* */ /* if ( error == FT_Err_Invalid_Outline ) */ /* ... */ /* */ /* FT_ERROR_BASE( errcode ) */ /* FT_ERROR_MODULE( errcode ) */ /* Get base error and module error code, respectively. */ /* */ /* */ /* It can also be used to create a module error message table easily */ /* with something like */ /* */ /* { */ /* #undef FTMODERR_H_ */ /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ /* #define FT_MODERR_START_LIST { */ /* #define FT_MODERR_END_LIST { 0, 0 } }; */ /* */ /* const struct */ /* { */ /* int mod_err_offset; */ /* const char* mod_err_msg */ /* } ft_mod_errors[] = */ /* */ /* #include FT_MODULE_ERRORS_H */ /* } */ /* */ /*************************************************************************/ #ifndef FTMODERR_H_ #define FTMODERR_H_ /*******************************************************************/ /*******************************************************************/ /***** *****/ /***** SETUP MACROS *****/ /***** *****/ /*******************************************************************/ /*******************************************************************/ #undef FT_NEED_EXTERN_C #ifndef FT_MODERRDEF #ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS #define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = v, #else #define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = 0, #endif #define FT_MODERR_START_LIST enum { #define FT_MODERR_END_LIST FT_Mod_Err_Max }; #ifdef __cplusplus #define FT_NEED_EXTERN_C extern "C" { #endif #endif /* !FT_MODERRDEF */ /*******************************************************************/ /*******************************************************************/ /***** *****/ /***** LIST MODULE ERROR BASES *****/ /***** *****/ /*******************************************************************/ /*******************************************************************/ #ifdef FT_MODERR_START_LIST FT_MODERR_START_LIST #endif FT_MODERRDEF( Base, 0x000, "base module" ) FT_MODERRDEF( Autofit, 0x100, "autofitter module" ) FT_MODERRDEF( BDF, 0x200, "BDF module" ) FT_MODERRDEF( Bzip2, 0x300, "Bzip2 module" ) FT_MODERRDEF( Cache, 0x400, "cache module" ) FT_MODERRDEF( CFF, 0x500, "CFF module" ) FT_MODERRDEF( CID, 0x600, "CID module" ) FT_MODERRDEF( Gzip, 0x700, "Gzip module" ) FT_MODERRDEF( LZW, 0x800, "LZW module" ) FT_MODERRDEF( OTvalid, 0x900, "OpenType validation module" ) FT_MODERRDEF( PCF, 0xA00, "PCF module" ) FT_MODERRDEF( PFR, 0xB00, "PFR module" ) FT_MODERRDEF( PSaux, 0xC00, "PS auxiliary module" ) FT_MODERRDEF( PShinter, 0xD00, "PS hinter module" ) FT_MODERRDEF( PSnames, 0xE00, "PS names module" ) FT_MODERRDEF( Raster, 0xF00, "raster module" ) FT_MODERRDEF( SFNT, 0x1000, "SFNT module" ) FT_MODERRDEF( Smooth, 0x1100, "smooth raster module" ) FT_MODERRDEF( TrueType, 0x1200, "TrueType module" ) FT_MODERRDEF( Type1, 0x1300, "Type 1 module" ) FT_MODERRDEF( Type42, 0x1400, "Type 42 module" ) FT_MODERRDEF( Winfonts, 0x1500, "Windows FON/FNT module" ) FT_MODERRDEF( GXvalid, 0x1600, "GX validation module" ) #ifdef FT_MODERR_END_LIST FT_MODERR_END_LIST #endif /*******************************************************************/ /*******************************************************************/ /***** *****/ /***** CLEANUP *****/ /***** *****/ /*******************************************************************/ /*******************************************************************/ #ifdef FT_NEED_EXTERN_C } #endif #undef FT_MODERR_START_LIST #undef FT_MODERR_END_LIST #undef FT_MODERRDEF #undef FT_NEED_EXTERN_C #endif /* FTMODERR_H_ */ /* END */ freetype2/freetype/ftimage.h 0000644 00000223630 15146341150 0012067 0 ustar 00 /***************************************************************************/ /* */ /* ftimage.h */ /* */ /* FreeType glyph image formats and default raster interface */ /* (specification). */ /* */ /* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* Note: A `raster' is simply a scan-line converter, used to render */ /* FT_Outlines into FT_Bitmaps. */ /* */ /*************************************************************************/ #ifndef FTIMAGE_H_ #define FTIMAGE_H_ /* STANDALONE_ is from ftgrays.c */ #ifndef STANDALONE_ #include <ft2build.h> #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* basic_types */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Type> */ /* FT_Pos */ /* */ /* <Description> */ /* The type FT_Pos is used to store vectorial coordinates. Depending */ /* on the context, these can represent distances in integer font */ /* units, or 16.16, or 26.6 fixed-point pixel coordinates. */ /* */ typedef signed long FT_Pos; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Vector */ /* */ /* <Description> */ /* A simple structure used to store a 2D vector; coordinates are of */ /* the FT_Pos type. */ /* */ /* <Fields> */ /* x :: The horizontal coordinate. */ /* y :: The vertical coordinate. */ /* */ typedef struct FT_Vector_ { FT_Pos x; FT_Pos y; } FT_Vector; /*************************************************************************/ /* */ /* <Struct> */ /* FT_BBox */ /* */ /* <Description> */ /* A structure used to hold an outline's bounding box, i.e., the */ /* coordinates of its extrema in the horizontal and vertical */ /* directions. */ /* */ /* <Fields> */ /* xMin :: The horizontal minimum (left-most). */ /* */ /* yMin :: The vertical minimum (bottom-most). */ /* */ /* xMax :: The horizontal maximum (right-most). */ /* */ /* yMax :: The vertical maximum (top-most). */ /* */ /* <Note> */ /* The bounding box is specified with the coordinates of the lower */ /* left and the upper right corner. In PostScript, those values are */ /* often called (llx,lly) and (urx,ury), respectively. */ /* */ /* If `yMin' is negative, this value gives the glyph's descender. */ /* Otherwise, the glyph doesn't descend below the baseline. */ /* Similarly, if `ymax' is positive, this value gives the glyph's */ /* ascender. */ /* */ /* `xMin' gives the horizontal distance from the glyph's origin to */ /* the left edge of the glyph's bounding box. If `xMin' is negative, */ /* the glyph extends to the left of the origin. */ /* */ typedef struct FT_BBox_ { FT_Pos xMin, yMin; FT_Pos xMax, yMax; } FT_BBox; /*************************************************************************/ /* */ /* <Enum> */ /* FT_Pixel_Mode */ /* */ /* <Description> */ /* An enumeration type used to describe the format of pixels in a */ /* given bitmap. Note that additional formats may be added in the */ /* future. */ /* */ /* <Values> */ /* FT_PIXEL_MODE_NONE :: */ /* Value~0 is reserved. */ /* */ /* FT_PIXEL_MODE_MONO :: */ /* A monochrome bitmap, using 1~bit per pixel. Note that pixels */ /* are stored in most-significant order (MSB), which means that */ /* the left-most pixel in a byte has value 128. */ /* */ /* FT_PIXEL_MODE_GRAY :: */ /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ /* images. Each pixel is stored in one byte. Note that the number */ /* of `gray' levels is stored in the `num_grays' field of the */ /* @FT_Bitmap structure (it generally is 256). */ /* */ /* FT_PIXEL_MODE_GRAY2 :: */ /* A 2-bit per pixel bitmap, used to represent embedded */ /* anti-aliased bitmaps in font files according to the OpenType */ /* specification. We haven't found a single font using this */ /* format, however. */ /* */ /* FT_PIXEL_MODE_GRAY4 :: */ /* A 4-bit per pixel bitmap, representing embedded anti-aliased */ /* bitmaps in font files according to the OpenType specification. */ /* We haven't found a single font using this format, however. */ /* */ /* FT_PIXEL_MODE_LCD :: */ /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ /* used for display on LCD displays; the bitmap is three times */ /* wider than the original glyph image. See also */ /* @FT_RENDER_MODE_LCD. */ /* */ /* FT_PIXEL_MODE_LCD_V :: */ /* An 8-bit bitmap, representing RGB or BGR decimated glyph images */ /* used for display on rotated LCD displays; the bitmap is three */ /* times taller than the original glyph image. See also */ /* @FT_RENDER_MODE_LCD_V. */ /* */ /* FT_PIXEL_MODE_BGRA :: */ /* [Since 2.5] An image with four 8-bit channels per pixel, */ /* representing a color image (such as emoticons) with alpha */ /* channel. For each pixel, the format is BGRA, which means, the */ /* blue channel comes first in memory. The color channels are */ /* pre-multiplied and in the sRGB colorspace. For example, full */ /* red at half-translucent opacity will be represented as */ /* `00,00,80,80', not `00,00,FF,80'. See also @FT_LOAD_COLOR. */ /* */ typedef enum FT_Pixel_Mode_ { FT_PIXEL_MODE_NONE = 0, FT_PIXEL_MODE_MONO, FT_PIXEL_MODE_GRAY, FT_PIXEL_MODE_GRAY2, FT_PIXEL_MODE_GRAY4, FT_PIXEL_MODE_LCD, FT_PIXEL_MODE_LCD_V, FT_PIXEL_MODE_BGRA, FT_PIXEL_MODE_MAX /* do not remove */ } FT_Pixel_Mode; /* these constants are deprecated; use the corresponding `FT_Pixel_Mode' */ /* values instead. */ #define ft_pixel_mode_none FT_PIXEL_MODE_NONE #define ft_pixel_mode_mono FT_PIXEL_MODE_MONO #define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY #define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 #define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 /*************************************************************************/ /* */ /* <Struct> */ /* FT_Bitmap */ /* */ /* <Description> */ /* A structure used to describe a bitmap or pixmap to the raster. */ /* Note that we now manage pixmaps of various depths through the */ /* `pixel_mode' field. */ /* */ /* <Fields> */ /* rows :: The number of bitmap rows. */ /* */ /* width :: The number of pixels in bitmap row. */ /* */ /* pitch :: The pitch's absolute value is the number of bytes */ /* taken by one bitmap row, including padding. */ /* However, the pitch is positive when the bitmap has */ /* a `down' flow, and negative when it has an `up' */ /* flow. In all cases, the pitch is an offset to add */ /* to a bitmap pointer in order to go down one row. */ /* */ /* Note that `padding' means the alignment of a */ /* bitmap to a byte border, and FreeType functions */ /* normally align to the smallest possible integer */ /* value. */ /* */ /* For the B/W rasterizer, `pitch' is always an even */ /* number. */ /* */ /* To change the pitch of a bitmap (say, to make it a */ /* multiple of 4), use @FT_Bitmap_Convert. */ /* Alternatively, you might use callback functions to */ /* directly render to the application's surface; see */ /* the file `example2.cpp' in the tutorial for a */ /* demonstration. */ /* */ /* buffer :: A typeless pointer to the bitmap buffer. This */ /* value should be aligned on 32-bit boundaries in */ /* most cases. */ /* */ /* num_grays :: This field is only used with */ /* @FT_PIXEL_MODE_GRAY; it gives the number of gray */ /* levels used in the bitmap. */ /* */ /* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. */ /* See @FT_Pixel_Mode for possible values. */ /* */ /* palette_mode :: This field is intended for paletted pixel modes; */ /* it indicates how the palette is stored. Not */ /* used currently. */ /* */ /* palette :: A typeless pointer to the bitmap palette; this */ /* field is intended for paletted pixel modes. Not */ /* used currently. */ /* */ typedef struct FT_Bitmap_ { unsigned int rows; unsigned int width; int pitch; unsigned char* buffer; unsigned short num_grays; unsigned char pixel_mode; unsigned char palette_mode; void* palette; } FT_Bitmap; /*************************************************************************/ /* */ /* <Section> */ /* outline_processing */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Struct> */ /* FT_Outline */ /* */ /* <Description> */ /* This structure is used to describe an outline to the scan-line */ /* converter. */ /* */ /* <Fields> */ /* n_contours :: The number of contours in the outline. */ /* */ /* n_points :: The number of points in the outline. */ /* */ /* points :: A pointer to an array of `n_points' @FT_Vector */ /* elements, giving the outline's point coordinates. */ /* */ /* tags :: A pointer to an array of `n_points' chars, giving */ /* each outline point's type. */ /* */ /* If bit~0 is unset, the point is `off' the curve, */ /* i.e., a Bezier control point, while it is `on' if */ /* set. */ /* */ /* Bit~1 is meaningful for `off' points only. If set, */ /* it indicates a third-order Bezier arc control point; */ /* and a second-order control point if unset. */ /* */ /* If bit~2 is set, bits 5-7 contain the drop-out mode */ /* (as defined in the OpenType specification; the value */ /* is the same as the argument to the SCANMODE */ /* instruction). */ /* */ /* Bits 3 and~4 are reserved for internal purposes. */ /* */ /* contours :: An array of `n_contours' shorts, giving the end */ /* point of each contour within the outline. For */ /* example, the first contour is defined by the points */ /* `0' to `contours[0]', the second one is defined by */ /* the points `contours[0]+1' to `contours[1]', etc. */ /* */ /* flags :: A set of bit flags used to characterize the outline */ /* and give hints to the scan-converter and hinter on */ /* how to convert/grid-fit it. See @FT_OUTLINE_XXX. */ /* */ /* <Note> */ /* The B/W rasterizer only checks bit~2 in the `tags' array for the */ /* first point of each contour. The drop-out mode as given with */ /* @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and */ /* @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden. */ /* */ typedef struct FT_Outline_ { short n_contours; /* number of contours in glyph */ short n_points; /* number of points in the glyph */ FT_Vector* points; /* the outline's points */ char* tags; /* the points flags */ short* contours; /* the contour end points */ int flags; /* outline masks */ } FT_Outline; /* */ /* Following limits must be consistent with */ /* FT_Outline.{n_contours,n_points} */ #define FT_OUTLINE_CONTOURS_MAX SHRT_MAX #define FT_OUTLINE_POINTS_MAX SHRT_MAX /*************************************************************************/ /* */ /* <Enum> */ /* FT_OUTLINE_XXX */ /* */ /* <Description> */ /* A list of bit-field constants use for the flags in an outline's */ /* `flags' field. */ /* */ /* <Values> */ /* FT_OUTLINE_NONE :: */ /* Value~0 is reserved. */ /* */ /* FT_OUTLINE_OWNER :: */ /* If set, this flag indicates that the outline's field arrays */ /* (i.e., `points', `flags', and `contours') are `owned' by the */ /* outline object, and should thus be freed when it is destroyed. */ /* */ /* FT_OUTLINE_EVEN_ODD_FILL :: */ /* By default, outlines are filled using the non-zero winding rule. */ /* If set to 1, the outline will be filled using the even-odd fill */ /* rule (only works with the smooth rasterizer). */ /* */ /* FT_OUTLINE_REVERSE_FILL :: */ /* By default, outside contours of an outline are oriented in */ /* clock-wise direction, as defined in the TrueType specification. */ /* This flag is set if the outline uses the opposite direction */ /* (typically for Type~1 fonts). This flag is ignored by the scan */ /* converter. */ /* */ /* FT_OUTLINE_IGNORE_DROPOUTS :: */ /* By default, the scan converter will try to detect drop-outs in */ /* an outline and correct the glyph bitmap to ensure consistent */ /* shape continuity. If set, this flag hints the scan-line */ /* converter to ignore such cases. See below for more information. */ /* */ /* FT_OUTLINE_SMART_DROPOUTS :: */ /* Select smart dropout control. If unset, use simple dropout */ /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See */ /* below for more information. */ /* */ /* FT_OUTLINE_INCLUDE_STUBS :: */ /* If set, turn pixels on for `stubs', otherwise exclude them. */ /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. See below for */ /* more information. */ /* */ /* FT_OUTLINE_HIGH_PRECISION :: */ /* This flag indicates that the scan-line converter should try to */ /* convert this outline to bitmaps with the highest possible */ /* quality. It is typically set for small character sizes. Note */ /* that this is only a hint that might be completely ignored by a */ /* given scan-converter. */ /* */ /* FT_OUTLINE_SINGLE_PASS :: */ /* This flag is set to force a given scan-converter to only use a */ /* single pass over the outline to render a bitmap glyph image. */ /* Normally, it is set for very large character sizes. It is only */ /* a hint that might be completely ignored by a given */ /* scan-converter. */ /* */ /* <Note> */ /* The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */ /* and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth */ /* rasterizer. */ /* */ /* There exists a second mechanism to pass the drop-out mode to the */ /* B/W rasterizer; see the `tags' field in @FT_Outline. */ /* */ /* Please refer to the description of the `SCANTYPE' instruction in */ /* the OpenType specification (in file `ttinst1.doc') how simple */ /* drop-outs, smart drop-outs, and stubs are defined. */ /* */ #define FT_OUTLINE_NONE 0x0 #define FT_OUTLINE_OWNER 0x1 #define FT_OUTLINE_EVEN_ODD_FILL 0x2 #define FT_OUTLINE_REVERSE_FILL 0x4 #define FT_OUTLINE_IGNORE_DROPOUTS 0x8 #define FT_OUTLINE_SMART_DROPOUTS 0x10 #define FT_OUTLINE_INCLUDE_STUBS 0x20 #define FT_OUTLINE_HIGH_PRECISION 0x100 #define FT_OUTLINE_SINGLE_PASS 0x200 /* these constants are deprecated; use the corresponding */ /* `FT_OUTLINE_XXX' values instead */ #define ft_outline_none FT_OUTLINE_NONE #define ft_outline_owner FT_OUTLINE_OWNER #define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL #define ft_outline_reverse_fill FT_OUTLINE_REVERSE_FILL #define ft_outline_ignore_dropouts FT_OUTLINE_IGNORE_DROPOUTS #define ft_outline_high_precision FT_OUTLINE_HIGH_PRECISION #define ft_outline_single_pass FT_OUTLINE_SINGLE_PASS /* */ #define FT_CURVE_TAG( flag ) ( flag & 3 ) #define FT_CURVE_TAG_ON 1 #define FT_CURVE_TAG_CONIC 0 #define FT_CURVE_TAG_CUBIC 2 #define FT_CURVE_TAG_HAS_SCANMODE 4 #define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ #define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ #define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ FT_CURVE_TAG_TOUCH_Y ) #define FT_Curve_Tag_On FT_CURVE_TAG_ON #define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC #define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC #define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X #define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Outline_MoveToFunc */ /* */ /* <Description> */ /* A function pointer type used to describe the signature of a `move */ /* to' function during outline walking/decomposition. */ /* */ /* A `move to' is emitted to start a new contour in an outline. */ /* */ /* <Input> */ /* to :: A pointer to the target point of the `move to'. */ /* */ /* user :: A typeless pointer, which is passed from the caller of the */ /* decomposition function. */ /* */ /* <Return> */ /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_MoveToFunc)( const FT_Vector* to, void* user ); #define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Outline_LineToFunc */ /* */ /* <Description> */ /* A function pointer type used to describe the signature of a `line */ /* to' function during outline walking/decomposition. */ /* */ /* A `line to' is emitted to indicate a segment in the outline. */ /* */ /* <Input> */ /* to :: A pointer to the target point of the `line to'. */ /* */ /* user :: A typeless pointer, which is passed from the caller of the */ /* decomposition function. */ /* */ /* <Return> */ /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_LineToFunc)( const FT_Vector* to, void* user ); #define FT_Outline_LineTo_Func FT_Outline_LineToFunc /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Outline_ConicToFunc */ /* */ /* <Description> */ /* A function pointer type used to describe the signature of a `conic */ /* to' function during outline walking or decomposition. */ /* */ /* A `conic to' is emitted to indicate a second-order Bezier arc in */ /* the outline. */ /* */ /* <Input> */ /* control :: An intermediate control point between the last position */ /* and the new target in `to'. */ /* */ /* to :: A pointer to the target end point of the conic arc. */ /* */ /* user :: A typeless pointer, which is passed from the caller of */ /* the decomposition function. */ /* */ /* <Return> */ /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_ConicToFunc)( const FT_Vector* control, const FT_Vector* to, void* user ); #define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Outline_CubicToFunc */ /* */ /* <Description> */ /* A function pointer type used to describe the signature of a `cubic */ /* to' function during outline walking or decomposition. */ /* */ /* A `cubic to' is emitted to indicate a third-order Bezier arc. */ /* */ /* <Input> */ /* control1 :: A pointer to the first Bezier control point. */ /* */ /* control2 :: A pointer to the second Bezier control point. */ /* */ /* to :: A pointer to the target end point. */ /* */ /* user :: A typeless pointer, which is passed from the caller of */ /* the decomposition function. */ /* */ /* <Return> */ /* Error code. 0~means success. */ /* */ typedef int (*FT_Outline_CubicToFunc)( const FT_Vector* control1, const FT_Vector* control2, const FT_Vector* to, void* user ); #define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc /*************************************************************************/ /* */ /* <Struct> */ /* FT_Outline_Funcs */ /* */ /* <Description> */ /* A structure to hold various function pointers used during outline */ /* decomposition in order to emit segments, conic, and cubic Beziers. */ /* */ /* <Fields> */ /* move_to :: The `move to' emitter. */ /* */ /* line_to :: The segment emitter. */ /* */ /* conic_to :: The second-order Bezier arc emitter. */ /* */ /* cubic_to :: The third-order Bezier arc emitter. */ /* */ /* shift :: The shift that is applied to coordinates before they */ /* are sent to the emitter. */ /* */ /* delta :: The delta that is applied to coordinates before they */ /* are sent to the emitter, but after the shift. */ /* */ /* <Note> */ /* The point coordinates sent to the emitters are the transformed */ /* version of the original coordinates (this is important for high */ /* accuracy during scan-conversion). The transformation is simple: */ /* */ /* { */ /* x' = (x << shift) - delta */ /* y' = (y << shift) - delta */ /* } */ /* */ /* Set the values of `shift' and `delta' to~0 to get the original */ /* point coordinates. */ /* */ typedef struct FT_Outline_Funcs_ { FT_Outline_MoveToFunc move_to; FT_Outline_LineToFunc line_to; FT_Outline_ConicToFunc conic_to; FT_Outline_CubicToFunc cubic_to; int shift; FT_Pos delta; } FT_Outline_Funcs; /*************************************************************************/ /* */ /* <Section> */ /* basic_types */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Macro> */ /* FT_IMAGE_TAG */ /* */ /* <Description> */ /* This macro converts four-letter tags to an unsigned long type. */ /* */ /* <Note> */ /* Since many 16-bit compilers don't like 32-bit enumerations, you */ /* should redefine this macro in case of problems to something like */ /* this: */ /* */ /* { */ /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value */ /* } */ /* */ /* to get a simple enumeration without assigning special numbers. */ /* */ #ifndef FT_IMAGE_TAG #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ value = ( ( (unsigned long)_x1 << 24 ) | \ ( (unsigned long)_x2 << 16 ) | \ ( (unsigned long)_x3 << 8 ) | \ (unsigned long)_x4 ) #endif /* FT_IMAGE_TAG */ /*************************************************************************/ /* */ /* <Enum> */ /* FT_Glyph_Format */ /* */ /* <Description> */ /* An enumeration type used to describe the format of a given glyph */ /* image. Note that this version of FreeType only supports two image */ /* formats, even though future font drivers will be able to register */ /* their own format. */ /* */ /* <Values> */ /* FT_GLYPH_FORMAT_NONE :: */ /* The value~0 is reserved. */ /* */ /* FT_GLYPH_FORMAT_COMPOSITE :: */ /* The glyph image is a composite of several other images. This */ /* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to */ /* report compound glyphs (like accented characters). */ /* */ /* FT_GLYPH_FORMAT_BITMAP :: */ /* The glyph image is a bitmap, and can be described as an */ /* @FT_Bitmap. You generally need to access the `bitmap' field of */ /* the @FT_GlyphSlotRec structure to read it. */ /* */ /* FT_GLYPH_FORMAT_OUTLINE :: */ /* The glyph image is a vectorial outline made of line segments */ /* and Bezier arcs; it can be described as an @FT_Outline; you */ /* generally want to access the `outline' field of the */ /* @FT_GlyphSlotRec structure to read it. */ /* */ /* FT_GLYPH_FORMAT_PLOTTER :: */ /* The glyph image is a vectorial path with no inside and outside */ /* contours. Some Type~1 fonts, like those in the Hershey family, */ /* contain glyphs in this format. These are described as */ /* @FT_Outline, but FreeType isn't currently capable of rendering */ /* them correctly. */ /* */ typedef enum FT_Glyph_Format_ { FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ), FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ), FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ), FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ), FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' ) } FT_Glyph_Format; /* these constants are deprecated; use the corresponding */ /* `FT_Glyph_Format' values instead. */ #define ft_glyph_format_none FT_GLYPH_FORMAT_NONE #define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE #define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP #define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE #define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** R A S T E R D E F I N I T I O N S *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* A raster is a scan converter, in charge of rendering an outline into */ /* a bitmap. This section contains the public API for rasters. */ /* */ /* Note that in FreeType 2, all rasters are now encapsulated within */ /* specific modules called `renderers'. See `ftrender.h' for more */ /* details on renderers. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Section> */ /* raster */ /* */ /* <Title> */ /* Scanline Converter */ /* */ /* <Abstract> */ /* How vectorial outlines are converted into bitmaps and pixmaps. */ /* */ /* <Description> */ /* This section contains technical definitions. */ /* */ /* <Order> */ /* FT_Raster */ /* FT_Span */ /* FT_SpanFunc */ /* */ /* FT_Raster_Params */ /* FT_RASTER_FLAG_XXX */ /* */ /* FT_Raster_NewFunc */ /* FT_Raster_DoneFunc */ /* FT_Raster_ResetFunc */ /* FT_Raster_SetModeFunc */ /* FT_Raster_RenderFunc */ /* FT_Raster_Funcs */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Type> */ /* FT_Raster */ /* */ /* <Description> */ /* An opaque handle (pointer) to a raster object. Each object can be */ /* used independently to convert an outline into a bitmap or pixmap. */ /* */ typedef struct FT_RasterRec_* FT_Raster; /*************************************************************************/ /* */ /* <Struct> */ /* FT_Span */ /* */ /* <Description> */ /* A structure used to model a single span of gray pixels when */ /* rendering an anti-aliased bitmap. */ /* */ /* <Fields> */ /* x :: The span's horizontal start position. */ /* */ /* len :: The span's length in pixels. */ /* */ /* coverage :: The span color/coverage, ranging from 0 (background) */ /* to 255 (foreground). */ /* */ /* <Note> */ /* This structure is used by the span drawing callback type named */ /* @FT_SpanFunc that takes the y~coordinate of the span as a */ /* parameter. */ /* */ /* The coverage value is always between 0 and 255. If you want less */ /* gray values, the callback function has to reduce them. */ /* */ typedef struct FT_Span_ { short x; unsigned short len; unsigned char coverage; } FT_Span; /*************************************************************************/ /* */ /* <FuncType> */ /* FT_SpanFunc */ /* */ /* <Description> */ /* A function used as a call-back by the anti-aliased renderer in */ /* order to let client applications draw themselves the gray pixel */ /* spans on each scan line. */ /* */ /* <Input> */ /* y :: The scanline's y~coordinate. */ /* */ /* count :: The number of spans to draw on this scanline. */ /* */ /* spans :: A table of `count' spans to draw on the scanline. */ /* */ /* user :: User-supplied data that is passed to the callback. */ /* */ /* <Note> */ /* This callback allows client applications to directly render the */ /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ /* */ /* This can be used to write anti-aliased outlines directly to a */ /* given background bitmap, and even perform translucency. */ /* */ typedef void (*FT_SpanFunc)( int y, int count, const FT_Span* spans, void* user ); #define FT_Raster_Span_Func FT_SpanFunc /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Raster_BitTest_Func */ /* */ /* <Description> */ /* Deprecated, unimplemented. */ /* */ typedef int (*FT_Raster_BitTest_Func)( int y, int x, void* user ); /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Raster_BitSet_Func */ /* */ /* <Description> */ /* Deprecated, unimplemented. */ /* */ typedef void (*FT_Raster_BitSet_Func)( int y, int x, void* user ); /*************************************************************************/ /* */ /* <Enum> */ /* FT_RASTER_FLAG_XXX */ /* */ /* <Description> */ /* A list of bit flag constants as used in the `flags' field of a */ /* @FT_Raster_Params structure. */ /* */ /* <Values> */ /* FT_RASTER_FLAG_DEFAULT :: This value is 0. */ /* */ /* FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ /* anti-aliased glyph image should be */ /* generated. Otherwise, it will be */ /* monochrome (1-bit). */ /* */ /* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ /* rendering. In this mode, client */ /* applications must provide their own span */ /* callback. This lets them directly */ /* draw or compose over an existing bitmap. */ /* If this bit is not set, the target */ /* pixmap's buffer _must_ be zeroed before */ /* rendering. */ /* */ /* Direct rendering is only possible with */ /* anti-aliased glyphs. */ /* */ /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ /* rendering mode. If set, the output will */ /* be clipped to a box specified in the */ /* `clip_box' field of the */ /* @FT_Raster_Params structure. */ /* */ /* Note that by default, the glyph bitmap */ /* is clipped to the target pixmap, except */ /* in direct rendering mode where all spans */ /* are generated if no clipping box is set. */ /* */ #define FT_RASTER_FLAG_DEFAULT 0x0 #define FT_RASTER_FLAG_AA 0x1 #define FT_RASTER_FLAG_DIRECT 0x2 #define FT_RASTER_FLAG_CLIP 0x4 /* these constants are deprecated; use the corresponding */ /* `FT_RASTER_FLAG_XXX' values instead */ #define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT #define ft_raster_flag_aa FT_RASTER_FLAG_AA #define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT #define ft_raster_flag_clip FT_RASTER_FLAG_CLIP /*************************************************************************/ /* */ /* <Struct> */ /* FT_Raster_Params */ /* */ /* <Description> */ /* A structure to hold the arguments used by a raster's render */ /* function. */ /* */ /* <Fields> */ /* target :: The target bitmap. */ /* */ /* source :: A pointer to the source glyph image (e.g., an */ /* @FT_Outline). */ /* */ /* flags :: The rendering flags. */ /* */ /* gray_spans :: The gray span drawing callback. */ /* */ /* black_spans :: Unused. */ /* */ /* bit_test :: Unused. */ /* */ /* bit_set :: Unused. */ /* */ /* user :: User-supplied data that is passed to each drawing */ /* callback. */ /* */ /* clip_box :: An optional clipping box. It is only used in */ /* direct rendering mode. Note that coordinates here */ /* should be expressed in _integer_ pixels (and not in */ /* 26.6 fixed-point units). */ /* */ /* <Note> */ /* An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA */ /* bit flag is set in the `flags' field, otherwise a monochrome */ /* bitmap is generated. */ /* */ /* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ /* raster will call the `gray_spans' callback to draw gray pixel */ /* spans. This allows direct composition over a pre-existing bitmap */ /* through user-provided callbacks to perform the span drawing and */ /* composition. Not supported by the monochrome rasterizer. */ /* */ typedef struct FT_Raster_Params_ { const FT_Bitmap* target; const void* source; int flags; FT_SpanFunc gray_spans; FT_SpanFunc black_spans; /* unused */ FT_Raster_BitTest_Func bit_test; /* unused */ FT_Raster_BitSet_Func bit_set; /* unused */ void* user; FT_BBox clip_box; } FT_Raster_Params; /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Raster_NewFunc */ /* */ /* <Description> */ /* A function used to create a new raster object. */ /* */ /* <Input> */ /* memory :: A handle to the memory allocator. */ /* */ /* <Output> */ /* raster :: A handle to the new raster object. */ /* */ /* <Return> */ /* Error code. 0~means success. */ /* */ /* <Note> */ /* The `memory' parameter is a typeless pointer in order to avoid */ /* un-wanted dependencies on the rest of the FreeType code. In */ /* practice, it is an @FT_Memory object, i.e., a handle to the */ /* standard FreeType memory allocator. However, this field can be */ /* completely ignored by a given raster implementation. */ /* */ typedef int (*FT_Raster_NewFunc)( void* memory, FT_Raster* raster ); #define FT_Raster_New_Func FT_Raster_NewFunc /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Raster_DoneFunc */ /* */ /* <Description> */ /* A function used to destroy a given raster object. */ /* */ /* <Input> */ /* raster :: A handle to the raster object. */ /* */ typedef void (*FT_Raster_DoneFunc)( FT_Raster raster ); #define FT_Raster_Done_Func FT_Raster_DoneFunc /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Raster_ResetFunc */ /* */ /* <Description> */ /* FreeType used to provide an area of memory called the `render */ /* pool' available to all registered rasterizers. This was not */ /* thread safe, however, and now FreeType never allocates this pool. */ /* */ /* This function is called after a new raster object is created. */ /* */ /* <Input> */ /* raster :: A handle to the new raster object. */ /* */ /* pool_base :: Previously, the address in memory of the render pool. */ /* Set this to NULL. */ /* */ /* pool_size :: Previously, the size in bytes of the render pool. */ /* Set this to 0. */ /* */ /* <Note> */ /* Rasterizers should rely on dynamic or stack allocation if they */ /* want to (a handle to the memory allocator is passed to the */ /* rasterizer constructor). */ /* */ typedef void (*FT_Raster_ResetFunc)( FT_Raster raster, unsigned char* pool_base, unsigned long pool_size ); #define FT_Raster_Reset_Func FT_Raster_ResetFunc /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Raster_SetModeFunc */ /* */ /* <Description> */ /* This function is a generic facility to change modes or attributes */ /* in a given raster. This can be used for debugging purposes, or */ /* simply to allow implementation-specific `features' in a given */ /* raster module. */ /* */ /* <Input> */ /* raster :: A handle to the new raster object. */ /* */ /* mode :: A 4-byte tag used to name the mode or property. */ /* */ /* args :: A pointer to the new mode/property to use. */ /* */ typedef int (*FT_Raster_SetModeFunc)( FT_Raster raster, unsigned long mode, void* args ); #define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc /*************************************************************************/ /* */ /* <FuncType> */ /* FT_Raster_RenderFunc */ /* */ /* <Description> */ /* Invoke a given raster to scan-convert a given glyph image into a */ /* target bitmap. */ /* */ /* <Input> */ /* raster :: A handle to the raster object. */ /* */ /* params :: A pointer to an @FT_Raster_Params structure used to */ /* store the rendering parameters. */ /* */ /* <Return> */ /* Error code. 0~means success. */ /* */ /* <Note> */ /* The exact format of the source image depends on the raster's glyph */ /* format defined in its @FT_Raster_Funcs structure. It can be an */ /* @FT_Outline or anything else in order to support a large array of */ /* glyph formats. */ /* */ /* Note also that the render function can fail and return a */ /* `FT_Err_Unimplemented_Feature' error code if the raster used does */ /* not support direct composition. */ /* */ /* XXX: For now, the standard raster doesn't support direct */ /* composition but this should change for the final release (see */ /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ /* for examples of distinct implementations that support direct */ /* composition). */ /* */ typedef int (*FT_Raster_RenderFunc)( FT_Raster raster, const FT_Raster_Params* params ); #define FT_Raster_Render_Func FT_Raster_RenderFunc /*************************************************************************/ /* */ /* <Struct> */ /* FT_Raster_Funcs */ /* */ /* <Description> */ /* A structure used to describe a given raster class to the library. */ /* */ /* <Fields> */ /* glyph_format :: The supported glyph format for this raster. */ /* */ /* raster_new :: The raster constructor. */ /* */ /* raster_reset :: Used to reset the render pool within the raster. */ /* */ /* raster_render :: A function to render a glyph into a given bitmap. */ /* */ /* raster_done :: The raster destructor. */ /* */ typedef struct FT_Raster_Funcs_ { FT_Glyph_Format glyph_format; FT_Raster_NewFunc raster_new; FT_Raster_ResetFunc raster_reset; FT_Raster_SetModeFunc raster_set_mode; FT_Raster_RenderFunc raster_render; FT_Raster_DoneFunc raster_done; } FT_Raster_Funcs; /* */ FT_END_HEADER #endif /* FTIMAGE_H_ */ /* END */ /* Local Variables: */ /* coding: utf-8 */ /* End: */ netiucv/iucv.h 0000644 00000003071 15146341150 0007341 0 ustar 00 /* Copyright (C) 2007-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __NETIUCV_IUCV_H #define __NETIUCV_IUCV_H 1 #include <features.h> #include <bits/sockaddr.h> __BEGIN_DECLS struct sockaddr_iucv { __SOCKADDR_COMMON (siucv_); unsigned short siucv_port; /* Reserved */ unsigned int siucv_addr; /* Reserved */ char siucv_nodeid[8]; /* Reserved */ char siucv_user_id[8]; /* Guest User Id */ char siucv_name[8]; /* Application Name */ }; __END_DECLS #define SOL_IUCV 277 /* IUCV level */ /* IUCV socket options (SOL_IUCV) */ #define SO_IPRMDATA_MSG 0x0080 /* Send/recv IPRM_DATA msgs */ #define SO_MSGLIMIT 0x1000 /* Get/set IUCV MSGLIMIT */ #define SO_MSGSIZE 0x0800 /* Get maximum msgsize */ /* IUCV related control messages (scm) */ #define SCM_IUCV_TRGCLS 0x0001 /* Target class control message */ #endif cursesapp.h 0000644 00000015167 15146341150 0006734 0 ustar 00 // * This makes emacs happy -*-Mode: C++;-*- /**************************************************************************** * Copyright (c) 1998-2005,2011 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, distribute with modifications, sublicense, and/or sell * * copies of the Software, and to permit persons to whom the Software is * * furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included * * in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * * * Except as contained in this notice, the name(s) of the above copyright * * holders shall not be used in advertising or otherwise to promote the * * sale, use or other dealings in this Software without prior written * * authorization. * ****************************************************************************/ /**************************************************************************** * Author: Juergen Pfeifer, 1997 * ****************************************************************************/ // $Id: cursesapp.h,v 1.12 2011/09/17 22:12:10 tom Exp $ #ifndef NCURSES_CURSESAPP_H_incl #define NCURSES_CURSESAPP_H_incl #include <cursslk.h> class NCURSES_IMPEXP NCursesApplication { public: typedef struct _slk_link { // This structure is used to maintain struct _slk_link* prev; // a stack of SLKs Soft_Label_Key_Set* SLKs; } SLK_Link; private: static int rinit(NCursesWindow& w); // Internal Init function for title static NCursesApplication* theApp; // Global ref. to the application static SLK_Link* slk_stack; protected: static NCursesWindow* titleWindow; // The Title Window (if any) bool b_Colors; // Is this a color application? NCursesWindow* Root_Window; // This is the stdscr equiv. // Initialization of attributes; // Rewrite this in your derived class if you prefer other settings virtual void init(bool bColors); // The number of lines for the title window. Default is no title window // You may rewrite this in your derived class virtual int titlesize() const { return 0; } // This method is called to put something into the title window initially // You may rewrite this in your derived class virtual void title() { } // The layout used for the Soft Label Keys. Default is to have no SLKs. // You may rewrite this in your derived class virtual Soft_Label_Key_Set::Label_Layout useSLKs() const { return Soft_Label_Key_Set::None; } // This method is called to initialize the SLKs. Default is nothing. // You may rewrite this in your derived class virtual void init_labels(Soft_Label_Key_Set& S) const { (void) S; } // Your derived class must implement this method. The return value must // be the exit value of your application. virtual int run() = 0; // The constructor is protected, so you may use it in your derived // class constructor. The argument tells whether or not you want colors. NCursesApplication(bool wantColors = FALSE); NCursesApplication& operator=(const NCursesApplication& rhs) { if (this != &rhs) { *this = rhs; } return *this; } NCursesApplication(const NCursesApplication& rhs) : b_Colors(rhs.b_Colors), Root_Window(rhs.Root_Window) { } public: virtual ~NCursesApplication(); // Get a pointer to the current application object static NCursesApplication* getApplication() { return theApp; } // This method runs the application and returns its exit value int operator()(void); // Process the commandline arguments. The default implementation simply // ignores them. Your derived class may rewrite this. virtual void handleArgs(int argc, char* argv[]) { (void) argc; (void) argv; } // Does this application use colors? inline bool useColors() const { return b_Colors; } // Push the Key Set S onto the SLK Stack. S then becomes the current set // of Soft Labelled Keys. void push(Soft_Label_Key_Set& S); // Throw away the current set of SLKs and make the previous one the // new current set. bool pop(); // Retrieve the current set of Soft Labelled Keys. Soft_Label_Key_Set* top() const; // Attributes to use for menu and forms foregrounds virtual chtype foregrounds() const { return b_Colors ? static_cast<chtype>(COLOR_PAIR(1)) : A_BOLD; } // Attributes to use for menu and forms backgrounds virtual chtype backgrounds() const { return b_Colors ? static_cast<chtype>(COLOR_PAIR(2)) : A_NORMAL; } // Attributes to use for inactive (menu) elements virtual chtype inactives() const { return b_Colors ? static_cast<chtype>(COLOR_PAIR(3)|A_DIM) : A_DIM; } // Attributes to use for (form) labels and SLKs virtual chtype labels() const { return b_Colors ? static_cast<chtype>(COLOR_PAIR(4)) : A_NORMAL; } // Attributes to use for form backgrounds virtual chtype dialog_backgrounds() const { return b_Colors ? static_cast<chtype>(COLOR_PAIR(4)) : A_NORMAL; } // Attributes to use as default for (form) window backgrounds virtual chtype window_backgrounds() const { return b_Colors ? static_cast<chtype>(COLOR_PAIR(5)) : A_NORMAL; } // Attributes to use for the title window virtual chtype screen_titles() const { return b_Colors ? static_cast<chtype>(COLOR_PAIR(6)) : A_BOLD; } }; #endif /* NCURSES_CURSESAPP_H_incl */ link.h 0000644 00000016062 15146341150 0005657 0 ustar 00 /* Data structure for communication from the run-time dynamic linker for loaded ELF shared objects. Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _LINK_H #define _LINK_H 1 #include <features.h> #include <elf.h> #include <dlfcn.h> #include <sys/types.h> /* We use this macro to refer to ELF types independent of the native wordsize. `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */ #define ElfW(type) _ElfW (Elf, __ELF_NATIVE_CLASS, type) #define _ElfW(e,w,t) _ElfW_1 (e, w, _##t) #define _ElfW_1(e,w,t) e##w##t #include <bits/elfclass.h> /* Defines __ELF_NATIVE_CLASS. */ #include <bits/link.h> /* Rendezvous structure used by the run-time dynamic linker to communicate details of shared object loading to the debugger. If the executable's dynamic section has a DT_DEBUG element, the run-time linker sets that element's value to the address where this structure can be found. */ struct r_debug { int r_version; /* Version number for this protocol. */ struct link_map *r_map; /* Head of the chain of loaded objects. */ /* This is the address of a function internal to the run-time linker, that will always be called when the linker begins to map in a library or unmap it, and again when the mapping change is complete. The debugger can set a breakpoint at this address if it wants to notice shared object mapping changes. */ ElfW(Addr) r_brk; enum { /* This state value describes the mapping change taking place when the `r_brk' address is called. */ RT_CONSISTENT, /* Mapping change is complete. */ RT_ADD, /* Beginning to add a new object. */ RT_DELETE /* Beginning to remove an object mapping. */ } r_state; ElfW(Addr) r_ldbase; /* Base address the linker is loaded at. */ }; /* This is the instance of that structure used by the dynamic linker. */ extern struct r_debug _r_debug; /* This symbol refers to the "dynamic structure" in the `.dynamic' section of whatever module refers to `_DYNAMIC'. So, to find its own `struct r_debug', a program could do: for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn) if (dyn->d_tag == DT_DEBUG) r_debug = (struct r_debug *) dyn->d_un.d_ptr; */ extern ElfW(Dyn) _DYNAMIC[]; /* Structure describing a loaded shared object. The `l_next' and `l_prev' members form a chain of all the shared objects loaded at startup. These data structures exist in space used by the run-time dynamic linker; modifying them may have disastrous results. */ struct link_map { /* These first few members are part of the protocol with the debugger. This is the same format used in SVR4. */ ElfW(Addr) l_addr; /* Difference between the address in the ELF file and the addresses in memory. */ char *l_name; /* Absolute file name object was found in. */ ElfW(Dyn) *l_ld; /* Dynamic section of the shared object. */ struct link_map *l_next, *l_prev; /* Chain of loaded objects. */ }; #ifdef __USE_GNU /* Version numbers for la_version handshake interface. */ #include <bits/link_lavcurrent.h> /* Activity types signaled through la_activity. */ enum { LA_ACT_CONSISTENT, /* Link map consistent again. */ LA_ACT_ADD, /* New object will be added. */ LA_ACT_DELETE /* Objects will be removed. */ }; /* Values representing origin of name for dynamic loading. */ enum { LA_SER_ORIG = 0x01, /* Original name. */ LA_SER_LIBPATH = 0x02, /* Directory from LD_LIBRARY_PATH. */ LA_SER_RUNPATH = 0x04, /* Directory from RPATH/RUNPATH. */ LA_SER_CONFIG = 0x08, /* Found through ldconfig. */ LA_SER_DEFAULT = 0x40, /* Default directory. */ LA_SER_SECURE = 0x80 /* Unused. */ }; /* Values for la_objopen return value. */ enum { LA_FLG_BINDTO = 0x01, /* Audit symbols bound to this object. */ LA_FLG_BINDFROM = 0x02 /* Audit symbols bound from this object. */ }; /* Values for la_symbind flags parameter. */ enum { LA_SYMB_NOPLTENTER = 0x01, /* la_pltenter will not be called. */ LA_SYMB_NOPLTEXIT = 0x02, /* la_pltexit will not be called. */ LA_SYMB_STRUCTCALL = 0x04, /* Return value is a structure. */ LA_SYMB_DLSYM = 0x08, /* Binding due to dlsym call. */ LA_SYMB_ALTVALUE = 0x10 /* Value has been changed by a previous la_symbind call. */ }; struct dl_phdr_info { ElfW(Addr) dlpi_addr; const char *dlpi_name; const ElfW(Phdr) *dlpi_phdr; ElfW(Half) dlpi_phnum; /* Note: Following members were introduced after the first version of this structure was available. Check the SIZE argument passed to the dl_iterate_phdr callback to determine whether or not each later member is available. */ /* Incremented when a new object may have been added. */ __extension__ unsigned long long int dlpi_adds; /* Incremented when an object may have been removed. */ __extension__ unsigned long long int dlpi_subs; /* If there is a PT_TLS segment, its module ID as used in TLS relocations, else zero. */ size_t dlpi_tls_modid; /* The address of the calling thread's instance of this module's PT_TLS segment, if it has one and it has been allocated in the calling thread, otherwise a null pointer. */ void *dlpi_tls_data; }; __BEGIN_DECLS extern int dl_iterate_phdr (int (*__callback) (struct dl_phdr_info *, size_t, void *), void *__data); /* Prototypes for the ld.so auditing interfaces. These are not defined anywhere in ld.so but instead have to be provided by the auditing DSO. */ extern unsigned int la_version (unsigned int __version); extern void la_activity (uintptr_t *__cookie, unsigned int __flag); extern char *la_objsearch (const char *__name, uintptr_t *__cookie, unsigned int __flag); extern unsigned int la_objopen (struct link_map *__map, Lmid_t __lmid, uintptr_t *__cookie); extern void la_preinit (uintptr_t *__cookie); extern uintptr_t la_symbind32 (Elf32_Sym *__sym, unsigned int __ndx, uintptr_t *__refcook, uintptr_t *__defcook, unsigned int *__flags, const char *__symname); extern uintptr_t la_symbind64 (Elf64_Sym *__sym, unsigned int __ndx, uintptr_t *__refcook, uintptr_t *__defcook, unsigned int *__flags, const char *__symname); extern unsigned int la_objclose (uintptr_t *__cookie); __END_DECLS #endif #endif /* link.h */ execinfo.h 0000644 00000002762 15146341150 0006524 0 ustar 00 /* Copyright (C) 1998-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _EXECINFO_H #define _EXECINFO_H 1 #include <features.h> __BEGIN_DECLS /* Store up to SIZE return address of the current program state in ARRAY and return the exact number of values stored. */ extern int backtrace (void **__array, int __size) __nonnull ((1)); /* Return names of functions from the backtrace list in ARRAY in a newly malloc()ed memory block. */ extern char **backtrace_symbols (void *const *__array, int __size) __THROW __nonnull ((1)); /* This function is similar to backtrace_symbols() but it writes the result immediately to a file. */ extern void backtrace_symbols_fd (void *const *__array, int __size, int __fd) __THROW __nonnull ((1)); __END_DECLS #endif /* execinfo.h */ libexslt/exslt.h 0000644 00000005712 15146341150 0007707 0 ustar 00 #ifndef __EXSLT_H__ #define __EXSLT_H__ #include <libxml/tree.h> #include <libxml/xpath.h> #include "exsltexports.h" #include <libexslt/exsltconfig.h> #ifdef __cplusplus extern "C" { #endif EXSLTPUBVAR const char *exsltLibraryVersion; EXSLTPUBVAR const int exsltLibexsltVersion; EXSLTPUBVAR const int exsltLibxsltVersion; EXSLTPUBVAR const int exsltLibxmlVersion; /** * EXSLT_COMMON_NAMESPACE: * * Namespace for EXSLT common functions */ #define EXSLT_COMMON_NAMESPACE ((const xmlChar *) "http://exslt.org/common") /** * EXSLT_CRYPTO_NAMESPACE: * * Namespace for EXSLT crypto functions */ #define EXSLT_CRYPTO_NAMESPACE ((const xmlChar *) "http://exslt.org/crypto") /** * EXSLT_MATH_NAMESPACE: * * Namespace for EXSLT math functions */ #define EXSLT_MATH_NAMESPACE ((const xmlChar *) "http://exslt.org/math") /** * EXSLT_SETS_NAMESPACE: * * Namespace for EXSLT set functions */ #define EXSLT_SETS_NAMESPACE ((const xmlChar *) "http://exslt.org/sets") /** * EXSLT_FUNCTIONS_NAMESPACE: * * Namespace for EXSLT functions extension functions */ #define EXSLT_FUNCTIONS_NAMESPACE ((const xmlChar *) "http://exslt.org/functions") /** * EXSLT_STRINGS_NAMESPACE: * * Namespace for EXSLT strings functions */ #define EXSLT_STRINGS_NAMESPACE ((const xmlChar *) "http://exslt.org/strings") /** * EXSLT_DATE_NAMESPACE: * * Namespace for EXSLT date functions */ #define EXSLT_DATE_NAMESPACE ((const xmlChar *) "http://exslt.org/dates-and-times") /** * EXSLT_DYNAMIC_NAMESPACE: * * Namespace for EXSLT dynamic functions */ #define EXSLT_DYNAMIC_NAMESPACE ((const xmlChar *) "http://exslt.org/dynamic") /** * SAXON_NAMESPACE: * * Namespace for SAXON extensions functions */ #define SAXON_NAMESPACE ((const xmlChar *) "http://icl.com/saxon") EXSLTPUBFUN void EXSLTCALL exsltCommonRegister (void); #ifdef EXSLT_CRYPTO_ENABLED EXSLTPUBFUN void EXSLTCALL exsltCryptoRegister (void); #endif EXSLTPUBFUN void EXSLTCALL exsltMathRegister (void); EXSLTPUBFUN void EXSLTCALL exsltSetsRegister (void); EXSLTPUBFUN void EXSLTCALL exsltFuncRegister (void); EXSLTPUBFUN void EXSLTCALL exsltStrRegister (void); EXSLTPUBFUN void EXSLTCALL exsltDateRegister (void); EXSLTPUBFUN void EXSLTCALL exsltSaxonRegister (void); EXSLTPUBFUN void EXSLTCALL exsltDynRegister(void); EXSLTPUBFUN void EXSLTCALL exsltRegisterAll (void); EXSLTPUBFUN int EXSLTCALL exsltDateXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix); EXSLTPUBFUN int EXSLTCALL exsltMathXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix); EXSLTPUBFUN int EXSLTCALL exsltSetsXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix); EXSLTPUBFUN int EXSLTCALL exsltStrXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix); #ifdef __cplusplus } #endif #endif /* __EXSLT_H__ */ libexslt/exsltconfig.h 0000644 00000002302 15146341150 0011065 0 ustar 00 /* * exsltconfig.h: compile-time version informations for the EXSLT library * * See Copyright for the status of this software. * * daniel@veillard.com */ #ifndef __XML_EXSLTCONFIG_H__ #define __XML_EXSLTCONFIG_H__ #ifdef __cplusplus extern "C" { #endif /** * LIBEXSLT_DOTTED_VERSION: * * the version string like "1.2.3" */ #define LIBEXSLT_DOTTED_VERSION "1.1.32" /** * LIBEXSLT_VERSION: * * the version number: 1.2.3 value is 10203 */ #define LIBEXSLT_VERSION 820 /** * LIBEXSLT_VERSION_STRING: * * the version number string, 1.2.3 value is "10203" */ #define LIBEXSLT_VERSION_STRING "820" /** * LIBEXSLT_VERSION_EXTRA: * * extra version information, used to show a CVS compilation */ #define LIBEXSLT_VERSION_EXTRA "" /** * WITH_CRYPTO: * * Whether crypto support is configured into exslt */ #if 1 #define EXSLT_CRYPTO_ENABLED #endif /** * ATTRIBUTE_UNUSED: * * This macro is used to flag unused function parameters to GCC */ #ifdef __GNUC__ #ifdef HAVE_ANSIDECL_H #include <ansidecl.h> #endif #ifndef ATTRIBUTE_UNUSED #define ATTRIBUTE_UNUSED __attribute__((unused)) #endif #else #define ATTRIBUTE_UNUSED #endif #ifdef __cplusplus } #endif #endif /* __XML_EXSLTCONFIG_H__ */ libexslt/exsltexports.h 0000644 00000006467 15146341150 0011344 0 ustar 00 /* * exsltexports.h : macros for marking symbols as exportable/importable. * * See Copyright for the status of this software. * * igor@zlatkovic.com */ #ifndef __EXSLT_EXPORTS_H__ #define __EXSLT_EXPORTS_H__ /** * EXSLTPUBFUN, EXSLTPUBVAR, EXSLTCALL * * Macros which declare an exportable function, an exportable variable and * the calling convention used for functions. * * Please use an extra block for every platform/compiler combination when * modifying this, rather than overlong #ifdef lines. This helps * readability as well as the fact that different compilers on the same * platform might need different definitions. */ /** * EXSLTPUBFUN: * * Macros which declare an exportable function */ #define EXSLTPUBFUN /** * EXSLTPUBVAR: * * Macros which declare an exportable variable */ #define EXSLTPUBVAR extern /** * EXSLTCALL: * * Macros which declare the called convention for exported functions */ #define EXSLTCALL /** DOC_DISABLE */ /* Windows platform with MS compiler */ #if defined(_WIN32) && defined(_MSC_VER) #undef EXSLTPUBFUN #undef EXSLTPUBVAR #undef EXSLTCALL #if defined(IN_LIBEXSLT) && !defined(LIBEXSLT_STATIC) #define EXSLTPUBFUN __declspec(dllexport) #define EXSLTPUBVAR __declspec(dllexport) #else #define EXSLTPUBFUN #if !defined(LIBEXSLT_STATIC) #define EXSLTPUBVAR __declspec(dllimport) extern #else #define EXSLTPUBVAR extern #endif #endif #define EXSLTCALL __cdecl #if !defined _REENTRANT #define _REENTRANT #endif #endif /* Windows platform with Borland compiler */ #if defined(_WIN32) && defined(__BORLANDC__) #undef EXSLTPUBFUN #undef EXSLTPUBVAR #undef EXSLTCALL #if defined(IN_LIBEXSLT) && !defined(LIBEXSLT_STATIC) #define EXSLTPUBFUN __declspec(dllexport) #define EXSLTPUBVAR __declspec(dllexport) extern #else #define EXSLTPUBFUN #if !defined(LIBEXSLT_STATIC) #define EXSLTPUBVAR __declspec(dllimport) extern #else #define EXSLTPUBVAR extern #endif #endif #define EXSLTCALL __cdecl #if !defined _REENTRANT #define _REENTRANT #endif #endif /* Windows platform with GNU compiler (Mingw) */ #if defined(_WIN32) && defined(__MINGW32__) #undef EXSLTPUBFUN #undef EXSLTPUBVAR #undef EXSLTCALL /* #if defined(IN_LIBEXSLT) && !defined(LIBEXSLT_STATIC) */ #if !defined(LIBEXSLT_STATIC) #define EXSLTPUBFUN __declspec(dllexport) #define EXSLTPUBVAR __declspec(dllexport) extern #else #define EXSLTPUBFUN #if !defined(LIBEXSLT_STATIC) #define EXSLTPUBVAR __declspec(dllimport) extern #else #define EXSLTPUBVAR extern #endif #endif #define EXSLTCALL __cdecl #if !defined _REENTRANT #define _REENTRANT #endif #endif /* Cygwin platform, GNU compiler */ #if defined(_WIN32) && defined(__CYGWIN__) #undef EXSLTPUBFUN #undef EXSLTPUBVAR #undef EXSLTCALL #if defined(IN_LIBEXSLT) && !defined(LIBEXSLT_STATIC) #define EXSLTPUBFUN __declspec(dllexport) #define EXSLTPUBVAR __declspec(dllexport) #else #define EXSLTPUBFUN #if !defined(LIBEXSLT_STATIC) #define EXSLTPUBVAR __declspec(dllimport) extern #else #define EXSLTPUBVAR #endif #endif #define EXSLTCALL __cdecl #endif /* Compatibility */ #if !defined(LIBEXSLT_PUBLIC) #define LIBEXSLT_PUBLIC EXSLTPUBVAR #endif #endif /* __EXSLT_EXPORTS_H__ */ libdb/db.h 0000444 00000360341 15146341150 0006363 0 ustar 00 /* * See the file LICENSE for redistribution information. * * Copyright (c) 1996, 2013 Oracle and/or its affiliates. All rights reserved. * * $Id$ * * db.h include file layout: * General. * Database Environment. * Locking subsystem. * Logging subsystem. * Shared buffer cache (mpool) subsystem. * Transaction subsystem. * Access methods. * Access method cursors. * Dbm/Ndbm, Hsearch historic interfaces. */ #ifndef _DB_H_ #define _DB_H_ #ifndef __NO_SYSTEM_INCLUDES #include <sys/types.h> #include <inttypes.h> #include <stdint.h> #include <stddef.h> #include <stdio.h> #include <unistd.h> #include <pthread.h> #endif #if defined(__cplusplus) extern "C" { #endif #undef __P #define __P(protos) protos /* * Berkeley DB version information. */ #define DB_VERSION_FAMILY 11 #define DB_VERSION_RELEASE 2 #define DB_VERSION_MAJOR 5 #define DB_VERSION_MINOR 3 #define DB_VERSION_PATCH 28 #define DB_VERSION_STRING "Berkeley DB 5.3.28: (September 9, 2013)" #define DB_VERSION_FULL_STRING "Berkeley DB 11g Release 2, library version 11.2.5.3.28: (September 9, 2013)" /* * !!! * Berkeley DB uses specifically sized types. If they're not provided by * the system, typedef them here. * * We protect them against multiple inclusion using __BIT_TYPES_DEFINED__, * as does BIND and Kerberos, since we don't know for sure what #include * files the user is using. * * !!! * We also provide the standard u_int, u_long etc., if they're not provided * by the system. */ #ifndef __BIT_TYPES_DEFINED__ #define __BIT_TYPES_DEFINED__ #endif /* * Missing ANSI types. * * uintmax_t -- * Largest unsigned type, used to align structures in memory. We don't store * floating point types in structures, so integral types should be sufficient * (and we don't have to worry about systems that store floats in other than * power-of-2 numbers of bytes). Additionally this fixes compilers that rewrite * structure assignments and ANSI C memcpy calls to be in-line instructions * that happen to require alignment. * * uintptr_t -- * Unsigned type that's the same size as a pointer. There are places where * DB modifies pointers by discarding the bottom bits to guarantee alignment. * We can't use uintmax_t, it may be larger than the pointer, and compilers * get upset about that. So far we haven't run on any machine where there's * no unsigned type the same size as a pointer -- here's hoping. */ #ifdef HAVE_MIXED_SIZE_ADDRESSING typedef u_int32_t db_size_t; #else typedef size_t db_size_t; #endif #ifdef HAVE_MIXED_SIZE_ADDRESSING typedef int32_t db_ssize_t; #else typedef ssize_t db_ssize_t; #endif /* * Sequences are only available on machines with 64-bit integral types. */ typedef int64_t db_seq_t; /* Thread and process identification. */ typedef pthread_t db_threadid_t; /* Basic types that are exported or quasi-exported. */ typedef u_int32_t db_pgno_t; /* Page number type. */ typedef u_int16_t db_indx_t; /* Page offset type. */ #define DB_MAX_PAGES 0xffffffff /* >= # of pages in a file */ typedef u_int32_t db_recno_t; /* Record number type. */ #define DB_MAX_RECORDS 0xffffffff /* >= # of records in a tree */ typedef u_int32_t db_timeout_t; /* Type of a timeout. */ /* * Region offsets are the difference between a pointer in a region and the * region's base address. With private environments, both addresses are the * result of calling malloc, and we can't assume anything about what malloc * will return, so region offsets have to be able to hold differences between * arbitrary pointers. */ typedef db_size_t roff_t; /* * Forward structure declarations, so we can declare pointers and * applications can get type checking. */ struct __channel; typedef struct __channel CHANNEL; struct __db; typedef struct __db DB; struct __db_bt_stat; typedef struct __db_bt_stat DB_BTREE_STAT; struct __db_channel; typedef struct __db_channel DB_CHANNEL; struct __db_cipher; typedef struct __db_cipher DB_CIPHER; struct __db_compact; typedef struct __db_compact DB_COMPACT; struct __db_dbt; typedef struct __db_dbt DBT; struct __db_distab; typedef struct __db_distab DB_DISTAB; struct __db_env; typedef struct __db_env DB_ENV; struct __db_h_stat; typedef struct __db_h_stat DB_HASH_STAT; struct __db_heap_rid; typedef struct __db_heap_rid DB_HEAP_RID; struct __db_heap_stat; typedef struct __db_heap_stat DB_HEAP_STAT; struct __db_ilock; typedef struct __db_ilock DB_LOCK_ILOCK; struct __db_lock_hstat; typedef struct __db_lock_hstat DB_LOCK_HSTAT; struct __db_lock_pstat; typedef struct __db_lock_pstat DB_LOCK_PSTAT; struct __db_lock_stat; typedef struct __db_lock_stat DB_LOCK_STAT; struct __db_lock_u; typedef struct __db_lock_u DB_LOCK; struct __db_locker; typedef struct __db_locker DB_LOCKER; struct __db_lockreq; typedef struct __db_lockreq DB_LOCKREQ; struct __db_locktab; typedef struct __db_locktab DB_LOCKTAB; struct __db_log; typedef struct __db_log DB_LOG; struct __db_log_cursor; typedef struct __db_log_cursor DB_LOGC; struct __db_log_stat; typedef struct __db_log_stat DB_LOG_STAT; struct __db_lsn; typedef struct __db_lsn DB_LSN; struct __db_mpool; typedef struct __db_mpool DB_MPOOL; struct __db_mpool_fstat;typedef struct __db_mpool_fstat DB_MPOOL_FSTAT; struct __db_mpool_stat; typedef struct __db_mpool_stat DB_MPOOL_STAT; struct __db_mpoolfile; typedef struct __db_mpoolfile DB_MPOOLFILE; struct __db_mutex_stat; typedef struct __db_mutex_stat DB_MUTEX_STAT; struct __db_mutex_t; typedef struct __db_mutex_t DB_MUTEX; struct __db_mutexmgr; typedef struct __db_mutexmgr DB_MUTEXMGR; struct __db_preplist; typedef struct __db_preplist DB_PREPLIST; struct __db_qam_stat; typedef struct __db_qam_stat DB_QUEUE_STAT; struct __db_rep; typedef struct __db_rep DB_REP; struct __db_rep_stat; typedef struct __db_rep_stat DB_REP_STAT; struct __db_repmgr_conn_err; typedef struct __db_repmgr_conn_err DB_REPMGR_CONN_ERR; struct __db_repmgr_site;typedef struct __db_repmgr_site DB_REPMGR_SITE; struct __db_repmgr_stat;typedef struct __db_repmgr_stat DB_REPMGR_STAT; struct __db_seq_record; typedef struct __db_seq_record DB_SEQ_RECORD; struct __db_seq_stat; typedef struct __db_seq_stat DB_SEQUENCE_STAT; struct __db_site; typedef struct __db_site DB_SITE; struct __db_sequence; typedef struct __db_sequence DB_SEQUENCE; struct __db_thread_info;typedef struct __db_thread_info DB_THREAD_INFO; struct __db_txn; typedef struct __db_txn DB_TXN; struct __db_txn_active; typedef struct __db_txn_active DB_TXN_ACTIVE; struct __db_txn_stat; typedef struct __db_txn_stat DB_TXN_STAT; struct __db_txn_token; typedef struct __db_txn_token DB_TXN_TOKEN; struct __db_txnmgr; typedef struct __db_txnmgr DB_TXNMGR; struct __dbc; typedef struct __dbc DBC; struct __dbc_internal; typedef struct __dbc_internal DBC_INTERNAL; struct __env; typedef struct __env ENV; struct __fh_t; typedef struct __fh_t DB_FH; struct __fname; typedef struct __fname FNAME; struct __key_range; typedef struct __key_range DB_KEY_RANGE; struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE; struct __db_logvrfy_config; typedef struct __db_logvrfy_config DB_LOG_VERIFY_CONFIG; /* * The Berkeley DB API flags are automatically-generated -- the following flag * names are no longer used, but remain for compatibility reasons. */ #define DB_DEGREE_2 DB_READ_COMMITTED #define DB_DIRTY_READ DB_READ_UNCOMMITTED #define DB_JOINENV 0x0 /* Key/data structure -- a Data-Base Thang. */ struct __db_dbt { void *data; /* Key/data */ u_int32_t size; /* key/data length */ u_int32_t ulen; /* RO: length of user buffer. */ u_int32_t dlen; /* RO: get/put record length. */ u_int32_t doff; /* RO: get/put record offset. */ void *app_data; #define DB_DBT_APPMALLOC 0x001 /* Callback allocated memory. */ #define DB_DBT_BULK 0x002 /* Internal: Insert if duplicate. */ #define DB_DBT_DUPOK 0x004 /* Internal: Insert if duplicate. */ #define DB_DBT_ISSET 0x008 /* Lower level calls set value. */ #define DB_DBT_MALLOC 0x010 /* Return in malloc'd memory. */ #define DB_DBT_MULTIPLE 0x020 /* References multiple records. */ #define DB_DBT_PARTIAL 0x040 /* Partial put/get. */ #define DB_DBT_REALLOC 0x080 /* Return in realloc'd memory. */ #define DB_DBT_READONLY 0x100 /* Readonly, don't update. */ #define DB_DBT_STREAMING 0x200 /* Internal: DBT is being streamed. */ #define DB_DBT_USERCOPY 0x400 /* Use the user-supplied callback. */ #define DB_DBT_USERMEM 0x800 /* Return in user's memory. */ u_int32_t flags; }; /******************************************************* * Mutexes. *******************************************************/ /* * When mixed size addressing is supported mutexes need to be the same size * independent of the process address size is. */ #ifdef HAVE_MIXED_SIZE_ADDRESSING typedef db_size_t db_mutex_t; #else typedef uintptr_t db_mutex_t; #endif struct __db_mutex_stat { /* SHARED */ /* The following fields are maintained in the region's copy. */ u_int32_t st_mutex_align; /* Mutex alignment */ u_int32_t st_mutex_tas_spins; /* Mutex test-and-set spins */ u_int32_t st_mutex_init; /* Initial mutex count */ u_int32_t st_mutex_cnt; /* Mutex count */ u_int32_t st_mutex_max; /* Mutex max */ u_int32_t st_mutex_free; /* Available mutexes */ u_int32_t st_mutex_inuse; /* Mutexes in use */ u_int32_t st_mutex_inuse_max; /* Maximum mutexes ever in use */ /* The following fields are filled-in from other places. */ #ifndef __TEST_DB_NO_STATISTICS uintmax_t st_region_wait; /* Region lock granted after wait. */ uintmax_t st_region_nowait; /* Region lock granted without wait. */ roff_t st_regsize; /* Region size. */ roff_t st_regmax; /* Region max. */ #endif }; /* This is the length of the buffer passed to DB_ENV->thread_id_string() */ #define DB_THREADID_STRLEN 128 /******************************************************* * Locking. *******************************************************/ #define DB_LOCKVERSION 1 #define DB_FILE_ID_LEN 20 /* Unique file ID length. */ /* * Deadlock detector modes; used in the DB_ENV structure to configure the * locking subsystem. */ #define DB_LOCK_NORUN 0 #define DB_LOCK_DEFAULT 1 /* Default policy. */ #define DB_LOCK_EXPIRE 2 /* Only expire locks, no detection. */ #define DB_LOCK_MAXLOCKS 3 /* Select locker with max locks. */ #define DB_LOCK_MAXWRITE 4 /* Select locker with max writelocks. */ #define DB_LOCK_MINLOCKS 5 /* Select locker with min locks. */ #define DB_LOCK_MINWRITE 6 /* Select locker with min writelocks. */ #define DB_LOCK_OLDEST 7 /* Select oldest locker. */ #define DB_LOCK_RANDOM 8 /* Select random locker. */ #define DB_LOCK_YOUNGEST 9 /* Select youngest locker. */ /* * Simple R/W lock modes and for multi-granularity intention locking. * * !!! * These values are NOT random, as they are used as an index into the lock * conflicts arrays, i.e., DB_LOCK_IWRITE must be == 3, and DB_LOCK_IREAD * must be == 4. */ typedef enum { DB_LOCK_NG=0, /* Not granted. */ DB_LOCK_READ=1, /* Shared/read. */ DB_LOCK_WRITE=2, /* Exclusive/write. */ DB_LOCK_WAIT=3, /* Wait for event */ DB_LOCK_IWRITE=4, /* Intent exclusive/write. */ DB_LOCK_IREAD=5, /* Intent to share/read. */ DB_LOCK_IWR=6, /* Intent to read and write. */ DB_LOCK_READ_UNCOMMITTED=7, /* Degree 1 isolation. */ DB_LOCK_WWRITE=8 /* Was Written. */ } db_lockmode_t; /* * Request types. */ typedef enum { DB_LOCK_DUMP=0, /* Display held locks. */ DB_LOCK_GET=1, /* Get the lock. */ DB_LOCK_GET_TIMEOUT=2, /* Get lock with a timeout. */ DB_LOCK_INHERIT=3, /* Pass locks to parent. */ DB_LOCK_PUT=4, /* Release the lock. */ DB_LOCK_PUT_ALL=5, /* Release locker's locks. */ DB_LOCK_PUT_OBJ=6, /* Release locker's locks on obj. */ DB_LOCK_PUT_READ=7, /* Release locker's read locks. */ DB_LOCK_TIMEOUT=8, /* Force a txn to timeout. */ DB_LOCK_TRADE=9, /* Trade locker ids on a lock. */ DB_LOCK_UPGRADE_WRITE=10 /* Upgrade writes for dirty reads. */ } db_lockop_t; /* * Status of a lock. */ typedef enum { DB_LSTAT_ABORTED=1, /* Lock belongs to an aborted txn. */ DB_LSTAT_EXPIRED=2, /* Lock has expired. */ DB_LSTAT_FREE=3, /* Lock is unallocated. */ DB_LSTAT_HELD=4, /* Lock is currently held. */ DB_LSTAT_PENDING=5, /* Lock was waiting and has been * promoted; waiting for the owner * to run and upgrade it to held. */ DB_LSTAT_WAITING=6 /* Lock is on the wait queue. */ }db_status_t; /* Lock statistics structure. */ struct __db_lock_stat { /* SHARED */ u_int32_t st_id; /* Last allocated locker ID. */ u_int32_t st_cur_maxid; /* Current maximum unused ID. */ u_int32_t st_initlocks; /* Initial number of locks in table. */ u_int32_t st_initlockers; /* Initial num of lockers in table. */ u_int32_t st_initobjects; /* Initial num of objects in table. */ u_int32_t st_locks; /* Current number of locks in table. */ u_int32_t st_lockers; /* Current num of lockers in table. */ u_int32_t st_objects; /* Current num of objects in table. */ u_int32_t st_maxlocks; /* Maximum number of locks in table. */ u_int32_t st_maxlockers; /* Maximum num of lockers in table. */ u_int32_t st_maxobjects; /* Maximum num of objects in table. */ u_int32_t st_partitions; /* number of partitions. */ u_int32_t st_tablesize; /* Size of object hash table. */ int32_t st_nmodes; /* Number of lock modes. */ u_int32_t st_nlockers; /* Current number of lockers. */ #ifndef __TEST_DB_NO_STATISTICS u_int32_t st_nlocks; /* Current number of locks. */ u_int32_t st_maxnlocks; /* Maximum number of locks so far. */ u_int32_t st_maxhlocks; /* Maximum number of locks in any bucket. */ uintmax_t st_locksteals; /* Number of lock steals so far. */ uintmax_t st_maxlsteals; /* Maximum number steals in any partition. */ u_int32_t st_maxnlockers; /* Maximum number of lockers so far. */ u_int32_t st_nobjects; /* Current number of objects. */ u_int32_t st_maxnobjects; /* Maximum number of objects so far. */ u_int32_t st_maxhobjects; /* Maximum number of objectsin any bucket. */ uintmax_t st_objectsteals; /* Number of objects steals so far. */ uintmax_t st_maxosteals; /* Maximum number of steals in any partition. */ uintmax_t st_nrequests; /* Number of lock gets. */ uintmax_t st_nreleases; /* Number of lock puts. */ uintmax_t st_nupgrade; /* Number of lock upgrades. */ uintmax_t st_ndowngrade; /* Number of lock downgrades. */ uintmax_t st_lock_wait; /* Lock conflicts w/ subsequent wait */ uintmax_t st_lock_nowait; /* Lock conflicts w/o subsequent wait */ uintmax_t st_ndeadlocks; /* Number of lock deadlocks. */ db_timeout_t st_locktimeout; /* Lock timeout. */ uintmax_t st_nlocktimeouts; /* Number of lock timeouts. */ db_timeout_t st_txntimeout; /* Transaction timeout. */ uintmax_t st_ntxntimeouts; /* Number of transaction timeouts. */ uintmax_t st_part_wait; /* Partition lock granted after wait. */ uintmax_t st_part_nowait; /* Partition lock granted without wait. */ uintmax_t st_part_max_wait; /* Max partition lock granted after wait. */ uintmax_t st_part_max_nowait; /* Max partition lock granted without wait. */ uintmax_t st_objs_wait; /* Object lock granted after wait. */ uintmax_t st_objs_nowait; /* Object lock granted without wait. */ uintmax_t st_lockers_wait; /* Locker lock granted after wait. */ uintmax_t st_lockers_nowait; /* Locker lock granted without wait. */ uintmax_t st_region_wait; /* Region lock granted after wait. */ uintmax_t st_region_nowait; /* Region lock granted without wait. */ u_int32_t st_hash_len; /* Max length of bucket. */ roff_t st_regsize; /* Region size. */ #endif }; struct __db_lock_hstat { /* SHARED */ uintmax_t st_nrequests; /* Number of lock gets. */ uintmax_t st_nreleases; /* Number of lock puts. */ uintmax_t st_nupgrade; /* Number of lock upgrades. */ uintmax_t st_ndowngrade; /* Number of lock downgrades. */ u_int32_t st_nlocks; /* Current number of locks. */ u_int32_t st_maxnlocks; /* Maximum number of locks so far. */ u_int32_t st_nobjects; /* Current number of objects. */ u_int32_t st_maxnobjects; /* Maximum number of objects so far. */ uintmax_t st_lock_wait; /* Lock conflicts w/ subsequent wait */ uintmax_t st_lock_nowait; /* Lock conflicts w/o subsequent wait */ uintmax_t st_nlocktimeouts; /* Number of lock timeouts. */ uintmax_t st_ntxntimeouts; /* Number of transaction timeouts. */ u_int32_t st_hash_len; /* Max length of bucket. */ }; struct __db_lock_pstat { /* SHARED */ u_int32_t st_nlocks; /* Current number of locks. */ u_int32_t st_maxnlocks; /* Maximum number of locks so far. */ u_int32_t st_nobjects; /* Current number of objects. */ u_int32_t st_maxnobjects; /* Maximum number of objects so far. */ uintmax_t st_locksteals; /* Number of lock steals so far. */ uintmax_t st_objectsteals; /* Number of objects steals so far. */ }; /* * DB_LOCK_ILOCK -- * Internal DB access method lock. */ struct __db_ilock { /* SHARED */ db_pgno_t pgno; /* Page being locked. */ u_int8_t fileid[DB_FILE_ID_LEN];/* File id. */ #define DB_HANDLE_LOCK 1 #define DB_RECORD_LOCK 2 #define DB_PAGE_LOCK 3 #define DB_DATABASE_LOCK 4 u_int32_t type; /* Type of lock. */ }; /* * DB_LOCK -- * The structure is allocated by the caller and filled in during a * lock_get request (or a lock_vec/DB_LOCK_GET). */ struct __db_lock_u { /* SHARED */ roff_t off; /* Offset of the lock in the region */ u_int32_t ndx; /* Index of the object referenced by * this lock; used for locking. */ u_int32_t gen; /* Generation number of this lock. */ db_lockmode_t mode; /* mode of this lock. */ }; /* Lock request structure. */ struct __db_lockreq { db_lockop_t op; /* Operation. */ db_lockmode_t mode; /* Requested mode. */ db_timeout_t timeout; /* Time to expire lock. */ DBT *obj; /* Object being locked. */ DB_LOCK lock; /* Lock returned. */ }; /******************************************************* * Logging. *******************************************************/ #define DB_LOGVERSION 19 /* Current log version. */ #define DB_LOGVERSION_LATCHING 15 /* Log version using latching: db-4.8 */ #define DB_LOGCHKSUM 12 /* Check sum headers: db-4.5 */ #define DB_LOGOLDVER 8 /* Oldest version supported: db-4.2 */ #define DB_LOGMAGIC 0x040988 /* * A DB_LSN has two parts, a fileid which identifies a specific file, and an * offset within that file. The fileid is an unsigned 4-byte quantity that * uniquely identifies a file within the log directory -- currently a simple * counter inside the log. The offset is also an unsigned 4-byte value. The * log manager guarantees the offset is never more than 4 bytes by switching * to a new log file before the maximum length imposed by an unsigned 4-byte * offset is reached. */ struct __db_lsn { /* SHARED */ u_int32_t file; /* File ID. */ u_int32_t offset; /* File offset. */ }; /* * Application-specified log record types start at DB_user_BEGIN, and must not * equal or exceed DB_debug_FLAG. * * DB_debug_FLAG is the high-bit of the u_int32_t that specifies a log record * type. If the flag is set, it's a log record that was logged for debugging * purposes only, even if it reflects a database change -- the change was part * of a non-durable transaction. */ #define DB_user_BEGIN 10000 #define DB_debug_FLAG 0x80000000 /* * DB_LOGC -- * Log cursor. */ struct __db_log_cursor { ENV *env; /* Environment */ DB_FH *fhp; /* File handle. */ DB_LSN lsn; /* Cursor: LSN */ u_int32_t len; /* Cursor: record length */ u_int32_t prev; /* Cursor: previous record's offset */ DBT dbt; /* Return DBT. */ DB_LSN p_lsn; /* Persist LSN. */ u_int32_t p_version; /* Persist version. */ u_int8_t *bp; /* Allocated read buffer. */ u_int32_t bp_size; /* Read buffer length in bytes. */ u_int32_t bp_rlen; /* Read buffer valid data length. */ DB_LSN bp_lsn; /* Read buffer first byte LSN. */ u_int32_t bp_maxrec; /* Max record length in the log file. */ /* DB_LOGC PUBLIC HANDLE LIST BEGIN */ int (*close) __P((DB_LOGC *, u_int32_t)); int (*get) __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t)); int (*version) __P((DB_LOGC *, u_int32_t *, u_int32_t)); /* DB_LOGC PUBLIC HANDLE LIST END */ #define DB_LOG_DISK 0x01 /* Log record came from disk. */ #define DB_LOG_LOCKED 0x02 /* Log region already locked */ #define DB_LOG_SILENT_ERR 0x04 /* Turn-off error messages. */ u_int32_t flags; }; /* Log statistics structure. */ struct __db_log_stat { /* SHARED */ u_int32_t st_magic; /* Log file magic number. */ u_int32_t st_version; /* Log file version number. */ int32_t st_mode; /* Log file permissions mode. */ u_int32_t st_lg_bsize; /* Log buffer size. */ u_int32_t st_lg_size; /* Log file size. */ u_int32_t st_wc_bytes; /* Bytes to log since checkpoint. */ u_int32_t st_wc_mbytes; /* Megabytes to log since checkpoint. */ u_int32_t st_fileid_init; /* Initial allocation for fileids. */ #ifndef __TEST_DB_NO_STATISTICS u_int32_t st_nfileid; /* Current number of fileids. */ u_int32_t st_maxnfileid; /* Maximum number of fileids used. */ uintmax_t st_record; /* Records entered into the log. */ u_int32_t st_w_bytes; /* Bytes to log. */ u_int32_t st_w_mbytes; /* Megabytes to log. */ uintmax_t st_wcount; /* Total I/O writes to the log. */ uintmax_t st_wcount_fill; /* Overflow writes to the log. */ uintmax_t st_rcount; /* Total I/O reads from the log. */ uintmax_t st_scount; /* Total syncs to the log. */ uintmax_t st_region_wait; /* Region lock granted after wait. */ uintmax_t st_region_nowait; /* Region lock granted without wait. */ u_int32_t st_cur_file; /* Current log file number. */ u_int32_t st_cur_offset; /* Current log file offset. */ u_int32_t st_disk_file; /* Known on disk log file number. */ u_int32_t st_disk_offset; /* Known on disk log file offset. */ u_int32_t st_maxcommitperflush; /* Max number of commits in a flush. */ u_int32_t st_mincommitperflush; /* Min number of commits in a flush. */ roff_t st_regsize; /* Region size. */ #endif }; /* * We need to record the first log record of a transaction. For user * defined logging this macro returns the place to put that information, * if it is need in rlsnp, otherwise it leaves it unchanged. We also * need to track the last record of the transaction, this returns the * place to put that info. */ #define DB_SET_TXN_LSNP(txn, blsnp, llsnp) \ ((txn)->set_txn_lsnp(txn, blsnp, llsnp)) /* * Definition of the structure which specifies marshalling of log records. */ typedef enum { LOGREC_Done, LOGREC_ARG, LOGREC_HDR, LOGREC_DATA, LOGREC_DB, LOGREC_DBOP, LOGREC_DBT, LOGREC_LOCKS, LOGREC_OP, LOGREC_PGDBT, LOGREC_PGDDBT, LOGREC_PGLIST, LOGREC_POINTER, LOGREC_TIME } log_rec_type_t; typedef const struct __log_rec_spec { log_rec_type_t type; u_int32_t offset; const char *name; const char fmt[4]; } DB_LOG_RECSPEC; /* * Size of a DBT in a log record. */ #define LOG_DBT_SIZE(dbt) \ (sizeof(u_int32_t) + ((dbt) == NULL ? 0 : (dbt)->size)) /******************************************************* * Shared buffer cache (mpool). *******************************************************/ /* Priority values for DB_MPOOLFILE->{put,set_priority}. */ typedef enum { DB_PRIORITY_UNCHANGED=0, DB_PRIORITY_VERY_LOW=1, DB_PRIORITY_LOW=2, DB_PRIORITY_DEFAULT=3, DB_PRIORITY_HIGH=4, DB_PRIORITY_VERY_HIGH=5 } DB_CACHE_PRIORITY; /* Per-process DB_MPOOLFILE information. */ struct __db_mpoolfile { DB_FH *fhp; /* Underlying file handle. */ /* * !!! * The ref, pinref and q fields are protected by the region lock. */ u_int32_t ref; /* Reference count. */ u_int32_t pinref; /* Pinned block reference count. */ /* * !!! * Explicit representations of structures from queue.h. * TAILQ_ENTRY(__db_mpoolfile) q; */ struct { struct __db_mpoolfile *tqe_next; struct __db_mpoolfile **tqe_prev; } q; /* Linked list of DB_MPOOLFILE's. */ /* * !!! * The rest of the fields (with the exception of the MP_FLUSH flag) * are not thread-protected, even when they may be modified at any * time by the application. The reason is the DB_MPOOLFILE handle * is single-threaded from the viewpoint of the application, and so * the only fields needing to be thread-protected are those accessed * by checkpoint or sync threads when using DB_MPOOLFILE structures * to flush buffers from the cache. */ ENV *env; /* Environment */ MPOOLFILE *mfp; /* Underlying MPOOLFILE. */ u_int32_t clear_len; /* Cleared length on created pages. */ u_int8_t /* Unique file ID. */ fileid[DB_FILE_ID_LEN]; int ftype; /* File type. */ int32_t lsn_offset; /* LSN offset in page. */ u_int32_t gbytes, bytes; /* Maximum file size. */ DBT *pgcookie; /* Byte-string passed to pgin/pgout. */ int32_t priority; /* Cache priority. */ void *addr; /* Address of mmap'd region. */ size_t len; /* Length of mmap'd region. */ u_int32_t config_flags; /* Flags to DB_MPOOLFILE->set_flags. */ /* DB_MPOOLFILE PUBLIC HANDLE LIST BEGIN */ int (*close) __P((DB_MPOOLFILE *, u_int32_t)); int (*get) __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, void *)); int (*get_clear_len) __P((DB_MPOOLFILE *, u_int32_t *)); int (*get_fileid) __P((DB_MPOOLFILE *, u_int8_t *)); int (*get_flags) __P((DB_MPOOLFILE *, u_int32_t *)); int (*get_ftype) __P((DB_MPOOLFILE *, int *)); int (*get_last_pgno) __P((DB_MPOOLFILE *, db_pgno_t *)); int (*get_lsn_offset) __P((DB_MPOOLFILE *, int32_t *)); int (*get_maxsize) __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t *)); int (*get_pgcookie) __P((DB_MPOOLFILE *, DBT *)); int (*get_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *)); int (*open) __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t)); int (*put) __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, u_int32_t)); int (*set_clear_len) __P((DB_MPOOLFILE *, u_int32_t)); int (*set_fileid) __P((DB_MPOOLFILE *, u_int8_t *)); int (*set_flags) __P((DB_MPOOLFILE *, u_int32_t, int)); int (*set_ftype) __P((DB_MPOOLFILE *, int)); int (*set_lsn_offset) __P((DB_MPOOLFILE *, int32_t)); int (*set_maxsize) __P((DB_MPOOLFILE *, u_int32_t, u_int32_t)); int (*set_pgcookie) __P((DB_MPOOLFILE *, DBT *)); int (*set_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY)); int (*sync) __P((DB_MPOOLFILE *)); /* DB_MPOOLFILE PUBLIC HANDLE LIST END */ /* * MP_FILEID_SET, MP_OPEN_CALLED and MP_READONLY do not need to be * thread protected because they are initialized before the file is * linked onto the per-process lists, and never modified. * * MP_FLUSH is thread protected because it is potentially read/set by * multiple threads of control. */ #define MP_FILEID_SET 0x001 /* Application supplied a file ID. */ #define MP_FLUSH 0x002 /* Was used to flush a buffer. */ #define MP_FOR_FLUSH 0x004 /* Was opened to flush a buffer. */ #define MP_MULTIVERSION 0x008 /* Opened for multiversion access. */ #define MP_OPEN_CALLED 0x010 /* File opened. */ #define MP_READONLY 0x020 /* File is readonly. */ #define MP_DUMMY 0x040 /* File is dummy for __memp_fput. */ u_int32_t flags; }; /* Mpool statistics structure. */ struct __db_mpool_stat { /* SHARED */ u_int32_t st_gbytes; /* Total cache size: GB. */ u_int32_t st_bytes; /* Total cache size: B. */ u_int32_t st_ncache; /* Number of cache regions. */ u_int32_t st_max_ncache; /* Maximum number of regions. */ db_size_t st_mmapsize; /* Maximum file size for mmap. */ int32_t st_maxopenfd; /* Maximum number of open fd's. */ int32_t st_maxwrite; /* Maximum buffers to write. */ db_timeout_t st_maxwrite_sleep; /* Sleep after writing max buffers. */ u_int32_t st_pages; /* Total number of pages. */ #ifndef __TEST_DB_NO_STATISTICS u_int32_t st_map; /* Pages from mapped files. */ uintmax_t st_cache_hit; /* Pages found in the cache. */ uintmax_t st_cache_miss; /* Pages not found in the cache. */ uintmax_t st_page_create; /* Pages created in the cache. */ uintmax_t st_page_in; /* Pages read in. */ uintmax_t st_page_out; /* Pages written out. */ uintmax_t st_ro_evict; /* Clean pages forced from the cache. */ uintmax_t st_rw_evict; /* Dirty pages forced from the cache. */ uintmax_t st_page_trickle; /* Pages written by memp_trickle. */ u_int32_t st_page_clean; /* Clean pages. */ u_int32_t st_page_dirty; /* Dirty pages. */ u_int32_t st_hash_buckets; /* Number of hash buckets. */ u_int32_t st_hash_mutexes; /* Number of hash bucket mutexes. */ u_int32_t st_pagesize; /* Assumed page size. */ u_int32_t st_hash_searches; /* Total hash chain searches. */ u_int32_t st_hash_longest; /* Longest hash chain searched. */ uintmax_t st_hash_examined; /* Total hash entries searched. */ uintmax_t st_hash_nowait; /* Hash lock granted with nowait. */ uintmax_t st_hash_wait; /* Hash lock granted after wait. */ uintmax_t st_hash_max_nowait; /* Max hash lock granted with nowait. */ uintmax_t st_hash_max_wait; /* Max hash lock granted after wait. */ uintmax_t st_region_nowait; /* Region lock granted with nowait. */ uintmax_t st_region_wait; /* Region lock granted after wait. */ uintmax_t st_mvcc_frozen; /* Buffers frozen. */ uintmax_t st_mvcc_thawed; /* Buffers thawed. */ uintmax_t st_mvcc_freed; /* Frozen buffers freed. */ uintmax_t st_alloc; /* Number of page allocations. */ uintmax_t st_alloc_buckets; /* Buckets checked during allocation. */ uintmax_t st_alloc_max_buckets;/* Max checked during allocation. */ uintmax_t st_alloc_pages; /* Pages checked during allocation. */ uintmax_t st_alloc_max_pages; /* Max checked during allocation. */ uintmax_t st_io_wait; /* Thread waited on buffer I/O. */ uintmax_t st_sync_interrupted; /* Number of times sync interrupted. */ roff_t st_regsize; /* Region size. */ roff_t st_regmax; /* Region max. */ #endif }; /* * Mpool file statistics structure. * The first fields in this structure must mirror the __db_mpool_fstat_int * structure, since content is mem copied between the two. */ struct __db_mpool_fstat { u_int32_t st_pagesize; /* Page size. */ #ifndef __TEST_DB_NO_STATISTICS u_int32_t st_map; /* Pages from mapped files. */ uintmax_t st_cache_hit; /* Pages found in the cache. */ uintmax_t st_cache_miss; /* Pages not found in the cache. */ uintmax_t st_page_create; /* Pages created in the cache. */ uintmax_t st_page_in; /* Pages read in. */ uintmax_t st_page_out; /* Pages written out. */ uintmax_t st_backup_spins; /* Number of spins during a copy. */ #endif char *file_name; /* File name. */ }; /******************************************************* * Transactions and recovery. *******************************************************/ #define DB_TXNVERSION 1 typedef enum { DB_TXN_ABORT=0, /* Public. */ DB_TXN_APPLY=1, /* Public. */ DB_TXN_BACKWARD_ROLL=3, /* Public. */ DB_TXN_FORWARD_ROLL=4, /* Public. */ DB_TXN_OPENFILES=5, /* Internal. */ DB_TXN_POPENFILES=6, /* Internal. */ DB_TXN_PRINT=7, /* Public. */ DB_TXN_LOG_VERIFY=8 /* Internal. */ } db_recops; /* * BACKWARD_ALLOC is used during the forward pass to pick up any aborted * allocations for files that were created during the forward pass. * The main difference between _ALLOC and _ROLL is that the entry for * the file not exist during the rollforward pass. */ #define DB_UNDO(op) ((op) == DB_TXN_ABORT || (op) == DB_TXN_BACKWARD_ROLL) #define DB_REDO(op) ((op) == DB_TXN_FORWARD_ROLL || (op) == DB_TXN_APPLY) struct __db_txn { DB_TXNMGR *mgrp; /* Pointer to transaction manager. */ DB_TXN *parent; /* Pointer to transaction's parent. */ DB_THREAD_INFO *thread_info; /* Pointer to thread information. */ u_int32_t txnid; /* Unique transaction id. */ char *name; /* Transaction name. */ DB_LOCKER *locker; /* Locker for this txn. */ void *td; /* Detail structure within region. */ db_timeout_t lock_timeout; /* Timeout for locks for this txn. */ void *txn_list; /* Undo information for parent. */ /* * !!! * Explicit representations of structures from queue.h. * TAILQ_ENTRY(__db_txn) links; */ struct { struct __db_txn *tqe_next; struct __db_txn **tqe_prev; } links; /* Links transactions off manager. */ /* * !!! * Explicit representations of structures from shqueue.h. * SH_TAILQ_ENTRY xa_links; * These links link together transactions that are active in * the same thread of control. */ struct { db_ssize_t stqe_next; db_ssize_t stqe_prev; } xa_links; /* Links XA transactions. */ /* * !!! * Explicit representations of structures from queue.h. * TAILQ_HEAD(__kids, __db_txn) kids; */ struct __kids { struct __db_txn *tqh_first; struct __db_txn **tqh_last; } kids; /* * !!! * Explicit representations of structures from queue.h. * TAILQ_HEAD(__events, __txn_event) events; */ struct { struct __txn_event *tqh_first; struct __txn_event **tqh_last; } events; /* Links deferred events. */ /* * !!! * Explicit representations of structures from queue.h. * STAILQ_HEAD(__logrec, __txn_logrec) logs; */ struct { struct __txn_logrec *stqh_first; struct __txn_logrec **stqh_last; } logs; /* Links in memory log records. */ /* * !!! * Explicit representations of structures from queue.h. * TAILQ_ENTRY(__db_txn) klinks; */ struct { struct __db_txn *tqe_next; struct __db_txn **tqe_prev; } klinks; /* Links of children in parent. */ /* * !!! * Explicit representations of structures from queue.h. * TAILQ_HEAD(__my_cursors, __dbc) my_cursors; */ struct __my_cursors { struct __dbc *tqh_first; struct __dbc **tqh_last; } my_cursors; /* * !!! * Explicit representations of structures from queue.h. * TAILQ_HEAD(__femfs, MPOOLFILE) femfs; * * These are DBs involved in file extension in this transaction. */ struct __femfs { DB *tqh_first; DB **tqh_last; } femfs; DB_TXN_TOKEN *token_buffer; /* User's commit token buffer. */ void *api_internal; /* C++ API private. */ void *xml_internal; /* XML API private. */ u_int32_t cursors; /* Number of cursors open for txn */ /* DB_TXN PUBLIC HANDLE LIST BEGIN */ int (*abort) __P((DB_TXN *)); int (*commit) __P((DB_TXN *, u_int32_t)); int (*discard) __P((DB_TXN *, u_int32_t)); int (*get_name) __P((DB_TXN *, const char **)); int (*get_priority) __P((DB_TXN *, u_int32_t *)); u_int32_t (*id) __P((DB_TXN *)); int (*prepare) __P((DB_TXN *, u_int8_t *)); int (*set_commit_token) __P((DB_TXN *, DB_TXN_TOKEN *)); int (*set_name) __P((DB_TXN *, const char *)); int (*set_priority) __P((DB_TXN *, u_int32_t)); int (*set_timeout) __P((DB_TXN *, db_timeout_t, u_int32_t)); /* DB_TXN PUBLIC HANDLE LIST END */ /* DB_TXN PRIVATE HANDLE LIST BEGIN */ void (*set_txn_lsnp) __P((DB_TXN *txn, DB_LSN **, DB_LSN **)); /* DB_TXN PRIVATE HANDLE LIST END */ #define TXN_XA_THREAD_NOTA 0 #define TXN_XA_THREAD_ASSOCIATED 1 #define TXN_XA_THREAD_SUSPENDED 2 #define TXN_XA_THREAD_UNASSOCIATED 3 u_int32_t xa_thr_status; #define TXN_CHILDCOMMIT 0x00001 /* Txn has committed. */ #define TXN_COMPENSATE 0x00002 /* Compensating transaction. */ #define TXN_DEADLOCK 0x00004 /* Txn has deadlocked. */ #define TXN_FAMILY 0x00008 /* Cursors/children are independent. */ #define TXN_IGNORE_LEASE 0x00010 /* Skip lease check at commit time. */ #define TXN_INFAMILY 0x00020 /* Part of a transaction family. */ #define TXN_LOCKTIMEOUT 0x00040 /* Txn has a lock timeout. */ #define TXN_MALLOC 0x00080 /* Structure allocated by TXN system. */ #define TXN_NOSYNC 0x00100 /* Do not sync on prepare and commit. */ #define TXN_NOWAIT 0x00200 /* Do not wait on locks. */ #define TXN_PRIVATE 0x00400 /* Txn owned by cursor. */ #define TXN_READONLY 0x00800 /* CDS group handle. */ #define TXN_READ_COMMITTED 0x01000 /* Txn has degree 2 isolation. */ #define TXN_READ_UNCOMMITTED 0x02000 /* Txn has degree 1 isolation. */ #define TXN_RESTORED 0x04000 /* Txn has been restored. */ #define TXN_SNAPSHOT 0x08000 /* Snapshot Isolation. */ #define TXN_SYNC 0x10000 /* Write and sync on prepare/commit. */ #define TXN_WRITE_NOSYNC 0x20000 /* Write only on prepare/commit. */ #define TXN_BULK 0x40000 /* Enable bulk loading optimization. */ u_int32_t flags; }; #define TXN_SYNC_FLAGS (TXN_SYNC | TXN_NOSYNC | TXN_WRITE_NOSYNC) /* * Structure used for two phase commit interface. * We set the size of our global transaction id (gid) to be 128 in order * to match that defined by the XA X/Open standard. */ #define DB_GID_SIZE 128 struct __db_preplist { DB_TXN *txn; u_int8_t gid[DB_GID_SIZE]; }; /* Transaction statistics structure. */ struct __db_txn_active { u_int32_t txnid; /* Transaction ID */ u_int32_t parentid; /* Transaction ID of parent */ pid_t pid; /* Process owning txn ID */ db_threadid_t tid; /* Thread owning txn ID */ DB_LSN lsn; /* LSN when transaction began */ DB_LSN read_lsn; /* Read LSN for MVCC */ u_int32_t mvcc_ref; /* MVCC reference count */ u_int32_t priority; /* Deadlock resolution priority */ #define TXN_ABORTED 1 #define TXN_COMMITTED 2 #define TXN_NEED_ABORT 3 #define TXN_PREPARED 4 #define TXN_RUNNING 5 u_int32_t status; /* Status of the transaction */ #define TXN_XA_ACTIVE 1 #define TXN_XA_DEADLOCKED 2 #define TXN_XA_IDLE 3 #define TXN_XA_PREPARED 4 #define TXN_XA_ROLLEDBACK 5 u_int32_t xa_status; /* XA status */ u_int8_t gid[DB_GID_SIZE]; /* Global transaction ID */ char name[51]; /* 50 bytes of name, nul termination */ }; struct __db_txn_stat { u_int32_t st_nrestores; /* number of restored transactions after recovery. */ #ifndef __TEST_DB_NO_STATISTICS DB_LSN st_last_ckp; /* lsn of the last checkpoint */ time_t st_time_ckp; /* time of last checkpoint */ u_int32_t st_last_txnid; /* last transaction id given out */ u_int32_t st_inittxns; /* inital txns allocated */ u_int32_t st_maxtxns; /* maximum txns possible */ uintmax_t st_naborts; /* number of aborted transactions */ uintmax_t st_nbegins; /* number of begun transactions */ uintmax_t st_ncommits; /* number of committed transactions */ u_int32_t st_nactive; /* number of active transactions */ u_int32_t st_nsnapshot; /* number of snapshot transactions */ u_int32_t st_maxnactive; /* maximum active transactions */ u_int32_t st_maxnsnapshot; /* maximum snapshot transactions */ uintmax_t st_region_wait; /* Region lock granted after wait. */ uintmax_t st_region_nowait; /* Region lock granted without wait. */ roff_t st_regsize; /* Region size. */ DB_TXN_ACTIVE *st_txnarray; /* array of active transactions */ #endif }; #define DB_TXN_TOKEN_SIZE 20 struct __db_txn_token { u_int8_t buf[DB_TXN_TOKEN_SIZE]; }; /******************************************************* * Replication. *******************************************************/ /* Special, out-of-band environment IDs. */ #define DB_EID_BROADCAST -1 #define DB_EID_INVALID -2 #define DB_EID_MASTER -3 #define DB_REP_DEFAULT_PRIORITY 100 /* Acknowledgement policies; 0 reserved as OOB. */ #define DB_REPMGR_ACKS_ALL 1 #define DB_REPMGR_ACKS_ALL_AVAILABLE 2 #define DB_REPMGR_ACKS_ALL_PEERS 3 #define DB_REPMGR_ACKS_NONE 4 #define DB_REPMGR_ACKS_ONE 5 #define DB_REPMGR_ACKS_ONE_PEER 6 #define DB_REPMGR_ACKS_QUORUM 7 /* Replication timeout configuration values. */ #define DB_REP_ACK_TIMEOUT 1 /* RepMgr acknowledgements. */ #define DB_REP_CHECKPOINT_DELAY 2 /* Master checkpoint delay. */ #define DB_REP_CONNECTION_RETRY 3 /* RepMgr connections. */ #define DB_REP_ELECTION_RETRY 4 /* RepMgr elect retries. */ #define DB_REP_ELECTION_TIMEOUT 5 /* Rep normal elections. */ #define DB_REP_FULL_ELECTION_TIMEOUT 6 /* Rep full elections. */ #define DB_REP_HEARTBEAT_MONITOR 7 /* RepMgr client HB monitor. */ #define DB_REP_HEARTBEAT_SEND 8 /* RepMgr master send freq. */ #define DB_REP_LEASE_TIMEOUT 9 /* Master leases. */ /* * Event notification types. (Tcl testing interface currently assumes there are * no more than 32 of these.) */ #define DB_EVENT_PANIC 0 #define DB_EVENT_REG_ALIVE 1 #define DB_EVENT_REG_PANIC 2 #define DB_EVENT_REP_CLIENT 3 #define DB_EVENT_REP_CONNECT_BROKEN 4 #define DB_EVENT_REP_CONNECT_ESTD 5 #define DB_EVENT_REP_CONNECT_TRY_FAILED 6 #define DB_EVENT_REP_DUPMASTER 7 #define DB_EVENT_REP_ELECTED 8 #define DB_EVENT_REP_ELECTION_FAILED 9 #define DB_EVENT_REP_INIT_DONE 10 #define DB_EVENT_REP_JOIN_FAILURE 11 #define DB_EVENT_REP_LOCAL_SITE_REMOVED 12 #define DB_EVENT_REP_MASTER 13 #define DB_EVENT_REP_MASTER_FAILURE 14 #define DB_EVENT_REP_NEWMASTER 15 #define DB_EVENT_REP_PERM_FAILED 16 #define DB_EVENT_REP_SITE_ADDED 17 #define DB_EVENT_REP_SITE_REMOVED 18 #define DB_EVENT_REP_STARTUPDONE 19 #define DB_EVENT_REP_WOULD_ROLLBACK 20 /* Undocumented; C API only. */ #define DB_EVENT_WRITE_FAILED 21 #define DB_EVENT_NO_SUCH_EVENT 0xffffffff /* OOB sentinel value */ /* Replication Manager site status. */ struct __db_repmgr_site { int eid; char *host; u_int port; #define DB_REPMGR_CONNECTED 1 #define DB_REPMGR_DISCONNECTED 2 u_int32_t status; #define DB_REPMGR_ISPEER 0x01 u_int32_t flags; }; /* Replication statistics. */ struct __db_rep_stat { /* SHARED */ /* !!! * Many replication statistics fields cannot be protected by a mutex * without an unacceptable performance penalty, since most message * processing is done without the need to hold a region-wide lock. * Fields whose comments end with a '+' may be updated without holding * the replication or log mutexes (as appropriate), and thus may be * off somewhat (or, on unreasonable architectures under unlucky * circumstances, garbaged). */ u_int32_t st_startup_complete; /* Site completed client sync-up. */ #ifndef __TEST_DB_NO_STATISTICS uintmax_t st_log_queued; /* Log records currently queued.+ */ u_int32_t st_status; /* Current replication status. */ DB_LSN st_next_lsn; /* Next LSN to use or expect. */ DB_LSN st_waiting_lsn; /* LSN we're awaiting, if any. */ DB_LSN st_max_perm_lsn; /* Maximum permanent LSN. */ db_pgno_t st_next_pg; /* Next pg we expect. */ db_pgno_t st_waiting_pg; /* pg we're awaiting, if any. */ u_int32_t st_dupmasters; /* # of times a duplicate master condition was detected.+ */ db_ssize_t st_env_id; /* Current environment ID. */ u_int32_t st_env_priority; /* Current environment priority. */ uintmax_t st_bulk_fills; /* Bulk buffer fills. */ uintmax_t st_bulk_overflows; /* Bulk buffer overflows. */ uintmax_t st_bulk_records; /* Bulk records stored. */ uintmax_t st_bulk_transfers; /* Transfers of bulk buffers. */ uintmax_t st_client_rerequests;/* Number of forced rerequests. */ uintmax_t st_client_svc_req; /* Number of client service requests received by this client. */ uintmax_t st_client_svc_miss; /* Number of client service requests missing on this client. */ u_int32_t st_gen; /* Current generation number. */ u_int32_t st_egen; /* Current election gen number. */ uintmax_t st_lease_chk; /* Lease validity checks. */ uintmax_t st_lease_chk_misses; /* Lease checks invalid. */ uintmax_t st_lease_chk_refresh; /* Lease refresh attempts. */ uintmax_t st_lease_sends; /* Lease messages sent live. */ uintmax_t st_log_duplicated; /* Log records received multiply.+ */ uintmax_t st_log_queued_max; /* Max. log records queued at once.+ */ uintmax_t st_log_queued_total; /* Total # of log recs. ever queued.+ */ uintmax_t st_log_records; /* Log records received and put.+ */ uintmax_t st_log_requested; /* Log recs. missed and requested.+ */ db_ssize_t st_master; /* Env. ID of the current master. */ uintmax_t st_master_changes; /* # of times we've switched masters. */ uintmax_t st_msgs_badgen; /* Messages with a bad generation #.+ */ uintmax_t st_msgs_processed; /* Messages received and processed.+ */ uintmax_t st_msgs_recover; /* Messages ignored because this site was a client in recovery.+ */ uintmax_t st_msgs_send_failures;/* # of failed message sends.+ */ uintmax_t st_msgs_sent; /* # of successful message sends.+ */ uintmax_t st_newsites; /* # of NEWSITE msgs. received.+ */ u_int32_t st_nsites; /* Current number of sites we will assume during elections. */ uintmax_t st_nthrottles; /* # of times we were throttled. */ uintmax_t st_outdated; /* # of times we detected and returned an OUTDATED condition.+ */ uintmax_t st_pg_duplicated; /* Pages received multiply.+ */ uintmax_t st_pg_records; /* Pages received and stored.+ */ uintmax_t st_pg_requested; /* Pages missed and requested.+ */ uintmax_t st_txns_applied; /* # of transactions applied.+ */ uintmax_t st_startsync_delayed;/* # of STARTSYNC msgs delayed.+ */ /* Elections generally. */ uintmax_t st_elections; /* # of elections held.+ */ uintmax_t st_elections_won; /* # of elections won by this site.+ */ /* Statistics about an in-progress election. */ db_ssize_t st_election_cur_winner; /* Current front-runner. */ u_int32_t st_election_gen; /* Election generation number. */ u_int32_t st_election_datagen; /* Election data generation number. */ DB_LSN st_election_lsn; /* Max. LSN of current winner. */ u_int32_t st_election_nsites; /* # of "registered voters". */ u_int32_t st_election_nvotes; /* # of "registered voters" needed. */ u_int32_t st_election_priority; /* Current election priority. */ int32_t st_election_status; /* Current election status. */ u_int32_t st_election_tiebreaker;/* Election tiebreaker value. */ u_int32_t st_election_votes; /* Votes received in this round. */ u_int32_t st_election_sec; /* Last election time seconds. */ u_int32_t st_election_usec; /* Last election time useconds. */ u_int32_t st_max_lease_sec; /* Maximum lease timestamp seconds. */ u_int32_t st_max_lease_usec; /* Maximum lease timestamp useconds. */ /* Undocumented statistics only used by the test system. */ #ifdef CONFIG_TEST u_int32_t st_filefail_cleanups; /* # of FILE_FAIL cleanups done. */ #endif #endif }; /* Replication Manager statistics. */ struct __db_repmgr_stat { /* SHARED */ uintmax_t st_perm_failed; /* # of insufficiently ack'ed msgs. */ uintmax_t st_msgs_queued; /* # msgs queued for network delay. */ uintmax_t st_msgs_dropped; /* # msgs discarded due to excessive queue length. */ uintmax_t st_connection_drop; /* Existing connections dropped. */ uintmax_t st_connect_fail; /* Failed new connection attempts. */ uintmax_t st_elect_threads; /* # of active election threads. */ uintmax_t st_max_elect_threads; /* Max concurrent e-threads ever. */ }; /* Replication Manager connection error. */ struct __db_repmgr_conn_err { int eid; /* Replication Environment ID. */ int error; /* System networking error code. */ }; /******************************************************* * Sequences. *******************************************************/ /* * The storage record for a sequence. */ struct __db_seq_record { u_int32_t seq_version; /* Version size/number. */ u_int32_t flags; /* DB_SEQ_XXX Flags. */ db_seq_t seq_value; /* Current value. */ db_seq_t seq_max; /* Max permitted. */ db_seq_t seq_min; /* Min permitted. */ }; /* * Handle for a sequence object. */ struct __db_sequence { DB *seq_dbp; /* DB handle for this sequence. */ db_mutex_t mtx_seq; /* Mutex if sequence is threaded. */ DB_SEQ_RECORD *seq_rp; /* Pointer to current data. */ DB_SEQ_RECORD seq_record; /* Data from DB_SEQUENCE. */ int32_t seq_cache_size; /* Number of values cached. */ db_seq_t seq_last_value; /* Last value cached. */ db_seq_t seq_prev_value; /* Last value returned. */ DBT seq_key; /* DBT pointing to sequence key. */ DBT seq_data; /* DBT pointing to seq_record. */ /* API-private structure: used by C++ and Java. */ void *api_internal; /* DB_SEQUENCE PUBLIC HANDLE LIST BEGIN */ int (*close) __P((DB_SEQUENCE *, u_int32_t)); int (*get) __P((DB_SEQUENCE *, DB_TXN *, int32_t, db_seq_t *, u_int32_t)); int (*get_cachesize) __P((DB_SEQUENCE *, int32_t *)); int (*get_db) __P((DB_SEQUENCE *, DB **)); int (*get_flags) __P((DB_SEQUENCE *, u_int32_t *)); int (*get_key) __P((DB_SEQUENCE *, DBT *)); int (*get_range) __P((DB_SEQUENCE *, db_seq_t *, db_seq_t *)); int (*initial_value) __P((DB_SEQUENCE *, db_seq_t)); int (*open) __P((DB_SEQUENCE *, DB_TXN *, DBT *, u_int32_t)); int (*remove) __P((DB_SEQUENCE *, DB_TXN *, u_int32_t)); int (*set_cachesize) __P((DB_SEQUENCE *, int32_t)); int (*set_flags) __P((DB_SEQUENCE *, u_int32_t)); int (*set_range) __P((DB_SEQUENCE *, db_seq_t, db_seq_t)); int (*stat) __P((DB_SEQUENCE *, DB_SEQUENCE_STAT **, u_int32_t)); int (*stat_print) __P((DB_SEQUENCE *, u_int32_t)); /* DB_SEQUENCE PUBLIC HANDLE LIST END */ }; struct __db_seq_stat { /* SHARED */ uintmax_t st_wait; /* Sequence lock granted w/o wait. */ uintmax_t st_nowait; /* Sequence lock granted after wait. */ db_seq_t st_current; /* Current value in db. */ db_seq_t st_value; /* Current cached value. */ db_seq_t st_last_value; /* Last cached value. */ db_seq_t st_min; /* Minimum value. */ db_seq_t st_max; /* Maximum value. */ int32_t st_cache_size; /* Cache size. */ u_int32_t st_flags; /* Flag value. */ }; /******************************************************* * Access methods. *******************************************************/ /* * Any new methods need to retain the original numbering. The type * is written in a log record so must be maintained. */ typedef enum { DB_BTREE=1, DB_HASH=2, DB_HEAP=6, DB_RECNO=3, DB_QUEUE=4, DB_UNKNOWN=5 /* Figure it out on open. */ } DBTYPE; #define DB_RENAMEMAGIC 0x030800 /* File has been renamed. */ #define DB_BTREEVERSION 9 /* Current btree version. */ #define DB_BTREEOLDVER 8 /* Oldest btree version supported. */ #define DB_BTREEMAGIC 0x053162 #define DB_HASHVERSION 9 /* Current hash version. */ #define DB_HASHOLDVER 7 /* Oldest hash version supported. */ #define DB_HASHMAGIC 0x061561 #define DB_HEAPVERSION 1 /* Current heap version. */ #define DB_HEAPOLDVER 1 /* Oldest heap version supported. */ #define DB_HEAPMAGIC 0x074582 #define DB_QAMVERSION 4 /* Current queue version. */ #define DB_QAMOLDVER 3 /* Oldest queue version supported. */ #define DB_QAMMAGIC 0x042253 #define DB_SEQUENCE_VERSION 2 /* Current sequence version. */ #define DB_SEQUENCE_OLDVER 1 /* Oldest sequence version supported. */ /* * DB access method and cursor operation values. Each value is an operation * code to which additional bit flags are added. */ #define DB_AFTER 1 /* Dbc.put */ #define DB_APPEND 2 /* Db.put */ #define DB_BEFORE 3 /* Dbc.put */ #define DB_CONSUME 4 /* Db.get */ #define DB_CONSUME_WAIT 5 /* Db.get */ #define DB_CURRENT 6 /* Dbc.get, Dbc.put, DbLogc.get */ #define DB_FIRST 7 /* Dbc.get, DbLogc->get */ #define DB_GET_BOTH 8 /* Db.get, Dbc.get */ #define DB_GET_BOTHC 9 /* Dbc.get (internal) */ #define DB_GET_BOTH_RANGE 10 /* Db.get, Dbc.get */ #define DB_GET_RECNO 11 /* Dbc.get */ #define DB_JOIN_ITEM 12 /* Dbc.get; don't do primary lookup */ #define DB_KEYFIRST 13 /* Dbc.put */ #define DB_KEYLAST 14 /* Dbc.put */ #define DB_LAST 15 /* Dbc.get, DbLogc->get */ #define DB_NEXT 16 /* Dbc.get, DbLogc->get */ #define DB_NEXT_DUP 17 /* Dbc.get */ #define DB_NEXT_NODUP 18 /* Dbc.get */ #define DB_NODUPDATA 19 /* Db.put, Dbc.put */ #define DB_NOOVERWRITE 20 /* Db.put */ #define DB_OVERWRITE_DUP 21 /* Dbc.put, Db.put; no DB_KEYEXIST */ #define DB_POSITION 22 /* Dbc.dup */ #define DB_PREV 23 /* Dbc.get, DbLogc->get */ #define DB_PREV_DUP 24 /* Dbc.get */ #define DB_PREV_NODUP 25 /* Dbc.get */ #define DB_SET 26 /* Dbc.get, DbLogc->get */ #define DB_SET_RANGE 27 /* Dbc.get */ #define DB_SET_RECNO 28 /* Db.get, Dbc.get */ #define DB_UPDATE_SECONDARY 29 /* Dbc.get, Dbc.del (internal) */ #define DB_SET_LTE 30 /* Dbc.get (internal) */ #define DB_GET_BOTH_LTE 31 /* Dbc.get (internal) */ /* This has to change when the max opcode hits 255. */ #define DB_OPFLAGS_MASK 0x000000ff /* Mask for operations flags. */ /* * DB (user visible) error return codes. * * !!! * We don't want our error returns to conflict with other packages where * possible, so pick a base error value that's hopefully not common. We * document that we own the error name space from -30,800 to -30,999. */ /* DB (public) error return codes. */ #define DB_BUFFER_SMALL (-30999)/* User memory too small for return. */ #define DB_DONOTINDEX (-30998)/* "Null" return from 2ndary callbk. */ #define DB_FOREIGN_CONFLICT (-30997)/* A foreign db constraint triggered. */ #define DB_HEAP_FULL (-30996)/* No free space in a heap file. */ #define DB_KEYEMPTY (-30995)/* Key/data deleted or never created. */ #define DB_KEYEXIST (-30994)/* The key/data pair already exists. */ #define DB_LOCK_DEADLOCK (-30993)/* Deadlock. */ #define DB_LOCK_NOTGRANTED (-30992)/* Lock unavailable. */ #define DB_LOG_BUFFER_FULL (-30991)/* In-memory log buffer full. */ #define DB_LOG_VERIFY_BAD (-30990)/* Log verification failed. */ #define DB_NOSERVER (-30989)/* Server panic return. */ #define DB_NOTFOUND (-30988)/* Key/data pair not found (EOF). */ #define DB_OLD_VERSION (-30987)/* Out-of-date version. */ #define DB_PAGE_NOTFOUND (-30986)/* Requested page not found. */ #define DB_REP_DUPMASTER (-30985)/* There are two masters. */ #define DB_REP_HANDLE_DEAD (-30984)/* Rolled back a commit. */ #define DB_REP_HOLDELECTION (-30983)/* Time to hold an election. */ #define DB_REP_IGNORE (-30982)/* This msg should be ignored.*/ #define DB_REP_ISPERM (-30981)/* Cached not written perm written.*/ #define DB_REP_JOIN_FAILURE (-30980)/* Unable to join replication group. */ #define DB_REP_LEASE_EXPIRED (-30979)/* Master lease has expired. */ #define DB_REP_LOCKOUT (-30978)/* API/Replication lockout now. */ #define DB_REP_NEWSITE (-30977)/* New site entered system. */ #define DB_REP_NOTPERM (-30976)/* Permanent log record not written. */ #define DB_REP_UNAVAIL (-30975)/* Site cannot currently be reached. */ #define DB_REP_WOULDROLLBACK (-30974)/* UNDOC: rollback inhibited by app. */ #define DB_RUNRECOVERY (-30973)/* Panic return. */ #define DB_SECONDARY_BAD (-30972)/* Secondary index corrupt. */ #define DB_TIMEOUT (-30971)/* Timed out on read consistency. */ #define DB_VERIFY_BAD (-30970)/* Verify failed; bad format. */ #define DB_VERSION_MISMATCH (-30969)/* Environment version mismatch. */ /* DB (private) error return codes. */ #define DB_ALREADY_ABORTED (-30899) #define DB_CHKSUM_FAIL (-30898)/* Checksum failed. */ #define DB_DELETED (-30897)/* Recovery file marked deleted. */ #define DB_EVENT_NOT_HANDLED (-30896)/* Forward event to application. */ #define DB_NEEDSPLIT (-30895)/* Page needs to be split. */ #define DB_REP_BULKOVF (-30894)/* Rep bulk buffer overflow. */ #define DB_REP_LOGREADY (-30893)/* Rep log ready for recovery. */ #define DB_REP_NEWMASTER (-30892)/* We have learned of a new master. */ #define DB_REP_PAGEDONE (-30891)/* This page was already done. */ #define DB_SURPRISE_KID (-30890)/* Child commit where parent didn't know it was a parent. */ #define DB_SWAPBYTES (-30889)/* Database needs byte swapping. */ #define DB_TXN_CKP (-30888)/* Encountered ckp record in log. */ #define DB_VERIFY_FATAL (-30887)/* DB->verify cannot proceed. */ /* Database handle. */ struct __db { /******************************************************* * Public: owned by the application. *******************************************************/ u_int32_t pgsize; /* Database logical page size. */ DB_CACHE_PRIORITY priority; /* Database priority in cache. */ /* Callbacks. */ int (*db_append_recno) __P((DB *, DBT *, db_recno_t)); void (*db_feedback) __P((DB *, int, int)); int (*dup_compare) __P((DB *, const DBT *, const DBT *)); void *app_private; /* Application-private handle. */ /******************************************************* * Private: owned by DB. *******************************************************/ DB_ENV *dbenv; /* Backing public environment. */ ENV *env; /* Backing private environment. */ DBTYPE type; /* DB access method type. */ DB_MPOOLFILE *mpf; /* Backing buffer pool. */ db_mutex_t mutex; /* Synchronization for free threading */ char *fname, *dname; /* File/database passed to DB->open. */ const char *dirname; /* Directory of DB file. */ u_int32_t open_flags; /* Flags passed to DB->open. */ u_int8_t fileid[DB_FILE_ID_LEN];/* File's unique ID for locking. */ u_int32_t adj_fileid; /* File's unique ID for curs. adj. */ #define DB_LOGFILEID_INVALID -1 FNAME *log_filename; /* File's naming info for logging. */ db_pgno_t meta_pgno; /* Meta page number */ DB_LOCKER *locker; /* Locker for handle locking. */ DB_LOCKER *cur_locker; /* Current handle lock holder. */ DB_TXN *cur_txn; /* Opening transaction. */ DB_LOCKER *associate_locker; /* Locker for DB->associate call. */ DB_LOCK handle_lock; /* Lock held on this handle. */ time_t timestamp; /* Handle timestamp for replication. */ u_int32_t fid_gen; /* Rep generation number for fids. */ /* * Returned data memory for DB->get() and friends. */ DBT my_rskey; /* Secondary key. */ DBT my_rkey; /* [Primary] key. */ DBT my_rdata; /* Data. */ /* * !!! * Some applications use DB but implement their own locking outside of * DB. If they're using fcntl(2) locking on the underlying database * file, and we open and close a file descriptor for that file, we will * discard their locks. The DB_FCNTL_LOCKING flag to DB->open is an * undocumented interface to support this usage which leaves any file * descriptors we open until DB->close. This will only work with the * DB->open interface and simple caches, e.g., creating a transaction * thread may open/close file descriptors this flag doesn't protect. * Locking with fcntl(2) on a file that you don't own is a very, very * unsafe thing to do. 'Nuff said. */ DB_FH *saved_open_fhp; /* Saved file handle. */ /* * Linked list of DBP's, linked from the ENV, used to keep track * of all open db handles for cursor adjustment. * * !!! * Explicit representations of structures from queue.h. * TAILQ_ENTRY(__db) dblistlinks; */ struct { struct __db *tqe_next; struct __db **tqe_prev; } dblistlinks; /* * Cursor queues. * * !!! * Explicit representations of structures from queue.h. * TAILQ_HEAD(__cq_fq, __dbc) free_queue; * TAILQ_HEAD(__cq_aq, __dbc) active_queue; * TAILQ_HEAD(__cq_jq, __dbc) join_queue; */ struct __cq_fq { struct __dbc *tqh_first; struct __dbc **tqh_last; } free_queue; struct __cq_aq { struct __dbc *tqh_first; struct __dbc **tqh_last; } active_queue; struct __cq_jq { struct __dbc *tqh_first; struct __dbc **tqh_last; } join_queue; /* * Secondary index support. * * Linked list of secondary indices -- set in the primary. * * !!! * Explicit representations of structures from queue.h. * LIST_HEAD(s_secondaries, __db); */ struct { struct __db *lh_first; } s_secondaries; /* * List entries for secondaries, and reference count of how many * threads are updating this secondary (see Dbc.put). * * !!! * Note that these are synchronized by the primary's mutex, but * filled in in the secondaries. * * !!! * Explicit representations of structures from queue.h. * LIST_ENTRY(__db) s_links; */ struct { struct __db *le_next; struct __db **le_prev; } s_links; u_int32_t s_refcnt; /* Secondary callback and free functions -- set in the secondary. */ int (*s_callback) __P((DB *, const DBT *, const DBT *, DBT *)); /* Reference to primary -- set in the secondary. */ DB *s_primary; #define DB_ASSOC_IMMUTABLE_KEY 0x00000001 /* Secondary key is immutable. */ #define DB_ASSOC_CREATE 0x00000002 /* Secondary db populated on open. */ /* Flags passed to associate -- set in the secondary. */ u_int32_t s_assoc_flags; /* * Foreign key support. * * Linked list of primary dbs -- set in the foreign db * * !!! * Explicit representations of structures from queue.h. * LIST_HEAD(f_primaries, __db); */ struct { struct __db_foreign_info *lh_first; } f_primaries; /* * !!! * Explicit representations of structures from queue.h. * TAILQ_ENTRY(__db) felink; * * Links in a list of DBs involved in file extension * during a transaction. These are to be used only while the * metadata is locked. */ struct { struct __db *tqe_next; struct __db **tqe_prev; } felink; /* Reference to foreign -- set in the secondary. */ DB *s_foreign; /* API-private structure: used by DB 1.85, C++, Java, Perl and Tcl */ void *api_internal; /* Subsystem-private structure. */ void *bt_internal; /* Btree/Recno access method. */ void *h_internal; /* Hash access method. */ void *heap_internal; /* Heap access method. */ void *p_internal; /* Partition informaiton. */ void *q_internal; /* Queue access method. */ /* DB PUBLIC HANDLE LIST BEGIN */ int (*associate) __P((DB *, DB_TXN *, DB *, int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); int (*associate_foreign) __P((DB *, DB *, int (*)(DB *, const DBT *, DBT *, const DBT *, int *), u_int32_t)); int (*close) __P((DB *, u_int32_t)); int (*compact) __P((DB *, DB_TXN *, DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *)); int (*cursor) __P((DB *, DB_TXN *, DBC **, u_int32_t)); int (*del) __P((DB *, DB_TXN *, DBT *, u_int32_t)); void (*err) __P((DB *, int, const char *, ...)); void (*errx) __P((DB *, const char *, ...)); int (*exists) __P((DB *, DB_TXN *, DBT *, u_int32_t)); int (*fd) __P((DB *, int *)); int (*get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); int (*get_alloc) __P((DB *, void *(**)(size_t), void *(**)(void *, size_t), void (**)(void *))); int (*get_append_recno) __P((DB *, int (**)(DB *, DBT *, db_recno_t))); int (*get_assoc_flags) __P((DB *, u_int32_t *)); int (*get_bt_compare) __P((DB *, int (**)(DB *, const DBT *, const DBT *))); int (*get_bt_compress) __P((DB *, int (**)(DB *, const DBT *, const DBT *, const DBT *, const DBT *, DBT *), int (**)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *))); int (*get_bt_minkey) __P((DB *, u_int32_t *)); int (*get_bt_prefix) __P((DB *, size_t (**)(DB *, const DBT *, const DBT *))); int (*get_byteswapped) __P((DB *, int *)); int (*get_cachesize) __P((DB *, u_int32_t *, u_int32_t *, int *)); int (*get_create_dir) __P((DB *, const char **)); int (*get_dbname) __P((DB *, const char **, const char **)); int (*get_dup_compare) __P((DB *, int (**)(DB *, const DBT *, const DBT *))); int (*get_encrypt_flags) __P((DB *, u_int32_t *)); DB_ENV *(*get_env) __P((DB *)); void (*get_errcall) __P((DB *, void (**)(const DB_ENV *, const char *, const char *))); void (*get_errfile) __P((DB *, FILE **)); void (*get_errpfx) __P((DB *, const char **)); int (*get_feedback) __P((DB *, void (**)(DB *, int, int))); int (*get_flags) __P((DB *, u_int32_t *)); int (*get_h_compare) __P((DB *, int (**)(DB *, const DBT *, const DBT *))); int (*get_h_ffactor) __P((DB *, u_int32_t *)); int (*get_h_hash) __P((DB *, u_int32_t (**)(DB *, const void *, u_int32_t))); int (*get_h_nelem) __P((DB *, u_int32_t *)); int (*get_heapsize) __P((DB *, u_int32_t *, u_int32_t *)); int (*get_heap_regionsize) __P((DB *, u_int32_t *)); int (*get_lk_exclusive) __P((DB *, int *, int *)); int (*get_lorder) __P((DB *, int *)); DB_MPOOLFILE *(*get_mpf) __P((DB *)); void (*get_msgcall) __P((DB *, void (**)(const DB_ENV *, const char *))); void (*get_msgfile) __P((DB *, FILE **)); int (*get_multiple) __P((DB *)); int (*get_open_flags) __P((DB *, u_int32_t *)); int (*get_pagesize) __P((DB *, u_int32_t *)); int (*get_partition_callback) __P((DB *, u_int32_t *, u_int32_t (**)(DB *, DBT *key))); int (*get_partition_dirs) __P((DB *, const char ***)); int (*get_partition_keys) __P((DB *, u_int32_t *, DBT **)); int (*get_priority) __P((DB *, DB_CACHE_PRIORITY *)); int (*get_q_extentsize) __P((DB *, u_int32_t *)); int (*get_re_delim) __P((DB *, int *)); int (*get_re_len) __P((DB *, u_int32_t *)); int (*get_re_pad) __P((DB *, int *)); int (*get_re_source) __P((DB *, const char **)); int (*get_transactional) __P((DB *)); int (*get_type) __P((DB *, DBTYPE *)); int (*join) __P((DB *, DBC **, DBC **, u_int32_t)); int (*key_range) __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t)); int (*open) __P((DB *, DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int)); int (*pget) __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); int (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); int (*remove) __P((DB *, const char *, const char *, u_int32_t)); int (*rename) __P((DB *, const char *, const char *, const char *, u_int32_t)); int (*set_alloc) __P((DB *, void *(*)(size_t), void *(*)(void *, size_t), void (*)(void *))); int (*set_append_recno) __P((DB *, int (*)(DB *, DBT *, db_recno_t))); int (*set_bt_compare) __P((DB *, int (*)(DB *, const DBT *, const DBT *))); int (*set_bt_compress) __P((DB *, int (*)(DB *, const DBT *, const DBT *, const DBT *, const DBT *, DBT *), int (*)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *))); int (*set_bt_minkey) __P((DB *, u_int32_t)); int (*set_bt_prefix) __P((DB *, size_t (*)(DB *, const DBT *, const DBT *))); int (*set_cachesize) __P((DB *, u_int32_t, u_int32_t, int)); int (*set_create_dir) __P((DB *, const char *)); int (*set_dup_compare) __P((DB *, int (*)(DB *, const DBT *, const DBT *))); int (*set_encrypt) __P((DB *, const char *, u_int32_t)); void (*set_errcall) __P((DB *, void (*)(const DB_ENV *, const char *, const char *))); void (*set_errfile) __P((DB *, FILE *)); void (*set_errpfx) __P((DB *, const char *)); int (*set_feedback) __P((DB *, void (*)(DB *, int, int))); int (*set_flags) __P((DB *, u_int32_t)); int (*set_h_compare) __P((DB *, int (*)(DB *, const DBT *, const DBT *))); int (*set_h_ffactor) __P((DB *, u_int32_t)); int (*set_h_hash) __P((DB *, u_int32_t (*)(DB *, const void *, u_int32_t))); int (*set_h_nelem) __P((DB *, u_int32_t)); int (*set_heapsize) __P((DB *, u_int32_t, u_int32_t, u_int32_t)); int (*set_heap_regionsize) __P((DB *, u_int32_t)); int (*set_lk_exclusive) __P((DB *, int)); int (*set_lorder) __P((DB *, int)); void (*set_msgcall) __P((DB *, void (*)(const DB_ENV *, const char *))); void (*set_msgfile) __P((DB *, FILE *)); int (*set_pagesize) __P((DB *, u_int32_t)); int (*set_paniccall) __P((DB *, void (*)(DB_ENV *, int))); int (*set_partition) __P((DB *, u_int32_t, DBT *, u_int32_t (*)(DB *, DBT *key))); int (*set_partition_dirs) __P((DB *, const char **)); int (*set_priority) __P((DB *, DB_CACHE_PRIORITY)); int (*set_q_extentsize) __P((DB *, u_int32_t)); int (*set_re_delim) __P((DB *, int)); int (*set_re_len) __P((DB *, u_int32_t)); int (*set_re_pad) __P((DB *, int)); int (*set_re_source) __P((DB *, const char *)); int (*sort_multiple) __P((DB *, DBT *, DBT *, u_int32_t)); int (*stat) __P((DB *, DB_TXN *, void *, u_int32_t)); int (*stat_print) __P((DB *, u_int32_t)); int (*sync) __P((DB *, u_int32_t)); int (*truncate) __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); int (*upgrade) __P((DB *, const char *, u_int32_t)); int (*verify) __P((DB *, const char *, const char *, FILE *, u_int32_t)); /* DB PUBLIC HANDLE LIST END */ /* DB PRIVATE HANDLE LIST BEGIN */ int (*dump) __P((DB *, const char *, int (*)(void *, const void *), void *, int, int)); int (*db_am_remove) __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, u_int32_t)); int (*db_am_rename) __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, const char *)); /* DB PRIVATE HANDLE LIST END */ /* * Never called; these are a place to save function pointers * so that we can undo an associate. */ int (*stored_get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); int (*stored_close) __P((DB *, u_int32_t)); /* Alternative handle close function, used by C++ API. */ int (*alt_close) __P((DB *, u_int32_t)); #define DB_OK_BTREE 0x01 #define DB_OK_HASH 0x02 #define DB_OK_HEAP 0x04 #define DB_OK_QUEUE 0x08 #define DB_OK_RECNO 0x10 u_int32_t am_ok; /* Legal AM choices. */ /* * This field really ought to be an AM_FLAG, but we have * have run out of bits. If/when we decide to split up * the flags, we can incorporate it. */ int preserve_fid; /* Do not free fileid on close. */ #define DB_AM_CHKSUM 0x00000001 /* Checksumming */ #define DB_AM_COMPENSATE 0x00000002 /* Created by compensating txn */ #define DB_AM_COMPRESS 0x00000004 /* Compressed BTree */ #define DB_AM_CREATED 0x00000008 /* Database was created upon open */ #define DB_AM_CREATED_MSTR 0x00000010 /* Encompassing file was created */ #define DB_AM_DBM_ERROR 0x00000020 /* Error in DBM/NDBM database */ #define DB_AM_DELIMITER 0x00000040 /* Variable length delimiter set */ #define DB_AM_DISCARD 0x00000080 /* Discard any cached pages */ #define DB_AM_DUP 0x00000100 /* DB_DUP */ #define DB_AM_DUPSORT 0x00000200 /* DB_DUPSORT */ #define DB_AM_ENCRYPT 0x00000400 /* Encryption */ #define DB_AM_FIXEDLEN 0x00000800 /* Fixed-length records */ #define DB_AM_INMEM 0x00001000 /* In-memory; no sync on close */ #define DB_AM_INORDER 0x00002000 /* DB_INORDER */ #define DB_AM_IN_RENAME 0x00004000 /* File is being renamed */ #define DB_AM_NOT_DURABLE 0x00008000 /* Do not log changes */ #define DB_AM_OPEN_CALLED 0x00010000 /* DB->open called */ #define DB_AM_PAD 0x00020000 /* Fixed-length record pad */ #define DB_AM_PARTDB 0x00040000 /* Handle for a database partition */ #define DB_AM_PGDEF 0x00080000 /* Page size was defaulted */ #define DB_AM_RDONLY 0x00100000 /* Database is readonly */ #define DB_AM_READ_UNCOMMITTED 0x00200000 /* Support degree 1 isolation */ #define DB_AM_RECNUM 0x00400000 /* DB_RECNUM */ #define DB_AM_RECOVER 0x00800000 /* DB opened by recovery routine */ #define DB_AM_RENUMBER 0x01000000 /* DB_RENUMBER */ #define DB_AM_REVSPLITOFF 0x02000000 /* DB_REVSPLITOFF */ #define DB_AM_SECONDARY 0x04000000 /* Database is a secondary index */ #define DB_AM_SNAPSHOT 0x08000000 /* DB_SNAPSHOT */ #define DB_AM_SUBDB 0x10000000 /* Subdatabases supported */ #define DB_AM_SWAP 0x20000000 /* Pages need to be byte-swapped */ #define DB_AM_TXN 0x40000000 /* Opened in a transaction */ #define DB_AM_VERIFYING 0x80000000 /* DB handle is in the verifier */ u_int32_t orig_flags; /* Flags at open, for refresh */ u_int32_t flags; #define DB2_AM_EXCL 0x00000001 /* Exclusively lock the handle */ #define DB2_AM_INTEXCL 0x00000002 /* Internal exclusive lock. */ #define DB2_AM_NOWAIT 0x00000004 /* Do not wait for handle lock */ u_int32_t orig_flags2; /* Second flags word; for refresh */ u_int32_t flags2; /* Second flags word */ }; /* * Macros for bulk operations. These are only intended for the C API. * For C++, use DbMultiple*Iterator or DbMultiple*Builder. * * Bulk operations store multiple entries into a single DBT structure. The * following macros assist with creating and reading these Multiple DBTs. * * The basic layout for single data items is: * * ------------------------------------------------------------------------- * | data1 | ... | dataN | ..... |-1 | dNLen | dNOff | ... | d1Len | d1Off | * ------------------------------------------------------------------------- * * For the DB_MULTIPLE_KEY* macros, the items are in key/data pairs, so data1 * would be a key, and data2 its corresponding value (N is always even). * * For the DB_MULTIPLE_RECNO* macros, the record number is stored along with * the len/off pair in the "header" section, and the list is zero terminated * (since -1 is a valid record number): * * -------------------------------------------------------------------------- * | d1 |..| dN |..| 0 | dNLen | dNOff | recnoN |..| d1Len | d1Off | recno1 | * -------------------------------------------------------------------------- */ #define DB_MULTIPLE_INIT(pointer, dbt) \ (pointer = (u_int8_t *)(dbt)->data + \ (dbt)->ulen - sizeof(u_int32_t)) #define DB_MULTIPLE_NEXT(pointer, dbt, retdata, retdlen) \ do { \ u_int32_t *__p = (u_int32_t *)(pointer); \ if (*__p == (u_int32_t)-1) { \ retdata = NULL; \ pointer = NULL; \ break; \ } \ retdata = (u_int8_t *)(dbt)->data + *__p--; \ retdlen = *__p--; \ pointer = __p; \ if (retdlen == 0 && retdata == (u_int8_t *)(dbt)->data) \ retdata = NULL; \ } while (0) #define DB_MULTIPLE_KEY_NEXT(pointer, dbt, retkey, retklen, retdata, retdlen) \ do { \ u_int32_t *__p = (u_int32_t *)(pointer); \ if (*__p == (u_int32_t)-1) { \ retdata = NULL; \ retkey = NULL; \ pointer = NULL; \ break; \ } \ retkey = (u_int8_t *)(dbt)->data + *__p--; \ retklen = *__p--; \ retdata = (u_int8_t *)(dbt)->data + *__p--; \ retdlen = *__p--; \ pointer = __p; \ } while (0) #define DB_MULTIPLE_RECNO_NEXT(pointer, dbt, recno, retdata, retdlen) \ do { \ u_int32_t *__p = (u_int32_t *)(pointer); \ if (*__p == (u_int32_t)0) { \ recno = 0; \ retdata = NULL; \ pointer = NULL; \ break; \ } \ recno = *__p--; \ retdata = (u_int8_t *)(dbt)->data + *__p--; \ retdlen = *__p--; \ pointer = __p; \ } while (0) #define DB_MULTIPLE_WRITE_INIT(pointer, dbt) \ do { \ (dbt)->flags |= DB_DBT_BULK; \ pointer = (u_int8_t *)(dbt)->data + \ (dbt)->ulen - sizeof(u_int32_t); \ *(u_int32_t *)(pointer) = (u_int32_t)-1; \ } while (0) #define DB_MULTIPLE_RESERVE_NEXT(pointer, dbt, writedata, writedlen) \ do { \ u_int32_t *__p = (u_int32_t *)(pointer); \ u_int32_t __off = ((pointer) == (u_int8_t *)(dbt)->data +\ (dbt)->ulen - sizeof(u_int32_t)) ? 0 : __p[1] + __p[2];\ if ((u_int8_t *)(dbt)->data + __off + (writedlen) > \ (u_int8_t *)(__p - 2)) \ writedata = NULL; \ else { \ writedata = (u_int8_t *)(dbt)->data + __off; \ __p[0] = __off; \ __p[-1] = (u_int32_t)(writedlen); \ __p[-2] = (u_int32_t)-1; \ pointer = __p - 2; \ } \ } while (0) #define DB_MULTIPLE_WRITE_NEXT(pointer, dbt, writedata, writedlen) \ do { \ void *__destd; \ DB_MULTIPLE_RESERVE_NEXT((pointer), (dbt), \ __destd, (writedlen)); \ if (__destd == NULL) \ pointer = NULL; \ else \ memcpy(__destd, (writedata), (writedlen)); \ } while (0) #define DB_MULTIPLE_KEY_RESERVE_NEXT(pointer, dbt, writekey, writeklen, writedata, writedlen) \ do { \ u_int32_t *__p = (u_int32_t *)(pointer); \ u_int32_t __off = ((pointer) == (u_int8_t *)(dbt)->data +\ (dbt)->ulen - sizeof(u_int32_t)) ? 0 : __p[1] + __p[2];\ if ((u_int8_t *)(dbt)->data + __off + (writeklen) + \ (writedlen) > (u_int8_t *)(__p - 4)) { \ writekey = NULL; \ writedata = NULL; \ } else { \ writekey = (u_int8_t *)(dbt)->data + __off; \ __p[0] = __off; \ __p[-1] = (u_int32_t)(writeklen); \ __p -= 2; \ __off += (u_int32_t)(writeklen); \ writedata = (u_int8_t *)(dbt)->data + __off; \ __p[0] = __off; \ __p[-1] = (u_int32_t)(writedlen); \ __p[-2] = (u_int32_t)-1; \ pointer = __p - 2; \ } \ } while (0) #define DB_MULTIPLE_KEY_WRITE_NEXT(pointer, dbt, writekey, writeklen, writedata, writedlen) \ do { \ void *__destk, *__destd; \ DB_MULTIPLE_KEY_RESERVE_NEXT((pointer), (dbt), \ __destk, (writeklen), __destd, (writedlen)); \ if (__destk == NULL) \ pointer = NULL; \ else { \ memcpy(__destk, (writekey), (writeklen)); \ if (__destd != NULL) \ memcpy(__destd, (writedata), (writedlen));\ } \ } while (0) #define DB_MULTIPLE_RECNO_WRITE_INIT(pointer, dbt) \ do { \ (dbt)->flags |= DB_DBT_BULK; \ pointer = (u_int8_t *)(dbt)->data + \ (dbt)->ulen - sizeof(u_int32_t); \ *(u_int32_t *)(pointer) = 0; \ } while (0) #define DB_MULTIPLE_RECNO_RESERVE_NEXT(pointer, dbt, recno, writedata, writedlen) \ do { \ u_int32_t *__p = (u_int32_t *)(pointer); \ u_int32_t __off = ((pointer) == (u_int8_t *)(dbt)->data +\ (dbt)->ulen - sizeof(u_int32_t)) ? 0 : __p[1] + __p[2]; \ if (((u_int8_t *)(dbt)->data + __off) + (writedlen) > \ (u_int8_t *)(__p - 3)) \ writedata = NULL; \ else { \ writedata = (u_int8_t *)(dbt)->data + __off; \ __p[0] = (u_int32_t)(recno); \ __p[-1] = __off; \ __p[-2] = (u_int32_t)(writedlen); \ __p[-3] = 0; \ pointer = __p - 3; \ } \ } while (0) #define DB_MULTIPLE_RECNO_WRITE_NEXT(pointer, dbt, recno, writedata, writedlen)\ do { \ void *__destd; \ DB_MULTIPLE_RECNO_RESERVE_NEXT((pointer), (dbt), \ (recno), __destd, (writedlen)); \ if (__destd == NULL) \ pointer = NULL; \ else if ((writedlen) != 0) \ memcpy(__destd, (writedata), (writedlen)); \ } while (0) struct __db_heap_rid { db_pgno_t pgno; /* Page number. */ db_indx_t indx; /* Index in the offset table. */ }; #define DB_HEAP_RID_SZ (sizeof(db_pgno_t) + sizeof(db_indx_t)) /******************************************************* * Access method cursors. *******************************************************/ struct __dbc { DB *dbp; /* Backing database */ DB_ENV *dbenv; /* Backing environment */ ENV *env; /* Backing environment */ DB_THREAD_INFO *thread_info; /* Thread that owns this cursor. */ DB_TXN *txn; /* Associated transaction. */ DB_CACHE_PRIORITY priority; /* Priority in cache. */ /* * Active/free cursor queues. * * !!! * Explicit representations of structures from queue.h. * TAILQ_ENTRY(__dbc) links; */ struct { DBC *tqe_next; DBC **tqe_prev; } links; /* * Cursor queue of the owning transaction. * * !!! * Explicit representations of structures from queue.h. * TAILQ_ENTRY(__dbc) txn_cursors; */ struct { DBC *tqe_next; /* next element */ DBC **tqe_prev; /* address of previous next element */ } txn_cursors; /* * The DBT *'s below are used by the cursor routines to return * data to the user when DBT flags indicate that DB should manage * the returned memory. They point at a DBT containing the buffer * and length that will be used, and "belonging" to the handle that * should "own" this memory. This may be a "my_*" field of this * cursor--the default--or it may be the corresponding field of * another cursor, a DB handle, a join cursor, etc. In general, it * will be whatever handle the user originally used for the current * DB interface call. */ DBT *rskey; /* Returned secondary key. */ DBT *rkey; /* Returned [primary] key. */ DBT *rdata; /* Returned data. */ DBT my_rskey; /* Space for returned secondary key. */ DBT my_rkey; /* Space for returned [primary] key. */ DBT my_rdata; /* Space for returned data. */ DB_LOCKER *lref; /* Reference to default locker. */ DB_LOCKER *locker; /* Locker for this operation. */ DBT lock_dbt; /* DBT referencing lock. */ DB_LOCK_ILOCK lock; /* Object to be locked. */ DB_LOCK mylock; /* CDB lock held on this cursor. */ DBTYPE dbtype; /* Cursor type. */ DBC_INTERNAL *internal; /* Access method private. */ /* DBC PUBLIC HANDLE LIST BEGIN */ int (*close) __P((DBC *)); int (*cmp) __P((DBC *, DBC *, int *, u_int32_t)); int (*count) __P((DBC *, db_recno_t *, u_int32_t)); int (*del) __P((DBC *, u_int32_t)); int (*dup) __P((DBC *, DBC **, u_int32_t)); int (*get) __P((DBC *, DBT *, DBT *, u_int32_t)); int (*get_priority) __P((DBC *, DB_CACHE_PRIORITY *)); int (*pget) __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); int (*put) __P((DBC *, DBT *, DBT *, u_int32_t)); int (*set_priority) __P((DBC *, DB_CACHE_PRIORITY)); /* DBC PUBLIC HANDLE LIST END */ /* The following are the method names deprecated in the 4.6 release. */ int (*c_close) __P((DBC *)); int (*c_count) __P((DBC *, db_recno_t *, u_int32_t)); int (*c_del) __P((DBC *, u_int32_t)); int (*c_dup) __P((DBC *, DBC **, u_int32_t)); int (*c_get) __P((DBC *, DBT *, DBT *, u_int32_t)); int (*c_pget) __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); int (*c_put) __P((DBC *, DBT *, DBT *, u_int32_t)); /* DBC PRIVATE HANDLE LIST BEGIN */ int (*am_bulk) __P((DBC *, DBT *, u_int32_t)); int (*am_close) __P((DBC *, db_pgno_t, int *)); int (*am_del) __P((DBC *, u_int32_t)); int (*am_destroy) __P((DBC *)); int (*am_get) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); int (*am_put) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); int (*am_writelock) __P((DBC *)); /* DBC PRIVATE HANDLE LIST END */ /* * DBC_DONTLOCK and DBC_RECOVER are used during recovery and transaction * abort. If a transaction is being aborted or recovered then DBC_RECOVER * will be set and locking and logging will be disabled on this cursor. If * we are performing a compensating transaction (e.g. free page processing) * then DB_DONTLOCK will be set to inhibit locking, but logging will still * be required. DB_DONTLOCK is also used if the whole database is locked. */ #define DBC_ACTIVE 0x00001 /* Cursor in use. */ #define DBC_BULK 0x00002 /* Bulk update cursor. */ #define DBC_DONTLOCK 0x00004 /* Don't lock on this cursor. */ #define DBC_DOWNREV 0x00008 /* Down rev replication master. */ #define DBC_DUPLICATE 0x00010 /* Create a duplicate cursor. */ #define DBC_ERROR 0x00020 /* Error in this request. */ #define DBC_FAMILY 0x00040 /* Part of a locker family. */ #define DBC_FROM_DB_GET 0x00080 /* Called from the DB->get() method. */ #define DBC_MULTIPLE 0x00100 /* Return Multiple data. */ #define DBC_MULTIPLE_KEY 0x00200 /* Return Multiple keys and data. */ #define DBC_OPD 0x00400 /* Cursor references off-page dups. */ #define DBC_OWN_LID 0x00800 /* Free lock id on destroy. */ #define DBC_PARTITIONED 0x01000 /* Cursor for a partitioned db. */ #define DBC_READ_COMMITTED 0x02000 /* Cursor has degree 2 isolation. */ #define DBC_READ_UNCOMMITTED 0x04000 /* Cursor has degree 1 isolation. */ #define DBC_RECOVER 0x08000 /* Recovery cursor; don't log/lock. */ #define DBC_RMW 0x10000 /* Acquire write flag in read op. */ #define DBC_TRANSIENT 0x20000 /* Cursor is transient. */ #define DBC_WAS_READ_COMMITTED 0x40000 /* Cursor holds a read commited lock. */ #define DBC_WRITECURSOR 0x80000 /* Cursor may be used to write (CDB). */ #define DBC_WRITER 0x100000 /* Cursor immediately writing (CDB). */ u_int32_t flags; }; /* Key range statistics structure */ struct __key_range { double less; double equal; double greater; }; /* Btree/Recno statistics structure. */ struct __db_bt_stat { /* SHARED */ u_int32_t bt_magic; /* Magic number. */ u_int32_t bt_version; /* Version number. */ u_int32_t bt_metaflags; /* Metadata flags. */ u_int32_t bt_nkeys; /* Number of unique keys. */ u_int32_t bt_ndata; /* Number of data items. */ u_int32_t bt_pagecnt; /* Page count. */ u_int32_t bt_pagesize; /* Page size. */ u_int32_t bt_minkey; /* Minkey value. */ u_int32_t bt_re_len; /* Fixed-length record length. */ u_int32_t bt_re_pad; /* Fixed-length record pad. */ u_int32_t bt_levels; /* Tree levels. */ u_int32_t bt_int_pg; /* Internal pages. */ u_int32_t bt_leaf_pg; /* Leaf pages. */ u_int32_t bt_dup_pg; /* Duplicate pages. */ u_int32_t bt_over_pg; /* Overflow pages. */ u_int32_t bt_empty_pg; /* Empty pages. */ u_int32_t bt_free; /* Pages on the free list. */ uintmax_t bt_int_pgfree; /* Bytes free in internal pages. */ uintmax_t bt_leaf_pgfree; /* Bytes free in leaf pages. */ uintmax_t bt_dup_pgfree; /* Bytes free in duplicate pages. */ uintmax_t bt_over_pgfree; /* Bytes free in overflow pages. */ }; struct __db_compact { /* Input Parameters. */ u_int32_t compact_fillpercent; /* Desired fillfactor: 1-100 */ db_timeout_t compact_timeout; /* Lock timeout. */ u_int32_t compact_pages; /* Max pages to process. */ /* Output Stats. */ u_int32_t compact_empty_buckets; /* Empty hash buckets found. */ u_int32_t compact_pages_free; /* Number of pages freed. */ u_int32_t compact_pages_examine; /* Number of pages examine. */ u_int32_t compact_levels; /* Number of levels removed. */ u_int32_t compact_deadlock; /* Number of deadlocks. */ db_pgno_t compact_pages_truncated; /* Pages truncated to OS. */ /* Internal. */ db_pgno_t compact_truncate; /* Exchange pages above here. */ }; /* Hash statistics structure. */ struct __db_h_stat { /* SHARED */ u_int32_t hash_magic; /* Magic number. */ u_int32_t hash_version; /* Version number. */ u_int32_t hash_metaflags; /* Metadata flags. */ u_int32_t hash_nkeys; /* Number of unique keys. */ u_int32_t hash_ndata; /* Number of data items. */ u_int32_t hash_pagecnt; /* Page count. */ u_int32_t hash_pagesize; /* Page size. */ u_int32_t hash_ffactor; /* Fill factor specified at create. */ u_int32_t hash_buckets; /* Number of hash buckets. */ u_int32_t hash_free; /* Pages on the free list. */ uintmax_t hash_bfree; /* Bytes free on bucket pages. */ u_int32_t hash_bigpages; /* Number of big key/data pages. */ uintmax_t hash_big_bfree; /* Bytes free on big item pages. */ u_int32_t hash_overflows; /* Number of overflow pages. */ uintmax_t hash_ovfl_free; /* Bytes free on ovfl pages. */ u_int32_t hash_dup; /* Number of dup pages. */ uintmax_t hash_dup_free; /* Bytes free on duplicate pages. */ }; /* Heap statistics structure. */ struct __db_heap_stat { /* SHARED */ u_int32_t heap_magic; /* Magic number. */ u_int32_t heap_version; /* Version number. */ u_int32_t heap_metaflags; /* Metadata flags. */ u_int32_t heap_nrecs; /* Number of records. */ u_int32_t heap_pagecnt; /* Page count. */ u_int32_t heap_pagesize; /* Page size. */ u_int32_t heap_nregions; /* Number of regions. */ u_int32_t heap_regionsize; /* Number of pages in a region. */ }; /* Queue statistics structure. */ struct __db_qam_stat { /* SHARED */ u_int32_t qs_magic; /* Magic number. */ u_int32_t qs_version; /* Version number. */ u_int32_t qs_metaflags; /* Metadata flags. */ u_int32_t qs_nkeys; /* Number of unique keys. */ u_int32_t qs_ndata; /* Number of data items. */ u_int32_t qs_pagesize; /* Page size. */ u_int32_t qs_extentsize; /* Pages per extent. */ u_int32_t qs_pages; /* Data pages. */ u_int32_t qs_re_len; /* Fixed-length record length. */ u_int32_t qs_re_pad; /* Fixed-length record pad. */ u_int32_t qs_pgfree; /* Bytes free in data pages. */ u_int32_t qs_first_recno; /* First not deleted record. */ u_int32_t qs_cur_recno; /* Next available record number. */ }; /******************************************************* * Environment. *******************************************************/ #define DB_REGION_MAGIC 0x120897 /* Environment magic number. */ /* * Database environment structure. * * This is the public database environment handle. The private environment * handle is the ENV structure. The user owns this structure, the library * owns the ENV structure. The reason there are two structures is because * the user's configuration outlives any particular DB_ENV->open call, and * separate structures allows us to easily discard internal information without * discarding the user's configuration. * * Fields in the DB_ENV structure should normally be set only by application * DB_ENV handle methods. */ /* * Memory configuration types. */ typedef enum { DB_MEM_LOCK=1, DB_MEM_LOCKOBJECT=2, DB_MEM_LOCKER=3, DB_MEM_LOGID=4, DB_MEM_TRANSACTION=5, DB_MEM_THREAD=6 } DB_MEM_CONFIG; /* * Backup configuration types. */ typedef enum { DB_BACKUP_READ_COUNT = 1, DB_BACKUP_READ_SLEEP = 2, DB_BACKUP_SIZE = 3, DB_BACKUP_WRITE_DIRECT = 4 } DB_BACKUP_CONFIG; struct __db_env { ENV *env; /* Linked ENV structure */ /* * The DB_ENV structure can be used concurrently, so field access is * protected. */ db_mutex_t mtx_db_env; /* DB_ENV structure mutex */ /* Error message callback */ void (*db_errcall) __P((const DB_ENV *, const char *, const char *)); FILE *db_errfile; /* Error message file stream */ const char *db_errpfx; /* Error message prefix */ /* Other message callback */ void (*db_msgcall) __P((const DB_ENV *, const char *)); FILE *db_msgfile; /* Other message file stream */ /* Other application callback functions */ int (*app_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); void (*db_event_func) __P((DB_ENV *, u_int32_t, void *)); void (*db_feedback) __P((DB_ENV *, int, int)); void (*db_free) __P((void *)); void (*db_paniccall) __P((DB_ENV *, int)); void *(*db_malloc) __P((size_t)); void *(*db_realloc) __P((void *, size_t)); int (*is_alive) __P((DB_ENV *, pid_t, db_threadid_t, u_int32_t)); void (*thread_id) __P((DB_ENV *, pid_t *, db_threadid_t *)); char *(*thread_id_string) __P((DB_ENV *, pid_t, db_threadid_t, char *)); /* Application specified paths */ char *db_log_dir; /* Database log file directory */ char *db_md_dir; /* Persistent metadata directory */ char *db_tmp_dir; /* Database tmp file directory */ char *db_create_dir; /* Create directory for data files */ char **db_data_dir; /* Database data file directories */ int data_cnt; /* Database data file slots */ int data_next; /* Next database data file slot */ char *intermediate_dir_mode; /* Intermediate directory perms */ long shm_key; /* shmget key */ char *passwd; /* Cryptography support */ size_t passwd_len; /* Private handle references */ void *app_private; /* Application-private handle */ void *api1_internal; /* C++, Perl API private */ void *api2_internal; /* Java API private */ u_int32_t verbose; /* DB_VERB_XXX flags */ /* Mutex configuration */ u_int32_t mutex_align; /* Mutex alignment */ u_int32_t mutex_cnt; /* Number of mutexes to configure */ u_int32_t mutex_inc; /* Number of mutexes to add */ u_int32_t mutex_max; /* Max number of mutexes */ u_int32_t mutex_tas_spins;/* Test-and-set spin count */ /* Locking configuration */ u_int8_t *lk_conflicts; /* Two dimensional conflict matrix */ int lk_modes; /* Number of lock modes in table */ u_int32_t lk_detect; /* Deadlock detect on all conflicts */ u_int32_t lk_max; /* Maximum number of locks */ u_int32_t lk_max_lockers;/* Maximum number of lockers */ u_int32_t lk_max_objects;/* Maximum number of locked objects */ u_int32_t lk_init; /* Initial number of locks */ u_int32_t lk_init_lockers;/* Initial number of lockers */ u_int32_t lk_init_objects;/* Initial number of locked objects */ u_int32_t lk_partitions ;/* Number of object partitions */ db_timeout_t lk_timeout; /* Lock timeout period */ /* Used during initialization */ u_int32_t locker_t_size; /* Locker hash table size. */ u_int32_t object_t_size; /* Object hash table size. */ /* Logging configuration */ u_int32_t lg_bsize; /* Buffer size */ u_int32_t lg_fileid_init; /* Initial allocation for fname structs */ int lg_filemode; /* Log file permission mode */ u_int32_t lg_regionmax; /* Region size */ u_int32_t lg_size; /* Log file size */ u_int32_t lg_flags; /* Log configuration */ /* Memory pool configuration */ u_int32_t mp_gbytes; /* Cache size: GB */ u_int32_t mp_bytes; /* Cache size: bytes */ u_int32_t mp_max_gbytes; /* Maximum cache size: GB */ u_int32_t mp_max_bytes; /* Maximum cache size: bytes */ size_t mp_mmapsize; /* Maximum file size for mmap */ int mp_maxopenfd; /* Maximum open file descriptors */ int mp_maxwrite; /* Maximum buffers to write */ u_int mp_ncache; /* Initial number of cache regions */ u_int32_t mp_pagesize; /* Average page size */ u_int32_t mp_tablesize; /* Approximate hash table size */ u_int32_t mp_mtxcount; /* Number of mutexs */ /* Sleep after writing max buffers */ db_timeout_t mp_maxwrite_sleep; /* Transaction configuration */ u_int32_t tx_init; /* Initial number of transactions */ u_int32_t tx_max; /* Maximum number of transactions */ time_t tx_timestamp; /* Recover to specific timestamp */ db_timeout_t tx_timeout; /* Timeout for transactions */ /* Thread tracking configuration */ u_int32_t thr_init; /* Thread count */ u_int32_t thr_max; /* Thread max */ roff_t memory_max; /* Maximum region memory */ /* * The following fields are not strictly user-owned, but they outlive * the ENV structure, and so are stored here. */ DB_FH *registry; /* DB_REGISTER file handle */ u_int32_t registry_off; /* * Offset of our slot. We can't use * off_t because its size depends on * build settings. */ db_timeout_t envreg_timeout; /* DB_REGISTER wait timeout */ #define DB_ENV_AUTO_COMMIT 0x00000001 /* DB_AUTO_COMMIT */ #define DB_ENV_CDB_ALLDB 0x00000002 /* CDB environment wide locking */ #define DB_ENV_FAILCHK 0x00000004 /* Failchk is running */ #define DB_ENV_DIRECT_DB 0x00000008 /* DB_DIRECT_DB set */ #define DB_ENV_DSYNC_DB 0x00000010 /* DB_DSYNC_DB set */ #define DB_ENV_DATABASE_LOCKING 0x00000020 /* Try database-level locking */ #define DB_ENV_MULTIVERSION 0x00000040 /* DB_MULTIVERSION set */ #define DB_ENV_NOLOCKING 0x00000080 /* DB_NOLOCKING set */ #define DB_ENV_NOMMAP 0x00000100 /* DB_NOMMAP set */ #define DB_ENV_NOPANIC 0x00000200 /* Okay if panic set */ #define DB_ENV_OVERWRITE 0x00000400 /* DB_OVERWRITE set */ #define DB_ENV_REGION_INIT 0x00000800 /* DB_REGION_INIT set */ #define DB_ENV_TIME_NOTGRANTED 0x00001000 /* DB_TIME_NOTGRANTED set */ #define DB_ENV_TXN_NOSYNC 0x00002000 /* DB_TXN_NOSYNC set */ #define DB_ENV_TXN_NOWAIT 0x00004000 /* DB_TXN_NOWAIT set */ #define DB_ENV_TXN_SNAPSHOT 0x00008000 /* DB_TXN_SNAPSHOT set */ #define DB_ENV_TXN_WRITE_NOSYNC 0x00010000 /* DB_TXN_WRITE_NOSYNC set */ #define DB_ENV_YIELDCPU 0x00020000 /* DB_YIELDCPU set */ #define DB_ENV_HOTBACKUP 0x00040000 /* DB_HOTBACKUP_IN_PROGRESS set */ #define DB_ENV_NOFLUSH 0x00080000 /* DB_NOFLUSH set */ u_int32_t flags; /* DB_ENV PUBLIC HANDLE LIST BEGIN */ int (*add_data_dir) __P((DB_ENV *, const char *)); int (*backup) __P((DB_ENV *, const char *, u_int32_t)); int (*cdsgroup_begin) __P((DB_ENV *, DB_TXN **)); int (*close) __P((DB_ENV *, u_int32_t)); int (*dbbackup) __P((DB_ENV *, const char *, const char *, u_int32_t)); int (*dbremove) __P((DB_ENV *, DB_TXN *, const char *, const char *, u_int32_t)); int (*dbrename) __P((DB_ENV *, DB_TXN *, const char *, const char *, const char *, u_int32_t)); void (*err) __P((const DB_ENV *, int, const char *, ...)); void (*errx) __P((const DB_ENV *, const char *, ...)); int (*failchk) __P((DB_ENV *, u_int32_t)); int (*fileid_reset) __P((DB_ENV *, const char *, u_int32_t)); int (*get_alloc) __P((DB_ENV *, void *(**)(size_t), void *(**)(void *, size_t), void (**)(void *))); int (*get_app_dispatch) __P((DB_ENV *, int (**)(DB_ENV *, DBT *, DB_LSN *, db_recops))); int (*get_cache_max) __P((DB_ENV *, u_int32_t *, u_int32_t *)); int (*get_cachesize) __P((DB_ENV *, u_int32_t *, u_int32_t *, int *)); int (*get_create_dir) __P((DB_ENV *, const char **)); int (*get_data_dirs) __P((DB_ENV *, const char ***)); int (*get_data_len) __P((DB_ENV *, u_int32_t *)); int (*get_backup_callbacks) __P((DB_ENV *, int (**)(DB_ENV *, const char *, const char *, void **), int (**)(DB_ENV *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), int (**)(DB_ENV *, const char *, void *))); int (*get_backup_config) __P((DB_ENV *, DB_BACKUP_CONFIG, u_int32_t *)); int (*get_encrypt_flags) __P((DB_ENV *, u_int32_t *)); void (*get_errcall) __P((DB_ENV *, void (**)(const DB_ENV *, const char *, const char *))); void (*get_errfile) __P((DB_ENV *, FILE **)); void (*get_errpfx) __P((DB_ENV *, const char **)); int (*get_flags) __P((DB_ENV *, u_int32_t *)); int (*get_feedback) __P((DB_ENV *, void (**)(DB_ENV *, int, int))); int (*get_home) __P((DB_ENV *, const char **)); int (*get_intermediate_dir_mode) __P((DB_ENV *, const char **)); int (*get_isalive) __P((DB_ENV *, int (**)(DB_ENV *, pid_t, db_threadid_t, u_int32_t))); int (*get_lg_bsize) __P((DB_ENV *, u_int32_t *)); int (*get_lg_dir) __P((DB_ENV *, const char **)); int (*get_lg_filemode) __P((DB_ENV *, int *)); int (*get_lg_max) __P((DB_ENV *, u_int32_t *)); int (*get_lg_regionmax) __P((DB_ENV *, u_int32_t *)); int (*get_lk_conflicts) __P((DB_ENV *, const u_int8_t **, int *)); int (*get_lk_detect) __P((DB_ENV *, u_int32_t *)); int (*get_lk_max_lockers) __P((DB_ENV *, u_int32_t *)); int (*get_lk_max_locks) __P((DB_ENV *, u_int32_t *)); int (*get_lk_max_objects) __P((DB_ENV *, u_int32_t *)); int (*get_lk_partitions) __P((DB_ENV *, u_int32_t *)); int (*get_lk_priority) __P((DB_ENV *, u_int32_t, u_int32_t *)); int (*get_lk_tablesize) __P((DB_ENV *, u_int32_t *)); int (*get_memory_init) __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t *)); int (*get_memory_max) __P((DB_ENV *, u_int32_t *, u_int32_t *)); int (*get_metadata_dir) __P((DB_ENV *, const char **)); int (*get_mp_max_openfd) __P((DB_ENV *, int *)); int (*get_mp_max_write) __P((DB_ENV *, int *, db_timeout_t *)); int (*get_mp_mmapsize) __P((DB_ENV *, size_t *)); int (*get_mp_mtxcount) __P((DB_ENV *, u_int32_t *)); int (*get_mp_pagesize) __P((DB_ENV *, u_int32_t *)); int (*get_mp_tablesize) __P((DB_ENV *, u_int32_t *)); void (*get_msgcall) __P((DB_ENV *, void (**)(const DB_ENV *, const char *))); void (*get_msgfile) __P((DB_ENV *, FILE **)); int (*get_open_flags) __P((DB_ENV *, u_int32_t *)); int (*get_shm_key) __P((DB_ENV *, long *)); int (*get_thread_count) __P((DB_ENV *, u_int32_t *)); int (*get_thread_id_fn) __P((DB_ENV *, void (**)(DB_ENV *, pid_t *, db_threadid_t *))); int (*get_thread_id_string_fn) __P((DB_ENV *, char *(**)(DB_ENV *, pid_t, db_threadid_t, char *))); int (*get_timeout) __P((DB_ENV *, db_timeout_t *, u_int32_t)); int (*get_tmp_dir) __P((DB_ENV *, const char **)); int (*get_tx_max) __P((DB_ENV *, u_int32_t *)); int (*get_tx_timestamp) __P((DB_ENV *, time_t *)); int (*get_verbose) __P((DB_ENV *, u_int32_t, int *)); int (*is_bigendian) __P((void)); int (*lock_detect) __P((DB_ENV *, u_int32_t, u_int32_t, int *)); int (*lock_get) __P((DB_ENV *, u_int32_t, u_int32_t, DBT *, db_lockmode_t, DB_LOCK *)); int (*lock_id) __P((DB_ENV *, u_int32_t *)); int (*lock_id_free) __P((DB_ENV *, u_int32_t)); int (*lock_put) __P((DB_ENV *, DB_LOCK *)); int (*lock_stat) __P((DB_ENV *, DB_LOCK_STAT **, u_int32_t)); int (*lock_stat_print) __P((DB_ENV *, u_int32_t)); int (*lock_vec) __P((DB_ENV *, u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **)); int (*log_archive) __P((DB_ENV *, char **[], u_int32_t)); int (*log_cursor) __P((DB_ENV *, DB_LOGC **, u_int32_t)); int (*log_file) __P((DB_ENV *, const DB_LSN *, char *, size_t)); int (*log_flush) __P((DB_ENV *, const DB_LSN *)); int (*log_get_config) __P((DB_ENV *, u_int32_t, int *)); int (*log_printf) __P((DB_ENV *, DB_TXN *, const char *, ...)); int (*log_put) __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t)); int (*log_put_record) __P((DB_ENV *, DB *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, DB_LOG_RECSPEC *, ...)); int (*log_read_record) __P((DB_ENV *, DB **, void *, void *, DB_LOG_RECSPEC *, u_int32_t, void **)); int (*log_set_config) __P((DB_ENV *, u_int32_t, int)); int (*log_stat) __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); int (*log_stat_print) __P((DB_ENV *, u_int32_t)); int (*log_verify) __P((DB_ENV *, const DB_LOG_VERIFY_CONFIG *)); int (*lsn_reset) __P((DB_ENV *, const char *, u_int32_t)); int (*memp_fcreate) __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t)); int (*memp_register) __P((DB_ENV *, int, int (*)(DB_ENV *, db_pgno_t, void *, DBT *), int (*)(DB_ENV *, db_pgno_t, void *, DBT *))); int (*memp_stat) __P((DB_ENV *, DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t)); int (*memp_stat_print) __P((DB_ENV *, u_int32_t)); int (*memp_sync) __P((DB_ENV *, DB_LSN *)); int (*memp_trickle) __P((DB_ENV *, int, int *)); int (*mutex_alloc) __P((DB_ENV *, u_int32_t, db_mutex_t *)); int (*mutex_free) __P((DB_ENV *, db_mutex_t)); int (*mutex_get_align) __P((DB_ENV *, u_int32_t *)); int (*mutex_get_increment) __P((DB_ENV *, u_int32_t *)); int (*mutex_get_init) __P((DB_ENV *, u_int32_t *)); int (*mutex_get_max) __P((DB_ENV *, u_int32_t *)); int (*mutex_get_tas_spins) __P((DB_ENV *, u_int32_t *)); int (*mutex_lock) __P((DB_ENV *, db_mutex_t)); int (*mutex_set_align) __P((DB_ENV *, u_int32_t)); int (*mutex_set_increment) __P((DB_ENV *, u_int32_t)); int (*mutex_set_init) __P((DB_ENV *, u_int32_t)); int (*mutex_set_max) __P((DB_ENV *, u_int32_t)); int (*mutex_set_tas_spins) __P((DB_ENV *, u_int32_t)); int (*mutex_stat) __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t)); int (*mutex_stat_print) __P((DB_ENV *, u_int32_t)); int (*mutex_unlock) __P((DB_ENV *, db_mutex_t)); int (*open) __P((DB_ENV *, const char *, u_int32_t, int)); int (*remove) __P((DB_ENV *, const char *, u_int32_t)); int (*rep_elect) __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); int (*rep_flush) __P((DB_ENV *)); int (*rep_get_clockskew) __P((DB_ENV *, u_int32_t *, u_int32_t *)); int (*rep_get_config) __P((DB_ENV *, u_int32_t, int *)); int (*rep_get_limit) __P((DB_ENV *, u_int32_t *, u_int32_t *)); int (*rep_get_nsites) __P((DB_ENV *, u_int32_t *)); int (*rep_get_priority) __P((DB_ENV *, u_int32_t *)); int (*rep_get_request) __P((DB_ENV *, u_int32_t *, u_int32_t *)); int (*rep_get_timeout) __P((DB_ENV *, int, u_int32_t *)); int (*rep_process_message) __P((DB_ENV *, DBT *, DBT *, int, DB_LSN *)); int (*rep_set_clockskew) __P((DB_ENV *, u_int32_t, u_int32_t)); int (*rep_set_config) __P((DB_ENV *, u_int32_t, int)); int (*rep_set_limit) __P((DB_ENV *, u_int32_t, u_int32_t)); int (*rep_set_nsites) __P((DB_ENV *, u_int32_t)); int (*rep_set_priority) __P((DB_ENV *, u_int32_t)); int (*rep_set_request) __P((DB_ENV *, u_int32_t, u_int32_t)); int (*rep_set_timeout) __P((DB_ENV *, int, db_timeout_t)); int (*rep_set_transport) __P((DB_ENV *, int, int (*)(DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u_int32_t))); int (*rep_start) __P((DB_ENV *, DBT *, u_int32_t)); int (*rep_stat) __P((DB_ENV *, DB_REP_STAT **, u_int32_t)); int (*rep_stat_print) __P((DB_ENV *, u_int32_t)); int (*rep_sync) __P((DB_ENV *, u_int32_t)); int (*repmgr_channel) __P((DB_ENV *, int, DB_CHANNEL **, u_int32_t)); int (*repmgr_get_ack_policy) __P((DB_ENV *, int *)); int (*repmgr_local_site) __P((DB_ENV *, DB_SITE **)); int (*repmgr_msg_dispatch) __P((DB_ENV *, void (*)(DB_ENV *, DB_CHANNEL *, DBT *, u_int32_t, u_int32_t), u_int32_t)); int (*repmgr_set_ack_policy) __P((DB_ENV *, int)); int (*repmgr_site) __P((DB_ENV *, const char *, u_int, DB_SITE**, u_int32_t)); int (*repmgr_site_by_eid) __P((DB_ENV *, int, DB_SITE**)); int (*repmgr_site_list) __P((DB_ENV *, u_int *, DB_REPMGR_SITE **)); int (*repmgr_start) __P((DB_ENV *, int, u_int32_t)); int (*repmgr_stat) __P((DB_ENV *, DB_REPMGR_STAT **, u_int32_t)); int (*repmgr_stat_print) __P((DB_ENV *, u_int32_t)); int (*set_alloc) __P((DB_ENV *, void *(*)(size_t), void *(*)(void *, size_t), void (*)(void *))); int (*set_app_dispatch) __P((DB_ENV *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops))); int (*set_cache_max) __P((DB_ENV *, u_int32_t, u_int32_t)); int (*set_cachesize) __P((DB_ENV *, u_int32_t, u_int32_t, int)); int (*set_create_dir) __P((DB_ENV *, const char *)); int (*set_data_dir) __P((DB_ENV *, const char *)); int (*set_data_len) __P((DB_ENV *, u_int32_t)); int (*set_backup_callbacks) __P((DB_ENV *, int (*)(DB_ENV *, const char *, const char *, void **), int (*)(DB_ENV *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), int (*)(DB_ENV *, const char *, void *))); int (*set_backup_config) __P((DB_ENV *, DB_BACKUP_CONFIG, u_int32_t)); int (*set_encrypt) __P((DB_ENV *, const char *, u_int32_t)); void (*set_errcall) __P((DB_ENV *, void (*)(const DB_ENV *, const char *, const char *))); void (*set_errfile) __P((DB_ENV *, FILE *)); void (*set_errpfx) __P((DB_ENV *, const char *)); int (*set_event_notify) __P((DB_ENV *, void (*)(DB_ENV *, u_int32_t, void *))); int (*set_feedback) __P((DB_ENV *, void (*)(DB_ENV *, int, int))); int (*set_flags) __P((DB_ENV *, u_int32_t, int)); int (*set_intermediate_dir_mode) __P((DB_ENV *, const char *)); int (*set_isalive) __P((DB_ENV *, int (*)(DB_ENV *, pid_t, db_threadid_t, u_int32_t))); int (*set_lg_bsize) __P((DB_ENV *, u_int32_t)); int (*set_lg_dir) __P((DB_ENV *, const char *)); int (*set_lg_filemode) __P((DB_ENV *, int)); int (*set_lg_max) __P((DB_ENV *, u_int32_t)); int (*set_lg_regionmax) __P((DB_ENV *, u_int32_t)); int (*set_lk_conflicts) __P((DB_ENV *, u_int8_t *, int)); int (*set_lk_detect) __P((DB_ENV *, u_int32_t)); int (*set_lk_max_lockers) __P((DB_ENV *, u_int32_t)); int (*set_lk_max_locks) __P((DB_ENV *, u_int32_t)); int (*set_lk_max_objects) __P((DB_ENV *, u_int32_t)); int (*set_lk_partitions) __P((DB_ENV *, u_int32_t)); int (*set_lk_priority) __P((DB_ENV *, u_int32_t, u_int32_t)); int (*set_lk_tablesize) __P((DB_ENV *, u_int32_t)); int (*set_memory_init) __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t)); int (*set_memory_max) __P((DB_ENV *, u_int32_t, u_int32_t)); int (*set_metadata_dir) __P((DB_ENV *, const char *)); int (*set_mp_max_openfd) __P((DB_ENV *, int)); int (*set_mp_max_write) __P((DB_ENV *, int, db_timeout_t)); int (*set_mp_mmapsize) __P((DB_ENV *, size_t)); int (*set_mp_mtxcount) __P((DB_ENV *, u_int32_t)); int (*set_mp_pagesize) __P((DB_ENV *, u_int32_t)); int (*set_mp_tablesize) __P((DB_ENV *, u_int32_t)); void (*set_msgcall) __P((DB_ENV *, void (*)(const DB_ENV *, const char *))); void (*set_msgfile) __P((DB_ENV *, FILE *)); int (*set_paniccall) __P((DB_ENV *, void (*)(DB_ENV *, int))); int (*set_shm_key) __P((DB_ENV *, long)); int (*set_thread_count) __P((DB_ENV *, u_int32_t)); int (*set_thread_id) __P((DB_ENV *, void (*)(DB_ENV *, pid_t *, db_threadid_t *))); int (*set_thread_id_string) __P((DB_ENV *, char *(*)(DB_ENV *, pid_t, db_threadid_t, char *))); int (*set_timeout) __P((DB_ENV *, db_timeout_t, u_int32_t)); int (*set_tmp_dir) __P((DB_ENV *, const char *)); int (*set_tx_max) __P((DB_ENV *, u_int32_t)); int (*set_tx_timestamp) __P((DB_ENV *, time_t *)); int (*set_verbose) __P((DB_ENV *, u_int32_t, int)); int (*txn_applied) __P((DB_ENV *, DB_TXN_TOKEN *, db_timeout_t, u_int32_t)); int (*stat_print) __P((DB_ENV *, u_int32_t)); int (*txn_begin) __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t)); int (*txn_checkpoint) __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); int (*txn_recover) __P((DB_ENV *, DB_PREPLIST *, long, long *, u_int32_t)); int (*txn_stat) __P((DB_ENV *, DB_TXN_STAT **, u_int32_t)); int (*txn_stat_print) __P((DB_ENV *, u_int32_t)); /* DB_ENV PUBLIC HANDLE LIST END */ /* DB_ENV PRIVATE HANDLE LIST BEGIN */ int (*prdbt) __P((DBT *, int, const char *, void *, int (*)(void *, const void *), int, int)); /* DB_ENV PRIVATE HANDLE LIST END */ }; /* * Dispatch structure for recovery, log verification and print routines. Since * internal and external routines take different arguments (ENV versus DB_ENV), * we need something more elaborate than a single pointer and size. */ struct __db_distab { int (**int_dispatch) __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); size_t int_size; int (**ext_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); size_t ext_size; }; /* * Log verification configuration structure. */ struct __db_logvrfy_config { int continue_after_fail, verbose; u_int32_t cachesize; const char *temp_envhome; const char *dbfile, *dbname; DB_LSN start_lsn, end_lsn; time_t start_time, end_time; }; struct __db_channel { CHANNEL *channel; /* Pointer to internal state details. */ int eid; /* Env. ID passed in constructor. */ db_timeout_t timeout; /* DB_CHANNEL PUBLIC HANDLE LIST BEGIN */ int (*close) __P((DB_CHANNEL *, u_int32_t)); int (*send_msg) __P((DB_CHANNEL *, DBT *, u_int32_t, u_int32_t)); int (*send_request) __P((DB_CHANNEL *, DBT *, u_int32_t, DBT *, db_timeout_t, u_int32_t)); int (*set_timeout) __P((DB_CHANNEL *, db_timeout_t)); /* DB_CHANNEL PUBLIC HANDLE LIST END */ }; struct __db_site { ENV *env; int eid; const char *host; u_int port; u_int32_t flags; /* DB_SITE PUBLIC HANDLE LIST BEGIN */ int (*get_address) __P((DB_SITE *, const char **, u_int *)); int (*get_config) __P((DB_SITE *, u_int32_t, u_int32_t *)); int (*get_eid) __P((DB_SITE *, int *)); int (*set_config) __P((DB_SITE *, u_int32_t, u_int32_t)); int (*remove) __P((DB_SITE *)); int (*close) __P((DB_SITE *)); /* DB_SITE PUBLIC HANDLE LIST END */ }; #if DB_DBM_HSEARCH != 0 /******************************************************* * Dbm/Ndbm historic interfaces. *******************************************************/ typedef struct __db DBM; #define DBM_INSERT 0 /* Flags to dbm_store(). */ #define DBM_REPLACE 1 /* * The DB support for ndbm(3) always appends this suffix to the * file name to avoid overwriting the user's original database. */ #define DBM_SUFFIX ".db" #if defined(_XPG4_2) typedef struct { char *dptr; size_t dsize; } datum; #else typedef struct { char *dptr; int dsize; } datum; #endif /* * Translate NDBM calls into DB calls so that DB doesn't step on the * application's name space. */ #define dbm_clearerr(a) __db_ndbm_clearerr(a) #define dbm_close(a) __db_ndbm_close(a) #define dbm_delete(a, b) __db_ndbm_delete(a, b) #define dbm_dirfno(a) __db_ndbm_dirfno(a) #define dbm_error(a) __db_ndbm_error(a) #define dbm_fetch(a, b) __db_ndbm_fetch(a, b) #define dbm_firstkey(a) __db_ndbm_firstkey(a) #define dbm_nextkey(a) __db_ndbm_nextkey(a) #define dbm_open(a, b, c) __db_ndbm_open(a, b, c) #define dbm_pagfno(a) __db_ndbm_pagfno(a) #define dbm_rdonly(a) __db_ndbm_rdonly(a) #define dbm_store(a, b, c, d) \ __db_ndbm_store(a, b, c, d) /* * Translate DBM calls into DB calls so that DB doesn't step on the * application's name space. * * The global variables dbrdonly, dirf and pagf were not retained when 4BSD * replaced the dbm interface with ndbm, and are not supported here. */ #define dbminit(a) __db_dbm_init(a) #define dbmclose __db_dbm_close #if !defined(__cplusplus) #define delete(a) __db_dbm_delete(a) #endif #define fetch(a) __db_dbm_fetch(a) #define firstkey __db_dbm_firstkey #define nextkey(a) __db_dbm_nextkey(a) #define store(a, b) __db_dbm_store(a, b) /******************************************************* * Hsearch historic interface. *******************************************************/ typedef enum { FIND, ENTER } ACTION; typedef struct entry { char *key; char *data; } ENTRY; #define hcreate(a) __db_hcreate(a) #define hdestroy __db_hdestroy #define hsearch(a, b) __db_hsearch(a, b) #endif /* DB_DBM_HSEARCH */ #if defined(__cplusplus) } #endif #endif /* !_DB_H_ */ /* DO NOT EDIT: automatically built by dist/s_apiflags. */ #define DB_AGGRESSIVE 0x00000001 #define DB_ARCH_ABS 0x00000001 #define DB_ARCH_DATA 0x00000002 #define DB_ARCH_LOG 0x00000004 #define DB_ARCH_REMOVE 0x00000008 #define DB_AUTO_COMMIT 0x00000100 #define DB_BACKUP_CLEAN 0x00000002 #define DB_BACKUP_FILES 0x00000008 #define DB_BACKUP_NO_LOGS 0x00000010 #define DB_BACKUP_SINGLE_DIR 0x00000020 #define DB_BACKUP_UPDATE 0x00000040 #define DB_BOOTSTRAP_HELPER 0x00000001 #define DB_CDB_ALLDB 0x00000040 #define DB_CHKSUM 0x00000008 #define DB_CKP_INTERNAL 0x00000002 #define DB_CREATE 0x00000001 #define DB_CURSOR_BULK 0x00000001 #define DB_CURSOR_TRANSIENT 0x00000008 #define DB_CXX_NO_EXCEPTIONS 0x00000002 #define DB_DATABASE_LOCKING 0x00000080 #define DB_DIRECT 0x00000020 #define DB_DIRECT_DB 0x00000200 #define DB_DSYNC_DB 0x00000400 #define DB_DUP 0x00000010 #define DB_DUPSORT 0x00000002 #define DB_DURABLE_UNKNOWN 0x00000040 #define DB_ENCRYPT 0x00000001 #define DB_ENCRYPT_AES 0x00000001 #define DB_EXCL 0x00000004 #define DB_EXTENT 0x00000100 #define DB_FAILCHK 0x00000010 #define DB_FAILCHK_ISALIVE 0x00000040 #define DB_FAST_STAT 0x00000001 #define DB_FCNTL_LOCKING 0x00000800 #define DB_FLUSH 0x00000002 #define DB_FORCE 0x00000001 #define DB_FORCESYNC 0x00000001 #define DB_FOREIGN_ABORT 0x00000001 #define DB_FOREIGN_CASCADE 0x00000002 #define DB_FOREIGN_NULLIFY 0x00000004 #define DB_FREELIST_ONLY 0x00000001 #define DB_FREE_SPACE 0x00000002 #define DB_GROUP_CREATOR 0x00000002 #define DB_HOTBACKUP_IN_PROGRESS 0x00000800 #define DB_IGNORE_LEASE 0x00001000 #define DB_IMMUTABLE_KEY 0x00000002 #define DB_INIT_CDB 0x00000080 #define DB_INIT_LOCK 0x00000100 #define DB_INIT_LOG 0x00000200 #define DB_INIT_MPOOL 0x00000400 #define DB_INIT_MUTEX 0x00000800 #define DB_INIT_REP 0x00001000 #define DB_INIT_TXN 0x00002000 #define DB_INORDER 0x00000020 #define DB_INTERNAL_PERSISTENT_DB 0x00001000 #define DB_INTERNAL_TEMPORARY_DB 0x00002000 #define DB_JOIN_NOSORT 0x00000001 #define DB_LEGACY 0x00000004 #define DB_LOCAL_SITE 0x00000008 #define DB_LOCKDOWN 0x00004000 #define DB_LOCK_CHECK 0x00000001 #define DB_LOCK_IGNORE_REC 0x00000002 #define DB_LOCK_NOWAIT 0x00000004 #define DB_LOCK_RECORD 0x00000008 #define DB_LOCK_SET_TIMEOUT 0x00000010 #define DB_LOCK_SWITCH 0x00000020 #define DB_LOCK_UPGRADE 0x00000040 #define DB_LOG_AUTO_REMOVE 0x00000001 #define DB_LOG_CHKPNT 0x00000001 #define DB_LOG_COMMIT 0x00000004 #define DB_LOG_DIRECT 0x00000002 #define DB_LOG_DSYNC 0x00000004 #define DB_LOG_IN_MEMORY 0x00000008 #define DB_LOG_NOCOPY 0x00000008 #define DB_LOG_NOT_DURABLE 0x00000010 #define DB_LOG_NO_DATA 0x00000002 #define DB_LOG_VERIFY_CAF 0x00000001 #define DB_LOG_VERIFY_DBFILE 0x00000002 #define DB_LOG_VERIFY_ERR 0x00000004 #define DB_LOG_VERIFY_FORWARD 0x00000008 #define DB_LOG_VERIFY_INTERR 0x00000010 #define DB_LOG_VERIFY_PARTIAL 0x00000020 #define DB_LOG_VERIFY_VERBOSE 0x00000040 #define DB_LOG_VERIFY_WARNING 0x00000080 #define DB_LOG_WRNOSYNC 0x00000020 #define DB_LOG_ZERO 0x00000010 #define DB_MPOOL_CREATE 0x00000001 #define DB_MPOOL_DIRTY 0x00000002 #define DB_MPOOL_DISCARD 0x00000001 #define DB_MPOOL_EDIT 0x00000004 #define DB_MPOOL_FREE 0x00000008 #define DB_MPOOL_LAST 0x00000010 #define DB_MPOOL_NEW 0x00000020 #define DB_MPOOL_NOFILE 0x00000001 #define DB_MPOOL_NOLOCK 0x00000004 #define DB_MPOOL_TRY 0x00000040 #define DB_MPOOL_UNLINK 0x00000002 #define DB_MULTIPLE 0x00000800 #define DB_MULTIPLE_KEY 0x00004000 #define DB_MULTIVERSION 0x00000008 #define DB_MUTEX_ALLOCATED 0x00000001 #define DB_MUTEX_LOCKED 0x00000002 #define DB_MUTEX_LOGICAL_LOCK 0x00000004 #define DB_MUTEX_PROCESS_ONLY 0x00000008 #define DB_MUTEX_SELF_BLOCK 0x00000010 #define DB_MUTEX_SHARED 0x00000020 #define DB_NOERROR 0x00004000 #define DB_NOFLUSH 0x00001000 #define DB_NOLOCKING 0x00002000 #define DB_NOMMAP 0x00000010 #define DB_NOORDERCHK 0x00000002 #define DB_NOPANIC 0x00004000 #define DB_NOSYNC 0x00000001 #define DB_NO_AUTO_COMMIT 0x00008000 #define DB_NO_CHECKPOINT 0x00008000 #define DB_ODDFILESIZE 0x00000080 #define DB_ORDERCHKONLY 0x00000004 #define DB_OVERWRITE 0x00008000 #define DB_PANIC_ENVIRONMENT 0x00010000 #define DB_PRINTABLE 0x00000008 #define DB_PRIVATE 0x00010000 #define DB_PR_PAGE 0x00000010 #define DB_PR_RECOVERYTEST 0x00000020 #define DB_RDONLY 0x00000400 #define DB_RDWRMASTER 0x00010000 #define DB_READ_COMMITTED 0x00000400 #define DB_READ_UNCOMMITTED 0x00000200 #define DB_RECNUM 0x00000040 #define DB_RECOVER 0x00000002 #define DB_RECOVER_FATAL 0x00020000 #define DB_REGION_INIT 0x00020000 #define DB_REGISTER 0x00040000 #define DB_RENUMBER 0x00000080 #define DB_REPMGR_CONF_2SITE_STRICT 0x00000001 #define DB_REPMGR_CONF_ELECTIONS 0x00000002 #define DB_REPMGR_NEED_RESPONSE 0x00000001 #define DB_REPMGR_PEER 0x00000010 #define DB_REP_ANYWHERE 0x00000001 #define DB_REP_CLIENT 0x00000001 #define DB_REP_CONF_AUTOINIT 0x00000004 #define DB_REP_CONF_AUTOROLLBACK 0x00000008 #define DB_REP_CONF_BULK 0x00000010 #define DB_REP_CONF_DELAYCLIENT 0x00000020 #define DB_REP_CONF_INMEM 0x00000040 #define DB_REP_CONF_LEASE 0x00000080 #define DB_REP_CONF_NOWAIT 0x00000100 #define DB_REP_ELECTION 0x00000004 #define DB_REP_MASTER 0x00000002 #define DB_REP_NOBUFFER 0x00000002 #define DB_REP_PERMANENT 0x00000004 #define DB_REP_REREQUEST 0x00000008 #define DB_REVSPLITOFF 0x00000100 #define DB_RMW 0x00002000 #define DB_SALVAGE 0x00000040 #define DB_SA_SKIPFIRSTKEY 0x00000080 #define DB_SA_UNKNOWNKEY 0x00000100 #define DB_SEQ_DEC 0x00000001 #define DB_SEQ_INC 0x00000002 #define DB_SEQ_RANGE_SET 0x00000004 #define DB_SEQ_WRAP 0x00000008 #define DB_SEQ_WRAPPED 0x00000010 #define DB_SET_LOCK_TIMEOUT 0x00000001 #define DB_SET_REG_TIMEOUT 0x00000004 #define DB_SET_TXN_NOW 0x00000008 #define DB_SET_TXN_TIMEOUT 0x00000002 #define DB_SHALLOW_DUP 0x00000100 #define DB_SNAPSHOT 0x00000200 #define DB_STAT_ALL 0x00000004 #define DB_STAT_ALLOC 0x00000008 #define DB_STAT_CLEAR 0x00000001 #define DB_STAT_LOCK_CONF 0x00000010 #define DB_STAT_LOCK_LOCKERS 0x00000020 #define DB_STAT_LOCK_OBJECTS 0x00000040 #define DB_STAT_LOCK_PARAMS 0x00000080 #define DB_STAT_MEMP_HASH 0x00000010 #define DB_STAT_MEMP_NOERROR 0x00000020 #define DB_STAT_SUBSYSTEM 0x00000002 #define DB_STAT_SUMMARY 0x00000010 #define DB_ST_DUPOK 0x00000200 #define DB_ST_DUPSET 0x00000400 #define DB_ST_DUPSORT 0x00000800 #define DB_ST_IS_RECNO 0x00001000 #define DB_ST_OVFL_LEAF 0x00002000 #define DB_ST_RECNUM 0x00004000 #define DB_ST_RELEN 0x00008000 #define DB_ST_TOPLEVEL 0x00010000 #define DB_SYSTEM_MEM 0x00080000 #define DB_THREAD 0x00000020 #define DB_TIME_NOTGRANTED 0x00040000 #define DB_TRUNCATE 0x00020000 #define DB_TXN_BULK 0x00000010 #define DB_TXN_FAMILY 0x00000040 #define DB_TXN_NOSYNC 0x00000001 #define DB_TXN_NOT_DURABLE 0x00000004 #define DB_TXN_NOWAIT 0x00000002 #define DB_TXN_SNAPSHOT 0x00000004 #define DB_TXN_SYNC 0x00000008 #define DB_TXN_WAIT 0x00000080 #define DB_TXN_WRITE_NOSYNC 0x00000020 #define DB_UNREF 0x00020000 #define DB_UPGRADE 0x00000001 #define DB_USE_ENVIRON 0x00000004 #define DB_USE_ENVIRON_ROOT 0x00000008 #define DB_VERB_BACKUP 0x00000001 #define DB_VERB_DEADLOCK 0x00000002 #define DB_VERB_FILEOPS 0x00000004 #define DB_VERB_FILEOPS_ALL 0x00000008 #define DB_VERB_RECOVERY 0x00000010 #define DB_VERB_REGISTER 0x00000020 #define DB_VERB_REPLICATION 0x00000040 #define DB_VERB_REPMGR_CONNFAIL 0x00000080 #define DB_VERB_REPMGR_MISC 0x00000100 #define DB_VERB_REP_ELECT 0x00000200 #define DB_VERB_REP_LEASE 0x00000400 #define DB_VERB_REP_MISC 0x00000800 #define DB_VERB_REP_MSGS 0x00001000 #define DB_VERB_REP_SYNC 0x00002000 #define DB_VERB_REP_SYSTEM 0x00004000 #define DB_VERB_REP_TEST 0x00008000 #define DB_VERB_WAITSFOR 0x00010000 #define DB_VERIFY 0x00000002 #define DB_VERIFY_PARTITION 0x00040000 #define DB_WRITECURSOR 0x00000010 #define DB_WRITELOCK 0x00000020 #define DB_WRITEOPEN 0x00040000 #define DB_XA_CREATE 0x00000001 #define DB_YIELDCPU 0x00080000 /* DO NOT EDIT: automatically built by dist/s_include. */ #ifndef _DB_EXT_PROT_IN_ #define _DB_EXT_PROT_IN_ #if defined(__cplusplus) extern "C" { #endif int db_copy __P((DB_ENV *, const char *, const char *, const char *)); int db_create __P((DB **, DB_ENV *, u_int32_t)); char *db_strerror __P((int)); int db_env_set_func_assert __P((void (*)(const char *, const char *, int))); int db_env_set_func_close __P((int (*)(int))); int db_env_set_func_dirfree __P((void (*)(char **, int))); int db_env_set_func_dirlist __P((int (*)(const char *, char ***, int *))); int db_env_set_func_exists __P((int (*)(const char *, int *))); int db_env_set_func_free __P((void (*)(void *))); int db_env_set_func_fsync __P((int (*)(int))); int db_env_set_func_ftruncate __P((int (*)(int, off_t))); int db_env_set_func_ioinfo __P((int (*)(const char *, int, u_int32_t *, u_int32_t *, u_int32_t *))); int db_env_set_func_malloc __P((void *(*)(size_t))); int db_env_set_func_file_map __P((int (*)(DB_ENV *, char *, size_t, int, void **), int (*)(DB_ENV *, void *))); int db_env_set_func_region_map __P((int (*)(DB_ENV *, char *, size_t, int *, void **), int (*)(DB_ENV *, void *))); int db_env_set_func_pread __P((ssize_t (*)(int, void *, size_t, off_t))); int db_env_set_func_pwrite __P((ssize_t (*)(int, const void *, size_t, off_t))); int db_env_set_func_open __P((int (*)(const char *, int, ...))); int db_env_set_func_read __P((ssize_t (*)(int, void *, size_t))); int db_env_set_func_realloc __P((void *(*)(void *, size_t))); int db_env_set_func_rename __P((int (*)(const char *, const char *))); int db_env_set_func_seek __P((int (*)(int, off_t, int))); int db_env_set_func_unlink __P((int (*)(const char *))); int db_env_set_func_write __P((ssize_t (*)(int, const void *, size_t))); int db_env_set_func_yield __P((int (*)(u_long, u_long))); int db_env_create __P((DB_ENV **, u_int32_t)); char *db_version __P((int *, int *, int *)); char *db_full_version __P((int *, int *, int *, int *, int *)); int log_compare __P((const DB_LSN *, const DB_LSN *)); #if defined(DB_WIN32) && !defined(DB_WINCE) int db_env_set_win_security __P((SECURITY_ATTRIBUTES *sa)); #endif int db_sequence_create __P((DB_SEQUENCE **, DB *, u_int32_t)); #if DB_DBM_HSEARCH != 0 int __db_ndbm_clearerr __P((DBM *)); void __db_ndbm_close __P((DBM *)); int __db_ndbm_delete __P((DBM *, datum)); int __db_ndbm_dirfno __P((DBM *)); int __db_ndbm_error __P((DBM *)); datum __db_ndbm_fetch __P((DBM *, datum)); datum __db_ndbm_firstkey __P((DBM *)); datum __db_ndbm_nextkey __P((DBM *)); DBM *__db_ndbm_open __P((const char *, int, int)); int __db_ndbm_pagfno __P((DBM *)); int __db_ndbm_rdonly __P((DBM *)); int __db_ndbm_store __P((DBM *, datum, datum, int)); int __db_dbm_close __P((void)); int __db_dbm_delete __P((datum)); datum __db_dbm_fetch __P((datum)); datum __db_dbm_firstkey __P((void)); int __db_dbm_init __P((char *)); datum __db_dbm_nextkey __P((datum)); int __db_dbm_store __P((datum, datum)); #endif #if DB_DBM_HSEARCH != 0 int __db_hcreate __P((size_t)); ENTRY *__db_hsearch __P((ENTRY, ACTION)); void __db_hdestroy __P((void)); #endif #if defined(__cplusplus) } #endif #endif /* !_DB_EXT_PROT_IN_ */ tic.h 0000644 00000032506 15146341150 0005502 0 ustar 00 /**************************************************************************** * Copyright (c) 1998-2012,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, distribute with modifications, sublicense, and/or sell * * copies of the Software, and to permit persons to whom the Software is * * furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included * * in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * * * Except as contained in this notice, the name(s) of the above copyright * * holders shall not be used in advertising or otherwise to promote the * * sale, use or other dealings in this Software without prior written * * authorization. * ****************************************************************************/ /**************************************************************************** * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * * and: Eric S. Raymond <esr@snark.thyrsus.com> * * and: Thomas E. Dickey 1996 on * ****************************************************************************/ /* * $Id: tic.h,v 1.75 2017/07/29 23:21:06 tom Exp $ * tic.h - Global variables and structures for the terminfo compiler. */ #ifndef __TIC_H #define __TIC_H /* *INDENT-OFF* */ #ifdef __cplusplus extern "C" { #endif #include <ncurses_cfg.h> #include <curses.h> /* for the _tracef() prototype, ERR/OK, bool defs */ /* ** The format of SVr2 compiled terminfo files is as follows: ** ** Header (12 bytes), containing information given below ** Names Section, containing the names of the terminal ** Boolean Section, containing the values of all of the ** boolean capabilities ** A null byte may be inserted here to make ** sure that the Number Section begins on an ** even word boundary. ** Number Section, containing the values of all of the numeric ** capabilities, each as a short integer ** String Section, containing short integer offsets into the ** String Table, one per string capability ** String Table, containing the actual characters of the string ** capabilities. ** ** In the SVr2 format, "short" means signed 16-bit numbers, which is sometimes ** inconvenient. The numbers are signed, to provide for absent and canceled ** values. ncurses6.1 introduced an extension to this compiled format, by ** making the Number Section a list of signed 32-bit integers. ** ** NOTE that all short integers in the file are stored using VAX/PDP-style ** byte-order, i.e., least-significant byte first. ** ** There is no structure definition here because it would only confuse ** matters. Terminfo format is a raw byte layout, not a structure ** dump. If you happen to be on a little-endian machine with 16-bit ** shorts that requires no padding between short members in a struct, ** then there is a natural C structure that captures the header, but ** not very helpfully. */ #define MAGIC 0432 /* first two bytes of a compiled entry */ #define MAGIC2 01036 /* first two bytes of a compiled 32-bit entry */ #undef BYTE #define BYTE(p,n) (unsigned char)((p)[n]) #define IS_NEG1(p) ((BYTE(p,0) == 0377) && (BYTE(p,1) == 0377)) #define IS_NEG2(p) ((BYTE(p,0) == 0376) && (BYTE(p,1) == 0377)) #define LOW_MSB(p) (BYTE(p,0) + 256*BYTE(p,1)) #define IS_TIC_MAGIC(p) (LOW_MSB(p) == MAGIC || LOW_MSB(p) == MAGIC2) #define quick_prefix(s) (!strncmp((s), "b64:", 4) || !strncmp((s), "hex:", 4)) /* * The "maximum" here is misleading; XSI guarantees minimum values, which a * given implementation may exceed. */ #define MAX_NAME_SIZE 512 /* maximum legal name field size (XSI:127) */ #define MAX_ENTRY_SIZE1 4096 /* maximum legal entry size (SVr2) */ #define MAX_ENTRY_SIZE2 32768 /* maximum legal entry size (ncurses6.1) */ #if NCURSES_EXT_COLORS && HAVE_INIT_EXTENDED_COLOR #define MAX_ENTRY_SIZE MAX_ENTRY_SIZE2 #else #define MAX_ENTRY_SIZE MAX_ENTRY_SIZE1 #endif /* * The maximum size of individual name or alias is guaranteed in XSI to be at * least 14, since that corresponds to the older filename lengths. Newer * systems allow longer aliases, though not many terminal descriptions are * written to use them. The MAX_ALIAS symbol is used for warnings. */ #if HAVE_LONG_FILE_NAMES #define MAX_ALIAS 32 /* smaller than POSIX minimum for PATH_MAX */ #else #define MAX_ALIAS 14 /* SVr3 filename length */ #endif /* location of user's personal info directory */ #define PRIVATE_INFO "%s/.terminfo" /* plug getenv("HOME") into %s */ /* * Some traces are designed to be used via tic's verbose option (and similar in * infocmp and toe) rather than the 'trace()' function. So we use the bits * above the normal trace() parameter as a debug-level. */ #define MAX_DEBUG_LEVEL 15 #define DEBUG_LEVEL(n) ((n) << TRACE_SHIFT) #define set_trace_level(n) \ _nc_tracing &= DEBUG_LEVEL(MAX_DEBUG_LEVEL) \ + DEBUG_LEVEL(MAX_DEBUG_LEVEL) - 1, \ _nc_tracing |= DEBUG_LEVEL(n) #ifdef TRACE #define DEBUG(n, a) if (_nc_tracing >= DEBUG_LEVEL(n)) _tracef a #else #define DEBUG(n, a) /*nothing*/ #endif /* * These are the types of tokens returned by the scanner. The first * three are also used in the hash table of capability names. The scanner * returns one of these values after loading the specifics into the global * structure curr_token. */ #define BOOLEAN 0 /* Boolean capability */ #define NUMBER 1 /* Numeric capability */ #define STRING 2 /* String-valued capability */ #define CANCEL 3 /* Capability to be cancelled in following tc's */ #define NAMES 4 /* The names for a terminal type */ #define UNDEF 5 /* Undefined */ #define NO_PUSHBACK -1 /* used in pushtype to indicate no pushback */ /* * The global structure in which the specific parts of a * scanned token are returned. */ struct token { char *tk_name; /* name of capability */ int tk_valnumber; /* value of capability (if a number) */ char *tk_valstring; /* value of capability (if a string) */ }; /* * Offsets to string capabilities, with the corresponding functionkey codes. */ struct tinfo_fkeys { unsigned offset; chtype code; }; typedef short HashValue; /* * The file comp_captab.c contains an array of these structures, one per * possible capability. These are indexed by a hash table array of pointers to * the same structures for use by the parser. */ struct name_table_entry { const char *nte_name; /* name to hash on */ int nte_type; /* BOOLEAN, NUMBER or STRING */ HashValue nte_index; /* index of associated variable in its array */ HashValue nte_link; /* index in table of next hash, or -1 */ }; /* * Use this structure to hide differences between terminfo and termcap tables. */ typedef struct { unsigned table_size; const HashValue *table_data; HashValue (*hash_of)(const char *); int (*compare_names)(const char *, const char *); } HashData; struct alias { const char *from; const char *to; const char *source; }; #define NOTFOUND ((struct name_table_entry *) 0) /* * The casts are required for correct sign-propagation with systems such as * AIX, IRIX64, Solaris which default to unsigned characters. The C standard * leaves this detail unspecified. */ /* out-of-band values for representing absent capabilities */ #define ABSENT_BOOLEAN ((signed char)-1) /* 255 */ #define ABSENT_NUMERIC (-1) #define ABSENT_STRING (char *)0 /* out-of-band values for representing cancels */ #define CANCELLED_BOOLEAN ((signed char)-2) /* 254 */ #define CANCELLED_NUMERIC (-2) #define CANCELLED_STRING (char *)(-1) #define VALID_BOOLEAN(s) ((unsigned char)(s) <= 1) /* reject "-1" */ #define VALID_NUMERIC(s) ((s) >= 0) #define VALID_STRING(s) ((s) != CANCELLED_STRING && (s) != ABSENT_STRING) /* termcap entries longer than this may break old binaries */ #define MAX_TERMCAP_LENGTH 1023 /* this is a documented limitation of terminfo */ #define MAX_TERMINFO_LENGTH 4096 #ifndef TERMINFO #define TERMINFO "/usr/share/terminfo" #endif #ifdef NCURSES_TERM_ENTRY_H_incl /* * These entrypoints are used only by the ncurses utilities such as tic. */ #ifdef NCURSES_INTERNALS /* access.c */ extern NCURSES_EXPORT(unsigned) _nc_pathlast (const char *); extern NCURSES_EXPORT(bool) _nc_is_abs_path (const char *); extern NCURSES_EXPORT(bool) _nc_is_dir_path (const char *); extern NCURSES_EXPORT(bool) _nc_is_file_path (const char *); extern NCURSES_EXPORT(char *) _nc_basename (char *); extern NCURSES_EXPORT(char *) _nc_rootname (char *); /* comp_captab.c */ extern NCURSES_EXPORT(const struct name_table_entry *) _nc_get_table (bool); extern NCURSES_EXPORT(const HashData *) _nc_get_hash_info (bool); extern NCURSES_EXPORT(const struct alias *) _nc_get_alias_table (bool); /* comp_hash.c: name lookup */ extern NCURSES_EXPORT(struct name_table_entry const *) _nc_find_type_entry (const char *, int, bool); /* comp_scan.c: lexical analysis */ extern NCURSES_EXPORT(int) _nc_get_token (bool); extern NCURSES_EXPORT(void) _nc_panic_mode (char); extern NCURSES_EXPORT(void) _nc_push_token (int); extern NCURSES_EXPORT_VAR(int) _nc_curr_col; extern NCURSES_EXPORT_VAR(int) _nc_curr_line; extern NCURSES_EXPORT_VAR(int) _nc_syntax; extern NCURSES_EXPORT_VAR(int) _nc_strict_bsd; extern NCURSES_EXPORT_VAR(long) _nc_comment_end; extern NCURSES_EXPORT_VAR(long) _nc_comment_start; extern NCURSES_EXPORT_VAR(long) _nc_curr_file_pos; extern NCURSES_EXPORT_VAR(long) _nc_start_line; #define SYN_TERMINFO 0 #define SYN_TERMCAP 1 /* comp_error.c: warning & abort messages */ extern NCURSES_EXPORT(const char *) _nc_get_source (void); extern NCURSES_EXPORT(void) _nc_err_abort (const char *const,...) GCC_PRINTFLIKE(1,2) GCC_NORETURN; extern NCURSES_EXPORT(void) _nc_get_type (char *name); extern NCURSES_EXPORT(void) _nc_set_source (const char *const); extern NCURSES_EXPORT(void) _nc_set_type (const char *const); extern NCURSES_EXPORT(void) _nc_syserr_abort (const char *const,...) GCC_PRINTFLIKE(1,2) GCC_NORETURN; extern NCURSES_EXPORT(void) _nc_warning (const char *const,...) GCC_PRINTFLIKE(1,2); extern NCURSES_EXPORT_VAR(bool) _nc_suppress_warnings; /* comp_scan.c */ extern NCURSES_EXPORT_VAR(struct token) _nc_curr_token; /* captoinfo.c: capability conversion */ extern NCURSES_EXPORT(char *) _nc_captoinfo (const char *, const char *, int const); extern NCURSES_EXPORT(char *) _nc_infotocap (const char *, const char *, int const); /* home_terminfo.c */ extern NCURSES_EXPORT(char *) _nc_home_terminfo (void); /* init_keytry.c */ #if BROKEN_LINKER #define _nc_tinfo_fkeys _nc_tinfo_fkeysf() extern NCURSES_EXPORT(const struct tinfo_fkeys *) _nc_tinfo_fkeysf (void); #else extern NCURSES_EXPORT_VAR(const struct tinfo_fkeys) _nc_tinfo_fkeys[]; #endif /* lib_tparm.c */ #define NUM_PARM 9 extern NCURSES_EXPORT_VAR(int) _nc_tparm_err; extern NCURSES_EXPORT(int) _nc_tparm_analyze(const char *, char **, int *); /* lib_trace.c */ extern NCURSES_EXPORT_VAR(unsigned) _nc_tracing; extern NCURSES_EXPORT(const char *) _nc_visbuf (const char *); extern NCURSES_EXPORT(const char *) _nc_visbuf2 (int, const char *); /* lib_tputs.c */ extern NCURSES_EXPORT_VAR(int) _nc_nulls_sent; /* Add one for every null sent */ /* comp_main.c: compiler main */ extern const char * _nc_progname; /* db_iterator.c */ extern NCURSES_EXPORT(const char *) _nc_next_db(DBDIRS *, int *); extern NCURSES_EXPORT(const char *) _nc_tic_dir (const char *); extern NCURSES_EXPORT(void) _nc_first_db(DBDIRS *, int *); extern NCURSES_EXPORT(void) _nc_last_db(void); /* write_entry.c */ extern NCURSES_EXPORT(int) _nc_tic_written (void); #endif /* NCURSES_INTERNALS */ /* * These entrypoints are used by tack. */ /* comp_hash.c: name lookup */ extern NCURSES_EXPORT(struct name_table_entry const *) _nc_find_entry (const char *, const HashValue *); extern NCURSES_EXPORT(const HashValue *) _nc_get_hash_table (bool); /* comp_scan.c: lexical analysis */ extern NCURSES_EXPORT(void) _nc_reset_input (FILE *, char *); /* comp_expand.c: expand string into readable form */ extern NCURSES_EXPORT(char *) _nc_tic_expand (const char *, bool, int); /* comp_scan.c: decode string from readable form */ extern NCURSES_EXPORT(int) _nc_trans_string (char *, char *); #endif /* NCURSES_TERM_ENTRY_H_incl */ #ifdef __cplusplus } #endif /* *INDENT-ON* */ #endif /* __TIC_H */ ctype.h 0000644 00000025323 15146341150 0006046 0 ustar 00 /* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* * ISO C99 Standard 7.4: Character handling <ctype.h> */ #ifndef _CTYPE_H #define _CTYPE_H 1 #include <features.h> #include <bits/types.h> __BEGIN_DECLS #ifndef _ISbit /* These are all the characteristics of characters. If there get to be more than 16 distinct characteristics, many things must be changed that use `unsigned short int's. The characteristics are stored always in network byte order (big endian). We define the bit value interpretations here dependent on the machine's byte order. */ # include <endian.h> # if __BYTE_ORDER == __BIG_ENDIAN # define _ISbit(bit) (1 << (bit)) # else /* __BYTE_ORDER == __LITTLE_ENDIAN */ # define _ISbit(bit) ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8)) # endif enum { _ISupper = _ISbit (0), /* UPPERCASE. */ _ISlower = _ISbit (1), /* lowercase. */ _ISalpha = _ISbit (2), /* Alphabetic. */ _ISdigit = _ISbit (3), /* Numeric. */ _ISxdigit = _ISbit (4), /* Hexadecimal numeric. */ _ISspace = _ISbit (5), /* Whitespace. */ _ISprint = _ISbit (6), /* Printing. */ _ISgraph = _ISbit (7), /* Graphical. */ _ISblank = _ISbit (8), /* Blank (usually SPC and TAB). */ _IScntrl = _ISbit (9), /* Control character. */ _ISpunct = _ISbit (10), /* Punctuation. */ _ISalnum = _ISbit (11) /* Alphanumeric. */ }; #endif /* ! _ISbit */ /* These are defined in ctype-info.c. The declarations here must match those in localeinfo.h. In the thread-specific locale model (see `uselocale' in <locale.h>) we cannot use global variables for these as was done in the past. Instead, the following accessor functions return the address of each variable, which is local to the current thread if multithreaded. These point into arrays of 384, so they can be indexed by any `unsigned char' value [0,255]; by EOF (-1); or by any `signed char' value [-128,-1). ISO C requires that the ctype functions work for `unsigned char' values and for EOF; we also support negative `signed char' values for broken old programs. The case conversion arrays are of `int's rather than `unsigned char's because tolower (EOF) must be EOF, which doesn't fit into an `unsigned char'. But today more important is that the arrays are also used for multi-byte character sets. */ extern const unsigned short int **__ctype_b_loc (void) __THROW __attribute__ ((__const__)); extern const __int32_t **__ctype_tolower_loc (void) __THROW __attribute__ ((__const__)); extern const __int32_t **__ctype_toupper_loc (void) __THROW __attribute__ ((__const__)); #ifndef __cplusplus # define __isctype(c, type) \ ((*__ctype_b_loc ())[(int) (c)] & (unsigned short int) type) #elif defined __USE_EXTERN_INLINES # define __isctype_f(type) \ __extern_inline int \ is##type (int __c) __THROW \ { \ return (*__ctype_b_loc ())[(int) (__c)] & (unsigned short int) _IS##type; \ } #endif #define __isascii(c) (((c) & ~0x7f) == 0) /* If C is a 7 bit value. */ #define __toascii(c) ((c) & 0x7f) /* Mask off high bits. */ #define __exctype(name) extern int name (int) __THROW /* The following names are all functions: int isCHARACTERISTIC(int c); which return nonzero iff C has CHARACTERISTIC. For the meaning of the characteristic names, see the `enum' above. */ __exctype (isalnum); __exctype (isalpha); __exctype (iscntrl); __exctype (isdigit); __exctype (islower); __exctype (isgraph); __exctype (isprint); __exctype (ispunct); __exctype (isspace); __exctype (isupper); __exctype (isxdigit); /* Return the lowercase version of C. */ extern int tolower (int __c) __THROW; /* Return the uppercase version of C. */ extern int toupper (int __c) __THROW; /* ISO C99 introduced one new function. */ #ifdef __USE_ISOC99 __exctype (isblank); #endif #ifdef __USE_GNU /* Test C for a set of character classes according to MASK. */ extern int isctype (int __c, int __mask) __THROW; #endif #if defined __USE_MISC || defined __USE_XOPEN /* Return nonzero iff C is in the ASCII set (i.e., is no more than 7 bits wide). */ extern int isascii (int __c) __THROW; /* Return the part of C that is in the ASCII set (i.e., the low-order 7 bits of C). */ extern int toascii (int __c) __THROW; /* These are the same as `toupper' and `tolower' except that they do not check the argument for being in the range of a `char'. */ __exctype (_toupper); __exctype (_tolower); #endif /* Use X/Open or use misc. */ /* This code is needed for the optimized mapping functions. */ #define __tobody(c, f, a, args) \ (__extension__ \ ({ int __res; \ if (sizeof (c) > 1) \ { \ if (__builtin_constant_p (c)) \ { \ int __c = (c); \ __res = __c < -128 || __c > 255 ? __c : (a)[__c]; \ } \ else \ __res = f args; \ } \ else \ __res = (a)[(int) (c)]; \ __res; })) #if !defined __NO_CTYPE # ifdef __isctype_f __isctype_f (alnum) __isctype_f (alpha) __isctype_f (cntrl) __isctype_f (digit) __isctype_f (lower) __isctype_f (graph) __isctype_f (print) __isctype_f (punct) __isctype_f (space) __isctype_f (upper) __isctype_f (xdigit) # ifdef __USE_ISOC99 __isctype_f (blank) # endif # elif defined __isctype # define isalnum(c) __isctype((c), _ISalnum) # define isalpha(c) __isctype((c), _ISalpha) # define iscntrl(c) __isctype((c), _IScntrl) # define isdigit(c) __isctype((c), _ISdigit) # define islower(c) __isctype((c), _ISlower) # define isgraph(c) __isctype((c), _ISgraph) # define isprint(c) __isctype((c), _ISprint) # define ispunct(c) __isctype((c), _ISpunct) # define isspace(c) __isctype((c), _ISspace) # define isupper(c) __isctype((c), _ISupper) # define isxdigit(c) __isctype((c), _ISxdigit) # ifdef __USE_ISOC99 # define isblank(c) __isctype((c), _ISblank) # endif # endif # ifdef __USE_EXTERN_INLINES __extern_inline int __NTH (tolower (int __c)) { return __c >= -128 && __c < 256 ? (*__ctype_tolower_loc ())[__c] : __c; } __extern_inline int __NTH (toupper (int __c)) { return __c >= -128 && __c < 256 ? (*__ctype_toupper_loc ())[__c] : __c; } # endif # if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus # define tolower(c) __tobody (c, tolower, *__ctype_tolower_loc (), (c)) # define toupper(c) __tobody (c, toupper, *__ctype_toupper_loc (), (c)) # endif /* Optimizing gcc */ # if defined __USE_MISC || defined __USE_XOPEN # define isascii(c) __isascii (c) # define toascii(c) __toascii (c) # define _tolower(c) ((int) (*__ctype_tolower_loc ())[(int) (c)]) # define _toupper(c) ((int) (*__ctype_toupper_loc ())[(int) (c)]) # endif #endif /* Not __NO_CTYPE. */ #ifdef __USE_XOPEN2K8 /* POSIX.1-2008 extended locale interface (see locale.h). */ # include <bits/types/locale_t.h> /* These definitions are similar to the ones above but all functions take as an argument a handle for the locale which shall be used. */ # define __isctype_l(c, type, locale) \ ((locale)->__ctype_b[(int) (c)] & (unsigned short int) type) # define __exctype_l(name) \ extern int name (int, locale_t) __THROW /* The following names are all functions: int isCHARACTERISTIC(int c, locale_t *locale); which return nonzero iff C has CHARACTERISTIC. For the meaning of the characteristic names, see the `enum' above. */ __exctype_l (isalnum_l); __exctype_l (isalpha_l); __exctype_l (iscntrl_l); __exctype_l (isdigit_l); __exctype_l (islower_l); __exctype_l (isgraph_l); __exctype_l (isprint_l); __exctype_l (ispunct_l); __exctype_l (isspace_l); __exctype_l (isupper_l); __exctype_l (isxdigit_l); __exctype_l (isblank_l); /* Return the lowercase version of C in locale L. */ extern int __tolower_l (int __c, locale_t __l) __THROW; extern int tolower_l (int __c, locale_t __l) __THROW; /* Return the uppercase version of C. */ extern int __toupper_l (int __c, locale_t __l) __THROW; extern int toupper_l (int __c, locale_t __l) __THROW; # if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus # define __tolower_l(c, locale) \ __tobody (c, __tolower_l, (locale)->__ctype_tolower, (c, locale)) # define __toupper_l(c, locale) \ __tobody (c, __toupper_l, (locale)->__ctype_toupper, (c, locale)) # define tolower_l(c, locale) __tolower_l ((c), (locale)) # define toupper_l(c, locale) __toupper_l ((c), (locale)) # endif /* Optimizing gcc */ # ifndef __NO_CTYPE # define __isalnum_l(c,l) __isctype_l((c), _ISalnum, (l)) # define __isalpha_l(c,l) __isctype_l((c), _ISalpha, (l)) # define __iscntrl_l(c,l) __isctype_l((c), _IScntrl, (l)) # define __isdigit_l(c,l) __isctype_l((c), _ISdigit, (l)) # define __islower_l(c,l) __isctype_l((c), _ISlower, (l)) # define __isgraph_l(c,l) __isctype_l((c), _ISgraph, (l)) # define __isprint_l(c,l) __isctype_l((c), _ISprint, (l)) # define __ispunct_l(c,l) __isctype_l((c), _ISpunct, (l)) # define __isspace_l(c,l) __isctype_l((c), _ISspace, (l)) # define __isupper_l(c,l) __isctype_l((c), _ISupper, (l)) # define __isxdigit_l(c,l) __isctype_l((c), _ISxdigit, (l)) # define __isblank_l(c,l) __isctype_l((c), _ISblank, (l)) # ifdef __USE_MISC # define __isascii_l(c,l) ((l), __isascii (c)) # define __toascii_l(c,l) ((l), __toascii (c)) # endif # define isalnum_l(c,l) __isalnum_l ((c), (l)) # define isalpha_l(c,l) __isalpha_l ((c), (l)) # define iscntrl_l(c,l) __iscntrl_l ((c), (l)) # define isdigit_l(c,l) __isdigit_l ((c), (l)) # define islower_l(c,l) __islower_l ((c), (l)) # define isgraph_l(c,l) __isgraph_l ((c), (l)) # define isprint_l(c,l) __isprint_l ((c), (l)) # define ispunct_l(c,l) __ispunct_l ((c), (l)) # define isspace_l(c,l) __isspace_l ((c), (l)) # define isupper_l(c,l) __isupper_l ((c), (l)) # define isxdigit_l(c,l) __isxdigit_l ((c), (l)) # define isblank_l(c,l) __isblank_l ((c), (l)) # ifdef __USE_MISC # define isascii_l(c,l) __isascii_l ((c), (l)) # define toascii_l(c,l) __toascii_l ((c), (l)) # endif # endif /* Not __NO_CTYPE. */ #endif /* Use POSIX 2008. */ __END_DECLS #endif /* ctype.h */ ulimit.h 0000644 00000003057 15146341150 0006225 0 ustar 00 /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _ULIMIT_H #define _ULIMIT_H 1 #include <features.h> /* Constants used as the first parameter for `ulimit'. They denote limits which can be set or retrieved using this function. */ enum { UL_GETFSIZE = 1, /* Return limit on the size of a file, in units of 512 bytes. */ #define UL_GETFSIZE UL_GETFSIZE UL_SETFSIZE, /* Set limit on the size of a file to second argument. */ #define UL_SETFSIZE UL_SETFSIZE __UL_GETMAXBRK, /* Return the maximum possible address of the data segment. */ __UL_GETOPENMAX /* Return the maximum number of files that the calling process can open.*/ }; __BEGIN_DECLS /* Control process limits according to CMD. */ extern long int ulimit (int __cmd, ...) __THROW; __END_DECLS #endif /* ulimit.h */ sgtty.h 0000644 00000002477 15146341150 0006101 0 ustar 00 /* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _SGTTY_H #define _SGTTY_H 1 #include <features.h> #include <sys/ioctl.h> /* On some systems this type is not defined by <bits/ioctl-types.h>; in that case, the functions are just stubs that return ENOSYS. */ struct sgttyb; __BEGIN_DECLS /* Fill in *PARAMS with terminal parameters associated with FD. */ extern int gtty (int __fd, struct sgttyb *__params) __THROW; /* Set the terminal parameters associated with FD to *PARAMS. */ extern int stty (int __fd, const struct sgttyb *__params) __THROW; __END_DECLS #endif /* sgtty.h */ ndbm.h 0000644 00000004626 15146341150 0005645 0 ustar 00 /* ndbm.h - The include file for ndbm users. */ /* This file is part of GDBM, the GNU data base manager, by Philip A. Nelson. Copyright (C) 1990-2011, 2017-2018 Free Software Foundation, Inc. GDBM 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 2, or (at your option) any later version. GDBM 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. You should have received a copy of the GNU General Public License along with GDBM. If not, see <http://www.gnu.org/licenses/>. You may contact the author by: e-mail: phil@cs.wwu.edu us-mail: Philip A. Nelson Computer Science Department Western Washington University Bellingham, WA 98226 *************************************************************************/ #include <gdbm.h> /* Parameters to dbm_store for simple insertion or replacement. */ #define DBM_INSERT GDBM_INSERT #define DBM_REPLACE GDBM_REPLACE /* The file information header. */ typedef struct { GDBM_FILE file; /* Actual gdbm file (held in the .pag file */ int dirfd; /* Descriptor of the .dir file */ datum _dbm_memory; /* Keeps the last returned key */ char *_dbm_fetch_val; /* Keeps the dptr of the last fetched datum */ gdbm_error _dbm_errno; /* Error code from the last failed call */ } DBM; /* Used internally by the library */ #define __gdbm_error_to_ndbm(dbm) \ do \ { \ if (gdbm_errno && gdbm_errno != GDBM_ITEM_NOT_FOUND) \ (dbm)->_dbm_errno = gdbm_errno; \ } \ while (0) /* These are the routines */ extern DBM *dbm_open (char *file, int flags, int mode); extern void dbm_close (DBM *dbf); extern datum dbm_fetch (DBM *dbf, datum key); extern int dbm_store (DBM *dbf, datum key, datum content, int flags); extern int dbm_delete (DBM *dbf, datum key); extern datum dbm_firstkey (DBM *dbf); extern datum dbm_nextkey (DBM *dbf); extern int dbm_error (DBM *dbf); extern void dbm_clearerr (DBM *dbf); extern int dbm_dirfno (DBM *dbf); extern int dbm_pagfno (DBM *dbf); extern int dbm_rdonly (DBM *dbf); tld.h 0000644 00000011052 15146341150 0005477 0 ustar 00 /* tld.h --- Declarations for TLD restriction checking. Copyright (C) 2004-2016 Simon Josefsson. Copyright (C) 2003-2014, 2016 Free Software Foundation, Inc. Author: Thomas Jacob, Internet24.de This file is part of GNU Libidn. GNU Libidn is free software: you can redistribute it and/or modify it under the terms of either: * the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. or * the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. or both in parallel, as here. GNU Libidn 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. You should have received copies of the GNU General Public License and the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef TLD_H # define TLD_H # ifndef IDNAPI # if defined LIBIDN_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY # define IDNAPI __attribute__((__visibility__("default"))) # elif defined LIBIDN_BUILDING && defined _MSC_VER && ! defined LIBIDN_STATIC # define IDNAPI __declspec(dllexport) # elif defined _MSC_VER && ! defined LIBIDN_STATIC # define IDNAPI __declspec(dllimport) # else # define IDNAPI # endif # endif # ifdef __cplusplus extern "C" { # endif /* Get size_t. */ # include <stdlib.h> /* Get uint32_t. */ # include <idn-int.h> /* Interval of valid code points in the TLD. */ struct Tld_table_element { uint32_t start; /* Start of range. */ uint32_t end; /* End of range, end == start if single. */ }; typedef struct Tld_table_element Tld_table_element; /* List valid code points in a TLD. */ struct Tld_table { const char *name; /* TLD name, e.g., "no". */ const char *version; /* Version string from TLD file. */ size_t nvalid; /* Number of entries in data. */ const Tld_table_element *valid; /* Sorted array of valid code points. */ }; typedef struct Tld_table Tld_table; /* Error codes. */ typedef enum { TLD_SUCCESS = 0, TLD_INVALID = 1, /* Invalid character found. */ TLD_NODATA = 2, /* Char, domain or inlen = 0. */ TLD_MALLOC_ERROR = 3, TLD_ICONV_ERROR = 4, TLD_NO_TLD = 5, /* Workaround typo in earlier versions. */ TLD_NOTLD = TLD_NO_TLD } Tld_rc; extern IDNAPI const char *tld_strerror (Tld_rc rc); /* Extract TLD, as ASCII string, of UCS4 domain name into "out". */ extern IDNAPI int tld_get_4 (const uint32_t * in, size_t inlen, char **out); extern IDNAPI int tld_get_4z (const uint32_t * in, char **out); extern IDNAPI int tld_get_z (const char *in, char **out); /* Return structure corresponding to the named TLD from specified * list of TLD tables, or return NULL if no matching TLD can be * found. */ extern IDNAPI const Tld_table *tld_get_table (const char *tld, const Tld_table ** tables); /* Return structure corresponding to the named TLD, first looking * thru overrides then thru built-in list, or return NULL if no * matching TLD can be found. */ extern IDNAPI const Tld_table * tld_default_table (const char *tld, const Tld_table ** overrides); /* Check NAMEPREPPED domain name for valid characters as defined by * the relevant registering body (plus [a-z0-9.-]). If error is * TLD_INVALID, set errpos to position of offending character. */ extern IDNAPI int tld_check_4t (const uint32_t * in, size_t inlen, size_t * errpos, const Tld_table * tld); extern IDNAPI int tld_check_4tz (const uint32_t * in, size_t * errpos, const Tld_table * tld); /* Utility interfaces that uses tld_get_4* to find TLD of string, then tld_default_table (with overrides) to find proper TLD table for the string, and then hands over to tld_check_4t*. */ extern IDNAPI int tld_check_4 (const uint32_t * in, size_t inlen, size_t * errpos, const Tld_table ** overrides); extern IDNAPI int tld_check_4z (const uint32_t * in, size_t * errpos, const Tld_table ** overrides); extern IDNAPI int tld_check_8z (const char *in, size_t * errpos, const Tld_table ** overrides); extern IDNAPI int tld_check_lz (const char *in, size_t * errpos, const Tld_table ** overrides); # ifdef __cplusplus } # endif #endif /* TLD_H */ netash/ash.h 0000644 00000002522 15146341150 0006753 0 ustar 00 /* Definitions for use with Linux AF_ASH sockets. Copyright (C) 1998-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _NETASH_ASH_H #define _NETASH_ASH_H 1 #include <features.h> #include <bits/sockaddr.h> struct sockaddr_ash { __SOCKADDR_COMMON (sash_); /* Common data: address family etc. */ int sash_ifindex; /* Interface to use. */ unsigned char sash_channel; /* Realtime or control. */ unsigned int sash_plen; unsigned char sash_prefix[16]; }; /* Values for `channel' member. */ #define ASH_CHANNEL_ANY 0 #define ASH_CHANNEL_CONTROL 1 #define ASH_CHANNEL_REALTIME 2 #endif /* netash/ash.h */ poll.h 0000644 00000000026 15146341150 0005661 0 ustar 00 #include <sys/poll.h> inttypes.h 0000644 00000027164 15146341150 0006606 0 ustar 00 /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* * ISO C99: 7.8 Format conversion of integer types <inttypes.h> */ #ifndef _INTTYPES_H #define _INTTYPES_H 1 #include <features.h> /* Get the type definitions. */ #include <stdint.h> /* Get a definition for wchar_t. But we must not define wchar_t itself. */ #ifndef ____gwchar_t_defined # ifdef __cplusplus # define __gwchar_t wchar_t # elif defined __WCHAR_TYPE__ typedef __WCHAR_TYPE__ __gwchar_t; # else # define __need_wchar_t # include <stddef.h> typedef wchar_t __gwchar_t; # endif # define ____gwchar_t_defined 1 #endif # if __WORDSIZE == 64 # define __PRI64_PREFIX "l" # define __PRIPTR_PREFIX "l" # else # define __PRI64_PREFIX "ll" # define __PRIPTR_PREFIX # endif /* Macros for printing format specifiers. */ /* Decimal notation. */ # define PRId8 "d" # define PRId16 "d" # define PRId32 "d" # define PRId64 __PRI64_PREFIX "d" # define PRIdLEAST8 "d" # define PRIdLEAST16 "d" # define PRIdLEAST32 "d" # define PRIdLEAST64 __PRI64_PREFIX "d" # define PRIdFAST8 "d" # define PRIdFAST16 __PRIPTR_PREFIX "d" # define PRIdFAST32 __PRIPTR_PREFIX "d" # define PRIdFAST64 __PRI64_PREFIX "d" # define PRIi8 "i" # define PRIi16 "i" # define PRIi32 "i" # define PRIi64 __PRI64_PREFIX "i" # define PRIiLEAST8 "i" # define PRIiLEAST16 "i" # define PRIiLEAST32 "i" # define PRIiLEAST64 __PRI64_PREFIX "i" # define PRIiFAST8 "i" # define PRIiFAST16 __PRIPTR_PREFIX "i" # define PRIiFAST32 __PRIPTR_PREFIX "i" # define PRIiFAST64 __PRI64_PREFIX "i" /* Octal notation. */ # define PRIo8 "o" # define PRIo16 "o" # define PRIo32 "o" # define PRIo64 __PRI64_PREFIX "o" # define PRIoLEAST8 "o" # define PRIoLEAST16 "o" # define PRIoLEAST32 "o" # define PRIoLEAST64 __PRI64_PREFIX "o" # define PRIoFAST8 "o" # define PRIoFAST16 __PRIPTR_PREFIX "o" # define PRIoFAST32 __PRIPTR_PREFIX "o" # define PRIoFAST64 __PRI64_PREFIX "o" /* Unsigned integers. */ # define PRIu8 "u" # define PRIu16 "u" # define PRIu32 "u" # define PRIu64 __PRI64_PREFIX "u" # define PRIuLEAST8 "u" # define PRIuLEAST16 "u" # define PRIuLEAST32 "u" # define PRIuLEAST64 __PRI64_PREFIX "u" # define PRIuFAST8 "u" # define PRIuFAST16 __PRIPTR_PREFIX "u" # define PRIuFAST32 __PRIPTR_PREFIX "u" # define PRIuFAST64 __PRI64_PREFIX "u" /* lowercase hexadecimal notation. */ # define PRIx8 "x" # define PRIx16 "x" # define PRIx32 "x" # define PRIx64 __PRI64_PREFIX "x" # define PRIxLEAST8 "x" # define PRIxLEAST16 "x" # define PRIxLEAST32 "x" # define PRIxLEAST64 __PRI64_PREFIX "x" # define PRIxFAST8 "x" # define PRIxFAST16 __PRIPTR_PREFIX "x" # define PRIxFAST32 __PRIPTR_PREFIX "x" # define PRIxFAST64 __PRI64_PREFIX "x" /* UPPERCASE hexadecimal notation. */ # define PRIX8 "X" # define PRIX16 "X" # define PRIX32 "X" # define PRIX64 __PRI64_PREFIX "X" # define PRIXLEAST8 "X" # define PRIXLEAST16 "X" # define PRIXLEAST32 "X" # define PRIXLEAST64 __PRI64_PREFIX "X" # define PRIXFAST8 "X" # define PRIXFAST16 __PRIPTR_PREFIX "X" # define PRIXFAST32 __PRIPTR_PREFIX "X" # define PRIXFAST64 __PRI64_PREFIX "X" /* Macros for printing `intmax_t' and `uintmax_t'. */ # define PRIdMAX __PRI64_PREFIX "d" # define PRIiMAX __PRI64_PREFIX "i" # define PRIoMAX __PRI64_PREFIX "o" # define PRIuMAX __PRI64_PREFIX "u" # define PRIxMAX __PRI64_PREFIX "x" # define PRIXMAX __PRI64_PREFIX "X" /* Macros for printing `intptr_t' and `uintptr_t'. */ # define PRIdPTR __PRIPTR_PREFIX "d" # define PRIiPTR __PRIPTR_PREFIX "i" # define PRIoPTR __PRIPTR_PREFIX "o" # define PRIuPTR __PRIPTR_PREFIX "u" # define PRIxPTR __PRIPTR_PREFIX "x" # define PRIXPTR __PRIPTR_PREFIX "X" /* Macros for scanning format specifiers. */ /* Signed decimal notation. */ # define SCNd8 "hhd" # define SCNd16 "hd" # define SCNd32 "d" # define SCNd64 __PRI64_PREFIX "d" # define SCNdLEAST8 "hhd" # define SCNdLEAST16 "hd" # define SCNdLEAST32 "d" # define SCNdLEAST64 __PRI64_PREFIX "d" # define SCNdFAST8 "hhd" # define SCNdFAST16 __PRIPTR_PREFIX "d" # define SCNdFAST32 __PRIPTR_PREFIX "d" # define SCNdFAST64 __PRI64_PREFIX "d" /* Signed decimal notation. */ # define SCNi8 "hhi" # define SCNi16 "hi" # define SCNi32 "i" # define SCNi64 __PRI64_PREFIX "i" # define SCNiLEAST8 "hhi" # define SCNiLEAST16 "hi" # define SCNiLEAST32 "i" # define SCNiLEAST64 __PRI64_PREFIX "i" # define SCNiFAST8 "hhi" # define SCNiFAST16 __PRIPTR_PREFIX "i" # define SCNiFAST32 __PRIPTR_PREFIX "i" # define SCNiFAST64 __PRI64_PREFIX "i" /* Unsigned decimal notation. */ # define SCNu8 "hhu" # define SCNu16 "hu" # define SCNu32 "u" # define SCNu64 __PRI64_PREFIX "u" # define SCNuLEAST8 "hhu" # define SCNuLEAST16 "hu" # define SCNuLEAST32 "u" # define SCNuLEAST64 __PRI64_PREFIX "u" # define SCNuFAST8 "hhu" # define SCNuFAST16 __PRIPTR_PREFIX "u" # define SCNuFAST32 __PRIPTR_PREFIX "u" # define SCNuFAST64 __PRI64_PREFIX "u" /* Octal notation. */ # define SCNo8 "hho" # define SCNo16 "ho" # define SCNo32 "o" # define SCNo64 __PRI64_PREFIX "o" # define SCNoLEAST8 "hho" # define SCNoLEAST16 "ho" # define SCNoLEAST32 "o" # define SCNoLEAST64 __PRI64_PREFIX "o" # define SCNoFAST8 "hho" # define SCNoFAST16 __PRIPTR_PREFIX "o" # define SCNoFAST32 __PRIPTR_PREFIX "o" # define SCNoFAST64 __PRI64_PREFIX "o" /* Hexadecimal notation. */ # define SCNx8 "hhx" # define SCNx16 "hx" # define SCNx32 "x" # define SCNx64 __PRI64_PREFIX "x" # define SCNxLEAST8 "hhx" # define SCNxLEAST16 "hx" # define SCNxLEAST32 "x" # define SCNxLEAST64 __PRI64_PREFIX "x" # define SCNxFAST8 "hhx" # define SCNxFAST16 __PRIPTR_PREFIX "x" # define SCNxFAST32 __PRIPTR_PREFIX "x" # define SCNxFAST64 __PRI64_PREFIX "x" /* Macros for scanning `intmax_t' and `uintmax_t'. */ # define SCNdMAX __PRI64_PREFIX "d" # define SCNiMAX __PRI64_PREFIX "i" # define SCNoMAX __PRI64_PREFIX "o" # define SCNuMAX __PRI64_PREFIX "u" # define SCNxMAX __PRI64_PREFIX "x" /* Macros for scaning `intptr_t' and `uintptr_t'. */ # define SCNdPTR __PRIPTR_PREFIX "d" # define SCNiPTR __PRIPTR_PREFIX "i" # define SCNoPTR __PRIPTR_PREFIX "o" # define SCNuPTR __PRIPTR_PREFIX "u" # define SCNxPTR __PRIPTR_PREFIX "x" __BEGIN_DECLS #if __WORDSIZE == 64 /* We have to define the `uintmax_t' type using `ldiv_t'. */ typedef struct { long int quot; /* Quotient. */ long int rem; /* Remainder. */ } imaxdiv_t; #else /* We have to define the `uintmax_t' type using `lldiv_t'. */ typedef struct { __extension__ long long int quot; /* Quotient. */ __extension__ long long int rem; /* Remainder. */ } imaxdiv_t; #endif /* Compute absolute value of N. */ extern intmax_t imaxabs (intmax_t __n) __THROW __attribute__ ((__const__)); /* Return the `imaxdiv_t' representation of the value of NUMER over DENOM. */ extern imaxdiv_t imaxdiv (intmax_t __numer, intmax_t __denom) __THROW __attribute__ ((__const__)); /* Like `strtol' but convert to `intmax_t'. */ extern intmax_t strtoimax (const char *__restrict __nptr, char **__restrict __endptr, int __base) __THROW; /* Like `strtoul' but convert to `uintmax_t'. */ extern uintmax_t strtoumax (const char *__restrict __nptr, char ** __restrict __endptr, int __base) __THROW; /* Like `wcstol' but convert to `intmax_t'. */ extern intmax_t wcstoimax (const __gwchar_t *__restrict __nptr, __gwchar_t **__restrict __endptr, int __base) __THROW; /* Like `wcstoul' but convert to `uintmax_t'. */ extern uintmax_t wcstoumax (const __gwchar_t *__restrict __nptr, __gwchar_t ** __restrict __endptr, int __base) __THROW; #ifdef __USE_EXTERN_INLINES # if __WORDSIZE == 64 extern long int __strtol_internal (const char *__restrict __nptr, char **__restrict __endptr, int __base, int __group) __THROW __nonnull ((1)) __wur; /* Like `strtol' but convert to `intmax_t'. */ __extern_inline intmax_t __NTH (strtoimax (const char *__restrict nptr, char **__restrict endptr, int base)) { return __strtol_internal (nptr, endptr, base, 0); } extern unsigned long int __strtoul_internal (const char *__restrict __nptr, char ** __restrict __endptr, int __base, int __group) __THROW __nonnull ((1)) __wur; /* Like `strtoul' but convert to `uintmax_t'. */ __extern_inline uintmax_t __NTH (strtoumax (const char *__restrict nptr, char **__restrict endptr, int base)) { return __strtoul_internal (nptr, endptr, base, 0); } extern long int __wcstol_internal (const __gwchar_t * __restrict __nptr, __gwchar_t **__restrict __endptr, int __base, int __group) __THROW __nonnull ((1)) __wur; /* Like `wcstol' but convert to `intmax_t'. */ __extern_inline intmax_t __NTH (wcstoimax (const __gwchar_t *__restrict nptr, __gwchar_t **__restrict endptr, int base)) { return __wcstol_internal (nptr, endptr, base, 0); } extern unsigned long int __wcstoul_internal (const __gwchar_t * __restrict __nptr, __gwchar_t ** __restrict __endptr, int __base, int __group) __THROW __nonnull ((1)) __wur; /* Like `wcstoul' but convert to `uintmax_t'. */ __extern_inline uintmax_t __NTH (wcstoumax (const __gwchar_t *__restrict nptr, __gwchar_t **__restrict endptr, int base)) { return __wcstoul_internal (nptr, endptr, base, 0); } # else /* __WORDSIZE == 32 */ __extension__ extern long long int __strtoll_internal (const char *__restrict __nptr, char **__restrict __endptr, int __base, int __group) __THROW __nonnull ((1)) __wur; /* Like `strtol' but convert to `intmax_t'. */ __extern_inline intmax_t __NTH (strtoimax (const char *__restrict nptr, char **__restrict endptr, int base)) { return __strtoll_internal (nptr, endptr, base, 0); } __extension__ extern unsigned long long int __strtoull_internal (const char * __restrict __nptr, char ** __restrict __endptr, int __base, int __group) __THROW __nonnull ((1)) __wur; /* Like `strtoul' but convert to `uintmax_t'. */ __extern_inline uintmax_t __NTH (strtoumax (const char *__restrict nptr, char **__restrict endptr, int base)) { return __strtoull_internal (nptr, endptr, base, 0); } __extension__ extern long long int __wcstoll_internal (const __gwchar_t *__restrict __nptr, __gwchar_t **__restrict __endptr, int __base, int __group) __THROW __nonnull ((1)) __wur; /* Like `wcstol' but convert to `intmax_t'. */ __extern_inline intmax_t __NTH (wcstoimax (const __gwchar_t *__restrict nptr, __gwchar_t **__restrict endptr, int base)) { return __wcstoll_internal (nptr, endptr, base, 0); } __extension__ extern unsigned long long int __wcstoull_internal (const __gwchar_t * __restrict __nptr, __gwchar_t ** __restrict __endptr, int __base, int __group) __THROW __nonnull ((1)) __wur; /* Like `wcstoul' but convert to `uintmax_t'. */ __extern_inline uintmax_t __NTH (wcstoumax (const __gwchar_t *__restrict nptr, __gwchar_t **__restrict endptr, int base)) { return __wcstoull_internal (nptr, endptr, base, 0); } # endif /* __WORDSIZE == 32 */ #endif /* Use extern inlines. */ __END_DECLS #endif /* inttypes.h */ mqueue.h 0000644 00000007257 15146341150 0006231 0 ustar 00 /* Copyright (C) 2004-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _MQUEUE_H #define _MQUEUE_H 1 #include <features.h> #include <sys/types.h> #include <fcntl.h> #include <bits/types/sigevent_t.h> #include <bits/types/struct_timespec.h> /* Get the definition of mqd_t and struct mq_attr. */ #include <bits/mqueue.h> __BEGIN_DECLS /* Establish connection between a process and a message queue NAME and return message queue descriptor or (mqd_t) -1 on error. OFLAG determines the type of access used. If O_CREAT is on OFLAG, the third argument is taken as a `mode_t', the mode of the created message queue, and the fourth argument is taken as `struct mq_attr *', pointer to message queue attributes. If the fourth argument is NULL, default attributes are used. */ extern mqd_t mq_open (const char *__name, int __oflag, ...) __THROW __nonnull ((1)); /* Removes the association between message queue descriptor MQDES and its message queue. */ extern int mq_close (mqd_t __mqdes) __THROW; /* Query status and attributes of message queue MQDES. */ extern int mq_getattr (mqd_t __mqdes, struct mq_attr *__mqstat) __THROW __nonnull ((2)); /* Set attributes associated with message queue MQDES and if OMQSTAT is not NULL also query its old attributes. */ extern int mq_setattr (mqd_t __mqdes, const struct mq_attr *__restrict __mqstat, struct mq_attr *__restrict __omqstat) __THROW __nonnull ((2)); /* Remove message queue named NAME. */ extern int mq_unlink (const char *__name) __THROW __nonnull ((1)); /* Register notification issued upon message arrival to an empty message queue MQDES. */ extern int mq_notify (mqd_t __mqdes, const struct sigevent *__notification) __THROW; /* Receive the oldest from highest priority messages in message queue MQDES. */ extern ssize_t mq_receive (mqd_t __mqdes, char *__msg_ptr, size_t __msg_len, unsigned int *__msg_prio) __nonnull ((2)); /* Add message pointed by MSG_PTR to message queue MQDES. */ extern int mq_send (mqd_t __mqdes, const char *__msg_ptr, size_t __msg_len, unsigned int __msg_prio) __nonnull ((2)); #ifdef __USE_XOPEN2K /* Receive the oldest from highest priority messages in message queue MQDES, stop waiting if ABS_TIMEOUT expires. */ extern ssize_t mq_timedreceive (mqd_t __mqdes, char *__restrict __msg_ptr, size_t __msg_len, unsigned int *__restrict __msg_prio, const struct timespec *__restrict __abs_timeout) __nonnull ((2, 5)); /* Add message pointed by MSG_PTR to message queue MQDES, stop blocking on full message queue if ABS_TIMEOUT expires. */ extern int mq_timedsend (mqd_t __mqdes, const char *__msg_ptr, size_t __msg_len, unsigned int __msg_prio, const struct timespec *__abs_timeout) __nonnull ((2, 5)); #endif /* Define some inlines helping to catch common problems. */ #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function \ && defined __va_arg_pack_len # include <bits/mqueue2.h> #endif __END_DECLS #endif /* mqueue.h */ errno.h 0000644 00000003216 15146341150 0006044 0 ustar 00 /* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* * ISO C99 Standard: 7.5 Errors <errno.h> */ #ifndef _ERRNO_H #define _ERRNO_H 1 #include <features.h> /* The system-specific definitions of the E* constants, as macros. */ #include <bits/errno.h> /* When included from assembly language, this header only provides the E* constants. */ #ifndef __ASSEMBLER__ __BEGIN_DECLS /* The error code set by various library functions. */ extern int *__errno_location (void) __THROW __attribute_const__; # define errno (*__errno_location ()) # ifdef __USE_GNU /* The full and simple forms of the name with which the program was invoked. These variables are set up automatically at startup based on the value of argv[0]. */ extern char *program_invocation_name; extern char *program_invocation_short_name; #include <bits/types/error_t.h> # endif /* __USE_GNU */ __END_DECLS #endif /* !__ASSEMBLER__ */ #endif /* errno.h */ libpng16/pnglibconf.h 0000644 00000016617 15146341150 0010473 0 ustar 00 /* pnglibconf.h - library build configuration */ /* libpng version 1.6.34, September 29, 2017 */ /* Copyright (c) 1998-2017 Glenn Randers-Pehrson */ /* This code is released under the libpng license. */ /* For conditions of distribution and use, see the disclaimer */ /* and license in png.h */ /* pnglibconf.h */ /* Machine generated file: DO NOT EDIT */ /* Derived from: scripts/pnglibconf.dfa */ #ifndef PNGLCONF_H #define PNGLCONF_H /* options */ #define PNG_16BIT_SUPPORTED #define PNG_ALIGNED_MEMORY_SUPPORTED /*#undef PNG_ARM_NEON_API_SUPPORTED*/ /*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ #define PNG_BENIGN_ERRORS_SUPPORTED #define PNG_BENIGN_READ_ERRORS_SUPPORTED /*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ #define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED #define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED #define PNG_COLORSPACE_SUPPORTED #define PNG_CONSOLE_IO_SUPPORTED #define PNG_CONVERT_tIME_SUPPORTED #define PNG_EASY_ACCESS_SUPPORTED /*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ #define PNG_ERROR_TEXT_SUPPORTED #define PNG_FIXED_POINT_SUPPORTED #define PNG_FLOATING_ARITHMETIC_SUPPORTED #define PNG_FLOATING_POINT_SUPPORTED #define PNG_FORMAT_AFIRST_SUPPORTED #define PNG_FORMAT_BGR_SUPPORTED #define PNG_GAMMA_SUPPORTED #define PNG_GET_PALETTE_MAX_SUPPORTED #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED #define PNG_INCH_CONVERSIONS_SUPPORTED #define PNG_INFO_IMAGE_SUPPORTED #define PNG_IO_STATE_SUPPORTED #define PNG_MNG_FEATURES_SUPPORTED #define PNG_POINTER_INDEXING_SUPPORTED /*#undef PNG_POWERPC_VSX_API_SUPPORTED*/ /*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/ #define PNG_PROGRESSIVE_READ_SUPPORTED #define PNG_READ_16BIT_SUPPORTED #define PNG_READ_ALPHA_MODE_SUPPORTED #define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED #define PNG_READ_BACKGROUND_SUPPORTED #define PNG_READ_BGR_SUPPORTED #define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED #define PNG_READ_COMPOSITE_NODIV_SUPPORTED #define PNG_READ_COMPRESSED_TEXT_SUPPORTED #define PNG_READ_EXPAND_16_SUPPORTED #define PNG_READ_EXPAND_SUPPORTED #define PNG_READ_FILLER_SUPPORTED #define PNG_READ_GAMMA_SUPPORTED #define PNG_READ_GET_PALETTE_MAX_SUPPORTED #define PNG_READ_GRAY_TO_RGB_SUPPORTED #define PNG_READ_INTERLACING_SUPPORTED #define PNG_READ_INT_FUNCTIONS_SUPPORTED #define PNG_READ_INVERT_ALPHA_SUPPORTED #define PNG_READ_INVERT_SUPPORTED #define PNG_READ_OPT_PLTE_SUPPORTED #define PNG_READ_PACKSWAP_SUPPORTED #define PNG_READ_PACK_SUPPORTED #define PNG_READ_QUANTIZE_SUPPORTED #define PNG_READ_RGB_TO_GRAY_SUPPORTED #define PNG_READ_SCALE_16_TO_8_SUPPORTED #define PNG_READ_SHIFT_SUPPORTED #define PNG_READ_STRIP_16_TO_8_SUPPORTED #define PNG_READ_STRIP_ALPHA_SUPPORTED #define PNG_READ_SUPPORTED #define PNG_READ_SWAP_ALPHA_SUPPORTED #define PNG_READ_SWAP_SUPPORTED #define PNG_READ_TEXT_SUPPORTED #define PNG_READ_TRANSFORMS_SUPPORTED #define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED #define PNG_READ_USER_CHUNKS_SUPPORTED #define PNG_READ_USER_TRANSFORM_SUPPORTED #define PNG_READ_bKGD_SUPPORTED #define PNG_READ_cHRM_SUPPORTED #define PNG_READ_eXIf_SUPPORTED #define PNG_READ_gAMA_SUPPORTED #define PNG_READ_hIST_SUPPORTED #define PNG_READ_iCCP_SUPPORTED #define PNG_READ_iTXt_SUPPORTED #define PNG_READ_oFFs_SUPPORTED #define PNG_READ_pCAL_SUPPORTED #define PNG_READ_pHYs_SUPPORTED #define PNG_READ_sBIT_SUPPORTED #define PNG_READ_sCAL_SUPPORTED #define PNG_READ_sPLT_SUPPORTED #define PNG_READ_sRGB_SUPPORTED #define PNG_READ_tEXt_SUPPORTED #define PNG_READ_tIME_SUPPORTED #define PNG_READ_tRNS_SUPPORTED #define PNG_READ_zTXt_SUPPORTED #define PNG_SAVE_INT_32_SUPPORTED #define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED #define PNG_SEQUENTIAL_READ_SUPPORTED #define PNG_SETJMP_SUPPORTED #define PNG_SET_OPTION_SUPPORTED #define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED #define PNG_SET_USER_LIMITS_SUPPORTED #define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED #define PNG_SIMPLIFIED_READ_BGR_SUPPORTED #define PNG_SIMPLIFIED_READ_SUPPORTED #define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED #define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED #define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED #define PNG_SIMPLIFIED_WRITE_SUPPORTED #define PNG_STDIO_SUPPORTED #define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED #define PNG_TEXT_SUPPORTED #define PNG_TIME_RFC1123_SUPPORTED #define PNG_UNKNOWN_CHUNKS_SUPPORTED #define PNG_USER_CHUNKS_SUPPORTED #define PNG_USER_LIMITS_SUPPORTED #define PNG_USER_MEM_SUPPORTED #define PNG_USER_TRANSFORM_INFO_SUPPORTED #define PNG_USER_TRANSFORM_PTR_SUPPORTED #define PNG_WARNINGS_SUPPORTED #define PNG_WRITE_16BIT_SUPPORTED #define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED #define PNG_WRITE_BGR_SUPPORTED #define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED #define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED #define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED #define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED #define PNG_WRITE_FILLER_SUPPORTED #define PNG_WRITE_FILTER_SUPPORTED #define PNG_WRITE_FLUSH_SUPPORTED #define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED #define PNG_WRITE_INTERLACING_SUPPORTED #define PNG_WRITE_INT_FUNCTIONS_SUPPORTED #define PNG_WRITE_INVERT_ALPHA_SUPPORTED #define PNG_WRITE_INVERT_SUPPORTED #define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED #define PNG_WRITE_PACKSWAP_SUPPORTED #define PNG_WRITE_PACK_SUPPORTED #define PNG_WRITE_SHIFT_SUPPORTED #define PNG_WRITE_SUPPORTED #define PNG_WRITE_SWAP_ALPHA_SUPPORTED #define PNG_WRITE_SWAP_SUPPORTED #define PNG_WRITE_TEXT_SUPPORTED #define PNG_WRITE_TRANSFORMS_SUPPORTED #define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED #define PNG_WRITE_USER_TRANSFORM_SUPPORTED #define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED #define PNG_WRITE_bKGD_SUPPORTED #define PNG_WRITE_cHRM_SUPPORTED #define PNG_WRITE_eXIf_SUPPORTED #define PNG_WRITE_gAMA_SUPPORTED #define PNG_WRITE_hIST_SUPPORTED #define PNG_WRITE_iCCP_SUPPORTED #define PNG_WRITE_iTXt_SUPPORTED #define PNG_WRITE_oFFs_SUPPORTED #define PNG_WRITE_pCAL_SUPPORTED #define PNG_WRITE_pHYs_SUPPORTED #define PNG_WRITE_sBIT_SUPPORTED #define PNG_WRITE_sCAL_SUPPORTED #define PNG_WRITE_sPLT_SUPPORTED #define PNG_WRITE_sRGB_SUPPORTED #define PNG_WRITE_tEXt_SUPPORTED #define PNG_WRITE_tIME_SUPPORTED #define PNG_WRITE_tRNS_SUPPORTED #define PNG_WRITE_zTXt_SUPPORTED #define PNG_bKGD_SUPPORTED #define PNG_cHRM_SUPPORTED #define PNG_eXIf_SUPPORTED #define PNG_gAMA_SUPPORTED #define PNG_hIST_SUPPORTED #define PNG_iCCP_SUPPORTED #define PNG_iTXt_SUPPORTED #define PNG_oFFs_SUPPORTED #define PNG_pCAL_SUPPORTED #define PNG_pHYs_SUPPORTED #define PNG_sBIT_SUPPORTED #define PNG_sCAL_SUPPORTED #define PNG_sPLT_SUPPORTED #define PNG_sRGB_SUPPORTED #define PNG_tEXt_SUPPORTED #define PNG_tIME_SUPPORTED #define PNG_tRNS_SUPPORTED #define PNG_zTXt_SUPPORTED /* end of options */ /* settings */ #define PNG_API_RULE 0 #define PNG_DEFAULT_READ_MACROS 1 #define PNG_GAMMA_THRESHOLD_FIXED 5000 #define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE #define PNG_INFLATE_BUF_SIZE 1024 #define PNG_LINKAGE_API extern #define PNG_LINKAGE_CALLBACK extern #define PNG_LINKAGE_DATA extern #define PNG_LINKAGE_FUNCTION extern #define PNG_MAX_GAMMA_8 11 #define PNG_QUANTIZE_BLUE_BITS 5 #define PNG_QUANTIZE_GREEN_BITS 5 #define PNG_QUANTIZE_RED_BITS 5 #define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1) #define PNG_TEXT_Z_DEFAULT_STRATEGY 0 #define PNG_USER_CHUNK_CACHE_MAX 1000 #define PNG_USER_CHUNK_MALLOC_MAX 1000000000 #define PNG_USER_HEIGHT_MAX 1000000 #define PNG_USER_WIDTH_MAX 1000000 #define PNG_ZBUF_SIZE 8192 #define PNG_ZLIB_VERNUM 0x12b0 #define PNG_Z_DEFAULT_COMPRESSION (-1) #define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 #define PNG_Z_DEFAULT_STRATEGY 1 #define PNG_sCAL_PRECISION 5 #define PNG_sRGB_PROFILE_CHECKS 2 /* end of settings */ #endif /* PNGLCONF_H */ idn-free.h 0000644 00000004650 15146341150 0006413 0 ustar 00 /* idn-free.h --- Invoke the free function to release memory Copyright (C) 2004-2016 Simon Josefsson This file is part of GNU Libidn. GNU Libidn is free software: you can redistribute it and/or modify it under the terms of either: * the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. or * the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. or both in parallel, as here. GNU Libidn 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. You should have received copies of the GNU General Public License and the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef IDN_FREE_H # define IDN_FREE_H # ifndef IDNAPI # if defined LIBIDN_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY # define IDNAPI __attribute__((__visibility__("default"))) # elif defined LIBIDN_BUILDING && defined _MSC_VER && ! defined LIBIDN_STATIC # define IDNAPI __declspec(dllexport) # elif defined _MSC_VER && ! defined LIBIDN_STATIC # define IDNAPI __declspec(dllimport) # else # define IDNAPI # endif # endif # ifdef __cplusplus extern "C" { # endif /* I don't recommend using this interface in general. Use `free'. * * I'm told Microsoft Windows may use one set of `malloc' and `free' * in a library, and another incompatible set in a statically compiled * application that link to the library, thus creating problems if the * application would invoke `free' on a pointer pointing to memory * allocated by the library. This motivated adding this function. * * The theory of isolating all memory allocations and de-allocations * within a code package (library) sounds good, to simplify hunting * down memory allocation related problems, but I'm not sure if it is * worth enough to motivate recommending this interface over calling * `free' directly, though. * * See the manual section 'Memory handling under Windows' for more * information. */ extern void IDNAPI idn_free (void *ptr); # ifdef __cplusplus } # endif #endif /* IDN_FREE_H */ ftw.h 0000644 00000012203 15146341150 0005513 0 ustar 00 /* Copyright (C) 1992-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* * X/Open Portability Guide 4.2: ftw.h */ #ifndef _FTW_H #define _FTW_H 1 #include <features.h> #include <sys/types.h> #include <sys/stat.h> __BEGIN_DECLS /* Values for the FLAG argument to the user function passed to `ftw' and 'nftw'. */ enum { FTW_F, /* Regular file. */ #define FTW_F FTW_F FTW_D, /* Directory. */ #define FTW_D FTW_D FTW_DNR, /* Unreadable directory. */ #define FTW_DNR FTW_DNR FTW_NS, /* Unstatable file. */ #define FTW_NS FTW_NS #if defined __USE_MISC || defined __USE_XOPEN_EXTENDED FTW_SL, /* Symbolic link. */ # define FTW_SL FTW_SL #endif #ifdef __USE_XOPEN_EXTENDED /* These flags are only passed from the `nftw' function. */ FTW_DP, /* Directory, all subdirs have been visited. */ # define FTW_DP FTW_DP FTW_SLN /* Symbolic link naming non-existing file. */ # define FTW_SLN FTW_SLN #endif /* extended X/Open */ }; #ifdef __USE_XOPEN_EXTENDED /* Flags for fourth argument of `nftw'. */ enum { FTW_PHYS = 1, /* Perform physical walk, ignore symlinks. */ # define FTW_PHYS FTW_PHYS FTW_MOUNT = 2, /* Report only files on same file system as the argument. */ # define FTW_MOUNT FTW_MOUNT FTW_CHDIR = 4, /* Change to current directory while processing it. */ # define FTW_CHDIR FTW_CHDIR FTW_DEPTH = 8 /* Report files in directory before directory itself.*/ # define FTW_DEPTH FTW_DEPTH # ifdef __USE_GNU , FTW_ACTIONRETVAL = 16 /* Assume callback to return FTW_* values instead of zero to continue and non-zero to terminate. */ # define FTW_ACTIONRETVAL FTW_ACTIONRETVAL # endif }; #ifdef __USE_GNU /* Return values from callback functions. */ enum { FTW_CONTINUE = 0, /* Continue with next sibling or for FTW_D with the first child. */ # define FTW_CONTINUE FTW_CONTINUE FTW_STOP = 1, /* Return from `ftw' or `nftw' with FTW_STOP as return value. */ # define FTW_STOP FTW_STOP FTW_SKIP_SUBTREE = 2, /* Only meaningful for FTW_D: Don't walk through the subtree, instead just continue with its next sibling. */ # define FTW_SKIP_SUBTREE FTW_SKIP_SUBTREE FTW_SKIP_SIBLINGS = 3,/* Continue with FTW_DP callback for current directory (if FTW_DEPTH) and then its siblings. */ # define FTW_SKIP_SIBLINGS FTW_SKIP_SIBLINGS }; #endif /* Structure used for fourth argument to callback function for `nftw'. */ struct FTW { int base; int level; }; #endif /* extended X/Open */ /* Convenient types for callback functions. */ typedef int (*__ftw_func_t) (const char *__filename, const struct stat *__status, int __flag); #ifdef __USE_LARGEFILE64 typedef int (*__ftw64_func_t) (const char *__filename, const struct stat64 *__status, int __flag); #endif #ifdef __USE_XOPEN_EXTENDED typedef int (*__nftw_func_t) (const char *__filename, const struct stat *__status, int __flag, struct FTW *__info); # ifdef __USE_LARGEFILE64 typedef int (*__nftw64_func_t) (const char *__filename, const struct stat64 *__status, int __flag, struct FTW *__info); # endif #endif /* Call a function on every element in a directory tree. This function is a possible cancellation point and therefore not marked with __THROW. */ #ifndef __USE_FILE_OFFSET64 extern int ftw (const char *__dir, __ftw_func_t __func, int __descriptors) __nonnull ((1, 2)); #else # ifdef __REDIRECT extern int __REDIRECT (ftw, (const char *__dir, __ftw_func_t __func, int __descriptors), ftw64) __nonnull ((1, 2)); # else # define ftw ftw64 # endif #endif #ifdef __USE_LARGEFILE64 extern int ftw64 (const char *__dir, __ftw64_func_t __func, int __descriptors) __nonnull ((1, 2)); #endif #ifdef __USE_XOPEN_EXTENDED /* Call a function on every element in a directory tree. FLAG allows to specify the behaviour more detailed. This function is a possible cancellation point and therefore not marked with __THROW. */ # ifndef __USE_FILE_OFFSET64 extern int nftw (const char *__dir, __nftw_func_t __func, int __descriptors, int __flag) __nonnull ((1, 2)); # else # ifdef __REDIRECT extern int __REDIRECT (nftw, (const char *__dir, __nftw_func_t __func, int __descriptors, int __flag), nftw64) __nonnull ((1, 2)); # else # define nftw nftw64 # endif # endif # ifdef __USE_LARGEFILE64 extern int nftw64 (const char *__dir, __nftw64_func_t __func, int __descriptors, int __flag) __nonnull ((1, 2)); # endif #endif __END_DECLS #endif /* ftw.h */ term.h 0000644 00000120346 15146341150 0005672 0 ustar 00 /**************************************************************************** * Copyright (c) 1998-2013,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, distribute with modifications, sublicense, and/or sell * * copies of the Software, and to permit persons to whom the Software is * * furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included * * in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * * * Except as contained in this notice, the name(s) of the above copyright * * holders shall not be used in advertising or otherwise to promote the * * sale, use or other dealings in this Software without prior written * * authorization. * ****************************************************************************/ /****************************************************************************/ /* Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 */ /* and: Eric S. Raymond <esr@snark.thyrsus.com> */ /* and: Thomas E. Dickey 1995-on */ /****************************************************************************/ /* $Id: MKterm.h.awk.in,v 1.67 2017/04/06 00:19:26 tom Exp $ */ /* ** term.h -- Definition of struct term */ #ifndef NCURSES_TERM_H_incl #define NCURSES_TERM_H_incl 1 #undef NCURSES_VERSION #define NCURSES_VERSION "6.1" #include <ncurses_dll.h> #ifdef __cplusplus extern "C" { #endif /* Make this file self-contained by providing defaults for the HAVE_TERMIO[S]_H * definition (based on the system for which this was configured). */ #undef NCURSES_CONST #define NCURSES_CONST const #undef NCURSES_SBOOL #define NCURSES_SBOOL char #undef NCURSES_USE_DATABASE #define NCURSES_USE_DATABASE 1 #undef NCURSES_USE_TERMCAP #define NCURSES_USE_TERMCAP 0 #undef NCURSES_XNAMES #define NCURSES_XNAMES 1 /* We will use these symbols to hide differences between * termios/termio/sgttyb interfaces. */ #undef TTY #undef SET_TTY #undef GET_TTY /* Assume POSIX termio if we have the header and function */ /* #if HAVE_TERMIOS_H && HAVE_TCGETATTR */ #if 1 && 1 #undef TERMIOS #define TERMIOS 1 #include <termios.h> #define TTY struct termios #else /* !HAVE_TERMIOS_H */ /* #if HAVE_TERMIO_H */ #if 1 #undef TERMIOS #define TERMIOS 1 #include <termio.h> #define TTY struct termio #else /* !HAVE_TERMIO_H */ #if __MINGW32__ # include <ncurses_mingw.h> # define TTY struct termios #else #undef TERMIOS #include <sgtty.h> #include <sys/ioctl.h> #define TTY struct sgttyb #endif /* MINGW32 */ #endif /* HAVE_TERMIO_H */ #endif /* HAVE_TERMIOS_H */ #ifdef TERMIOS #define GET_TTY(fd, buf) tcgetattr(fd, buf) #define SET_TTY(fd, buf) tcsetattr(fd, TCSADRAIN, buf) #else #define GET_TTY(fd, buf) gtty(fd, buf) #define SET_TTY(fd, buf) stty(fd, buf) #endif #define NAMESIZE 256 /* The cast works because TERMTYPE is the first data in TERMINAL */ #define CUR ((TERMTYPE *)(cur_term))-> #define auto_left_margin CUR Booleans[0] #define auto_right_margin CUR Booleans[1] #define no_esc_ctlc CUR Booleans[2] #define ceol_standout_glitch CUR Booleans[3] #define eat_newline_glitch CUR Booleans[4] #define erase_overstrike CUR Booleans[5] #define generic_type CUR Booleans[6] #define hard_copy CUR Booleans[7] #define has_meta_key CUR Booleans[8] #define has_status_line CUR Booleans[9] #define insert_null_glitch CUR Booleans[10] #define memory_above CUR Booleans[11] #define memory_below CUR Booleans[12] #define move_insert_mode CUR Booleans[13] #define move_standout_mode CUR Booleans[14] #define over_strike CUR Booleans[15] #define status_line_esc_ok CUR Booleans[16] #define dest_tabs_magic_smso CUR Booleans[17] #define tilde_glitch CUR Booleans[18] #define transparent_underline CUR Booleans[19] #define xon_xoff CUR Booleans[20] #define needs_xon_xoff CUR Booleans[21] #define prtr_silent CUR Booleans[22] #define hard_cursor CUR Booleans[23] #define non_rev_rmcup CUR Booleans[24] #define no_pad_char CUR Booleans[25] #define non_dest_scroll_region CUR Booleans[26] #define can_change CUR Booleans[27] #define back_color_erase CUR Booleans[28] #define hue_lightness_saturation CUR Booleans[29] #define col_addr_glitch CUR Booleans[30] #define cr_cancels_micro_mode CUR Booleans[31] #define has_print_wheel CUR Booleans[32] #define row_addr_glitch CUR Booleans[33] #define semi_auto_right_margin CUR Booleans[34] #define cpi_changes_res CUR Booleans[35] #define lpi_changes_res CUR Booleans[36] #define columns CUR Numbers[0] #define init_tabs CUR Numbers[1] #define lines CUR Numbers[2] #define lines_of_memory CUR Numbers[3] #define magic_cookie_glitch CUR Numbers[4] #define padding_baud_rate CUR Numbers[5] #define virtual_terminal CUR Numbers[6] #define width_status_line CUR Numbers[7] #define num_labels CUR Numbers[8] #define label_height CUR Numbers[9] #define label_width CUR Numbers[10] #define max_attributes CUR Numbers[11] #define maximum_windows CUR Numbers[12] #define max_colors CUR Numbers[13] #define max_pairs CUR Numbers[14] #define no_color_video CUR Numbers[15] #define buffer_capacity CUR Numbers[16] #define dot_vert_spacing CUR Numbers[17] #define dot_horz_spacing CUR Numbers[18] #define max_micro_address CUR Numbers[19] #define max_micro_jump CUR Numbers[20] #define micro_col_size CUR Numbers[21] #define micro_line_size CUR Numbers[22] #define number_of_pins CUR Numbers[23] #define output_res_char CUR Numbers[24] #define output_res_line CUR Numbers[25] #define output_res_horz_inch CUR Numbers[26] #define output_res_vert_inch CUR Numbers[27] #define print_rate CUR Numbers[28] #define wide_char_size CUR Numbers[29] #define buttons CUR Numbers[30] #define bit_image_entwining CUR Numbers[31] #define bit_image_type CUR Numbers[32] #define back_tab CUR Strings[0] #define bell CUR Strings[1] #define carriage_return CUR Strings[2] #define change_scroll_region CUR Strings[3] #define clear_all_tabs CUR Strings[4] #define clear_screen CUR Strings[5] #define clr_eol CUR Strings[6] #define clr_eos CUR Strings[7] #define column_address CUR Strings[8] #define command_character CUR Strings[9] #define cursor_address CUR Strings[10] #define cursor_down CUR Strings[11] #define cursor_home CUR Strings[12] #define cursor_invisible CUR Strings[13] #define cursor_left CUR Strings[14] #define cursor_mem_address CUR Strings[15] #define cursor_normal CUR Strings[16] #define cursor_right CUR Strings[17] #define cursor_to_ll CUR Strings[18] #define cursor_up CUR Strings[19] #define cursor_visible CUR Strings[20] #define delete_character CUR Strings[21] #define delete_line CUR Strings[22] #define dis_status_line CUR Strings[23] #define down_half_line CUR Strings[24] #define enter_alt_charset_mode CUR Strings[25] #define enter_blink_mode CUR Strings[26] #define enter_bold_mode CUR Strings[27] #define enter_ca_mode CUR Strings[28] #define enter_delete_mode CUR Strings[29] #define enter_dim_mode CUR Strings[30] #define enter_insert_mode CUR Strings[31] #define enter_secure_mode CUR Strings[32] #define enter_protected_mode CUR Strings[33] #define enter_reverse_mode CUR Strings[34] #define enter_standout_mode CUR Strings[35] #define enter_underline_mode CUR Strings[36] #define erase_chars CUR Strings[37] #define exit_alt_charset_mode CUR Strings[38] #define exit_attribute_mode CUR Strings[39] #define exit_ca_mode CUR Strings[40] #define exit_delete_mode CUR Strings[41] #define exit_insert_mode CUR Strings[42] #define exit_standout_mode CUR Strings[43] #define exit_underline_mode CUR Strings[44] #define flash_screen CUR Strings[45] #define form_feed CUR Strings[46] #define from_status_line CUR Strings[47] #define init_1string CUR Strings[48] #define init_2string CUR Strings[49] #define init_3string CUR Strings[50] #define init_file CUR Strings[51] #define insert_character CUR Strings[52] #define insert_line CUR Strings[53] #define insert_padding CUR Strings[54] #define key_backspace CUR Strings[55] #define key_catab CUR Strings[56] #define key_clear CUR Strings[57] #define key_ctab CUR Strings[58] #define key_dc CUR Strings[59] #define key_dl CUR Strings[60] #define key_down CUR Strings[61] #define key_eic CUR Strings[62] #define key_eol CUR Strings[63] #define key_eos CUR Strings[64] #define key_f0 CUR Strings[65] #define key_f1 CUR Strings[66] #define key_f10 CUR Strings[67] #define key_f2 CUR Strings[68] #define key_f3 CUR Strings[69] #define key_f4 CUR Strings[70] #define key_f5 CUR Strings[71] #define key_f6 CUR Strings[72] #define key_f7 CUR Strings[73] #define key_f8 CUR Strings[74] #define key_f9 CUR Strings[75] #define key_home CUR Strings[76] #define key_ic CUR Strings[77] #define key_il CUR Strings[78] #define key_left CUR Strings[79] #define key_ll CUR Strings[80] #define key_npage CUR Strings[81] #define key_ppage CUR Strings[82] #define key_right CUR Strings[83] #define key_sf CUR Strings[84] #define key_sr CUR Strings[85] #define key_stab CUR Strings[86] #define key_up CUR Strings[87] #define keypad_local CUR Strings[88] #define keypad_xmit CUR Strings[89] #define lab_f0 CUR Strings[90] #define lab_f1 CUR Strings[91] #define lab_f10 CUR Strings[92] #define lab_f2 CUR Strings[93] #define lab_f3 CUR Strings[94] #define lab_f4 CUR Strings[95] #define lab_f5 CUR Strings[96] #define lab_f6 CUR Strings[97] #define lab_f7 CUR Strings[98] #define lab_f8 CUR Strings[99] #define lab_f9 CUR Strings[100] #define meta_off CUR Strings[101] #define meta_on CUR Strings[102] #define newline CUR Strings[103] #define pad_char CUR Strings[104] #define parm_dch CUR Strings[105] #define parm_delete_line CUR Strings[106] #define parm_down_cursor CUR Strings[107] #define parm_ich CUR Strings[108] #define parm_index CUR Strings[109] #define parm_insert_line CUR Strings[110] #define parm_left_cursor CUR Strings[111] #define parm_right_cursor CUR Strings[112] #define parm_rindex CUR Strings[113] #define parm_up_cursor CUR Strings[114] #define pkey_key CUR Strings[115] #define pkey_local CUR Strings[116] #define pkey_xmit CUR Strings[117] #define print_screen CUR Strings[118] #define prtr_off CUR Strings[119] #define prtr_on CUR Strings[120] #define repeat_char CUR Strings[121] #define reset_1string CUR Strings[122] #define reset_2string CUR Strings[123] #define reset_3string CUR Strings[124] #define reset_file CUR Strings[125] #define restore_cursor CUR Strings[126] #define row_address CUR Strings[127] #define save_cursor CUR Strings[128] #define scroll_forward CUR Strings[129] #define scroll_reverse CUR Strings[130] #define set_attributes CUR Strings[131] #define set_tab CUR Strings[132] #define set_window CUR Strings[133] #define tab CUR Strings[134] #define to_status_line CUR Strings[135] #define underline_char CUR Strings[136] #define up_half_line CUR Strings[137] #define init_prog CUR Strings[138] #define key_a1 CUR Strings[139] #define key_a3 CUR Strings[140] #define key_b2 CUR Strings[141] #define key_c1 CUR Strings[142] #define key_c3 CUR Strings[143] #define prtr_non CUR Strings[144] #define char_padding CUR Strings[145] #define acs_chars CUR Strings[146] #define plab_norm CUR Strings[147] #define key_btab CUR Strings[148] #define enter_xon_mode CUR Strings[149] #define exit_xon_mode CUR Strings[150] #define enter_am_mode CUR Strings[151] #define exit_am_mode CUR Strings[152] #define xon_character CUR Strings[153] #define xoff_character CUR Strings[154] #define ena_acs CUR Strings[155] #define label_on CUR Strings[156] #define label_off CUR Strings[157] #define key_beg CUR Strings[158] #define key_cancel CUR Strings[159] #define key_close CUR Strings[160] #define key_command CUR Strings[161] #define key_copy CUR Strings[162] #define key_create CUR Strings[163] #define key_end CUR Strings[164] #define key_enter CUR Strings[165] #define key_exit CUR Strings[166] #define key_find CUR Strings[167] #define key_help CUR Strings[168] #define key_mark CUR Strings[169] #define key_message CUR Strings[170] #define key_move CUR Strings[171] #define key_next CUR Strings[172] #define key_open CUR Strings[173] #define key_options CUR Strings[174] #define key_previous CUR Strings[175] #define key_print CUR Strings[176] #define key_redo CUR Strings[177] #define key_reference CUR Strings[178] #define key_refresh CUR Strings[179] #define key_replace CUR Strings[180] #define key_restart CUR Strings[181] #define key_resume CUR Strings[182] #define key_save CUR Strings[183] #define key_suspend CUR Strings[184] #define key_undo CUR Strings[185] #define key_sbeg CUR Strings[186] #define key_scancel CUR Strings[187] #define key_scommand CUR Strings[188] #define key_scopy CUR Strings[189] #define key_screate CUR Strings[190] #define key_sdc CUR Strings[191] #define key_sdl CUR Strings[192] #define key_select CUR Strings[193] #define key_send CUR Strings[194] #define key_seol CUR Strings[195] #define key_sexit CUR Strings[196] #define key_sfind CUR Strings[197] #define key_shelp CUR Strings[198] #define key_shome CUR Strings[199] #define key_sic CUR Strings[200] #define key_sleft CUR Strings[201] #define key_smessage CUR Strings[202] #define key_smove CUR Strings[203] #define key_snext CUR Strings[204] #define key_soptions CUR Strings[205] #define key_sprevious CUR Strings[206] #define key_sprint CUR Strings[207] #define key_sredo CUR Strings[208] #define key_sreplace CUR Strings[209] #define key_sright CUR Strings[210] #define key_srsume CUR Strings[211] #define key_ssave CUR Strings[212] #define key_ssuspend CUR Strings[213] #define key_sundo CUR Strings[214] #define req_for_input CUR Strings[215] #define key_f11 CUR Strings[216] #define key_f12 CUR Strings[217] #define key_f13 CUR Strings[218] #define key_f14 CUR Strings[219] #define key_f15 CUR Strings[220] #define key_f16 CUR Strings[221] #define key_f17 CUR Strings[222] #define key_f18 CUR Strings[223] #define key_f19 CUR Strings[224] #define key_f20 CUR Strings[225] #define key_f21 CUR Strings[226] #define key_f22 CUR Strings[227] #define key_f23 CUR Strings[228] #define key_f24 CUR Strings[229] #define key_f25 CUR Strings[230] #define key_f26 CUR Strings[231] #define key_f27 CUR Strings[232] #define key_f28 CUR Strings[233] #define key_f29 CUR Strings[234] #define key_f30 CUR Strings[235] #define key_f31 CUR Strings[236] #define key_f32 CUR Strings[237] #define key_f33 CUR Strings[238] #define key_f34 CUR Strings[239] #define key_f35 CUR Strings[240] #define key_f36 CUR Strings[241] #define key_f37 CUR Strings[242] #define key_f38 CUR Strings[243] #define key_f39 CUR Strings[244] #define key_f40 CUR Strings[245] #define key_f41 CUR Strings[246] #define key_f42 CUR Strings[247] #define key_f43 CUR Strings[248] #define key_f44 CUR Strings[249] #define key_f45 CUR Strings[250] #define key_f46 CUR Strings[251] #define key_f47 CUR Strings[252] #define key_f48 CUR Strings[253] #define key_f49 CUR Strings[254] #define key_f50 CUR Strings[255] #define key_f51 CUR Strings[256] #define key_f52 CUR Strings[257] #define key_f53 CUR Strings[258] #define key_f54 CUR Strings[259] #define key_f55 CUR Strings[260] #define key_f56 CUR Strings[261] #define key_f57 CUR Strings[262] #define key_f58 CUR Strings[263] #define key_f59 CUR Strings[264] #define key_f60 CUR Strings[265] #define key_f61 CUR Strings[266] #define key_f62 CUR Strings[267] #define key_f63 CUR Strings[268] #define clr_bol CUR Strings[269] #define clear_margins CUR Strings[270] #define set_left_margin CUR Strings[271] #define set_right_margin CUR Strings[272] #define label_format CUR Strings[273] #define set_clock CUR Strings[274] #define display_clock CUR Strings[275] #define remove_clock CUR Strings[276] #define create_window CUR Strings[277] #define goto_window CUR Strings[278] #define hangup CUR Strings[279] #define dial_phone CUR Strings[280] #define quick_dial CUR Strings[281] #define tone CUR Strings[282] #define pulse CUR Strings[283] #define flash_hook CUR Strings[284] #define fixed_pause CUR Strings[285] #define wait_tone CUR Strings[286] #define user0 CUR Strings[287] #define user1 CUR Strings[288] #define user2 CUR Strings[289] #define user3 CUR Strings[290] #define user4 CUR Strings[291] #define user5 CUR Strings[292] #define user6 CUR Strings[293] #define user7 CUR Strings[294] #define user8 CUR Strings[295] #define user9 CUR Strings[296] #define orig_pair CUR Strings[297] #define orig_colors CUR Strings[298] #define initialize_color CUR Strings[299] #define initialize_pair CUR Strings[300] #define set_color_pair CUR Strings[301] #define set_foreground CUR Strings[302] #define set_background CUR Strings[303] #define change_char_pitch CUR Strings[304] #define change_line_pitch CUR Strings[305] #define change_res_horz CUR Strings[306] #define change_res_vert CUR Strings[307] #define define_char CUR Strings[308] #define enter_doublewide_mode CUR Strings[309] #define enter_draft_quality CUR Strings[310] #define enter_italics_mode CUR Strings[311] #define enter_leftward_mode CUR Strings[312] #define enter_micro_mode CUR Strings[313] #define enter_near_letter_quality CUR Strings[314] #define enter_normal_quality CUR Strings[315] #define enter_shadow_mode CUR Strings[316] #define enter_subscript_mode CUR Strings[317] #define enter_superscript_mode CUR Strings[318] #define enter_upward_mode CUR Strings[319] #define exit_doublewide_mode CUR Strings[320] #define exit_italics_mode CUR Strings[321] #define exit_leftward_mode CUR Strings[322] #define exit_micro_mode CUR Strings[323] #define exit_shadow_mode CUR Strings[324] #define exit_subscript_mode CUR Strings[325] #define exit_superscript_mode CUR Strings[326] #define exit_upward_mode CUR Strings[327] #define micro_column_address CUR Strings[328] #define micro_down CUR Strings[329] #define micro_left CUR Strings[330] #define micro_right CUR Strings[331] #define micro_row_address CUR Strings[332] #define micro_up CUR Strings[333] #define order_of_pins CUR Strings[334] #define parm_down_micro CUR Strings[335] #define parm_left_micro CUR Strings[336] #define parm_right_micro CUR Strings[337] #define parm_up_micro CUR Strings[338] #define select_char_set CUR Strings[339] #define set_bottom_margin CUR Strings[340] #define set_bottom_margin_parm CUR Strings[341] #define set_left_margin_parm CUR Strings[342] #define set_right_margin_parm CUR Strings[343] #define set_top_margin CUR Strings[344] #define set_top_margin_parm CUR Strings[345] #define start_bit_image CUR Strings[346] #define start_char_set_def CUR Strings[347] #define stop_bit_image CUR Strings[348] #define stop_char_set_def CUR Strings[349] #define subscript_characters CUR Strings[350] #define superscript_characters CUR Strings[351] #define these_cause_cr CUR Strings[352] #define zero_motion CUR Strings[353] #define char_set_names CUR Strings[354] #define key_mouse CUR Strings[355] #define mouse_info CUR Strings[356] #define req_mouse_pos CUR Strings[357] #define get_mouse CUR Strings[358] #define set_a_foreground CUR Strings[359] #define set_a_background CUR Strings[360] #define pkey_plab CUR Strings[361] #define device_type CUR Strings[362] #define code_set_init CUR Strings[363] #define set0_des_seq CUR Strings[364] #define set1_des_seq CUR Strings[365] #define set2_des_seq CUR Strings[366] #define set3_des_seq CUR Strings[367] #define set_lr_margin CUR Strings[368] #define set_tb_margin CUR Strings[369] #define bit_image_repeat CUR Strings[370] #define bit_image_newline CUR Strings[371] #define bit_image_carriage_return CUR Strings[372] #define color_names CUR Strings[373] #define define_bit_image_region CUR Strings[374] #define end_bit_image_region CUR Strings[375] #define set_color_band CUR Strings[376] #define set_page_length CUR Strings[377] #define display_pc_char CUR Strings[378] #define enter_pc_charset_mode CUR Strings[379] #define exit_pc_charset_mode CUR Strings[380] #define enter_scancode_mode CUR Strings[381] #define exit_scancode_mode CUR Strings[382] #define pc_term_options CUR Strings[383] #define scancode_escape CUR Strings[384] #define alt_scancode_esc CUR Strings[385] #define enter_horizontal_hl_mode CUR Strings[386] #define enter_left_hl_mode CUR Strings[387] #define enter_low_hl_mode CUR Strings[388] #define enter_right_hl_mode CUR Strings[389] #define enter_top_hl_mode CUR Strings[390] #define enter_vertical_hl_mode CUR Strings[391] #define set_a_attributes CUR Strings[392] #define set_pglen_inch CUR Strings[393] #define BOOLWRITE 37 #define NUMWRITE 33 #define STRWRITE 394 /* older synonyms for some capabilities */ #define beehive_glitch no_esc_ctlc #define teleray_glitch dest_tabs_magic_smso #define micro_char_size micro_col_size #ifdef __INTERNAL_CAPS_VISIBLE #define termcap_init2 CUR Strings[394] #define termcap_reset CUR Strings[395] #define magic_cookie_glitch_ul CUR Numbers[33] #define backspaces_with_bs CUR Booleans[37] #define crt_no_scrolling CUR Booleans[38] #define no_correctly_working_cr CUR Booleans[39] #define carriage_return_delay CUR Numbers[34] #define new_line_delay CUR Numbers[35] #define linefeed_if_not_lf CUR Strings[396] #define backspace_if_not_bs CUR Strings[397] #define gnu_has_meta_key CUR Booleans[40] #define linefeed_is_newline CUR Booleans[41] #define backspace_delay CUR Numbers[36] #define horizontal_tab_delay CUR Numbers[37] #define number_of_function_keys CUR Numbers[38] #define other_non_function_keys CUR Strings[398] #define arrow_key_map CUR Strings[399] #define has_hardware_tabs CUR Booleans[42] #define return_does_clr_eol CUR Booleans[43] #define acs_ulcorner CUR Strings[400] #define acs_llcorner CUR Strings[401] #define acs_urcorner CUR Strings[402] #define acs_lrcorner CUR Strings[403] #define acs_ltee CUR Strings[404] #define acs_rtee CUR Strings[405] #define acs_btee CUR Strings[406] #define acs_ttee CUR Strings[407] #define acs_hline CUR Strings[408] #define acs_vline CUR Strings[409] #define acs_plus CUR Strings[410] #define memory_lock CUR Strings[411] #define memory_unlock CUR Strings[412] #define box_chars_1 CUR Strings[413] #endif /* __INTERNAL_CAPS_VISIBLE */ /* * Predefined terminfo array sizes */ #define BOOLCOUNT 44 #define NUMCOUNT 39 #define STRCOUNT 414 /* used by code for comparing entries */ #define acs_chars_index 146 typedef struct termtype { /* in-core form of terminfo data */ char *term_names; /* str_table offset of term names */ char *str_table; /* pointer to string table */ NCURSES_SBOOL *Booleans; /* array of boolean values */ short *Numbers; /* array of integer values */ char **Strings; /* array of string offsets */ #if NCURSES_XNAMES char *ext_str_table; /* pointer to extended string table */ char **ext_Names; /* corresponding names */ unsigned short num_Booleans;/* count total Booleans */ unsigned short num_Numbers; /* count total Numbers */ unsigned short num_Strings; /* count total Strings */ unsigned short ext_Booleans;/* count extensions to Booleans */ unsigned short ext_Numbers; /* count extensions to Numbers */ unsigned short ext_Strings; /* count extensions to Strings */ #endif /* NCURSES_XNAMES */ } TERMTYPE; /* * The only reason these structures are visible is for read-only use. * Programs which modify the data are not, never were, portable across * curses implementations. */ #ifdef NCURSES_INTERNALS typedef struct termtype2 { /* in-core form of terminfo data */ char *term_names; /* str_table offset of term names */ char *str_table; /* pointer to string table */ NCURSES_SBOOL *Booleans; /* array of boolean values */ int *Numbers; /* array of integer values */ char **Strings; /* array of string offsets */ #if NCURSES_XNAMES char *ext_str_table; /* pointer to extended string table */ char **ext_Names; /* corresponding names */ unsigned short num_Booleans;/* count total Booleans */ unsigned short num_Numbers; /* count total Numbers */ unsigned short num_Strings; /* count total Strings */ unsigned short ext_Booleans;/* count extensions to Booleans */ unsigned short ext_Numbers; /* count extensions to Numbers */ unsigned short ext_Strings; /* count extensions to Strings */ #endif /* NCURSES_XNAMES */ } TERMTYPE2; typedef struct term { /* describe an actual terminal */ TERMTYPE type; /* terminal type description */ short Filedes; /* file description being written to */ TTY Ottyb; /* original state of the terminal */ TTY Nttyb; /* current state of the terminal */ int _baudrate; /* used to compute padding */ char * _termname; /* used for termname() */ TERMTYPE2 type2; /* extended terminal type description */ } TERMINAL; #else typedef struct term TERMINAL; #endif /* NCURSES_INTERNALS */ #if 0 && !0 extern NCURSES_EXPORT_VAR(TERMINAL *) cur_term; #elif 0 NCURSES_WRAPPED_VAR(TERMINAL *, cur_term); #define cur_term NCURSES_PUBLIC_VAR(cur_term()) #else extern NCURSES_EXPORT_VAR(TERMINAL *) cur_term; #endif #if 0 || 0 NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, boolnames); NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, boolcodes); NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, boolfnames); NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, numnames); NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, numcodes); NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, numfnames); NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, strnames); NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, strcodes); NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, strfnames); #define boolnames NCURSES_PUBLIC_VAR(boolnames()) #define boolcodes NCURSES_PUBLIC_VAR(boolcodes()) #define boolfnames NCURSES_PUBLIC_VAR(boolfnames()) #define numnames NCURSES_PUBLIC_VAR(numnames()) #define numcodes NCURSES_PUBLIC_VAR(numcodes()) #define numfnames NCURSES_PUBLIC_VAR(numfnames()) #define strnames NCURSES_PUBLIC_VAR(strnames()) #define strcodes NCURSES_PUBLIC_VAR(strcodes()) #define strfnames NCURSES_PUBLIC_VAR(strfnames()) #else extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) boolnames[]; extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) boolcodes[]; extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) boolfnames[]; extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) numnames[]; extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) numcodes[]; extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) numfnames[]; extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) strnames[]; extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) strcodes[]; extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) strfnames[]; #endif /* * These entrypoints are used only by the ncurses utilities such as tic. */ #ifdef NCURSES_INTERNALS extern NCURSES_EXPORT(int) _nc_set_tty_mode (TTY *buf); extern NCURSES_EXPORT(int) _nc_read_entry2 (const char * const, char * const, TERMTYPE2 *const); extern NCURSES_EXPORT(int) _nc_read_file_entry (const char *const, TERMTYPE2 *); extern NCURSES_EXPORT(int) _nc_read_termtype (TERMTYPE2 *, char *, int); extern NCURSES_EXPORT(char *) _nc_first_name (const char *const); extern NCURSES_EXPORT(int) _nc_name_match (const char *const, const char *const, const char *const); #endif /* NCURSES_INTERNALS */ /* * These entrypoints are used by tack. */ extern NCURSES_EXPORT(const TERMTYPE *) _nc_fallback (const char *); extern NCURSES_EXPORT(int) _nc_read_entry (const char * const, char * const, TERMTYPE *const); /* Normal entry points */ extern NCURSES_EXPORT(TERMINAL *) set_curterm (TERMINAL *); extern NCURSES_EXPORT(int) del_curterm (TERMINAL *); /* miscellaneous entry points */ extern NCURSES_EXPORT(int) restartterm (NCURSES_CONST char *, int, int *); extern NCURSES_EXPORT(int) setupterm (NCURSES_CONST char *,int,int *); /* terminfo entry points, also declared in curses.h */ #if !defined(__NCURSES_H) extern NCURSES_EXPORT(char *) tigetstr (NCURSES_CONST char *); extern NCURSES_EXPORT_VAR(char) ttytype[]; extern NCURSES_EXPORT(int) putp (const char *); extern NCURSES_EXPORT(int) tigetflag (NCURSES_CONST char *); extern NCURSES_EXPORT(int) tigetnum (NCURSES_CONST char *); #if 1 /* NCURSES_TPARM_VARARGS */ extern NCURSES_EXPORT(char *) tparm (NCURSES_CONST char *, ...); /* special */ #else extern NCURSES_EXPORT(char *) tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long); /* special */ extern NCURSES_EXPORT(char *) tparm_varargs (NCURSES_CONST char *, ...); /* special */ #endif extern NCURSES_EXPORT(char *) tiparm (const char *, ...); /* special */ #endif /* __NCURSES_H */ /* termcap database emulation (XPG4 uses const only for 2nd param of tgetent) */ #if !defined(NCURSES_TERMCAP_H_incl) extern NCURSES_EXPORT(char *) tgetstr (NCURSES_CONST char *, char **); extern NCURSES_EXPORT(char *) tgoto (const char *, int, int); extern NCURSES_EXPORT(int) tgetent (char *, const char *); extern NCURSES_EXPORT(int) tgetflag (NCURSES_CONST char *); extern NCURSES_EXPORT(int) tgetnum (NCURSES_CONST char *); extern NCURSES_EXPORT(int) tputs (const char *, int, int (*)(int)); #endif /* NCURSES_TERMCAP_H_incl */ /* * Include curses.h before term.h to enable these extensions. */ #if defined(NCURSES_SP_FUNCS) && (NCURSES_SP_FUNCS != 0) extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tigetstr) (SCREEN*, NCURSES_CONST char *); extern NCURSES_EXPORT(int) NCURSES_SP_NAME(putp) (SCREEN*, const char *); extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tigetflag) (SCREEN*, NCURSES_CONST char *); extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tigetnum) (SCREEN*, NCURSES_CONST char *); #if 1 /* NCURSES_TPARM_VARARGS */ extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tparm) (SCREEN*, NCURSES_CONST char *, ...); /* special */ #else extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tparm) (SCREEN*, NCURSES_CONST char *, long,long,long,long,long,long,long,long,long); /* special */ extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tparm_varargs) (SCREEN*, NCURSES_CONST char *, ...); /* special */ #endif /* termcap database emulation (XPG4 uses const only for 2nd param of tgetent) */ extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tgetstr) (SCREEN*, NCURSES_CONST char *, char **); extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tgoto) (SCREEN*, const char *, int, int); extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tgetent) (SCREEN*, char *, const char *); extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tgetflag) (SCREEN*, NCURSES_CONST char *); extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tgetnum) (SCREEN*, NCURSES_CONST char *); extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tputs) (SCREEN*, const char *, int, NCURSES_SP_OUTC); extern NCURSES_EXPORT(TERMINAL *) NCURSES_SP_NAME(set_curterm) (SCREEN*, TERMINAL *); extern NCURSES_EXPORT(int) NCURSES_SP_NAME(del_curterm) (SCREEN*, TERMINAL *); extern NCURSES_EXPORT(int) NCURSES_SP_NAME(restartterm) (SCREEN*, NCURSES_CONST char *, int, int *); #endif /* NCURSES_SP_FUNCS */ #ifdef __cplusplus } #endif #endif /* NCURSES_TERM_H_incl */ strings.h 0000644 00000011220 15146341150 0006402 0 ustar 00 /* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _STRINGS_H #define _STRINGS_H 1 #include <features.h> #define __need_size_t #include <stddef.h> /* Tell the caller that we provide correct C++ prototypes. */ #if defined __cplusplus && __GNUC_PREREQ (4, 4) # define __CORRECT_ISO_CPP_STRINGS_H_PROTO #endif __BEGIN_DECLS #if defined __USE_MISC || !defined __USE_XOPEN2K8 /* Compare N bytes of S1 and S2 (same as memcmp). */ extern int bcmp (const void *__s1, const void *__s2, size_t __n) __THROW __attribute_pure__ __nonnull ((1, 2)); /* Copy N bytes of SRC to DEST (like memmove, but args reversed). */ extern void bcopy (const void *__src, void *__dest, size_t __n) __THROW __nonnull ((1, 2)); /* Set N bytes of S to 0. */ extern void bzero (void *__s, size_t __n) __THROW __nonnull ((1)); /* Find the first occurrence of C in S (same as strchr). */ # ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO extern "C++" { extern char *index (char *__s, int __c) __THROW __asm ("index") __attribute_pure__ __nonnull ((1)); extern const char *index (const char *__s, int __c) __THROW __asm ("index") __attribute_pure__ __nonnull ((1)); # if defined __OPTIMIZE__ __extern_always_inline char * index (char *__s, int __c) __THROW { return __builtin_index (__s, __c); } __extern_always_inline const char * index (const char *__s, int __c) __THROW { return __builtin_index (__s, __c); } # endif } # else extern char *index (const char *__s, int __c) __THROW __attribute_pure__ __nonnull ((1)); # endif /* Find the last occurrence of C in S (same as strrchr). */ # ifdef __CORRECT_ISO_CPP_STRINGS_H_PROTO extern "C++" { extern char *rindex (char *__s, int __c) __THROW __asm ("rindex") __attribute_pure__ __nonnull ((1)); extern const char *rindex (const char *__s, int __c) __THROW __asm ("rindex") __attribute_pure__ __nonnull ((1)); # if defined __OPTIMIZE__ __extern_always_inline char * rindex (char *__s, int __c) __THROW { return __builtin_rindex (__s, __c); } __extern_always_inline const char * rindex (const char *__s, int __c) __THROW { return __builtin_rindex (__s, __c); } # endif } # else extern char *rindex (const char *__s, int __c) __THROW __attribute_pure__ __nonnull ((1)); # endif #endif #if defined __USE_MISC || !defined __USE_XOPEN2K8 || defined __USE_XOPEN2K8XSI /* Return the position of the first bit set in I, or 0 if none are set. The least-significant bit is position 1, the most-significant 32. */ extern int ffs (int __i) __THROW __attribute_const__; #endif /* The following two functions are non-standard but necessary for non-32 bit platforms. */ # ifdef __USE_MISC extern int ffsl (long int __l) __THROW __attribute_const__; __extension__ extern int ffsll (long long int __ll) __THROW __attribute_const__; # endif /* Compare S1 and S2, ignoring case. */ extern int strcasecmp (const char *__s1, const char *__s2) __THROW __attribute_pure__ __nonnull ((1, 2)); /* Compare no more than N chars of S1 and S2, ignoring case. */ extern int strncasecmp (const char *__s1, const char *__s2, size_t __n) __THROW __attribute_pure__ __nonnull ((1, 2)); #ifdef __USE_XOPEN2K8 /* POSIX.1-2008 extended locale interface (see locale.h). */ # include <bits/types/locale_t.h> /* Compare S1 and S2, ignoring case, using collation rules from LOC. */ extern int strcasecmp_l (const char *__s1, const char *__s2, locale_t __loc) __THROW __attribute_pure__ __nonnull ((1, 2, 3)); /* Compare no more than N chars of S1 and S2, ignoring case, using collation rules from LOC. */ extern int strncasecmp_l (const char *__s1, const char *__s2, size_t __n, locale_t __loc) __THROW __attribute_pure__ __nonnull ((1, 2, 4)); #endif __END_DECLS #if __GNUC_PREREQ (3,4) && __USE_FORTIFY_LEVEL > 0 \ && defined __fortify_function /* Functions with security checks. */ # if defined __USE_MISC || !defined __USE_XOPEN2K8 # include <bits/strings_fortified.h> # endif #endif #endif /* strings.h */ perf/perf_dlfilter.h 0000644 00000013152 15146341150 0010474 0 ustar 00 /* SPDX-License-Identifier: GPL-2.0 */ /* * perf_dlfilter.h: API for perf --dlfilter shared object * Copyright (c) 2021, Intel Corporation. */ #ifndef _LINUX_PERF_DLFILTER_H #define _LINUX_PERF_DLFILTER_H #include <linux/perf_event.h> #include <linux/types.h> /* Definitions for perf_dlfilter_sample flags */ enum { PERF_DLFILTER_FLAG_BRANCH = 1ULL << 0, PERF_DLFILTER_FLAG_CALL = 1ULL << 1, PERF_DLFILTER_FLAG_RETURN = 1ULL << 2, PERF_DLFILTER_FLAG_CONDITIONAL = 1ULL << 3, PERF_DLFILTER_FLAG_SYSCALLRET = 1ULL << 4, PERF_DLFILTER_FLAG_ASYNC = 1ULL << 5, PERF_DLFILTER_FLAG_INTERRUPT = 1ULL << 6, PERF_DLFILTER_FLAG_TX_ABORT = 1ULL << 7, PERF_DLFILTER_FLAG_TRACE_BEGIN = 1ULL << 8, PERF_DLFILTER_FLAG_TRACE_END = 1ULL << 9, PERF_DLFILTER_FLAG_IN_TX = 1ULL << 10, PERF_DLFILTER_FLAG_VMENTRY = 1ULL << 11, PERF_DLFILTER_FLAG_VMEXIT = 1ULL << 12, }; /* * perf sample event information (as per perf script and <linux/perf_event.h>) */ struct perf_dlfilter_sample { __u32 size; /* Size of this structure (for compatibility checking) */ __u16 ins_lat; /* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */ __u16 p_stage_cyc; /* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */ __u64 ip; __s32 pid; __s32 tid; __u64 time; __u64 addr; __u64 id; __u64 stream_id; __u64 period; __u64 weight; /* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */ __u64 transaction; /* Refer PERF_SAMPLE_TRANSACTION in <linux/perf_event.h> */ __u64 insn_cnt; /* For instructions-per-cycle (IPC) */ __u64 cyc_cnt; /* For instructions-per-cycle (IPC) */ __s32 cpu; __u32 flags; /* Refer PERF_DLFILTER_FLAG_* above */ __u64 data_src; /* Refer PERF_SAMPLE_DATA_SRC in <linux/perf_event.h> */ __u64 phys_addr; /* Refer PERF_SAMPLE_PHYS_ADDR in <linux/perf_event.h> */ __u64 data_page_size; /* Refer PERF_SAMPLE_DATA_PAGE_SIZE in <linux/perf_event.h> */ __u64 code_page_size; /* Refer PERF_SAMPLE_CODE_PAGE_SIZE in <linux/perf_event.h> */ __u64 cgroup; /* Refer PERF_SAMPLE_CGROUP in <linux/perf_event.h> */ __u8 cpumode; /* Refer CPUMODE_MASK etc in <linux/perf_event.h> */ __u8 addr_correlates_sym; /* True => resolve_addr() can be called */ __u16 misc; /* Refer perf_event_header in <linux/perf_event.h> */ __u32 raw_size; /* Refer PERF_SAMPLE_RAW in <linux/perf_event.h> */ const void *raw_data; /* Refer PERF_SAMPLE_RAW in <linux/perf_event.h> */ __u64 brstack_nr; /* Number of brstack entries */ const struct perf_branch_entry *brstack; /* Refer <linux/perf_event.h> */ __u64 raw_callchain_nr; /* Number of raw_callchain entries */ const __u64 *raw_callchain; /* Refer <linux/perf_event.h> */ const char *event; }; /* * Address location (as per perf script) */ struct perf_dlfilter_al { __u32 size; /* Size of this structure (for compatibility checking) */ __u32 symoff; const char *sym; __u64 addr; /* Mapped address (from dso) */ __u64 sym_start; __u64 sym_end; const char *dso; __u8 sym_binding; /* STB_LOCAL, STB_GLOBAL or STB_WEAK, refer <elf.h> */ __u8 is_64_bit; /* Only valid if dso is not NULL */ __u8 is_kernel_ip; /* True if in kernel space */ __u32 buildid_size; __u8 *buildid; /* Below members are only populated by resolve_ip() */ __u8 filtered; /* True if this sample event will be filtered out */ const char *comm; }; struct perf_dlfilter_fns { /* Return information about ip */ const struct perf_dlfilter_al *(*resolve_ip)(void *ctx); /* Return information about addr (if addr_correlates_sym) */ const struct perf_dlfilter_al *(*resolve_addr)(void *ctx); /* Return arguments from --dlarg option */ char **(*args)(void *ctx, int *dlargc); /* * Return information about address (al->size must be set before * calling). Returns 0 on success, -1 otherwise. */ __s32 (*resolve_address)(void *ctx, __u64 address, struct perf_dlfilter_al *al); /* Return instruction bytes and length */ const __u8 *(*insn)(void *ctx, __u32 *length); /* Return source file name and line number */ const char *(*srcline)(void *ctx, __u32 *line_number); /* Return perf_event_attr, refer <linux/perf_event.h> */ struct perf_event_attr *(*attr)(void *ctx); /* Read object code, return numbers of bytes read */ __s32 (*object_code)(void *ctx, __u64 ip, void *buf, __u32 len); /* Reserved */ void *(*reserved[120])(void *); }; /* * If implemented, 'start' will be called at the beginning, * before any calls to 'filter_event'. Return 0 to indicate success, * or return a negative error code. '*data' can be assigned for use * by other functions. 'ctx' is needed for calls to perf_dlfilter_fns, * but most perf_dlfilter_fns are not valid when called from 'start'. */ int start(void **data, void *ctx); /* * If implemented, 'stop' will be called at the end, * after any calls to 'filter_event'. Return 0 to indicate success, or * return a negative error code. 'data' is set by start(). 'ctx' is * needed for calls to perf_dlfilter_fns, but most perf_dlfilter_fns * are not valid when called from 'stop'. */ int stop(void *data, void *ctx); /* * If implemented, 'filter_event' will be called for each sample * event. Return 0 to keep the sample event, 1 to filter it out, or * return a negative error code. 'data' is set by start(). 'ctx' is * needed for calls to perf_dlfilter_fns. */ int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx); /* * The same as 'filter_event' except it is called before internal * filtering. */ int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx); /* * If implemented, return a one-line description of the filter, and optionally * a longer description. */ const char *filter_description(const char **long_description); #endif nss.h 0000644 00000003526 15146341150 0005526 0 ustar 00 /* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ /* Define interface to NSS. This is meant for the interface functions and for implementors of new services. */ #ifndef _NSS_H #define _NSS_H 1 #include <features.h> #include <stdint.h> __BEGIN_DECLS /* Possible results of lookup using a nss_* function. */ enum nss_status { NSS_STATUS_TRYAGAIN = -2, NSS_STATUS_UNAVAIL, NSS_STATUS_NOTFOUND, NSS_STATUS_SUCCESS, NSS_STATUS_RETURN }; /* Data structure used for the 'gethostbyname4_r' function. */ struct gaih_addrtuple { struct gaih_addrtuple *next; char *name; int family; uint32_t addr[4]; uint32_t scopeid; }; /* Overwrite service selection for database DBNAME using specification in STRING. This function should only be used by system programs which have to work around non-existing services (e.e., while booting). Attention: Using this function repeatedly will slowly eat up the whole memory since previous selection data cannot be freed. */ extern int __nss_configure_lookup (const char *__dbname, const char *__string) __THROW; __END_DECLS #endif /* nss.h */ c++/8/stdexcept 0000644 00000017447 15146341150 0007226 0 ustar 00 // Standard exception classes -*- C++ -*- // Copyright (C) 2001-2018 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/stdexcept * This is a Standard C++ Library header. */ // // ISO C++ 19.1 Exception classes // #ifndef _GLIBCXX_STDEXCEPT #define _GLIBCXX_STDEXCEPT 1 #pragma GCC system_header #include <exception> #include <string> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if _GLIBCXX_USE_DUAL_ABI #if _GLIBCXX_USE_CXX11_ABI // Emulates an old COW string when the new std::string is in use. struct __cow_string { union { const char* _M_p; char _M_bytes[sizeof(const char*)]; }; __cow_string(); __cow_string(const std::string&); __cow_string(const char*, size_t); __cow_string(const __cow_string&) _GLIBCXX_USE_NOEXCEPT; __cow_string& operator=(const __cow_string&) _GLIBCXX_USE_NOEXCEPT; ~__cow_string(); #if __cplusplus >= 201103L __cow_string(__cow_string&&) noexcept; __cow_string& operator=(__cow_string&&) noexcept; #endif }; typedef basic_string<char> __sso_string; #else // _GLIBCXX_USE_CXX11_ABI typedef basic_string<char> __cow_string; // Emulates a new SSO string when the old std::string is in use. struct __sso_string { struct __str { const char* _M_p; size_t _M_string_length; char _M_local_buf[16]; }; union { __str _M_s; char _M_bytes[sizeof(__str)]; }; __sso_string() _GLIBCXX_USE_NOEXCEPT; __sso_string(const std::string&); __sso_string(const char*, size_t); __sso_string(const __sso_string&); __sso_string& operator=(const __sso_string&); ~__sso_string(); #if __cplusplus >= 201103L __sso_string(__sso_string&&) noexcept; __sso_string& operator=(__sso_string&&) noexcept; #endif }; #endif // _GLIBCXX_USE_CXX11_ABI #else // _GLIBCXX_USE_DUAL_ABI typedef basic_string<char> __sso_string; typedef basic_string<char> __cow_string; #endif /** * @addtogroup exceptions * @{ */ /** Logic errors represent problems in the internal logic of a program; * in theory, these are preventable, and even detectable before the * program runs (e.g., violations of class invariants). * @brief One of two subclasses of exception. */ class logic_error : public exception { __cow_string _M_msg; public: /** Takes a character string describing the error. */ explicit logic_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit logic_error(const char*) _GLIBCXX_TXN_SAFE; #endif #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS logic_error(const logic_error&) _GLIBCXX_USE_NOEXCEPT; logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT; #endif virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause of * the current error (the same string passed to the ctor). */ virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; # ifdef _GLIBCXX_TM_TS_INTERNAL friend void* ::_txnal_logic_error_get_msg(void* e); # endif }; /** Thrown by the library, or by you, to report domain errors (domain in * the mathematical sense). */ class domain_error : public logic_error { public: explicit domain_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit domain_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~domain_error() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown to report invalid arguments to functions. */ class invalid_argument : public logic_error { public: explicit invalid_argument(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit invalid_argument(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~invalid_argument() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown when an object is constructed that would exceed its maximum * permitted size (e.g., a basic_string instance). */ class length_error : public logic_error { public: explicit length_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit length_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~length_error() _GLIBCXX_USE_NOEXCEPT; }; /** This represents an argument whose value is not within the expected * range (e.g., boundary checks in basic_string). */ class out_of_range : public logic_error { public: explicit out_of_range(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit out_of_range(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~out_of_range() _GLIBCXX_USE_NOEXCEPT; }; /** Runtime errors represent problems outside the scope of a program; * they cannot be easily predicted and can generally only be caught as * the program executes. * @brief One of two subclasses of exception. */ class runtime_error : public exception { __cow_string _M_msg; public: /** Takes a character string describing the error. */ explicit runtime_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit runtime_error(const char*) _GLIBCXX_TXN_SAFE; #endif #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS runtime_error(const runtime_error&) _GLIBCXX_USE_NOEXCEPT; runtime_error& operator=(const runtime_error&) _GLIBCXX_USE_NOEXCEPT; #endif virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause of * the current error (the same string passed to the ctor). */ virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; # ifdef _GLIBCXX_TM_TS_INTERNAL friend void* ::_txnal_runtime_error_get_msg(void* e); # endif }; /** Thrown to indicate range errors in internal computations. */ class range_error : public runtime_error { public: explicit range_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit range_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~range_error() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown to indicate arithmetic overflow. */ class overflow_error : public runtime_error { public: explicit overflow_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit overflow_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~overflow_error() _GLIBCXX_USE_NOEXCEPT; }; /** Thrown to indicate arithmetic underflow. */ class underflow_error : public runtime_error { public: explicit underflow_error(const string& __arg) _GLIBCXX_TXN_SAFE; #if __cplusplus >= 201103L explicit underflow_error(const char*) _GLIBCXX_TXN_SAFE; #endif virtual ~underflow_error() _GLIBCXX_USE_NOEXCEPT; }; // @} group exceptions _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _GLIBCXX_STDEXCEPT */ c++/8/deque 0000644 00000005151 15146341150 0006313 0 ustar 00 // <deque> -*- C++ -*- // Copyright (C) 2001-2018 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) 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/deque * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_DEQUE #define _GLIBCXX_DEQUE 1 #pragma GCC system_header #include <bits/stl_algobase.h> #include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> #include <bits/stl_deque.h> #include <bits/range_access.h> #include <bits/deque.tcc> #ifdef _GLIBCXX_DEBUG # include <debug/deque> #endif #ifdef _GLIBCXX_PROFILE # include <profile/deque> #endif #endif /* _GLIBCXX_DEQUE */ c++/8/functional 0000644 00000111566 15146341150 0007362 0 ustar 00 // <functional> -*- C++ -*- // Copyright (C) 2001-2018 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) 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/functional * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_FUNCTIONAL #define _GLIBCXX_FUNCTIONAL 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/stl_function.h> #if __cplusplus >= 201103L #include <new> #include <tuple> #include <type_traits> #include <bits/functional_hash.h> #include <bits/invoke.h> #include <bits/refwrap.h> // std::reference_wrapper and _Mem_fn_traits #include <bits/std_function.h> // std::function #if __cplusplus > 201402L # include <unordered_map> # include <vector> # include <array> # include <utility> # include <bits/stl_algo.h> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus > 201402L # define __cpp_lib_invoke 201411 /// Invoke a callable object. template<typename _Callable, typename... _Args> inline invoke_result_t<_Callable, _Args...> invoke(_Callable&& __fn, _Args&&... __args) noexcept(is_nothrow_invocable_v<_Callable, _Args...>) { return std::__invoke(std::forward<_Callable>(__fn), std::forward<_Args>(__args)...); } #endif template<typename _MemFunPtr, bool __is_mem_fn = is_member_function_pointer<_MemFunPtr>::value> class _Mem_fn_base : public _Mem_fn_traits<_MemFunPtr>::__maybe_type { using _Traits = _Mem_fn_traits<_MemFunPtr>; using _Arity = typename _Traits::__arity; using _Varargs = typename _Traits::__vararg; template<typename _Func, typename... _BoundArgs> friend struct _Bind_check_arity; _MemFunPtr _M_pmf; public: using result_type = typename _Traits::__result_type; explicit constexpr _Mem_fn_base(_MemFunPtr __pmf) noexcept : _M_pmf(__pmf) { } template<typename... _Args> auto operator()(_Args&&... __args) const noexcept(noexcept( std::__invoke(_M_pmf, std::forward<_Args>(__args)...))) -> decltype(std::__invoke(_M_pmf, std::forward<_Args>(__args)...)) { return std::__invoke(_M_pmf, std::forward<_Args>(__args)...); } }; // Partial specialization for member object pointers. template<typename _MemObjPtr> class _Mem_fn_base<_MemObjPtr, false> { using _Arity = integral_constant<size_t, 0>; using _Varargs = false_type; template<typename _Func, typename... _BoundArgs> friend struct _Bind_check_arity; _MemObjPtr _M_pm; public: explicit constexpr _Mem_fn_base(_MemObjPtr __pm) noexcept : _M_pm(__pm) { } template<typename _Tp> auto operator()(_Tp&& __obj) const noexcept(noexcept(std::__invoke(_M_pm, std::forward<_Tp>(__obj)))) -> decltype(std::__invoke(_M_pm, std::forward<_Tp>(__obj))) { return std::__invoke(_M_pm, std::forward<_Tp>(__obj)); } }; template<typename _MemberPointer> struct _Mem_fn; // undefined template<typename _Res, typename _Class> struct _Mem_fn<_Res _Class::*> : _Mem_fn_base<_Res _Class::*> { using _Mem_fn_base<_Res _Class::*>::_Mem_fn_base; }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2048. Unnecessary mem_fn overloads /** * @brief Returns a function object that forwards to the member * pointer @a pm. * @ingroup functors */ template<typename _Tp, typename _Class> inline _Mem_fn<_Tp _Class::*> mem_fn(_Tp _Class::* __pm) noexcept { return _Mem_fn<_Tp _Class::*>(__pm); } /** * @brief Determines if the given type _Tp is a function object that * should be treated as a subexpression when evaluating calls to * function objects returned by bind(). * * C++11 [func.bind.isbind]. * @ingroup binders */ template<typename _Tp> struct is_bind_expression : public false_type { }; /** * @brief Determines if the given type _Tp is a placeholder in a * bind() expression and, if so, which placeholder it is. * * C++11 [func.bind.isplace]. * @ingroup binders */ template<typename _Tp> struct is_placeholder : public integral_constant<int, 0> { }; #if __cplusplus > 201402L template <typename _Tp> inline constexpr bool is_bind_expression_v = is_bind_expression<_Tp>::value; template <typename _Tp> inline constexpr int is_placeholder_v = is_placeholder<_Tp>::value; #endif // C++17 /** @brief The type of placeholder objects defined by libstdc++. * @ingroup binders */ template<int _Num> struct _Placeholder { }; /** @namespace std::placeholders * @brief ISO C++11 entities sub-namespace for functional. * @ingroup binders */ namespace placeholders { /* Define a large number of placeholders. There is no way to * simplify this with variadic templates, because we're introducing * unique names for each. */ extern const _Placeholder<1> _1; extern const _Placeholder<2> _2; extern const _Placeholder<3> _3; extern const _Placeholder<4> _4; extern const _Placeholder<5> _5; extern const _Placeholder<6> _6; extern const _Placeholder<7> _7; extern const _Placeholder<8> _8; extern const _Placeholder<9> _9; extern const _Placeholder<10> _10; extern const _Placeholder<11> _11; extern const _Placeholder<12> _12; extern const _Placeholder<13> _13; extern const _Placeholder<14> _14; extern const _Placeholder<15> _15; extern const _Placeholder<16> _16; extern const _Placeholder<17> _17; extern const _Placeholder<18> _18; extern const _Placeholder<19> _19; extern const _Placeholder<20> _20; extern const _Placeholder<21> _21; extern const _Placeholder<22> _22; extern const _Placeholder<23> _23; extern const _Placeholder<24> _24; extern const _Placeholder<25> _25; extern const _Placeholder<26> _26; extern const _Placeholder<27> _27; extern const _Placeholder<28> _28; extern const _Placeholder<29> _29; } /** * Partial specialization of is_placeholder that provides the placeholder * number for the placeholder objects defined by libstdc++. * @ingroup binders */ template<int _Num> struct is_placeholder<_Placeholder<_Num> > : public integral_constant<int, _Num> { }; template<int _Num> struct is_placeholder<const _Placeholder<_Num> > : public integral_constant<int, _Num> { }; // Like tuple_element_t but SFINAE-friendly. template<std::size_t __i, typename _Tuple> using _Safe_tuple_element_t = typename enable_if<(__i < tuple_size<_Tuple>::value), tuple_element<__i, _Tuple>>::type::type; /** * Maps an argument to bind() into an actual argument to the bound * function object [func.bind.bind]/10. Only the first parameter should * be specified: the rest are used to determine among the various * implementations. Note that, although this class is a function * object, it isn't entirely normal because it takes only two * parameters regardless of the number of parameters passed to the * bind expression. The first parameter is the bound argument and * the second parameter is a tuple containing references to the * rest of the arguments. */ template<typename _Arg, bool _IsBindExp = is_bind_expression<_Arg>::value, bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)> class _Mu; /** * If the argument is reference_wrapper<_Tp>, returns the * underlying reference. * C++11 [func.bind.bind] p10 bullet 1. */ template<typename _Tp> class _Mu<reference_wrapper<_Tp>, false, false> { public: /* Note: This won't actually work for const volatile * reference_wrappers, because reference_wrapper::get() is const * but not volatile-qualified. This might be a defect in the TR. */ template<typename _CVRef, typename _Tuple> _Tp& operator()(_CVRef& __arg, _Tuple&) const volatile { return __arg.get(); } }; /** * If the argument is a bind expression, we invoke the underlying * function object with the same cv-qualifiers as we are given and * pass along all of our arguments (unwrapped). * C++11 [func.bind.bind] p10 bullet 2. */ template<typename _Arg> class _Mu<_Arg, true, false> { public: template<typename _CVArg, typename... _Args> auto operator()(_CVArg& __arg, tuple<_Args...>& __tuple) const volatile -> decltype(__arg(declval<_Args>()...)) { // Construct an index tuple and forward to __call typedef typename _Build_index_tuple<sizeof...(_Args)>::__type _Indexes; return this->__call(__arg, __tuple, _Indexes()); } private: // Invokes the underlying function object __arg by unpacking all // of the arguments in the tuple. template<typename _CVArg, typename... _Args, std::size_t... _Indexes> auto __call(_CVArg& __arg, tuple<_Args...>& __tuple, const _Index_tuple<_Indexes...>&) const volatile -> decltype(__arg(declval<_Args>()...)) { return __arg(std::get<_Indexes>(std::move(__tuple))...); } }; /** * If the argument is a placeholder for the Nth argument, returns * a reference to the Nth argument to the bind function object. * C++11 [func.bind.bind] p10 bullet 3. */ template<typename _Arg> class _Mu<_Arg, false, true> { public: template<typename _Tuple> _Safe_tuple_element_t<(is_placeholder<_Arg>::value - 1), _Tuple>&& operator()(const volatile _Arg&, _Tuple& __tuple) const volatile { return ::std::get<(is_placeholder<_Arg>::value - 1)>(std::move(__tuple)); } }; /** * If the argument is just a value, returns a reference to that * value. The cv-qualifiers on the reference are determined by the caller. * C++11 [func.bind.bind] p10 bullet 4. */ template<typename _Arg> class _Mu<_Arg, false, false> { public: template<typename _CVArg, typename _Tuple> _CVArg&& operator()(_CVArg&& __arg, _Tuple&) const volatile { return std::forward<_CVArg>(__arg); } }; // std::get<I> for volatile-qualified tuples template<std::size_t _Ind, typename... _Tp> inline auto __volget(volatile tuple<_Tp...>& __tuple) -> __tuple_element_t<_Ind, tuple<_Tp...>> volatile& { return std::get<_Ind>(const_cast<tuple<_Tp...>&>(__tuple)); } // std::get<I> for const-volatile-qualified tuples template<std::size_t _Ind, typename... _Tp> inline auto __volget(const volatile tuple<_Tp...>& __tuple) -> __tuple_element_t<_Ind, tuple<_Tp...>> const volatile& { return std::get<_Ind>(const_cast<const tuple<_Tp...>&>(__tuple)); } /// Type of the function object returned from bind(). template<typename _Signature> struct _Bind; template<typename _Functor, typename... _Bound_args> class _Bind<_Functor(_Bound_args...)> : public _Weak_result_type<_Functor> { typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type _Bound_indexes; _Functor _M_f; tuple<_Bound_args...> _M_bound_args; // Call unqualified template<typename _Result, typename... _Args, std::size_t... _Indexes> _Result __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { return std::__invoke(_M_f, _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)... ); } // Call as const template<typename _Result, typename... _Args, std::size_t... _Indexes> _Result __call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { return std::__invoke(_M_f, _Mu<_Bound_args>()(std::get<_Indexes>(_M_bound_args), __args)... ); } // Call as volatile template<typename _Result, typename... _Args, std::size_t... _Indexes> _Result __call_v(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { return std::__invoke(_M_f, _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)... ); } // Call as const volatile template<typename _Result, typename... _Args, std::size_t... _Indexes> _Result __call_c_v(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { return std::__invoke(_M_f, _Mu<_Bound_args>()(__volget<_Indexes>(_M_bound_args), __args)... ); } template<typename _BoundArg, typename _CallArgs> using _Mu_type = decltype( _Mu<typename remove_cv<_BoundArg>::type>()( std::declval<_BoundArg&>(), std::declval<_CallArgs&>()) ); template<typename _Fn, typename _CallArgs, typename... _BArgs> using _Res_type_impl = typename result_of< _Fn&(_Mu_type<_BArgs, _CallArgs>&&...) >::type; template<typename _CallArgs> using _Res_type = _Res_type_impl<_Functor, _CallArgs, _Bound_args...>; template<typename _CallArgs> using __dependent = typename enable_if<bool(tuple_size<_CallArgs>::value+1), _Functor>::type; template<typename _CallArgs, template<class> class __cv_quals> using _Res_type_cv = _Res_type_impl< typename __cv_quals<__dependent<_CallArgs>>::type, _CallArgs, typename __cv_quals<_Bound_args>::type...>; public: template<typename... _Args> explicit _Bind(const _Functor& __f, _Args&&... __args) : _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...) { } template<typename... _Args> explicit _Bind(_Functor&& __f, _Args&&... __args) : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...) { } _Bind(const _Bind&) = default; _Bind(_Bind&& __b) : _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args)) { } // Call unqualified template<typename... _Args, typename _Result = _Res_type<tuple<_Args...>>> _Result operator()(_Args&&... __args) { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const template<typename... _Args, typename _Result = _Res_type_cv<tuple<_Args...>, add_const>> _Result operator()(_Args&&... __args) const { return this->__call_c<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } #if __cplusplus > 201402L # define _GLIBCXX_DEPR_BIND \ [[deprecated("std::bind does not support volatile in C++17")]] #else # define _GLIBCXX_DEPR_BIND #endif // Call as volatile template<typename... _Args, typename _Result = _Res_type_cv<tuple<_Args...>, add_volatile>> _GLIBCXX_DEPR_BIND _Result operator()(_Args&&... __args) volatile { return this->__call_v<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const volatile template<typename... _Args, typename _Result = _Res_type_cv<tuple<_Args...>, add_cv>> _GLIBCXX_DEPR_BIND _Result operator()(_Args&&... __args) const volatile { return this->__call_c_v<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } }; /// Type of the function object returned from bind<R>(). template<typename _Result, typename _Signature> struct _Bind_result; template<typename _Result, typename _Functor, typename... _Bound_args> class _Bind_result<_Result, _Functor(_Bound_args...)> { typedef typename _Build_index_tuple<sizeof...(_Bound_args)>::__type _Bound_indexes; _Functor _M_f; tuple<_Bound_args...> _M_bound_args; // sfinae types template<typename _Res> using __enable_if_void = typename enable_if<is_void<_Res>{}>::type; template<typename _Res> using __disable_if_void = typename enable_if<!is_void<_Res>{}, _Result>::type; // Call unqualified template<typename _Res, typename... _Args, std::size_t... _Indexes> __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { return std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call unqualified, return void template<typename _Res, typename... _Args, std::size_t... _Indexes> __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) { std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call as const template<typename _Res, typename... _Args, std::size_t... _Indexes> __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { return std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call as const, return void template<typename _Res, typename... _Args, std::size_t... _Indexes> __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const { std::__invoke(_M_f, _Mu<_Bound_args>() (std::get<_Indexes>(_M_bound_args), __args)...); } // Call as volatile template<typename _Res, typename... _Args, std::size_t... _Indexes> __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { return std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } // Call as volatile, return void template<typename _Res, typename... _Args, std::size_t... _Indexes> __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) volatile { std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } // Call as const volatile template<typename _Res, typename... _Args, std::size_t... _Indexes> __disable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { return std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } // Call as const volatile, return void template<typename _Res, typename... _Args, std::size_t... _Indexes> __enable_if_void<_Res> __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const volatile { std::__invoke(_M_f, _Mu<_Bound_args>() (__volget<_Indexes>(_M_bound_args), __args)...); } public: typedef _Result result_type; template<typename... _Args> explicit _Bind_result(const _Functor& __f, _Args&&... __args) : _M_f(__f), _M_bound_args(std::forward<_Args>(__args)...) { } template<typename... _Args> explicit _Bind_result(_Functor&& __f, _Args&&... __args) : _M_f(std::move(__f)), _M_bound_args(std::forward<_Args>(__args)...) { } _Bind_result(const _Bind_result&) = default; _Bind_result(_Bind_result&& __b) : _M_f(std::move(__b._M_f)), _M_bound_args(std::move(__b._M_bound_args)) { } // Call unqualified template<typename... _Args> result_type operator()(_Args&&... __args) { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const template<typename... _Args> result_type operator()(_Args&&... __args) const { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as volatile template<typename... _Args> _GLIBCXX_DEPR_BIND result_type operator()(_Args&&... __args) volatile { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } // Call as const volatile template<typename... _Args> _GLIBCXX_DEPR_BIND result_type operator()(_Args&&... __args) const volatile { return this->__call<_Result>( std::forward_as_tuple(std::forward<_Args>(__args)...), _Bound_indexes()); } }; #undef _GLIBCXX_DEPR_BIND /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template<typename _Signature> struct is_bind_expression<_Bind<_Signature> > : public true_type { }; /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template<typename _Signature> struct is_bind_expression<const _Bind<_Signature> > : public true_type { }; /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template<typename _Signature> struct is_bind_expression<volatile _Bind<_Signature> > : public true_type { }; /** * @brief Class template _Bind is always a bind expression. * @ingroup binders */ template<typename _Signature> struct is_bind_expression<const volatile _Bind<_Signature>> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template<typename _Result, typename _Signature> struct is_bind_expression<_Bind_result<_Result, _Signature>> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template<typename _Result, typename _Signature> struct is_bind_expression<const _Bind_result<_Result, _Signature>> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template<typename _Result, typename _Signature> struct is_bind_expression<volatile _Bind_result<_Result, _Signature>> : public true_type { }; /** * @brief Class template _Bind_result is always a bind expression. * @ingroup binders */ template<typename _Result, typename _Signature> struct is_bind_expression<const volatile _Bind_result<_Result, _Signature>> : public true_type { }; template<typename _Func, typename... _BoundArgs> struct _Bind_check_arity { }; template<typename _Ret, typename... _Args, typename... _BoundArgs> struct _Bind_check_arity<_Ret (*)(_Args...), _BoundArgs...> { static_assert(sizeof...(_BoundArgs) == sizeof...(_Args), "Wrong number of arguments for function"); }; template<typename _Ret, typename... _Args, typename... _BoundArgs> struct _Bind_check_arity<_Ret (*)(_Args......), _BoundArgs...> { static_assert(sizeof...(_BoundArgs) >= sizeof...(_Args), "Wrong number of arguments for function"); }; template<typename _Tp, typename _Class, typename... _BoundArgs> struct _Bind_check_arity<_Tp _Class::*, _BoundArgs...> { using _Arity = typename _Mem_fn<_Tp _Class::*>::_Arity; using _Varargs = typename _Mem_fn<_Tp _Class::*>::_Varargs; static_assert(_Varargs::value ? sizeof...(_BoundArgs) >= _Arity::value + 1 : sizeof...(_BoundArgs) == _Arity::value + 1, "Wrong number of arguments for pointer-to-member"); }; // Trait type used to remove std::bind() from overload set via SFINAE // when first argument has integer type, so that std::bind() will // not be a better match than ::bind() from the BSD Sockets API. template<typename _Tp, typename _Tp2 = typename decay<_Tp>::type> using __is_socketlike = __or_<is_integral<_Tp2>, is_enum<_Tp2>>; template<bool _SocketLike, typename _Func, typename... _BoundArgs> struct _Bind_helper : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...> { typedef typename decay<_Func>::type __func_type; typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type; }; // Partial specialization for is_socketlike == true, does not define // nested type so std::bind() will not participate in overload resolution // when the first argument might be a socket file descriptor. template<typename _Func, typename... _BoundArgs> struct _Bind_helper<true, _Func, _BoundArgs...> { }; /** * @brief Function template for std::bind. * @ingroup binders */ template<typename _Func, typename... _BoundArgs> inline typename _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type bind(_Func&& __f, _BoundArgs&&... __args) { typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type; return typename __helper_type::type(std::forward<_Func>(__f), std::forward<_BoundArgs>(__args)...); } template<typename _Result, typename _Func, typename... _BoundArgs> struct _Bindres_helper : _Bind_check_arity<typename decay<_Func>::type, _BoundArgs...> { typedef typename decay<_Func>::type __functor_type; typedef _Bind_result<_Result, __functor_type(typename decay<_BoundArgs>::type...)> type; }; /** * @brief Function template for std::bind<R>. * @ingroup binders */ template<typename _Result, typename _Func, typename... _BoundArgs> inline typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type bind(_Func&& __f, _BoundArgs&&... __args) { typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type; return typename __helper_type::type(std::forward<_Func>(__f), std::forward<_BoundArgs>(__args)...); } #if __cplusplus >= 201402L /// Generalized negator. template<typename _Fn> class _Not_fn { template<typename _Fn2, typename... _Args> using __inv_res_t = typename __invoke_result<_Fn2, _Args...>::type; template<typename _Tp> static decltype(!std::declval<_Tp>()) _S_not() noexcept(noexcept(!std::declval<_Tp>())); public: template<typename _Fn2> _Not_fn(_Fn2&& __fn, int) : _M_fn(std::forward<_Fn2>(__fn)) { } _Not_fn(const _Not_fn& __fn) = default; _Not_fn(_Not_fn&& __fn) = default; ~_Not_fn() = default; // Macro to define operator() with given cv-qualifiers ref-qualifiers, // forwarding _M_fn and the function arguments with the same qualifiers, // and deducing the return type and exception-specification. #define _GLIBCXX_NOT_FN_CALL_OP( _QUALS ) \ template<typename... _Args> \ decltype(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>()) \ operator()(_Args&&... __args) _QUALS \ noexcept(__is_nothrow_invocable<_Fn _QUALS, _Args...>::value \ && noexcept(_S_not<__inv_res_t<_Fn _QUALS, _Args...>>())) \ { \ return !std::__invoke(std::forward< _Fn _QUALS >(_M_fn), \ std::forward<_Args>(__args)...); \ } _GLIBCXX_NOT_FN_CALL_OP( & ) _GLIBCXX_NOT_FN_CALL_OP( const & ) _GLIBCXX_NOT_FN_CALL_OP( && ) _GLIBCXX_NOT_FN_CALL_OP( const && ) #undef _GLIBCXX_NOT_FN_CALL private: _Fn _M_fn; }; template<typename _Tp, typename _Pred> struct __is_byte_like : false_type { }; template<typename _Tp> struct __is_byte_like<_Tp, equal_to<_Tp>> : __bool_constant<sizeof(_Tp) == 1 && is_integral<_Tp>::value> { }; template<typename _Tp> struct __is_byte_like<_Tp, equal_to<void>> : __bool_constant<sizeof(_Tp) == 1 && is_integral<_Tp>::value> { }; #if __cplusplus >= 201703L // Declare std::byte (full definition is in <cstddef>). enum class byte : unsigned char; template<> struct __is_byte_like<byte, equal_to<byte>> : true_type { }; template<> struct __is_byte_like<byte, equal_to<void>> : true_type { }; #define __cpp_lib_not_fn 201603 /// [func.not_fn] Function template not_fn template<typename _Fn> inline auto not_fn(_Fn&& __fn) noexcept(std::is_nothrow_constructible<std::decay_t<_Fn>, _Fn&&>::value) { return _Not_fn<std::decay_t<_Fn>>{std::forward<_Fn>(__fn), 0}; } // Searchers #define __cpp_lib_boyer_moore_searcher 201603 template<typename _ForwardIterator1, typename _BinaryPredicate = equal_to<>> class default_searcher { public: default_searcher(_ForwardIterator1 __pat_first, _ForwardIterator1 __pat_last, _BinaryPredicate __pred = _BinaryPredicate()) : _M_m(__pat_first, __pat_last, std::move(__pred)) { } template<typename _ForwardIterator2> pair<_ForwardIterator2, _ForwardIterator2> operator()(_ForwardIterator2 __first, _ForwardIterator2 __last) const { _ForwardIterator2 __first_ret = std::search(__first, __last, std::get<0>(_M_m), std::get<1>(_M_m), std::get<2>(_M_m)); auto __ret = std::make_pair(__first_ret, __first_ret); if (__ret.first != __last) std::advance(__ret.second, std::distance(std::get<0>(_M_m), std::get<1>(_M_m))); return __ret; } private: tuple<_ForwardIterator1, _ForwardIterator1, _BinaryPredicate> _M_m; }; template<typename _Key, typename _Tp, typename _Hash, typename _Pred> struct __boyer_moore_map_base { template<typename _RAIter> __boyer_moore_map_base(_RAIter __pat, size_t __patlen, _Hash&& __hf, _Pred&& __pred) : _M_bad_char{ __patlen, std::move(__hf), std::move(__pred) } { if (__patlen > 0) for (__diff_type __i = 0; __i < __patlen - 1; ++__i) _M_bad_char[__pat[__i]] = __patlen - 1 - __i; } using __diff_type = _Tp; __diff_type _M_lookup(_Key __key, __diff_type __not_found) const { auto __iter = _M_bad_char.find(__key); if (__iter == _M_bad_char.end()) return __not_found; return __iter->second; } _Pred _M_pred() const { return _M_bad_char.key_eq(); } _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _Pred> _M_bad_char; }; template<typename _Tp, size_t _Len, typename _Pred> struct __boyer_moore_array_base { template<typename _RAIter, typename _Unused> __boyer_moore_array_base(_RAIter __pat, size_t __patlen, _Unused&&, _Pred&& __pred) : _M_bad_char{ _GLIBCXX_STD_C::array<_Tp, _Len>{}, std::move(__pred) } { std::get<0>(_M_bad_char).fill(__patlen); if (__patlen > 0) for (__diff_type __i = 0; __i < __patlen - 1; ++__i) { auto __ch = __pat[__i]; using _UCh = make_unsigned_t<decltype(__ch)>; auto __uch = static_cast<_UCh>(__ch); std::get<0>(_M_bad_char)[__uch] = __patlen - 1 - __i; } } using __diff_type = _Tp; template<typename _Key> __diff_type _M_lookup(_Key __key, __diff_type __not_found) const { auto __ukey = static_cast<make_unsigned_t<_Key>>(__key); if (__ukey >= _Len) return __not_found; return std::get<0>(_M_bad_char)[__ukey]; } const _Pred& _M_pred() const { return std::get<1>(_M_bad_char); } tuple<_GLIBCXX_STD_C::array<_Tp, _Len>, _Pred> _M_bad_char; }; // Use __boyer_moore_array_base when pattern consists of narrow characters // (or std::byte) and uses std::equal_to as the predicate. template<typename _RAIter, typename _Hash, typename _Pred, typename _Val = typename iterator_traits<_RAIter>::value_type, typename _Diff = typename iterator_traits<_RAIter>::difference_type> using __boyer_moore_base_t = conditional_t<__is_byte_like<_Val, _Pred>::value, __boyer_moore_array_base<_Diff, 256, _Pred>, __boyer_moore_map_base<_Val, _Diff, _Hash, _Pred>>; template<typename _RAIter, typename _Hash = hash<typename iterator_traits<_RAIter>::value_type>, typename _BinaryPredicate = equal_to<>> class boyer_moore_searcher : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> { using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; using typename _Base::__diff_type; public: boyer_moore_searcher(_RAIter __pat_first, _RAIter __pat_last, _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()); template<typename _RandomAccessIterator2> pair<_RandomAccessIterator2, _RandomAccessIterator2> operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const; private: bool _M_is_prefix(_RAIter __word, __diff_type __len, __diff_type __pos) { const auto& __pred = this->_M_pred(); __diff_type __suffixlen = __len - __pos; for (__diff_type __i = 0; __i < __suffixlen; ++__i) if (!__pred(__word[__i], __word[__pos + __i])) return false; return true; } __diff_type _M_suffix_length(_RAIter __word, __diff_type __len, __diff_type __pos) { const auto& __pred = this->_M_pred(); __diff_type __i = 0; while (__pred(__word[__pos - __i], __word[__len - 1 - __i]) && __i < __pos) { ++__i; } return __i; } template<typename _Tp> __diff_type _M_bad_char_shift(_Tp __c) const { return this->_M_lookup(__c, _M_pat_end - _M_pat); } _RAIter _M_pat; _RAIter _M_pat_end; _GLIBCXX_STD_C::vector<__diff_type> _M_good_suffix; }; template<typename _RAIter, typename _Hash = hash<typename iterator_traits<_RAIter>::value_type>, typename _BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher : __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate> { using _Base = __boyer_moore_base_t<_RAIter, _Hash, _BinaryPredicate>; using typename _Base::__diff_type; public: boyer_moore_horspool_searcher(_RAIter __pat, _RAIter __pat_end, _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), _M_pat(__pat), _M_pat_end(__pat_end) { } template<typename _RandomAccessIterator2> pair<_RandomAccessIterator2, _RandomAccessIterator2> operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { const auto& __pred = this->_M_pred(); auto __patlen = _M_pat_end - _M_pat; if (__patlen == 0) return std::make_pair(__first, __first); auto __len = __last - __first; while (__len >= __patlen) { for (auto __scan = __patlen - 1; __pred(__first[__scan], _M_pat[__scan]); --__scan) if (__scan == 0) return std::make_pair(__first, __first + __patlen); auto __shift = _M_bad_char_shift(__first[__patlen - 1]); __len -= __shift; __first += __shift; } return std::make_pair(__last, __last); } private: template<typename _Tp> __diff_type _M_bad_char_shift(_Tp __c) const { return this->_M_lookup(__c, _M_pat_end - _M_pat); } _RAIter _M_pat; _RAIter _M_pat_end; }; template<typename _RAIter, typename _Hash, typename _BinaryPredicate> boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: boyer_moore_searcher(_RAIter __pat, _RAIter __pat_end, _Hash __hf, _BinaryPredicate __pred) : _Base(__pat, __pat_end - __pat, std::move(__hf), std::move(__pred)), _M_pat(__pat), _M_pat_end(__pat_end), _M_good_suffix(__pat_end - __pat) { auto __patlen = __pat_end - __pat; if (__patlen == 0) return; __diff_type __last_prefix = __patlen - 1; for (__diff_type __p = __patlen - 1; __p >= 0; --__p) { if (_M_is_prefix(__pat, __patlen, __p + 1)) __last_prefix = __p + 1; _M_good_suffix[__p] = __last_prefix + (__patlen - 1 - __p); } for (__diff_type __p = 0; __p < __patlen - 1; ++__p) { auto __slen = _M_suffix_length(__pat, __patlen, __p); auto __pos = __patlen - 1 - __slen; if (!__pred(__pat[__p - __slen], __pat[__pos])) _M_good_suffix[__pos] = __patlen - 1 - __p + __slen; } } template<typename _RAIter, typename _Hash, typename _BinaryPredicate> template<typename _RandomAccessIterator2> pair<_RandomAccessIterator2, _RandomAccessIterator2> boyer_moore_searcher<_RAIter, _Hash, _BinaryPredicate>:: operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { auto __patlen = _M_pat_end - _M_pat; if (__patlen == 0) return std::make_pair(__first, __first); const auto& __pred = this->_M_pred(); __diff_type __i = __patlen - 1; auto __stringlen = __last - __first; while (__i < __stringlen) { __diff_type __j = __patlen - 1; while (__j >= 0 && __pred(__first[__i], _M_pat[__j])) { --__i; --__j; } if (__j < 0) { const auto __match = __first + __i + 1; return std::make_pair(__match, __match + __patlen); } __i += std::max(_M_bad_char_shift(__first[__i]), _M_good_suffix[__j]); } return std::make_pair(__last, __last); } #endif // C++17 #endif // C++14 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_FUNCTIONAL c++/8/type_traits 0000644 00000247557 15146341150 0007601 0 ustar 00 // C++11 <type_traits> -*- C++ -*- // Copyright (C) 2007-2018 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/type_traits * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_TYPE_TRAITS #define _GLIBCXX_TYPE_TRAITS 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <bits/c++config.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup metaprogramming Metaprogramming * @ingroup utilities * * Template utilities for compile-time introspection and modification, * including type classification traits, type property inspection traits * and type transformation traits. * * @{ */ /// integral_constant template<typename _Tp, _Tp __v> struct integral_constant { static constexpr _Tp value = __v; typedef _Tp value_type; typedef integral_constant<_Tp, __v> type; constexpr operator value_type() const noexcept { return value; } #if __cplusplus > 201103L #define __cpp_lib_integral_constant_callable 201304 constexpr value_type operator()() const noexcept { return value; } #endif }; template<typename _Tp, _Tp __v> constexpr _Tp integral_constant<_Tp, __v>::value; /// The type used as a compile-time boolean with true value. typedef integral_constant<bool, true> true_type; /// The type used as a compile-time boolean with false value. typedef integral_constant<bool, false> false_type; template<bool __v> using __bool_constant = integral_constant<bool, __v>; #if __cplusplus > 201402L # define __cpp_lib_bool_constant 201505 template<bool __v> using bool_constant = integral_constant<bool, __v>; #endif // Meta programming helper types. template<bool, typename, typename> struct conditional; template<typename...> struct __or_; template<> struct __or_<> : public false_type { }; template<typename _B1> struct __or_<_B1> : public _B1 { }; template<typename _B1, typename _B2> struct __or_<_B1, _B2> : public conditional<_B1::value, _B1, _B2>::type { }; template<typename _B1, typename _B2, typename _B3, typename... _Bn> struct __or_<_B1, _B2, _B3, _Bn...> : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type { }; template<typename...> struct __and_; template<> struct __and_<> : public true_type { }; template<typename _B1> struct __and_<_B1> : public _B1 { }; template<typename _B1, typename _B2> struct __and_<_B1, _B2> : public conditional<_B1::value, _B2, _B1>::type { }; template<typename _B1, typename _B2, typename _B3, typename... _Bn> struct __and_<_B1, _B2, _B3, _Bn...> : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type { }; template<typename _Pp> struct __not_ : public __bool_constant<!bool(_Pp::value)> { }; #if __cplusplus >= 201703L #define __cpp_lib_logical_traits 201510 template<typename... _Bn> struct conjunction : __and_<_Bn...> { }; template<typename... _Bn> struct disjunction : __or_<_Bn...> { }; template<typename _Pp> struct negation : __not_<_Pp> { }; template<typename... _Bn> inline constexpr bool conjunction_v = conjunction<_Bn...>::value; template<typename... _Bn> inline constexpr bool disjunction_v = disjunction<_Bn...>::value; template<typename _Pp> inline constexpr bool negation_v = negation<_Pp>::value; #endif // C++17 // For several sfinae-friendly trait implementations we transport both the // result information (as the member type) and the failure information (no // member type). This is very similar to std::enable_if, but we cannot use // them, because we need to derive from them as an implementation detail. template<typename _Tp> struct __success_type { typedef _Tp type; }; struct __failure_type { }; // Primary type categories. template<typename> struct remove_cv; template<typename> struct __is_void_helper : public false_type { }; template<> struct __is_void_helper<void> : public true_type { }; /// is_void template<typename _Tp> struct is_void : public __is_void_helper<typename remove_cv<_Tp>::type>::type { }; template<typename> struct __is_integral_helper : public false_type { }; template<> struct __is_integral_helper<bool> : public true_type { }; template<> struct __is_integral_helper<char> : public true_type { }; template<> struct __is_integral_helper<signed char> : public true_type { }; template<> struct __is_integral_helper<unsigned char> : public true_type { }; #ifdef _GLIBCXX_USE_WCHAR_T template<> struct __is_integral_helper<wchar_t> : public true_type { }; #endif template<> struct __is_integral_helper<char16_t> : public true_type { }; template<> struct __is_integral_helper<char32_t> : public true_type { }; template<> struct __is_integral_helper<short> : public true_type { }; template<> struct __is_integral_helper<unsigned short> : public true_type { }; template<> struct __is_integral_helper<int> : public true_type { }; template<> struct __is_integral_helper<unsigned int> : public true_type { }; template<> struct __is_integral_helper<long> : public true_type { }; template<> struct __is_integral_helper<unsigned long> : public true_type { }; template<> struct __is_integral_helper<long long> : public true_type { }; template<> struct __is_integral_helper<unsigned long long> : public true_type { }; // Conditionalizing on __STRICT_ANSI__ here will break any port that // uses one of these types for size_t. #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0> : public true_type { }; template<> struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_0> : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1> : public true_type { }; template<> struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_1> : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2> : public true_type { }; template<> struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_2> : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3> : public true_type { }; template<> struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_3> : public true_type { }; #endif /// is_integral template<typename _Tp> struct is_integral : public __is_integral_helper<typename remove_cv<_Tp>::type>::type { }; template<typename> struct __is_floating_point_helper : public false_type { }; template<> struct __is_floating_point_helper<float> : public true_type { }; template<> struct __is_floating_point_helper<double> : public true_type { }; template<> struct __is_floating_point_helper<long double> : public true_type { }; #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) template<> struct __is_floating_point_helper<__float128> : public true_type { }; #endif /// is_floating_point template<typename _Tp> struct is_floating_point : public __is_floating_point_helper<typename remove_cv<_Tp>::type>::type { }; /// is_array template<typename> struct is_array : public false_type { }; template<typename _Tp, std::size_t _Size> struct is_array<_Tp[_Size]> : public true_type { }; template<typename _Tp> struct is_array<_Tp[]> : public true_type { }; template<typename> struct __is_pointer_helper : public false_type { }; template<typename _Tp> struct __is_pointer_helper<_Tp*> : public true_type { }; /// is_pointer template<typename _Tp> struct is_pointer : public __is_pointer_helper<typename remove_cv<_Tp>::type>::type { }; /// is_lvalue_reference template<typename> struct is_lvalue_reference : public false_type { }; template<typename _Tp> struct is_lvalue_reference<_Tp&> : public true_type { }; /// is_rvalue_reference template<typename> struct is_rvalue_reference : public false_type { }; template<typename _Tp> struct is_rvalue_reference<_Tp&&> : public true_type { }; template<typename> struct is_function; template<typename> struct __is_member_object_pointer_helper : public false_type { }; template<typename _Tp, typename _Cp> struct __is_member_object_pointer_helper<_Tp _Cp::*> : public integral_constant<bool, !is_function<_Tp>::value> { }; /// is_member_object_pointer template<typename _Tp> struct is_member_object_pointer : public __is_member_object_pointer_helper< typename remove_cv<_Tp>::type>::type { }; template<typename> struct __is_member_function_pointer_helper : public false_type { }; template<typename _Tp, typename _Cp> struct __is_member_function_pointer_helper<_Tp _Cp::*> : public integral_constant<bool, is_function<_Tp>::value> { }; /// is_member_function_pointer template<typename _Tp> struct is_member_function_pointer : public __is_member_function_pointer_helper< typename remove_cv<_Tp>::type>::type { }; /// is_enum template<typename _Tp> struct is_enum : public integral_constant<bool, __is_enum(_Tp)> { }; /// is_union template<typename _Tp> struct is_union : public integral_constant<bool, __is_union(_Tp)> { }; /// is_class template<typename _Tp> struct is_class : public integral_constant<bool, __is_class(_Tp)> { }; /// is_function template<typename> struct is_function : public false_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) const _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) const & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) const && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) const _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) const & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) const && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) volatile _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) volatile & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) volatile && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) volatile _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) volatile & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) volatile && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) const volatile _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) const volatile & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes...) const volatile && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) const volatile _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) const volatile & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct is_function<_Res(_ArgTypes......) const volatile && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; #define __cpp_lib_is_null_pointer 201309 template<typename> struct __is_null_pointer_helper : public false_type { }; template<> struct __is_null_pointer_helper<std::nullptr_t> : public true_type { }; /// is_null_pointer (LWG 2247). template<typename _Tp> struct is_null_pointer : public __is_null_pointer_helper<typename remove_cv<_Tp>::type>::type { }; /// __is_nullptr_t (extension). template<typename _Tp> struct __is_nullptr_t : public is_null_pointer<_Tp> { }; // Composite type categories. /// is_reference template<typename _Tp> struct is_reference : public __or_<is_lvalue_reference<_Tp>, is_rvalue_reference<_Tp>>::type { }; /// is_arithmetic template<typename _Tp> struct is_arithmetic : public __or_<is_integral<_Tp>, is_floating_point<_Tp>>::type { }; /// is_fundamental template<typename _Tp> struct is_fundamental : public __or_<is_arithmetic<_Tp>, is_void<_Tp>, is_null_pointer<_Tp>>::type { }; /// is_object template<typename _Tp> struct is_object : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>, is_void<_Tp>>>::type { }; template<typename> struct is_member_pointer; /// is_scalar template<typename _Tp> struct is_scalar : public __or_<is_arithmetic<_Tp>, is_enum<_Tp>, is_pointer<_Tp>, is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type { }; /// is_compound template<typename _Tp> struct is_compound : public integral_constant<bool, !is_fundamental<_Tp>::value> { }; template<typename _Tp> struct __is_member_pointer_helper : public false_type { }; template<typename _Tp, typename _Cp> struct __is_member_pointer_helper<_Tp _Cp::*> : public true_type { }; /// is_member_pointer template<typename _Tp> struct is_member_pointer : public __is_member_pointer_helper<typename remove_cv<_Tp>::type>::type { }; // Utility to detect referenceable types ([defns.referenceable]). template<typename _Tp> struct __is_referenceable : public __or_<is_object<_Tp>, is_reference<_Tp>>::type { }; template<typename _Res, typename... _Args _GLIBCXX_NOEXCEPT_PARM> struct __is_referenceable<_Res(_Args...) _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template<typename _Res, typename... _Args _GLIBCXX_NOEXCEPT_PARM> struct __is_referenceable<_Res(_Args......) _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; // Type properties. /// is_const template<typename> struct is_const : public false_type { }; template<typename _Tp> struct is_const<_Tp const> : public true_type { }; /// is_volatile template<typename> struct is_volatile : public false_type { }; template<typename _Tp> struct is_volatile<_Tp volatile> : public true_type { }; /// is_trivial template<typename _Tp> struct is_trivial : public integral_constant<bool, __is_trivial(_Tp)> { }; // is_trivially_copyable template<typename _Tp> struct is_trivially_copyable : public integral_constant<bool, __is_trivially_copyable(_Tp)> { }; /// is_standard_layout template<typename _Tp> struct is_standard_layout : public integral_constant<bool, __is_standard_layout(_Tp)> { }; /// is_pod // Could use is_standard_layout && is_trivial instead of the builtin. template<typename _Tp> struct is_pod : public integral_constant<bool, __is_pod(_Tp)> { }; /// is_literal_type template<typename _Tp> struct is_literal_type : public integral_constant<bool, __is_literal_type(_Tp)> { }; /// is_empty template<typename _Tp> struct is_empty : public integral_constant<bool, __is_empty(_Tp)> { }; /// is_polymorphic template<typename _Tp> struct is_polymorphic : public integral_constant<bool, __is_polymorphic(_Tp)> { }; #if __cplusplus >= 201402L #define __cpp_lib_is_final 201402L /// is_final template<typename _Tp> struct is_final : public integral_constant<bool, __is_final(_Tp)> { }; #endif /// is_abstract template<typename _Tp> struct is_abstract : public integral_constant<bool, __is_abstract(_Tp)> { }; template<typename _Tp, bool = is_arithmetic<_Tp>::value> struct __is_signed_helper : public false_type { }; template<typename _Tp> struct __is_signed_helper<_Tp, true> : public integral_constant<bool, _Tp(-1) < _Tp(0)> { }; /// is_signed template<typename _Tp> struct is_signed : public __is_signed_helper<_Tp>::type { }; /// is_unsigned template<typename _Tp> struct is_unsigned : public __and_<is_arithmetic<_Tp>, __not_<is_signed<_Tp>>> { }; // Destructible and constructible type properties. /** * @brief Utility to simplify expressions used in unevaluated operands * @ingroup utilities */ template<typename _Tp, typename _Up = _Tp&&> _Up __declval(int); template<typename _Tp> _Tp __declval(long); template<typename _Tp> auto declval() noexcept -> decltype(__declval<_Tp>(0)); template<typename, unsigned = 0> struct extent; template<typename> struct remove_all_extents; template<typename _Tp> struct __is_array_known_bounds : public integral_constant<bool, (extent<_Tp>::value > 0)> { }; template<typename _Tp> struct __is_array_unknown_bounds : public __and_<is_array<_Tp>, __not_<extent<_Tp>>> { }; // In N3290 is_destructible does not say anything about function // types and abstract types, see LWG 2049. This implementation // describes function types as non-destructible and all complete // object types as destructible, iff the explicit destructor // call expression is wellformed. struct __do_is_destructible_impl { template<typename _Tp, typename = decltype(declval<_Tp&>().~_Tp())> static true_type __test(int); template<typename> static false_type __test(...); }; template<typename _Tp> struct __is_destructible_impl : public __do_is_destructible_impl { typedef decltype(__test<_Tp>(0)) type; }; template<typename _Tp, bool = __or_<is_void<_Tp>, __is_array_unknown_bounds<_Tp>, is_function<_Tp>>::value, bool = __or_<is_reference<_Tp>, is_scalar<_Tp>>::value> struct __is_destructible_safe; template<typename _Tp> struct __is_destructible_safe<_Tp, false, false> : public __is_destructible_impl<typename remove_all_extents<_Tp>::type>::type { }; template<typename _Tp> struct __is_destructible_safe<_Tp, true, false> : public false_type { }; template<typename _Tp> struct __is_destructible_safe<_Tp, false, true> : public true_type { }; /// is_destructible template<typename _Tp> struct is_destructible : public __is_destructible_safe<_Tp>::type { }; // is_nothrow_destructible requires that is_destructible is // satisfied as well. We realize that by mimicing the // implementation of is_destructible but refer to noexcept(expr) // instead of decltype(expr). struct __do_is_nt_destructible_impl { template<typename _Tp> static integral_constant<bool, noexcept(declval<_Tp&>().~_Tp())> __test(int); template<typename> static false_type __test(...); }; template<typename _Tp> struct __is_nt_destructible_impl : public __do_is_nt_destructible_impl { typedef decltype(__test<_Tp>(0)) type; }; template<typename _Tp, bool = __or_<is_void<_Tp>, __is_array_unknown_bounds<_Tp>, is_function<_Tp>>::value, bool = __or_<is_reference<_Tp>, is_scalar<_Tp>>::value> struct __is_nt_destructible_safe; template<typename _Tp> struct __is_nt_destructible_safe<_Tp, false, false> : public __is_nt_destructible_impl<typename remove_all_extents<_Tp>::type>::type { }; template<typename _Tp> struct __is_nt_destructible_safe<_Tp, true, false> : public false_type { }; template<typename _Tp> struct __is_nt_destructible_safe<_Tp, false, true> : public true_type { }; /// is_nothrow_destructible template<typename _Tp> struct is_nothrow_destructible : public __is_nt_destructible_safe<_Tp>::type { }; /// is_constructible template<typename _Tp, typename... _Args> struct is_constructible : public __bool_constant<__is_constructible(_Tp, _Args...)> { }; /// is_default_constructible template<typename _Tp> struct is_default_constructible : public is_constructible<_Tp>::type { }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_copy_constructible_impl; template<typename _Tp> struct __is_copy_constructible_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_copy_constructible_impl<_Tp, true> : public is_constructible<_Tp, const _Tp&> { }; /// is_copy_constructible template<typename _Tp> struct is_copy_constructible : public __is_copy_constructible_impl<_Tp> { }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_move_constructible_impl; template<typename _Tp> struct __is_move_constructible_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_move_constructible_impl<_Tp, true> : public is_constructible<_Tp, _Tp&&> { }; /// is_move_constructible template<typename _Tp> struct is_move_constructible : public __is_move_constructible_impl<_Tp> { }; template<bool, typename _Tp, typename... _Args> struct __is_nt_constructible_impl : public false_type { }; template<typename _Tp, typename... _Args> struct __is_nt_constructible_impl<true, _Tp, _Args...> : public __bool_constant<noexcept(_Tp(std::declval<_Args>()...))> { }; template<typename _Tp, typename _Arg> struct __is_nt_constructible_impl<true, _Tp, _Arg> : public __bool_constant<noexcept(static_cast<_Tp>(std::declval<_Arg>()))> { }; template<typename _Tp> struct __is_nt_constructible_impl<true, _Tp> : public __bool_constant<noexcept(_Tp())> { }; template<typename _Tp, size_t _Num> struct __is_nt_constructible_impl<true, _Tp[_Num]> : public __bool_constant<noexcept(typename remove_all_extents<_Tp>::type())> { }; template<typename _Tp, typename... _Args> using __is_nothrow_constructible_impl = __is_nt_constructible_impl<__is_constructible(_Tp, _Args...), _Tp, _Args...>; /// is_nothrow_constructible template<typename _Tp, typename... _Args> struct is_nothrow_constructible : public __is_nothrow_constructible_impl<_Tp, _Args...>::type { }; /// is_nothrow_default_constructible template<typename _Tp> struct is_nothrow_default_constructible : public __is_nothrow_constructible_impl<_Tp>::type { }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_nothrow_copy_constructible_impl; template<typename _Tp> struct __is_nothrow_copy_constructible_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_nothrow_copy_constructible_impl<_Tp, true> : public is_nothrow_constructible<_Tp, const _Tp&> { }; /// is_nothrow_copy_constructible template<typename _Tp> struct is_nothrow_copy_constructible : public __is_nothrow_copy_constructible_impl<_Tp> { }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_nothrow_move_constructible_impl; template<typename _Tp> struct __is_nothrow_move_constructible_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_nothrow_move_constructible_impl<_Tp, true> : public is_nothrow_constructible<_Tp, _Tp&&> { }; /// is_nothrow_move_constructible template<typename _Tp> struct is_nothrow_move_constructible : public __is_nothrow_move_constructible_impl<_Tp> { }; /// is_assignable template<typename _Tp, typename _Up> struct is_assignable : public __bool_constant<__is_assignable(_Tp, _Up)> { }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_copy_assignable_impl; template<typename _Tp> struct __is_copy_assignable_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_copy_assignable_impl<_Tp, true> : public is_assignable<_Tp&, const _Tp&> { }; /// is_copy_assignable template<typename _Tp> struct is_copy_assignable : public __is_copy_assignable_impl<_Tp> { }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_move_assignable_impl; template<typename _Tp> struct __is_move_assignable_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_move_assignable_impl<_Tp, true> : public is_assignable<_Tp&, _Tp&&> { }; /// is_move_assignable template<typename _Tp> struct is_move_assignable : public __is_move_assignable_impl<_Tp> { }; template<typename _Tp, typename _Up> struct __is_nt_assignable_impl : public integral_constant<bool, noexcept(declval<_Tp>() = declval<_Up>())> { }; /// is_nothrow_assignable template<typename _Tp, typename _Up> struct is_nothrow_assignable : public __and_<is_assignable<_Tp, _Up>, __is_nt_assignable_impl<_Tp, _Up>> { }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_nt_copy_assignable_impl; template<typename _Tp> struct __is_nt_copy_assignable_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_nt_copy_assignable_impl<_Tp, true> : public is_nothrow_assignable<_Tp&, const _Tp&> { }; /// is_nothrow_copy_assignable template<typename _Tp> struct is_nothrow_copy_assignable : public __is_nt_copy_assignable_impl<_Tp> { }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_nt_move_assignable_impl; template<typename _Tp> struct __is_nt_move_assignable_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_nt_move_assignable_impl<_Tp, true> : public is_nothrow_assignable<_Tp&, _Tp&&> { }; /// is_nothrow_move_assignable template<typename _Tp> struct is_nothrow_move_assignable : public __is_nt_move_assignable_impl<_Tp> { }; /// is_trivially_constructible template<typename _Tp, typename... _Args> struct is_trivially_constructible : public __and_<is_constructible<_Tp, _Args...>, __bool_constant< __is_trivially_constructible(_Tp, _Args...)>>::type { }; /// is_trivially_default_constructible template<typename _Tp> struct is_trivially_default_constructible : public is_trivially_constructible<_Tp>::type { }; struct __do_is_implicitly_default_constructible_impl { template <typename _Tp> static void __helper(const _Tp&); template <typename _Tp> static true_type __test(const _Tp&, decltype(__helper<const _Tp&>({}))* = 0); static false_type __test(...); }; template<typename _Tp> struct __is_implicitly_default_constructible_impl : public __do_is_implicitly_default_constructible_impl { typedef decltype(__test(declval<_Tp>())) type; }; template<typename _Tp> struct __is_implicitly_default_constructible_safe : public __is_implicitly_default_constructible_impl<_Tp>::type { }; template <typename _Tp> struct __is_implicitly_default_constructible : public __and_<is_default_constructible<_Tp>, __is_implicitly_default_constructible_safe<_Tp>> { }; /// is_trivially_copy_constructible template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_trivially_copy_constructible_impl; template<typename _Tp> struct __is_trivially_copy_constructible_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_trivially_copy_constructible_impl<_Tp, true> : public __and_<is_copy_constructible<_Tp>, integral_constant<bool, __is_trivially_constructible(_Tp, const _Tp&)>> { }; template<typename _Tp> struct is_trivially_copy_constructible : public __is_trivially_copy_constructible_impl<_Tp> { }; /// is_trivially_move_constructible template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_trivially_move_constructible_impl; template<typename _Tp> struct __is_trivially_move_constructible_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_trivially_move_constructible_impl<_Tp, true> : public __and_<is_move_constructible<_Tp>, integral_constant<bool, __is_trivially_constructible(_Tp, _Tp&&)>> { }; template<typename _Tp> struct is_trivially_move_constructible : public __is_trivially_move_constructible_impl<_Tp> { }; /// is_trivially_assignable template<typename _Tp, typename _Up> struct is_trivially_assignable : public __bool_constant<__is_trivially_assignable(_Tp, _Up)> { }; /// is_trivially_copy_assignable template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_trivially_copy_assignable_impl; template<typename _Tp> struct __is_trivially_copy_assignable_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_trivially_copy_assignable_impl<_Tp, true> : public __and_<is_copy_assignable<_Tp>, integral_constant<bool, __is_trivially_assignable(_Tp&, const _Tp&)>> { }; template<typename _Tp> struct is_trivially_copy_assignable : public __is_trivially_copy_assignable_impl<_Tp> { }; /// is_trivially_move_assignable template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __is_trivially_move_assignable_impl; template<typename _Tp> struct __is_trivially_move_assignable_impl<_Tp, false> : public false_type { }; template<typename _Tp> struct __is_trivially_move_assignable_impl<_Tp, true> : public __and_<is_move_assignable<_Tp>, integral_constant<bool, __is_trivially_assignable(_Tp&, _Tp&&)>> { }; template<typename _Tp> struct is_trivially_move_assignable : public __is_trivially_move_assignable_impl<_Tp> { }; /// is_trivially_destructible template<typename _Tp> struct is_trivially_destructible : public __and_<is_destructible<_Tp>, integral_constant<bool, __has_trivial_destructor(_Tp)>> { }; /// has_virtual_destructor template<typename _Tp> struct has_virtual_destructor : public integral_constant<bool, __has_virtual_destructor(_Tp)> { }; // type property queries. /// alignment_of template<typename _Tp> struct alignment_of : public integral_constant<std::size_t, alignof(_Tp)> { }; /// rank template<typename> struct rank : public integral_constant<std::size_t, 0> { }; template<typename _Tp, std::size_t _Size> struct rank<_Tp[_Size]> : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; template<typename _Tp> struct rank<_Tp[]> : public integral_constant<std::size_t, 1 + rank<_Tp>::value> { }; /// extent template<typename, unsigned _Uint> struct extent : public integral_constant<std::size_t, 0> { }; template<typename _Tp, unsigned _Uint, std::size_t _Size> struct extent<_Tp[_Size], _Uint> : public integral_constant<std::size_t, _Uint == 0 ? _Size : extent<_Tp, _Uint - 1>::value> { }; template<typename _Tp, unsigned _Uint> struct extent<_Tp[], _Uint> : public integral_constant<std::size_t, _Uint == 0 ? 0 : extent<_Tp, _Uint - 1>::value> { }; // Type relations. /// is_same template<typename, typename> struct is_same : public false_type { }; template<typename _Tp> struct is_same<_Tp, _Tp> : public true_type { }; /// is_base_of template<typename _Base, typename _Derived> struct is_base_of : public integral_constant<bool, __is_base_of(_Base, _Derived)> { }; template<typename _From, typename _To, bool = __or_<is_void<_From>, is_function<_To>, is_array<_To>>::value> struct __is_convertible_helper { typedef typename is_void<_To>::type type; }; template<typename _From, typename _To> class __is_convertible_helper<_From, _To, false> { template<typename _To1> static void __test_aux(_To1); template<typename _From1, typename _To1, typename = decltype(__test_aux<_To1>(std::declval<_From1>()))> static true_type __test(int); template<typename, typename> static false_type __test(...); public: typedef decltype(__test<_From, _To>(0)) type; }; /// is_convertible template<typename _From, typename _To> struct is_convertible : public __is_convertible_helper<_From, _To>::type { }; // Const-volatile modifications. /// remove_const template<typename _Tp> struct remove_const { typedef _Tp type; }; template<typename _Tp> struct remove_const<_Tp const> { typedef _Tp type; }; /// remove_volatile template<typename _Tp> struct remove_volatile { typedef _Tp type; }; template<typename _Tp> struct remove_volatile<_Tp volatile> { typedef _Tp type; }; /// remove_cv template<typename _Tp> struct remove_cv { typedef typename remove_const<typename remove_volatile<_Tp>::type>::type type; }; /// add_const template<typename _Tp> struct add_const { typedef _Tp const type; }; /// add_volatile template<typename _Tp> struct add_volatile { typedef _Tp volatile type; }; /// add_cv template<typename _Tp> struct add_cv { typedef typename add_const<typename add_volatile<_Tp>::type>::type type; }; #if __cplusplus > 201103L #define __cpp_lib_transformation_trait_aliases 201304 /// Alias template for remove_const template<typename _Tp> using remove_const_t = typename remove_const<_Tp>::type; /// Alias template for remove_volatile template<typename _Tp> using remove_volatile_t = typename remove_volatile<_Tp>::type; /// Alias template for remove_cv template<typename _Tp> using remove_cv_t = typename remove_cv<_Tp>::type; /// Alias template for add_const template<typename _Tp> using add_const_t = typename add_const<_Tp>::type; /// Alias template for add_volatile template<typename _Tp> using add_volatile_t = typename add_volatile<_Tp>::type; /// Alias template for add_cv template<typename _Tp> using add_cv_t = typename add_cv<_Tp>::type; #endif // Reference transformations. /// remove_reference template<typename _Tp> struct remove_reference { typedef _Tp type; }; template<typename _Tp> struct remove_reference<_Tp&> { typedef _Tp type; }; template<typename _Tp> struct remove_reference<_Tp&&> { typedef _Tp type; }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __add_lvalue_reference_helper { typedef _Tp type; }; template<typename _Tp> struct __add_lvalue_reference_helper<_Tp, true> { typedef _Tp& type; }; /// add_lvalue_reference template<typename _Tp> struct add_lvalue_reference : public __add_lvalue_reference_helper<_Tp> { }; template<typename _Tp, bool = __is_referenceable<_Tp>::value> struct __add_rvalue_reference_helper { typedef _Tp type; }; template<typename _Tp> struct __add_rvalue_reference_helper<_Tp, true> { typedef _Tp&& type; }; /// add_rvalue_reference template<typename _Tp> struct add_rvalue_reference : public __add_rvalue_reference_helper<_Tp> { }; #if __cplusplus > 201103L /// Alias template for remove_reference template<typename _Tp> using remove_reference_t = typename remove_reference<_Tp>::type; /// Alias template for add_lvalue_reference template<typename _Tp> using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type; /// Alias template for add_rvalue_reference template<typename _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; #endif // Sign modifications. // Utility for constructing identically cv-qualified types. template<typename _Unqualified, bool _IsConst, bool _IsVol> struct __cv_selector; template<typename _Unqualified> struct __cv_selector<_Unqualified, false, false> { typedef _Unqualified __type; }; template<typename _Unqualified> struct __cv_selector<_Unqualified, false, true> { typedef volatile _Unqualified __type; }; template<typename _Unqualified> struct __cv_selector<_Unqualified, true, false> { typedef const _Unqualified __type; }; template<typename _Unqualified> struct __cv_selector<_Unqualified, true, true> { typedef const volatile _Unqualified __type; }; template<typename _Qualified, typename _Unqualified, bool _IsConst = is_const<_Qualified>::value, bool _IsVol = is_volatile<_Qualified>::value> class __match_cv_qualifiers { typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; public: typedef typename __match::__type __type; }; // Utility for finding the unsigned versions of signed integral types. template<typename _Tp> struct __make_unsigned { typedef _Tp __type; }; template<> struct __make_unsigned<char> { typedef unsigned char __type; }; template<> struct __make_unsigned<signed char> { typedef unsigned char __type; }; template<> struct __make_unsigned<short> { typedef unsigned short __type; }; template<> struct __make_unsigned<int> { typedef unsigned int __type; }; template<> struct __make_unsigned<long> { typedef unsigned long __type; }; template<> struct __make_unsigned<long long> { typedef unsigned long long __type; }; #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> { typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1> { typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2> { typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3> { typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; }; #endif // Select between integral and enum: not possible to be both. template<typename _Tp, bool _IsInt = is_integral<_Tp>::value, bool _IsEnum = is_enum<_Tp>::value> class __make_unsigned_selector; template<typename _Tp> class __make_unsigned_selector<_Tp, true, false> { typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt; typedef typename __unsignedt::__type __unsigned_type; typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned; public: typedef typename __cv_unsigned::__type __type; }; template<typename _Tp> class __make_unsigned_selector<_Tp, false, true> { // With -fshort-enums, an enum may be as small as a char. typedef unsigned char __smallest; static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest); static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short); static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int); static const bool __b3 = sizeof(_Tp) <= sizeof(unsigned long); typedef conditional<__b3, unsigned long, unsigned long long> __cond3; typedef typename __cond3::type __cond3_type; typedef conditional<__b2, unsigned int, __cond3_type> __cond2; typedef typename __cond2::type __cond2_type; typedef conditional<__b1, unsigned short, __cond2_type> __cond1; typedef typename __cond1::type __cond1_type; typedef typename conditional<__b0, __smallest, __cond1_type>::type __unsigned_type; typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned; public: typedef typename __cv_unsigned::__type __type; }; // Given an integral/enum type, return the corresponding unsigned // integer type. // Primary template. /// make_unsigned template<typename _Tp> struct make_unsigned { typedef typename __make_unsigned_selector<_Tp>::__type type; }; // Integral, but don't define. template<> struct make_unsigned<bool>; // Utility for finding the signed versions of unsigned integral types. template<typename _Tp> struct __make_signed { typedef _Tp __type; }; template<> struct __make_signed<char> { typedef signed char __type; }; template<> struct __make_signed<unsigned char> { typedef signed char __type; }; template<> struct __make_signed<unsigned short> { typedef signed short __type; }; template<> struct __make_signed<unsigned int> { typedef signed int __type; }; template<> struct __make_signed<unsigned long> { typedef signed long __type; }; template<> struct __make_signed<unsigned long long> { typedef signed long long __type; }; #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_0> { typedef __GLIBCXX_TYPE_INT_N_0 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) template<> struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_1> { typedef __GLIBCXX_TYPE_INT_N_1 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) template<> struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_2> { typedef __GLIBCXX_TYPE_INT_N_2 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) template<> struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_3> { typedef __GLIBCXX_TYPE_INT_N_3 __type; }; #endif // Select between integral and enum: not possible to be both. template<typename _Tp, bool _IsInt = is_integral<_Tp>::value, bool _IsEnum = is_enum<_Tp>::value> class __make_signed_selector; template<typename _Tp> class __make_signed_selector<_Tp, true, false> { typedef __make_signed<typename remove_cv<_Tp>::type> __signedt; typedef typename __signedt::__type __signed_type; typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed; public: typedef typename __cv_signed::__type __type; }; template<typename _Tp> class __make_signed_selector<_Tp, false, true> { typedef typename __make_unsigned_selector<_Tp>::__type __unsigned_type; public: typedef typename __make_signed_selector<__unsigned_type>::__type __type; }; // Given an integral/enum type, return the corresponding signed // integer type. // Primary template. /// make_signed template<typename _Tp> struct make_signed { typedef typename __make_signed_selector<_Tp>::__type type; }; // Integral, but don't define. template<> struct make_signed<bool>; #if __cplusplus > 201103L /// Alias template for make_signed template<typename _Tp> using make_signed_t = typename make_signed<_Tp>::type; /// Alias template for make_unsigned template<typename _Tp> using make_unsigned_t = typename make_unsigned<_Tp>::type; #endif // Array modifications. /// remove_extent template<typename _Tp> struct remove_extent { typedef _Tp type; }; template<typename _Tp, std::size_t _Size> struct remove_extent<_Tp[_Size]> { typedef _Tp type; }; template<typename _Tp> struct remove_extent<_Tp[]> { typedef _Tp type; }; /// remove_all_extents template<typename _Tp> struct remove_all_extents { typedef _Tp type; }; template<typename _Tp, std::size_t _Size> struct remove_all_extents<_Tp[_Size]> { typedef typename remove_all_extents<_Tp>::type type; }; template<typename _Tp> struct remove_all_extents<_Tp[]> { typedef typename remove_all_extents<_Tp>::type type; }; #if __cplusplus > 201103L /// Alias template for remove_extent template<typename _Tp> using remove_extent_t = typename remove_extent<_Tp>::type; /// Alias template for remove_all_extents template<typename _Tp> using remove_all_extents_t = typename remove_all_extents<_Tp>::type; #endif // Pointer modifications. template<typename _Tp, typename> struct __remove_pointer_helper { typedef _Tp type; }; template<typename _Tp, typename _Up> struct __remove_pointer_helper<_Tp, _Up*> { typedef _Up type; }; /// remove_pointer template<typename _Tp> struct remove_pointer : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> { }; /// add_pointer template<typename _Tp, bool = __or_<__is_referenceable<_Tp>, is_void<_Tp>>::value> struct __add_pointer_helper { typedef _Tp type; }; template<typename _Tp> struct __add_pointer_helper<_Tp, true> { typedef typename remove_reference<_Tp>::type* type; }; template<typename _Tp> struct add_pointer : public __add_pointer_helper<_Tp> { }; #if __cplusplus > 201103L /// Alias template for remove_pointer template<typename _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type; /// Alias template for add_pointer template<typename _Tp> using add_pointer_t = typename add_pointer<_Tp>::type; #endif template<std::size_t _Len> struct __aligned_storage_msa { union __type { unsigned char __data[_Len]; struct __attribute__((__aligned__)) { } __align; }; }; /** * @brief Alignment type. * * The value of _Align is a default-alignment which shall be the * most stringent alignment requirement for any C++ object type * whose size is no greater than _Len (3.9). The member typedef * type shall be a POD type suitable for use as uninitialized * storage for any object whose size is at most _Len and whose * alignment is a divisor of _Align. */ template<std::size_t _Len, std::size_t _Align = __alignof__(typename __aligned_storage_msa<_Len>::__type)> struct aligned_storage { union type { unsigned char __data[_Len]; struct __attribute__((__aligned__((_Align)))) { } __align; }; }; template <typename... _Types> struct __strictest_alignment { static const size_t _S_alignment = 0; static const size_t _S_size = 0; }; template <typename _Tp, typename... _Types> struct __strictest_alignment<_Tp, _Types...> { static const size_t _S_alignment = alignof(_Tp) > __strictest_alignment<_Types...>::_S_alignment ? alignof(_Tp) : __strictest_alignment<_Types...>::_S_alignment; static const size_t _S_size = sizeof(_Tp) > __strictest_alignment<_Types...>::_S_size ? sizeof(_Tp) : __strictest_alignment<_Types...>::_S_size; }; /** * @brief Provide aligned storage for types. * * [meta.trans.other] * * Provides aligned storage for any of the provided types of at * least size _Len. * * @see aligned_storage */ template <size_t _Len, typename... _Types> struct aligned_union { private: static_assert(sizeof...(_Types) != 0, "At least one type is required"); using __strictest = __strictest_alignment<_Types...>; static const size_t _S_len = _Len > __strictest::_S_size ? _Len : __strictest::_S_size; public: /// The value of the strictest alignment of _Types. static const size_t alignment_value = __strictest::_S_alignment; /// The storage. typedef typename aligned_storage<_S_len, alignment_value>::type type; }; template <size_t _Len, typename... _Types> const size_t aligned_union<_Len, _Types...>::alignment_value; // Decay trait for arrays and functions, used for perfect forwarding // in make_pair, make_tuple, etc. template<typename _Up, bool _IsArray = is_array<_Up>::value, bool _IsFunction = is_function<_Up>::value> struct __decay_selector; // NB: DR 705. template<typename _Up> struct __decay_selector<_Up, false, false> { typedef typename remove_cv<_Up>::type __type; }; template<typename _Up> struct __decay_selector<_Up, true, false> { typedef typename remove_extent<_Up>::type* __type; }; template<typename _Up> struct __decay_selector<_Up, false, true> { typedef typename add_pointer<_Up>::type __type; }; /// decay template<typename _Tp> class decay { typedef typename remove_reference<_Tp>::type __remove_type; public: typedef typename __decay_selector<__remove_type>::__type type; }; template<typename _Tp> class reference_wrapper; // Helper which adds a reference to a type when given a reference_wrapper template<typename _Tp> struct __strip_reference_wrapper { typedef _Tp __type; }; template<typename _Tp> struct __strip_reference_wrapper<reference_wrapper<_Tp> > { typedef _Tp& __type; }; template<typename _Tp> struct __decay_and_strip { typedef typename __strip_reference_wrapper< typename decay<_Tp>::type>::__type __type; }; // Primary template. /// Define a member typedef @c type only if a boolean constant is true. template<bool, typename _Tp = void> struct enable_if { }; // Partial specialization for true. template<typename _Tp> struct enable_if<true, _Tp> { typedef _Tp type; }; template<typename... _Cond> using _Require = typename enable_if<__and_<_Cond...>::value>::type; // Primary template. /// Define a member typedef @c type to one of two argument types. template<bool _Cond, typename _Iftrue, typename _Iffalse> struct conditional { typedef _Iftrue type; }; // Partial specialization for false. template<typename _Iftrue, typename _Iffalse> struct conditional<false, _Iftrue, _Iffalse> { typedef _Iffalse type; }; /// common_type template<typename... _Tp> struct common_type; // Sfinae-friendly common_type implementation: struct __do_common_type_impl { template<typename _Tp, typename _Up> static __success_type<typename decay<decltype (true ? std::declval<_Tp>() : std::declval<_Up>())>::type> _S_test(int); template<typename, typename> static __failure_type _S_test(...); }; template<typename _Tp, typename _Up> struct __common_type_impl : private __do_common_type_impl { typedef decltype(_S_test<_Tp, _Up>(0)) type; }; struct __do_member_type_wrapper { template<typename _Tp> static __success_type<typename _Tp::type> _S_test(int); template<typename> static __failure_type _S_test(...); }; template<typename _Tp> struct __member_type_wrapper : private __do_member_type_wrapper { typedef decltype(_S_test<_Tp>(0)) type; }; template<typename _CTp, typename... _Args> struct __expanded_common_type_wrapper { typedef common_type<typename _CTp::type, _Args...> type; }; template<typename... _Args> struct __expanded_common_type_wrapper<__failure_type, _Args...> { typedef __failure_type type; }; template<> struct common_type<> { }; template<typename _Tp> struct common_type<_Tp> : common_type<_Tp, _Tp> { }; template<typename _Tp, typename _Up> struct common_type<_Tp, _Up> : public __common_type_impl<_Tp, _Up>::type { }; template<typename _Tp, typename _Up, typename... _Vp> struct common_type<_Tp, _Up, _Vp...> : public __expanded_common_type_wrapper<typename __member_type_wrapper< common_type<_Tp, _Up>>::type, _Vp...>::type { }; /// The underlying type of an enum. template<typename _Tp> struct underlying_type { typedef __underlying_type(_Tp) type; }; template<typename _Tp> struct __declval_protector { static const bool __stop = false; }; template<typename _Tp> auto declval() noexcept -> decltype(__declval<_Tp>(0)) { static_assert(__declval_protector<_Tp>::__stop, "declval() must not be used!"); return __declval<_Tp>(0); } // wchar_t, char16_t and char32_t are integral types but are neither // signed integer types nor unsigned integer types, so must be // transformed to the integer type with the smallest rank that has the // same size and signedness. // Use the partial specialization for enumeration types to do that, // which means these explicit specializations must be defined after // std::conditional has been defined. #if defined(_GLIBCXX_USE_WCHAR_T) template<> struct __make_unsigned<wchar_t> { using __type = typename __make_unsigned_selector<wchar_t, false, true>::__type; }; template<> struct __make_signed<wchar_t> { using __type = typename __make_signed_selector<wchar_t, false, true>::__type; }; #endif template<> struct __make_unsigned<char16_t> { using __type = typename __make_unsigned_selector<char16_t, false, true>::__type; }; template<> struct __make_signed<char16_t> { using __type = typename __make_signed_selector<char16_t, false, true>::__type; }; template<> struct __make_unsigned<char32_t> { using __type = typename __make_unsigned_selector<char32_t, false, true>::__type; }; template<> struct __make_signed<char32_t> { using __type = typename __make_signed_selector<char32_t, false, true>::__type; }; /// result_of template<typename _Signature> class result_of; // Sfinae-friendly result_of implementation: #define __cpp_lib_result_of_sfinae 201210 struct __invoke_memfun_ref { }; struct __invoke_memfun_deref { }; struct __invoke_memobj_ref { }; struct __invoke_memobj_deref { }; struct __invoke_other { }; // Associate a tag type with a specialization of __success_type. template<typename _Tp, typename _Tag> struct __result_of_success : __success_type<_Tp> { using __invoke_type = _Tag; }; // [func.require] paragraph 1 bullet 1: struct __result_of_memfun_ref_impl { template<typename _Fp, typename _Tp1, typename... _Args> static __result_of_success<decltype( (std::declval<_Tp1>().*std::declval<_Fp>())(std::declval<_Args>()...) ), __invoke_memfun_ref> _S_test(int); template<typename...> static __failure_type _S_test(...); }; template<typename _MemPtr, typename _Arg, typename... _Args> struct __result_of_memfun_ref : private __result_of_memfun_ref_impl { typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; }; // [func.require] paragraph 1 bullet 2: struct __result_of_memfun_deref_impl { template<typename _Fp, typename _Tp1, typename... _Args> static __result_of_success<decltype( ((*std::declval<_Tp1>()).*std::declval<_Fp>())(std::declval<_Args>()...) ), __invoke_memfun_deref> _S_test(int); template<typename...> static __failure_type _S_test(...); }; template<typename _MemPtr, typename _Arg, typename... _Args> struct __result_of_memfun_deref : private __result_of_memfun_deref_impl { typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; }; // [func.require] paragraph 1 bullet 3: struct __result_of_memobj_ref_impl { template<typename _Fp, typename _Tp1> static __result_of_success<decltype( std::declval<_Tp1>().*std::declval<_Fp>() ), __invoke_memobj_ref> _S_test(int); template<typename, typename> static __failure_type _S_test(...); }; template<typename _MemPtr, typename _Arg> struct __result_of_memobj_ref : private __result_of_memobj_ref_impl { typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; }; // [func.require] paragraph 1 bullet 4: struct __result_of_memobj_deref_impl { template<typename _Fp, typename _Tp1> static __result_of_success<decltype( (*std::declval<_Tp1>()).*std::declval<_Fp>() ), __invoke_memobj_deref> _S_test(int); template<typename, typename> static __failure_type _S_test(...); }; template<typename _MemPtr, typename _Arg> struct __result_of_memobj_deref : private __result_of_memobj_deref_impl { typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; }; template<typename _MemPtr, typename _Arg> struct __result_of_memobj; template<typename _Res, typename _Class, typename _Arg> struct __result_of_memobj<_Res _Class::*, _Arg> { typedef typename remove_cv<typename remove_reference< _Arg>::type>::type _Argval; typedef _Res _Class::* _MemPtr; typedef typename conditional<__or_<is_same<_Argval, _Class>, is_base_of<_Class, _Argval>>::value, __result_of_memobj_ref<_MemPtr, _Arg>, __result_of_memobj_deref<_MemPtr, _Arg> >::type::type type; }; template<typename _MemPtr, typename _Arg, typename... _Args> struct __result_of_memfun; template<typename _Res, typename _Class, typename _Arg, typename... _Args> struct __result_of_memfun<_Res _Class::*, _Arg, _Args...> { typedef typename remove_cv<typename remove_reference< _Arg>::type>::type _Argval; typedef _Res _Class::* _MemPtr; typedef typename conditional<__or_<is_same<_Argval, _Class>, is_base_of<_Class, _Argval>>::value, __result_of_memfun_ref<_MemPtr, _Arg, _Args...>, __result_of_memfun_deref<_MemPtr, _Arg, _Args...> >::type::type type; }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2219. INVOKE-ing a pointer to member with a reference_wrapper // as the object expression // Used by result_of, invoke etc. to unwrap a reference_wrapper. template<typename _Tp, typename _Up = typename decay<_Tp>::type> struct __inv_unwrap { using type = _Tp; }; template<typename _Tp, typename _Up> struct __inv_unwrap<_Tp, reference_wrapper<_Up>> { using type = _Up&; }; template<bool, bool, typename _Functor, typename... _ArgTypes> struct __result_of_impl { typedef __failure_type type; }; template<typename _MemPtr, typename _Arg> struct __result_of_impl<true, false, _MemPtr, _Arg> : public __result_of_memobj<typename decay<_MemPtr>::type, typename __inv_unwrap<_Arg>::type> { }; template<typename _MemPtr, typename _Arg, typename... _Args> struct __result_of_impl<false, true, _MemPtr, _Arg, _Args...> : public __result_of_memfun<typename decay<_MemPtr>::type, typename __inv_unwrap<_Arg>::type, _Args...> { }; // [func.require] paragraph 1 bullet 5: struct __result_of_other_impl { template<typename _Fn, typename... _Args> static __result_of_success<decltype( std::declval<_Fn>()(std::declval<_Args>()...) ), __invoke_other> _S_test(int); template<typename...> static __failure_type _S_test(...); }; template<typename _Functor, typename... _ArgTypes> struct __result_of_impl<false, false, _Functor, _ArgTypes...> : private __result_of_other_impl { typedef decltype(_S_test<_Functor, _ArgTypes...>(0)) type; }; // __invoke_result (std::invoke_result for C++11) template<typename _Functor, typename... _ArgTypes> struct __invoke_result : public __result_of_impl< is_member_object_pointer< typename remove_reference<_Functor>::type >::value, is_member_function_pointer< typename remove_reference<_Functor>::type >::value, _Functor, _ArgTypes... >::type { }; template<typename _Functor, typename... _ArgTypes> struct result_of<_Functor(_ArgTypes...)> : public __invoke_result<_Functor, _ArgTypes...> { }; #if __cplusplus >= 201402L /// Alias template for aligned_storage template<size_t _Len, size_t _Align = __alignof__(typename __aligned_storage_msa<_Len>::__type)> using aligned_storage_t = typename aligned_storage<_Len, _Align>::type; template <size_t _Len, typename... _Types> using aligned_union_t = typename aligned_union<_Len, _Types...>::type; /// Alias template for decay template<typename _Tp> using decay_t = typename decay<_Tp>::type; /// Alias template for enable_if template<bool _Cond, typename _Tp = void> using enable_if_t = typename enable_if<_Cond, _Tp>::type; /// Alias template for conditional template<bool _Cond, typename _Iftrue, typename _Iffalse> using conditional_t = typename conditional<_Cond, _Iftrue, _Iffalse>::type; /// Alias template for common_type template<typename... _Tp> using common_type_t = typename common_type<_Tp...>::type; /// Alias template for underlying_type template<typename _Tp> using underlying_type_t = typename underlying_type<_Tp>::type; /// Alias template for result_of template<typename _Tp> using result_of_t = typename result_of<_Tp>::type; #endif // C++14 // __enable_if_t (std::enable_if_t for C++11) template<bool _Cond, typename _Tp = void> using __enable_if_t = typename enable_if<_Cond, _Tp>::type; // __void_t (std::void_t for C++11) template<typename...> using __void_t = void; #if __cplusplus >= 201703L || !defined(__STRICT_ANSI__) // c++17 or gnu++11 #define __cpp_lib_void_t 201411 /// A metafunction that always yields void, used for detecting valid types. template<typename...> using void_t = void; #endif /// Implementation of the detection idiom (negative case). template<typename _Default, typename _AlwaysVoid, template<typename...> class _Op, typename... _Args> struct __detector { using value_t = false_type; using type = _Default; }; /// Implementation of the detection idiom (positive case). template<typename _Default, template<typename...> class _Op, typename... _Args> struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...> { using value_t = true_type; using type = _Op<_Args...>; }; // Detect whether _Op<_Args...> is a valid type, use _Default if not. template<typename _Default, template<typename...> class _Op, typename... _Args> using __detected_or = __detector<_Default, void, _Op, _Args...>; // _Op<_Args...> if that is a valid type, otherwise _Default. template<typename _Default, template<typename...> class _Op, typename... _Args> using __detected_or_t = typename __detected_or<_Default, _Op, _Args...>::type; /// @} group metaprogramming /** * Use SFINAE to determine if the type _Tp has a publicly-accessible * member type _NTYPE. */ #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \ template<typename _Tp, typename = __void_t<>> \ struct __has_##_NTYPE \ : false_type \ { }; \ template<typename _Tp> \ struct __has_##_NTYPE<_Tp, __void_t<typename _Tp::_NTYPE>> \ : true_type \ { }; template <typename _Tp> struct __is_swappable; template <typename _Tp> struct __is_nothrow_swappable; template<typename... _Elements> class tuple; template<typename> struct __is_tuple_like_impl : false_type { }; template<typename... _Tps> struct __is_tuple_like_impl<tuple<_Tps...>> : true_type { }; // Internal type trait that allows us to sfinae-protect tuple_cat. template<typename _Tp> struct __is_tuple_like : public __is_tuple_like_impl<typename remove_cv< typename remove_reference<_Tp>::type>::type>::type { }; template<typename _Tp> inline typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>, is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value>::type swap(_Tp&, _Tp&) noexcept(__and_<is_nothrow_move_constructible<_Tp>, is_nothrow_move_assignable<_Tp>>::value); template<typename _Tp, size_t _Nm> inline typename enable_if<__is_swappable<_Tp>::value>::type swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) noexcept(__is_nothrow_swappable<_Tp>::value); namespace __swappable_details { using std::swap; struct __do_is_swappable_impl { template<typename _Tp, typename = decltype(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))> static true_type __test(int); template<typename> static false_type __test(...); }; struct __do_is_nothrow_swappable_impl { template<typename _Tp> static __bool_constant< noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())) > __test(int); template<typename> static false_type __test(...); }; } // namespace __swappable_details template<typename _Tp> struct __is_swappable_impl : public __swappable_details::__do_is_swappable_impl { typedef decltype(__test<_Tp>(0)) type; }; template<typename _Tp> struct __is_nothrow_swappable_impl : public __swappable_details::__do_is_nothrow_swappable_impl { typedef decltype(__test<_Tp>(0)) type; }; template<typename _Tp> struct __is_swappable : public __is_swappable_impl<_Tp>::type { }; template<typename _Tp> struct __is_nothrow_swappable : public __is_nothrow_swappable_impl<_Tp>::type { }; #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 #define __cpp_lib_is_swappable 201603 /// Metafunctions used for detecting swappable types: p0185r1 /// is_swappable template<typename _Tp> struct is_swappable : public __is_swappable_impl<_Tp>::type { }; /// is_nothrow_swappable template<typename _Tp> struct is_nothrow_swappable : public __is_nothrow_swappable_impl<_Tp>::type { }; #if __cplusplus >= 201402L /// is_swappable_v template<typename _Tp> _GLIBCXX17_INLINE constexpr bool is_swappable_v = is_swappable<_Tp>::value; /// is_nothrow_swappable_v template<typename _Tp> _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value; #endif // __cplusplus >= 201402L namespace __swappable_with_details { using std::swap; struct __do_is_swappable_with_impl { template<typename _Tp, typename _Up, typename = decltype(swap(std::declval<_Tp>(), std::declval<_Up>())), typename = decltype(swap(std::declval<_Up>(), std::declval<_Tp>()))> static true_type __test(int); template<typename, typename> static false_type __test(...); }; struct __do_is_nothrow_swappable_with_impl { template<typename _Tp, typename _Up> static __bool_constant< noexcept(swap(std::declval<_Tp>(), std::declval<_Up>())) && noexcept(swap(std::declval<_Up>(), std::declval<_Tp>())) > __test(int); template<typename, typename> static false_type __test(...); }; } // namespace __swappable_with_details template<typename _Tp, typename _Up> struct __is_swappable_with_impl : public __swappable_with_details::__do_is_swappable_with_impl { typedef decltype(__test<_Tp, _Up>(0)) type; }; // Optimization for the homogenous lvalue case, not required: template<typename _Tp> struct __is_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_swappable_impl { typedef decltype(__test<_Tp&>(0)) type; }; template<typename _Tp, typename _Up> struct __is_nothrow_swappable_with_impl : public __swappable_with_details::__do_is_nothrow_swappable_with_impl { typedef decltype(__test<_Tp, _Up>(0)) type; }; // Optimization for the homogenous lvalue case, not required: template<typename _Tp> struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_nothrow_swappable_impl { typedef decltype(__test<_Tp&>(0)) type; }; /// is_swappable_with template<typename _Tp, typename _Up> struct is_swappable_with : public __is_swappable_with_impl<_Tp, _Up>::type { }; /// is_nothrow_swappable_with template<typename _Tp, typename _Up> struct is_nothrow_swappable_with : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type { }; #if __cplusplus >= 201402L /// is_swappable_with_v template<typename _Tp, typename _Up> _GLIBCXX17_INLINE constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value; /// is_nothrow_swappable_with_v template<typename _Tp, typename _Up> _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_Tp, _Up>::value; #endif // __cplusplus >= 201402L #endif// c++1z or gnu++11 // __is_invocable (std::is_invocable for C++11) template<typename _Result, typename _Ret, typename = void> struct __is_invocable_impl : false_type { }; template<typename _Result, typename _Ret> struct __is_invocable_impl<_Result, _Ret, __void_t<typename _Result::type>> : __or_<is_void<_Ret>, is_convertible<typename _Result::type, _Ret>>::type { }; template<typename _Fn, typename... _ArgTypes> struct __is_invocable : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type { }; template<typename _Fn, typename _Tp, typename... _Args> constexpr bool __call_is_nt(__invoke_memfun_ref) { using _Up = typename __inv_unwrap<_Tp>::type; return noexcept((std::declval<_Up>().*std::declval<_Fn>())( std::declval<_Args>()...)); } template<typename _Fn, typename _Tp, typename... _Args> constexpr bool __call_is_nt(__invoke_memfun_deref) { return noexcept(((*std::declval<_Tp>()).*std::declval<_Fn>())( std::declval<_Args>()...)); } template<typename _Fn, typename _Tp> constexpr bool __call_is_nt(__invoke_memobj_ref) { using _Up = typename __inv_unwrap<_Tp>::type; return noexcept(std::declval<_Up>().*std::declval<_Fn>()); } template<typename _Fn, typename _Tp> constexpr bool __call_is_nt(__invoke_memobj_deref) { return noexcept((*std::declval<_Tp>()).*std::declval<_Fn>()); } template<typename _Fn, typename... _Args> constexpr bool __call_is_nt(__invoke_other) { return noexcept(std::declval<_Fn>()(std::declval<_Args>()...)); } template<typename _Result, typename _Fn, typename... _Args> struct __call_is_nothrow : __bool_constant< std::__call_is_nt<_Fn, _Args...>(typename _Result::__invoke_type{}) > { }; template<typename _Fn, typename... _Args> using __call_is_nothrow_ = __call_is_nothrow<__invoke_result<_Fn, _Args...>, _Fn, _Args...>; // __is_nothrow_invocable (std::is_nothrow_invocable for C++11) template<typename _Fn, typename... _Args> struct __is_nothrow_invocable : __and_<__is_invocable<_Fn, _Args...>, __call_is_nothrow_<_Fn, _Args...>>::type { }; struct __nonesuch { __nonesuch() = delete; ~__nonesuch() = delete; __nonesuch(__nonesuch const&) = delete; void operator=(__nonesuch const&) = delete; }; #if __cplusplus >= 201703L # define __cpp_lib_is_invocable 201703 /// std::invoke_result template<typename _Functor, typename... _ArgTypes> struct invoke_result : public __invoke_result<_Functor, _ArgTypes...> { }; /// std::invoke_result_t template<typename _Fn, typename... _Args> using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; /// std::is_invocable template<typename _Fn, typename... _ArgTypes> struct is_invocable : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type { }; /// std::is_invocable_r template<typename _Ret, typename _Fn, typename... _ArgTypes> struct is_invocable_r : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>::type { }; /// std::is_nothrow_invocable template<typename _Fn, typename... _ArgTypes> struct is_nothrow_invocable : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>, __call_is_nothrow_<_Fn, _ArgTypes...>>::type { }; template<typename _Result, typename _Ret, typename = void> struct __is_nt_invocable_impl : false_type { }; template<typename _Result, typename _Ret> struct __is_nt_invocable_impl<_Result, _Ret, __void_t<typename _Result::type>> : __or_<is_void<_Ret>, __and_<is_convertible<typename _Result::type, _Ret>, is_nothrow_constructible<_Ret, typename _Result::type>>> { }; /// std::is_nothrow_invocable_r template<typename _Ret, typename _Fn, typename... _ArgTypes> struct is_nothrow_invocable_r : __and_<__is_nt_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>, __call_is_nothrow_<_Fn, _ArgTypes...>>::type { }; /// std::is_invocable_v template<typename _Fn, typename... _Args> inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; /// std::is_nothrow_invocable_v template<typename _Fn, typename... _Args> inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value; /// std::is_invocable_r_v template<typename _Fn, typename... _Args> inline constexpr bool is_invocable_r_v = is_invocable_r<_Fn, _Args...>::value; /// std::is_nothrow_invocable_r_v template<typename _Fn, typename... _Args> inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Fn, _Args...>::value; #endif // C++17 #if __cplusplus >= 201703L # define __cpp_lib_type_trait_variable_templates 201510L template <typename _Tp> inline constexpr bool is_void_v = is_void<_Tp>::value; template <typename _Tp> inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value; template <typename _Tp> inline constexpr bool is_integral_v = is_integral<_Tp>::value; template <typename _Tp> inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value; template <typename _Tp> inline constexpr bool is_array_v = is_array<_Tp>::value; template <typename _Tp> inline constexpr bool is_pointer_v = is_pointer<_Tp>::value; template <typename _Tp> inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value; template <typename _Tp> inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value; template <typename _Tp> inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value; template <typename _Tp> inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value; template <typename _Tp> inline constexpr bool is_enum_v = is_enum<_Tp>::value; template <typename _Tp> inline constexpr bool is_union_v = is_union<_Tp>::value; template <typename _Tp> inline constexpr bool is_class_v = is_class<_Tp>::value; template <typename _Tp> inline constexpr bool is_function_v = is_function<_Tp>::value; template <typename _Tp> inline constexpr bool is_reference_v = is_reference<_Tp>::value; template <typename _Tp> inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value; template <typename _Tp> inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value; template <typename _Tp> inline constexpr bool is_object_v = is_object<_Tp>::value; template <typename _Tp> inline constexpr bool is_scalar_v = is_scalar<_Tp>::value; template <typename _Tp> inline constexpr bool is_compound_v = is_compound<_Tp>::value; template <typename _Tp> inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value; template <typename _Tp> inline constexpr bool is_const_v = is_const<_Tp>::value; template <typename _Tp> inline constexpr bool is_volatile_v = is_volatile<_Tp>::value; template <typename _Tp> inline constexpr bool is_trivial_v = is_trivial<_Tp>::value; template <typename _Tp> inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<_Tp>::value; template <typename _Tp> inline constexpr bool is_standard_layout_v = is_standard_layout<_Tp>::value; template <typename _Tp> inline constexpr bool is_pod_v = is_pod<_Tp>::value; template <typename _Tp> inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value; template <typename _Tp> inline constexpr bool is_empty_v = is_empty<_Tp>::value; template <typename _Tp> inline constexpr bool is_polymorphic_v = is_polymorphic<_Tp>::value; template <typename _Tp> inline constexpr bool is_abstract_v = is_abstract<_Tp>::value; template <typename _Tp> inline constexpr bool is_final_v = is_final<_Tp>::value; template <typename _Tp> inline constexpr bool is_signed_v = is_signed<_Tp>::value; template <typename _Tp> inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value; template <typename _Tp, typename... _Args> inline constexpr bool is_constructible_v = is_constructible<_Tp, _Args...>::value; template <typename _Tp> inline constexpr bool is_default_constructible_v = is_default_constructible<_Tp>::value; template <typename _Tp> inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value; template <typename _Tp> inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value; template <typename _Tp, typename _Up> inline constexpr bool is_assignable_v = is_assignable<_Tp, _Up>::value; template <typename _Tp> inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value; template <typename _Tp> inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value; template <typename _Tp> inline constexpr bool is_destructible_v = is_destructible<_Tp>::value; template <typename _Tp, typename... _Args> inline constexpr bool is_trivially_constructible_v = is_trivially_constructible<_Tp, _Args...>::value; template <typename _Tp> inline constexpr bool is_trivially_default_constructible_v = is_trivially_default_constructible<_Tp>::value; template <typename _Tp> inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<_Tp>::value; template <typename _Tp> inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<_Tp>::value; template <typename _Tp, typename _Up> inline constexpr bool is_trivially_assignable_v = is_trivially_assignable<_Tp, _Up>::value; template <typename _Tp> inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<_Tp>::value; template <typename _Tp> inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<_Tp>::value; template <typename _Tp> inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value; template <typename _Tp, typename... _Args> inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, _Args...>::value; template <typename _Tp> inline constexpr bool is_nothrow_default_constructible_v = is_nothrow_default_constructible<_Tp>::value; template <typename _Tp> inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<_Tp>::value; template <typename _Tp> inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<_Tp>::value; template <typename _Tp, typename _Up> inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<_Tp, _Up>::value; template <typename _Tp> inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<_Tp>::value; template <typename _Tp> inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value; template <typename _Tp> inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value; template <typename _Tp> inline constexpr bool has_virtual_destructor_v = has_virtual_destructor<_Tp>::value; template <typename _Tp> inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value; template <typename _Tp> inline constexpr size_t rank_v = rank<_Tp>::value; template <typename _Tp, unsigned _Idx = 0> inline constexpr size_t extent_v = extent<_Tp, _Idx>::value; template <typename _Tp, typename _Up> inline constexpr bool is_same_v = is_same<_Tp, _Up>::value; template <typename _Base, typename _Derived> inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value; template <typename _From, typename _To> inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value; #if __GNUC__ >= 7 # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1 #elif defined(__is_identifier) // For non-GNU compilers: # if ! __is_identifier(__has_unique_object_representations) # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1 # endif #endif #ifdef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP # define __cpp_lib_has_unique_object_representations 201606 /// has_unique_object_representations template<typename _Tp> struct has_unique_object_representations : bool_constant<__has_unique_object_representations( remove_cv_t<remove_all_extents_t<_Tp>> )> { }; template<typename _Tp> inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<_Tp>::value; #endif #undef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP #if __GNUC__ >= 7 # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1 #elif defined(__is_identifier) // For non-GNU compilers: # if ! __is_identifier(__is_aggregate) # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1 # endif #endif #ifdef _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE #define __cpp_lib_is_aggregate 201703 /// is_aggregate template<typename _Tp> struct is_aggregate : bool_constant<__is_aggregate(remove_cv_t<_Tp>)> { }; /// is_aggregate_v template<typename _Tp> inline constexpr bool is_aggregate_v = is_aggregate<_Tp>::value; #endif #undef _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE #endif // C++17 #if __cplusplus > 201703L /// Byte order enum class endian { little = __ORDER_LITTLE_ENDIAN__, big = __ORDER_BIG_ENDIAN__, native = __BYTE_ORDER__ }; #endif // C++2a _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_TYPE_TRAITS c++/8/set 0000644 00000004777 15146341150 0006020 0 ustar 00 // <set> -*- C++ -*- // Copyright (C) 2001-2018 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/set * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_SET #define _GLIBCXX_SET 1 #pragma GCC system_header #include <bits/stl_tree.h> #include <bits/stl_set.h> #include <bits/stl_multiset.h> #include <bits/range_access.h> #ifdef _GLIBCXX_DEBUG # include <debug/set> #endif #ifdef _GLIBCXX_PROFILE # include <profile/set> #endif #endif /* _GLIBCXX_SET */ c++/8/cstdarg 0000644 00000003514 15146341150 0006640 0 ustar 00 // -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cstdarg * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c stdarg.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.4.6 C library // #pragma GCC system_header #undef __need___va_list #include <bits/c++config.h> #include <stdarg.h> #ifndef _GLIBCXX_CSTDARG #define _GLIBCXX_CSTDARG 1 // Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 #ifndef va_end #define va_end(ap) va_end (ap) #endif namespace std { using ::va_list; } // namespace std #endif c++/8/csetjmp 0000644 00000003635 15146341150 0006662 0 ustar 00 // -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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 csetjmp * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c setjmp.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.4.6 C library // #pragma GCC system_header #include <bits/c++config.h> #include <setjmp.h> #ifndef _GLIBCXX_CSETJMP #define _GLIBCXX_CSETJMP 1 // Get rid of those macros defined in <setjmp.h> in lieu of real functions. #undef longjmp // Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 #ifndef setjmp #define setjmp(env) setjmp (env) #endif namespace std { using ::jmp_buf; using ::longjmp; } // namespace std #endif c++/8/cwctype 0000644 00000005351 15146341150 0006670 0 ustar 00 // -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cwctype * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c wctype.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: <cwctype> // #pragma GCC system_header #include <bits/c++config.h> #if _GLIBCXX_HAVE_WCTYPE_H #if __GLIBC__ == 2 && __GLIBC_MINOR__ < 10 // Work around glibc BZ 9694 #include <stddef.h> #endif #include <wctype.h> #endif // _GLIBCXX_HAVE_WCTYPE_H #ifndef _GLIBCXX_CWCTYPE #define _GLIBCXX_CWCTYPE 1 // Get rid of those macros defined in <wctype.h> in lieu of real functions. #undef iswalnum #undef iswalpha #if _GLIBCXX_HAVE_ISWBLANK # undef iswblank #endif #undef iswcntrl #undef iswctype #undef iswdigit #undef iswgraph #undef iswlower #undef iswprint #undef iswpunct #undef iswspace #undef iswupper #undef iswxdigit #undef towctrans #undef towlower #undef towupper #undef wctrans #undef wctype #if _GLIBCXX_USE_WCHAR_T namespace std { using ::wctrans_t; using ::wctype_t; using ::wint_t; using ::iswalnum; using ::iswalpha; #if _GLIBCXX_HAVE_ISWBLANK using ::iswblank; #endif using ::iswcntrl; using ::iswctype; using ::iswdigit; using ::iswgraph; using ::iswlower; using ::iswprint; using ::iswpunct; using ::iswspace; using ::iswupper; using ::iswxdigit; using ::towctrans; using ::towlower; using ::towupper; using ::wctrans; using ::wctype; } // namespace #endif //_GLIBCXX_USE_WCHAR_T #endif // _GLIBCXX_CWCTYPE c++/8/map 0000644 00000004777 15146341150 0006002 0 ustar 00 // <map> -*- C++ -*- // Copyright (C) 2001-2018 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/map * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_MAP #define _GLIBCXX_MAP 1 #pragma GCC system_header #include <bits/stl_tree.h> #include <bits/stl_map.h> #include <bits/stl_multimap.h> #include <bits/range_access.h> #ifdef _GLIBCXX_DEBUG # include <debug/map> #endif #ifdef _GLIBCXX_PROFILE # include <profile/map> #endif #endif /* _GLIBCXX_MAP */ c++/8/ext/functional 0000644 00000033724 15146341150 0010161 0 ustar 00 // Functional extensions -*- C++ -*- // Copyright (C) 2002-2018 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 * 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 ext/functional * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_FUNCTIONAL #define _EXT_FUNCTIONAL 1 #pragma GCC system_header #include <functional> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::unary_function; using std::binary_function; using std::mem_fun1_t; using std::const_mem_fun1_t; using std::mem_fun1_ref_t; using std::const_mem_fun1_ref_t; /** The @c identity_element functions are not part of the C++ * standard; SGI provided them as an extension. Its argument is an * operation, and its return value is the identity element for that * operation. It is overloaded for addition and multiplication, * and you can overload it for your own nefarious operations. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template <class _Tp> inline _Tp identity_element(std::plus<_Tp>) { return _Tp(0); } /// An \link SGIextensions SGI extension \endlink. template <class _Tp> inline _Tp identity_element(std::multiplies<_Tp>) { return _Tp(1); } /** @} */ /** As an extension to the binders, SGI provided composition functors and * wrapper functions to aid in their creation. The @c unary_compose * functor is constructed from two functions/functors, @c f and @c g. * Calling @c operator() with a single argument @c x returns @c f(g(x)). * The function @c compose1 takes the two functions and constructs a * @c unary_compose variable for you. * * @c binary_compose is constructed from three functors, @c f, @c g1, * and @c g2. Its @c operator() returns @c f(g1(x),g2(x)). The function * compose2 takes f, g1, and g2, and constructs the @c binary_compose * instance for you. For example, if @c f returns an int, then * \code * int answer = (compose2(f,g1,g2))(x); * \endcode * is equivalent to * \code * int temp1 = g1(x); * int temp2 = g2(x); * int answer = f(temp1,temp2); * \endcode * But the first form is more compact, and can be passed around as a * functor to other algorithms. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template <class _Operation1, class _Operation2> class unary_compose : public unary_function<typename _Operation2::argument_type, typename _Operation1::result_type> { protected: _Operation1 _M_fn1; _Operation2 _M_fn2; public: unary_compose(const _Operation1& __x, const _Operation2& __y) : _M_fn1(__x), _M_fn2(__y) {} typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { return _M_fn1(_M_fn2(__x)); } }; /// An \link SGIextensions SGI extension \endlink. template <class _Operation1, class _Operation2> inline unary_compose<_Operation1, _Operation2> compose1(const _Operation1& __fn1, const _Operation2& __fn2) { return unary_compose<_Operation1,_Operation2>(__fn1, __fn2); } /// An \link SGIextensions SGI extension \endlink. template <class _Operation1, class _Operation2, class _Operation3> class binary_compose : public unary_function<typename _Operation2::argument_type, typename _Operation1::result_type> { protected: _Operation1 _M_fn1; _Operation2 _M_fn2; _Operation3 _M_fn3; public: binary_compose(const _Operation1& __x, const _Operation2& __y, const _Operation3& __z) : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { } typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const { return _M_fn1(_M_fn2(__x), _M_fn3(__x)); } }; /// An \link SGIextensions SGI extension \endlink. template <class _Operation1, class _Operation2, class _Operation3> inline binary_compose<_Operation1, _Operation2, _Operation3> compose2(const _Operation1& __fn1, const _Operation2& __fn2, const _Operation3& __fn3) { return binary_compose<_Operation1, _Operation2, _Operation3> (__fn1, __fn2, __fn3); } /** @} */ /** As an extension, SGI provided a functor called @c identity. When a * functor is required but no operations are desired, this can be used as a * pass-through. Its @c operator() returns its argument unchanged. * * @addtogroup SGIextensions */ template <class _Tp> struct identity : public std::_Identity<_Tp> {}; /** @c select1st and @c select2nd are extensions provided by SGI. Their * @c operator()s * take a @c std::pair as an argument, and return either the first member * or the second member, respectively. They can be used (especially with * the composition functors) to @a strip data from a sequence before * performing the remainder of an algorithm. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template <class _Pair> struct select1st : public std::_Select1st<_Pair> {}; /// An \link SGIextensions SGI extension \endlink. template <class _Pair> struct select2nd : public std::_Select2nd<_Pair> {}; /** @} */ // extension documented next template <class _Arg1, class _Arg2> struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } }; template <class _Arg1, class _Arg2> struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } }; /** The @c operator() of the @c project1st functor takes two arbitrary * arguments and returns the first one, while @c project2nd returns the * second one. They are extensions provided by SGI. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template <class _Arg1, class _Arg2> struct project1st : public _Project1st<_Arg1, _Arg2> {}; /// An \link SGIextensions SGI extension \endlink. template <class _Arg1, class _Arg2> struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; /** @} */ // extension documented next template <class _Result> struct _Constant_void_fun { typedef _Result result_type; result_type _M_val; _Constant_void_fun(const result_type& __v) : _M_val(__v) {} const result_type& operator()() const { return _M_val; } }; template <class _Result, class _Argument> struct _Constant_unary_fun { typedef _Argument argument_type; typedef _Result result_type; result_type _M_val; _Constant_unary_fun(const result_type& __v) : _M_val(__v) {} const result_type& operator()(const _Argument&) const { return _M_val; } }; template <class _Result, class _Arg1, class _Arg2> struct _Constant_binary_fun { typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; _Result _M_val; _Constant_binary_fun(const _Result& __v) : _M_val(__v) {} const result_type& operator()(const _Arg1&, const _Arg2&) const { return _M_val; } }; /** These three functors are each constructed from a single arbitrary * variable/value. Later, their @c operator()s completely ignore any * arguments passed, and return the stored value. * - @c constant_void_fun's @c operator() takes no arguments * - @c constant_unary_fun's @c operator() takes one argument (ignored) * - @c constant_binary_fun's @c operator() takes two arguments (ignored) * * The helper creator functions @c constant0, @c constant1, and * @c constant2 each take a @a result argument and construct variables of * the appropriate functor type. * * @addtogroup SGIextensions * @{ */ /// An \link SGIextensions SGI extension \endlink. template <class _Result> struct constant_void_fun : public _Constant_void_fun<_Result> { constant_void_fun(const _Result& __v) : _Constant_void_fun<_Result>(__v) {} }; /// An \link SGIextensions SGI extension \endlink. template <class _Result, class _Argument = _Result> struct constant_unary_fun : public _Constant_unary_fun<_Result, _Argument> { constant_unary_fun(const _Result& __v) : _Constant_unary_fun<_Result, _Argument>(__v) {} }; /// An \link SGIextensions SGI extension \endlink. template <class _Result, class _Arg1 = _Result, class _Arg2 = _Arg1> struct constant_binary_fun : public _Constant_binary_fun<_Result, _Arg1, _Arg2> { constant_binary_fun(const _Result& __v) : _Constant_binary_fun<_Result, _Arg1, _Arg2>(__v) {} }; /// An \link SGIextensions SGI extension \endlink. template <class _Result> inline constant_void_fun<_Result> constant0(const _Result& __val) { return constant_void_fun<_Result>(__val); } /// An \link SGIextensions SGI extension \endlink. template <class _Result> inline constant_unary_fun<_Result, _Result> constant1(const _Result& __val) { return constant_unary_fun<_Result, _Result>(__val); } /// An \link SGIextensions SGI extension \endlink. template <class _Result> inline constant_binary_fun<_Result,_Result,_Result> constant2(const _Result& __val) { return constant_binary_fun<_Result, _Result, _Result>(__val); } /** @} */ /** The @c subtractive_rng class is documented on * <a href="http://www.sgi.com/tech/stl/">SGI's site</a>. * Note that this code assumes that @c int is 32 bits. * * @ingroup SGIextensions */ class subtractive_rng : public unary_function<unsigned int, unsigned int> { private: unsigned int _M_table[55]; size_t _M_index1; size_t _M_index2; public: /// Returns a number less than the argument. unsigned int operator()(unsigned int __limit) { _M_index1 = (_M_index1 + 1) % 55; _M_index2 = (_M_index2 + 1) % 55; _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2]; return _M_table[_M_index1] % __limit; } void _M_initialize(unsigned int __seed) { unsigned int __k = 1; _M_table[54] = __seed; size_t __i; for (__i = 0; __i < 54; __i++) { size_t __ii = (21 * (__i + 1) % 55) - 1; _M_table[__ii] = __k; __k = __seed - __k; __seed = _M_table[__ii]; } for (int __loop = 0; __loop < 4; __loop++) { for (__i = 0; __i < 55; __i++) _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; } _M_index1 = 0; _M_index2 = 31; } /// Ctor allowing you to initialize the seed. subtractive_rng(unsigned int __seed) { _M_initialize(__seed); } /// Default ctor; initializes its state with some number you don't see. subtractive_rng() { _M_initialize(161803398u); } }; // Mem_fun adaptor helper functions mem_fun1 and mem_fun1_ref, // provided for backward compatibility, they are no longer part of // the C++ standard. template <class _Ret, class _Tp, class _Arg> inline mem_fun1_t<_Ret, _Tp, _Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } template <class _Ret, class _Tp, class _Arg> inline const_mem_fun1_t<_Ret, _Tp, _Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } template <class _Ret, class _Tp, class _Arg> inline mem_fun1_ref_t<_Ret, _Tp, _Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } template <class _Ret, class _Tp, class _Arg> inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/ropeimpl.h 0000644 00000136465 15146341150 0010102 0 ustar 00 // SGI's rope class implementation -*- C++ -*- // Copyright (C) 2001-2018 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) 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 ropeimpl.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/rope} */ #include <cstdio> #include <ostream> #include <bits/functexcept.h> #include <ext/algorithm> // For copy_n and lexicographical_compare_3way #include <ext/memory> // For uninitialized_copy_n #include <ext/numeric> // For power namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::printf; using std::basic_ostream; using std::__throw_length_error; using std::_Destroy; using std::__uninitialized_fill_n_a; // Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf // if necessary. Assumes _M_path_end[leaf_index] and leaf_pos are correct. // Results in a valid buf_ptr if the iterator can be legitimately // dereferenced. template <class _CharT, class _Alloc> void _Rope_iterator_base<_CharT, _Alloc>:: _S_setbuf(_Rope_iterator_base<_CharT, _Alloc>& __x) { const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index]; size_t __leaf_pos = __x._M_leaf_pos; size_t __pos = __x._M_current_pos; switch(__leaf->_M_tag) { case __detail::_S_leaf: __x._M_buf_start = ((_Rope_RopeLeaf<_CharT, _Alloc>*)__leaf)->_M_data; __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos); __x._M_buf_end = __x._M_buf_start + __leaf->_M_size; break; case __detail::_S_function: case __detail::_S_substringfn: { size_t __len = _S_iterator_buf_len; size_t __buf_start_pos = __leaf_pos; size_t __leaf_end = __leaf_pos + __leaf->_M_size; char_producer<_CharT>* __fn = ((_Rope_RopeFunction<_CharT, _Alloc>*)__leaf)->_M_fn; if (__buf_start_pos + __len <= __pos) { __buf_start_pos = __pos - __len / 4; if (__buf_start_pos + __len > __leaf_end) __buf_start_pos = __leaf_end - __len; } if (__buf_start_pos + __len > __leaf_end) __len = __leaf_end - __buf_start_pos; (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf); __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos); __x._M_buf_start = __x._M_tmp_buf; __x._M_buf_end = __x._M_tmp_buf + __len; } break; default: break; } } // Set path and buffer inside a rope iterator. We assume that // pos and root are already set. template <class _CharT, class _Alloc> void _Rope_iterator_base<_CharT, _Alloc>:: _S_setcache(_Rope_iterator_base<_CharT, _Alloc>& __x) { const _RopeRep* __path[int(__detail::_S_max_rope_depth) + 1]; const _RopeRep* __curr_rope; int __curr_depth = -1; /* index into path */ size_t __curr_start_pos = 0; size_t __pos = __x._M_current_pos; unsigned char __dirns = 0; // Bit vector marking right turns in the path if (__pos >= __x._M_root->_M_size) { __x._M_buf_ptr = 0; return; } __curr_rope = __x._M_root; if (0 != __curr_rope->_M_c_string) { /* Treat the root as a leaf. */ __x._M_buf_start = __curr_rope->_M_c_string; __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size; __x._M_buf_ptr = __curr_rope->_M_c_string + __pos; __x._M_path_end[0] = __curr_rope; __x._M_leaf_index = 0; __x._M_leaf_pos = 0; return; } for(;;) { ++__curr_depth; __path[__curr_depth] = __curr_rope; switch(__curr_rope->_M_tag) { case __detail::_S_leaf: case __detail::_S_function: case __detail::_S_substringfn: __x._M_leaf_pos = __curr_start_pos; goto done; case __detail::_S_concat: { _Rope_RopeConcatenation<_CharT, _Alloc>* __c = (_Rope_RopeConcatenation<_CharT, _Alloc>*)__curr_rope; _RopeRep* __left = __c->_M_left; size_t __left_len = __left->_M_size; __dirns <<= 1; if (__pos >= __curr_start_pos + __left_len) { __dirns |= 1; __curr_rope = __c->_M_right; __curr_start_pos += __left_len; } else __curr_rope = __left; } break; } } done: // Copy last section of path into _M_path_end. { int __i = -1; int __j = __curr_depth + 1 - int(_S_path_cache_len); if (__j < 0) __j = 0; while (__j <= __curr_depth) __x._M_path_end[++__i] = __path[__j++]; __x._M_leaf_index = __i; } __x._M_path_directions = __dirns; _S_setbuf(__x); } // Specialized version of the above. Assumes that // the path cache is valid for the previous position. template <class _CharT, class _Alloc> void _Rope_iterator_base<_CharT, _Alloc>:: _S_setcache_for_incr(_Rope_iterator_base<_CharT, _Alloc>& __x) { int __current_index = __x._M_leaf_index; const _RopeRep* __current_node = __x._M_path_end[__current_index]; size_t __len = __current_node->_M_size; size_t __node_start_pos = __x._M_leaf_pos; unsigned char __dirns = __x._M_path_directions; _Rope_RopeConcatenation<_CharT, _Alloc>* __c; if (__x._M_current_pos - __node_start_pos < __len) { /* More stuff in this leaf, we just didn't cache it. */ _S_setbuf(__x); return; } // node_start_pos is starting position of last_node. while (--__current_index >= 0) { if (!(__dirns & 1) /* Path turned left */) break; __current_node = __x._M_path_end[__current_index]; __c = (_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node; // Otherwise we were in the right child. Thus we should pop // the concatenation node. __node_start_pos -= __c->_M_left->_M_size; __dirns >>= 1; } if (__current_index < 0) { // We underflowed the cache. Punt. _S_setcache(__x); return; } __current_node = __x._M_path_end[__current_index]; __c = (_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node; // current_node is a concatenation node. We are positioned on the first // character in its right child. // node_start_pos is starting position of current_node. __node_start_pos += __c->_M_left->_M_size; __current_node = __c->_M_right; __x._M_path_end[++__current_index] = __current_node; __dirns |= 1; while (__detail::_S_concat == __current_node->_M_tag) { ++__current_index; if (int(_S_path_cache_len) == __current_index) { int __i; for (__i = 0; __i < int(_S_path_cache_len) - 1; __i++) __x._M_path_end[__i] = __x._M_path_end[__i+1]; --__current_index; } __current_node = ((_Rope_RopeConcatenation<_CharT, _Alloc>*)__current_node)->_M_left; __x._M_path_end[__current_index] = __current_node; __dirns <<= 1; // node_start_pos is unchanged. } __x._M_leaf_index = __current_index; __x._M_leaf_pos = __node_start_pos; __x._M_path_directions = __dirns; _S_setbuf(__x); } template <class _CharT, class _Alloc> void _Rope_iterator_base<_CharT, _Alloc>:: _M_incr(size_t __n) { _M_current_pos += __n; if (0 != _M_buf_ptr) { size_t __chars_left = _M_buf_end - _M_buf_ptr; if (__chars_left > __n) _M_buf_ptr += __n; else if (__chars_left == __n) { _M_buf_ptr += __n; _S_setcache_for_incr(*this); } else _M_buf_ptr = 0; } } template <class _CharT, class _Alloc> void _Rope_iterator_base<_CharT, _Alloc>:: _M_decr(size_t __n) { if (0 != _M_buf_ptr) { size_t __chars_left = _M_buf_ptr - _M_buf_start; if (__chars_left >= __n) _M_buf_ptr -= __n; else _M_buf_ptr = 0; } _M_current_pos -= __n; } template <class _CharT, class _Alloc> void _Rope_iterator<_CharT, _Alloc>:: _M_check() { if (_M_root_rope->_M_tree_ptr != this->_M_root) { // _Rope was modified. Get things fixed up. _RopeRep::_S_unref(this->_M_root); this->_M_root = _M_root_rope->_M_tree_ptr; _RopeRep::_S_ref(this->_M_root); this->_M_buf_ptr = 0; } } template <class _CharT, class _Alloc> inline _Rope_const_iterator<_CharT, _Alloc>:: _Rope_const_iterator(const _Rope_iterator<_CharT, _Alloc>& __x) : _Rope_iterator_base<_CharT, _Alloc>(__x) { } template <class _CharT, class _Alloc> inline _Rope_iterator<_CharT, _Alloc>:: _Rope_iterator(rope<_CharT, _Alloc>& __r, size_t __pos) : _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos), _M_root_rope(&__r) { _RopeRep::_S_ref(this->_M_root); } template <class _CharT, class _Alloc> inline size_t rope<_CharT, _Alloc>:: _S_char_ptr_len(const _CharT* __s) { const _CharT* __p = __s; while (!_S_is0(*__p)) ++__p; return (__p - __s); } #ifndef __GC template <class _CharT, class _Alloc> inline void _Rope_RopeRep<_CharT, _Alloc>:: _M_free_c_string() { _CharT* __cstr = _M_c_string; if (0 != __cstr) { size_t __size = this->_M_size + 1; _Destroy(__cstr, __cstr + __size, _M_get_allocator()); this->_Data_deallocate(__cstr, __size); } } template <class _CharT, class _Alloc> inline void _Rope_RopeRep<_CharT, _Alloc>:: _S_free_string(_CharT* __s, size_t __n, allocator_type& __a) { if (!_S_is_basic_char_type((_CharT*)0)) _Destroy(__s, __s + __n, __a); // This has to be a static member, so this gets a bit messy __a.deallocate(__s, _Rope_RopeLeaf<_CharT, _Alloc>::_S_rounded_up_size(__n)); } // There are several reasons for not doing this with virtual destructors // and a class specific delete operator: // - A class specific delete operator can't easily get access to // allocator instances if we need them. // - Any virtual function would need a 4 or byte vtable pointer; // this only requires a one byte tag per object. template <class _CharT, class _Alloc> void _Rope_RopeRep<_CharT, _Alloc>:: _M_free_tree() { switch(_M_tag) { case __detail::_S_leaf: { _Rope_RopeLeaf<_CharT, _Alloc>* __l = (_Rope_RopeLeaf<_CharT, _Alloc>*)this; __l->_Rope_RopeLeaf<_CharT, _Alloc>::~_Rope_RopeLeaf(); this->_L_deallocate(__l, 1); break; } case __detail::_S_concat: { _Rope_RopeConcatenation<_CharT,_Alloc>* __c = (_Rope_RopeConcatenation<_CharT, _Alloc>*)this; __c->_Rope_RopeConcatenation<_CharT, _Alloc>:: ~_Rope_RopeConcatenation(); this->_C_deallocate(__c, 1); break; } case __detail::_S_function: { _Rope_RopeFunction<_CharT, _Alloc>* __f = (_Rope_RopeFunction<_CharT, _Alloc>*)this; __f->_Rope_RopeFunction<_CharT, _Alloc>::~_Rope_RopeFunction(); this->_F_deallocate(__f, 1); break; } case __detail::_S_substringfn: { _Rope_RopeSubstring<_CharT, _Alloc>* __ss = (_Rope_RopeSubstring<_CharT, _Alloc>*)this; __ss->_Rope_RopeSubstring<_CharT, _Alloc>:: ~_Rope_RopeSubstring(); this->_S_deallocate(__ss, 1); break; } } } #else template <class _CharT, class _Alloc> inline void _Rope_RopeRep<_CharT, _Alloc>:: _S_free_string(const _CharT*, size_t, allocator_type) { } #endif // Concatenate a C string onto a leaf rope by copying the rope data. // Used for short ropes. template <class _CharT, class _Alloc> typename rope<_CharT, _Alloc>::_RopeLeaf* rope<_CharT, _Alloc>:: _S_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, size_t __len) { size_t __old_len = __r->_M_size; _CharT* __new_data = (_CharT*) rope::_Data_allocate(_S_rounded_up_size(__old_len + __len)); _RopeLeaf* __result; uninitialized_copy_n(__r->_M_data, __old_len, __new_data); uninitialized_copy_n(__iter, __len, __new_data + __old_len); _S_cond_store_eos(__new_data[__old_len + __len]); __try { __result = _S_new_RopeLeaf(__new_data, __old_len + __len, __r->_M_get_allocator()); } __catch(...) { _RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len, __r->_M_get_allocator()); __throw_exception_again; } return __result; } #ifndef __GC // As above, but it's OK to clobber original if refcount is 1 template <class _CharT, class _Alloc> typename rope<_CharT,_Alloc>::_RopeLeaf* rope<_CharT, _Alloc>:: _S_destr_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, size_t __len) { if (__r->_M_ref_count > 1) return _S_leaf_concat_char_iter(__r, __iter, __len); size_t __old_len = __r->_M_size; if (_S_allocated_capacity(__old_len) >= __old_len + __len) { // The space has been partially initialized for the standard // character types. But that doesn't matter for those types. uninitialized_copy_n(__iter, __len, __r->_M_data + __old_len); if (_S_is_basic_char_type((_CharT*)0)) _S_cond_store_eos(__r->_M_data[__old_len + __len]); else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) { __r->_M_free_c_string(); __r->_M_c_string = 0; } __r->_M_size = __old_len + __len; __r->_M_ref_count = 2; return __r; } else { _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len); return __result; } } #endif // Assumes left and right are not 0. // Does not increment (nor decrement on exception) child reference counts. // Result has ref count 1. template <class _CharT, class _Alloc> typename rope<_CharT, _Alloc>::_RopeRep* rope<_CharT, _Alloc>:: _S_tree_concat(_RopeRep* __left, _RopeRep* __right) { _RopeConcatenation* __result = _S_new_RopeConcatenation(__left, __right, __left-> _M_get_allocator()); size_t __depth = __result->_M_depth; if (__depth > 20 && (__result->_M_size < 1000 || __depth > size_t(__detail::_S_max_rope_depth))) { _RopeRep* __balanced; __try { __balanced = _S_balance(__result); __result->_M_unref_nonnil(); } __catch(...) { rope::_C_deallocate(__result,1); __throw_exception_again; } // In case of exception, we need to deallocate // otherwise dangling result node. But caller // still owns its children. Thus unref is // inappropriate. return __balanced; } else return __result; } template <class _CharT, class _Alloc> typename rope<_CharT, _Alloc>::_RopeRep* rope<_CharT, _Alloc>:: _S_concat_char_iter(_RopeRep* __r, const _CharT*__s, size_t __slen) { _RopeRep* __result; if (0 == __slen) { _S_ref(__r); return __r; } if (0 == __r) return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator()); if (__r->_M_tag == __detail::_S_leaf && __r->_M_size + __slen <= size_t(_S_copy_max)) { __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); return __result; } if (__detail::_S_concat == __r->_M_tag && __detail::_S_leaf == ((_RopeConcatenation*) __r)->_M_right->_M_tag) { _RopeLeaf* __right = (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right); if (__right->_M_size + __slen <= size_t(_S_copy_max)) { _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left; _RopeRep* __nright = _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen); __left->_M_ref_nonnil(); __try { __result = _S_tree_concat(__left, __nright); } __catch(...) { _S_unref(__left); _S_unref(__nright); __throw_exception_again; } return __result; } } _RopeRep* __nright = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator()); __try { __r->_M_ref_nonnil(); __result = _S_tree_concat(__r, __nright); } __catch(...) { _S_unref(__r); _S_unref(__nright); __throw_exception_again; } return __result; } #ifndef __GC template <class _CharT, class _Alloc> typename rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>:: _S_destr_concat_char_iter(_RopeRep* __r, const _CharT* __s, size_t __slen) { _RopeRep* __result; if (0 == __r) return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator()); size_t __count = __r->_M_ref_count; size_t __orig_size = __r->_M_size; if (__count > 1) return _S_concat_char_iter(__r, __s, __slen); if (0 == __slen) { __r->_M_ref_count = 2; // One more than before return __r; } if (__orig_size + __slen <= size_t(_S_copy_max) && __detail::_S_leaf == __r->_M_tag) { __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); return __result; } if (__detail::_S_concat == __r->_M_tag) { _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*) __r)->_M_right); if (__detail::_S_leaf == __right->_M_tag && __right->_M_size + __slen <= size_t(_S_copy_max)) { _RopeRep* __new_right = _S_destr_leaf_concat_char_iter(__right, __s, __slen); if (__right == __new_right) __new_right->_M_ref_count = 1; else __right->_M_unref_nonnil(); __r->_M_ref_count = 2; // One more than before. ((_RopeConcatenation*)__r)->_M_right = __new_right; __r->_M_size = __orig_size + __slen; if (0 != __r->_M_c_string) { __r->_M_free_c_string(); __r->_M_c_string = 0; } return __r; } } _RopeRep* __right = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->_M_get_allocator()); __r->_M_ref_nonnil(); __try { __result = _S_tree_concat(__r, __right); } __catch(...) { _S_unref(__r); _S_unref(__right); __throw_exception_again; } return __result; } #endif /* !__GC */ template <class _CharT, class _Alloc> typename rope<_CharT, _Alloc>::_RopeRep* rope<_CharT, _Alloc>:: _S_concat(_RopeRep* __left, _RopeRep* __right) { if (0 == __left) { _S_ref(__right); return __right; } if (0 == __right) { __left->_M_ref_nonnil(); return __left; } if (__detail::_S_leaf == __right->_M_tag) { if (__detail::_S_leaf == __left->_M_tag) { if (__right->_M_size + __left->_M_size <= size_t(_S_copy_max)) return _S_leaf_concat_char_iter((_RopeLeaf*)__left, ((_RopeLeaf*)__right)->_M_data, __right->_M_size); } else if (__detail::_S_concat == __left->_M_tag && __detail::_S_leaf == ((_RopeConcatenation*) __left)->_M_right->_M_tag) { _RopeLeaf* __leftright = (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right); if (__leftright->_M_size + __right->_M_size <= size_t(_S_copy_max)) { _RopeRep* __leftleft = ((_RopeConcatenation*)__left)->_M_left; _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright, ((_RopeLeaf*) __right)-> _M_data, __right->_M_size); __leftleft->_M_ref_nonnil(); __try { return(_S_tree_concat(__leftleft, __rest)); } __catch(...) { _S_unref(__leftleft); _S_unref(__rest); __throw_exception_again; } } } } __left->_M_ref_nonnil(); __right->_M_ref_nonnil(); __try { return(_S_tree_concat(__left, __right)); } __catch(...) { _S_unref(__left); _S_unref(__right); __throw_exception_again; } } template <class _CharT, class _Alloc> typename rope<_CharT, _Alloc>::_RopeRep* rope<_CharT, _Alloc>:: _S_substring(_RopeRep* __base, size_t __start, size_t __endp1) { if (0 == __base) return 0; size_t __len = __base->_M_size; size_t __adj_endp1; const size_t __lazy_threshold = 128; if (__endp1 >= __len) { if (0 == __start) { __base->_M_ref_nonnil(); return __base; } else __adj_endp1 = __len; } else __adj_endp1 = __endp1; switch(__base->_M_tag) { case __detail::_S_concat: { _RopeConcatenation* __c = (_RopeConcatenation*)__base; _RopeRep* __left = __c->_M_left; _RopeRep* __right = __c->_M_right; size_t __left_len = __left->_M_size; _RopeRep* __result; if (__adj_endp1 <= __left_len) return _S_substring(__left, __start, __endp1); else if (__start >= __left_len) return _S_substring(__right, __start - __left_len, __adj_endp1 - __left_len); _Self_destruct_ptr __left_result(_S_substring(__left, __start, __left_len)); _Self_destruct_ptr __right_result(_S_substring(__right, 0, __endp1 - __left_len)); __result = _S_concat(__left_result, __right_result); return __result; } case __detail::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__base; _RopeLeaf* __result; size_t __result_len; if (__start >= __adj_endp1) return 0; __result_len = __adj_endp1 - __start; if (__result_len > __lazy_threshold) goto lazy; #ifdef __GC const _CharT* __section = __l->_M_data + __start; __result = _S_new_RopeLeaf(__section, __result_len, __base->_M_get_allocator()); __result->_M_c_string = 0; // Not eos terminated. #else // We should sometimes create substring node instead. __result = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__l->_M_data + __start, __result_len, __base-> _M_get_allocator()); #endif return __result; } case __detail::_S_substringfn: // Avoid introducing multiple layers of substring nodes. { _RopeSubstring* __old = (_RopeSubstring*)__base; size_t __result_len; if (__start >= __adj_endp1) return 0; __result_len = __adj_endp1 - __start; if (__result_len > __lazy_threshold) { _RopeSubstring* __result = _S_new_RopeSubstring(__old->_M_base, __start + __old->_M_start, __adj_endp1 - __start, __base->_M_get_allocator()); return __result; } // *** else fall through: *** } case __detail::_S_function: { _RopeFunction* __f = (_RopeFunction*)__base; _CharT* __section; size_t __result_len; if (__start >= __adj_endp1) return 0; __result_len = __adj_endp1 - __start; if (__result_len > __lazy_threshold) goto lazy; __section = (_CharT*) rope::_Data_allocate(_S_rounded_up_size(__result_len)); __try { (*(__f->_M_fn))(__start, __result_len, __section); } __catch(...) { _RopeRep::__STL_FREE_STRING(__section, __result_len, __base->_M_get_allocator()); __throw_exception_again; } _S_cond_store_eos(__section[__result_len]); return _S_new_RopeLeaf(__section, __result_len, __base->_M_get_allocator()); } } lazy: { // Create substring node. return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start, __base->_M_get_allocator()); } } template<class _CharT> class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> { private: _CharT* _M_buf_ptr; public: _Rope_flatten_char_consumer(_CharT* __buffer) { _M_buf_ptr = __buffer; } ~_Rope_flatten_char_consumer() {} bool operator()(const _CharT* __leaf, size_t __n) { uninitialized_copy_n(__leaf, __n, _M_buf_ptr); _M_buf_ptr += __n; return true; } }; template<class _CharT> class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> { private: _CharT _M_pattern; public: size_t _M_count; // Number of nonmatching characters _Rope_find_char_char_consumer(_CharT __p) : _M_pattern(__p), _M_count(0) {} ~_Rope_find_char_char_consumer() {} bool operator()(const _CharT* __leaf, size_t __n) { size_t __i; for (__i = 0; __i < __n; __i++) { if (__leaf[__i] == _M_pattern) { _M_count += __i; return false; } } _M_count += __n; return true; } }; template<class _CharT, class _Traits> // Here _CharT is both the stream and rope character type. class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> { private: typedef basic_ostream<_CharT,_Traits> _Insert_ostream; _Insert_ostream& _M_o; public: _Rope_insert_char_consumer(_Insert_ostream& __writer) : _M_o(__writer) {} ~_Rope_insert_char_consumer() { } // Caller is presumed to own the ostream bool operator() (const _CharT* __leaf, size_t __n); // Returns true to continue traversal. }; template<class _CharT, class _Traits> bool _Rope_insert_char_consumer<_CharT, _Traits>:: operator()(const _CharT* __leaf, size_t __n) { size_t __i; // We assume that formatting is set up correctly for each element. for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); return true; } template <class _CharT, class _Alloc> bool rope<_CharT, _Alloc>:: _S_apply_to_pieces(_Rope_char_consumer<_CharT>& __c, const _RopeRep* __r, size_t __begin, size_t __end) { if (0 == __r) return true; switch(__r->_M_tag) { case __detail::_S_concat: { _RopeConcatenation* __conc = (_RopeConcatenation*)__r; _RopeRep* __left = __conc->_M_left; size_t __left_len = __left->_M_size; if (__begin < __left_len) { size_t __left_end = std::min(__left_len, __end); if (!_S_apply_to_pieces(__c, __left, __begin, __left_end)) return false; } if (__end > __left_len) { _RopeRep* __right = __conc->_M_right; size_t __right_start = std::max(__left_len, __begin); if (!_S_apply_to_pieces(__c, __right, __right_start - __left_len, __end - __left_len)) return false; } } return true; case __detail::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; return __c(__l->_M_data + __begin, __end - __begin); } case __detail::_S_function: case __detail::_S_substringfn: { _RopeFunction* __f = (_RopeFunction*)__r; size_t __len = __end - __begin; bool __result; _CharT* __buffer = (_CharT*)_Alloc().allocate(__len * sizeof(_CharT)); __try { (*(__f->_M_fn))(__begin, __len, __buffer); __result = __c(__buffer, __len); _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); } __catch(...) { _Alloc().deallocate(__buffer, __len * sizeof(_CharT)); __throw_exception_again; } return __result; } default: return false; } } template<class _CharT, class _Traits> inline void _Rope_fill(basic_ostream<_CharT, _Traits>& __o, size_t __n) { char __f = __o.fill(); size_t __i; for (__i = 0; __i < __n; __i++) __o.put(__f); } template <class _CharT> inline bool _Rope_is_simple(_CharT*) { return false; } inline bool _Rope_is_simple(char*) { return true; } inline bool _Rope_is_simple(wchar_t*) { return true; } template<class _CharT, class _Traits, class _Alloc> basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __o, const rope<_CharT, _Alloc>& __r) { size_t __w = __o.width(); bool __left = bool(__o.flags() & std::ios::left); size_t __pad_len; size_t __rope_len = __r.size(); _Rope_insert_char_consumer<_CharT, _Traits> __c(__o); bool __is_simple = _Rope_is_simple((_CharT*)0); if (__rope_len < __w) __pad_len = __w - __rope_len; else __pad_len = 0; if (!__is_simple) __o.width(__w / __rope_len); __try { if (__is_simple && !__left && __pad_len > 0) _Rope_fill(__o, __pad_len); __r.apply_to_pieces(0, __r.size(), __c); if (__is_simple && __left && __pad_len > 0) _Rope_fill(__o, __pad_len); if (!__is_simple) __o.width(__w); } __catch(...) { if (!__is_simple) __o.width(__w); __throw_exception_again; } return __o; } template <class _CharT, class _Alloc> _CharT* rope<_CharT, _Alloc>:: _S_flatten(_RopeRep* __r, size_t __start, size_t __len, _CharT* __buffer) { _Rope_flatten_char_consumer<_CharT> __c(__buffer); _S_apply_to_pieces(__c, __r, __start, __start + __len); return(__buffer + __len); } template <class _CharT, class _Alloc> size_t rope<_CharT, _Alloc>:: find(_CharT __pattern, size_t __start) const { _Rope_find_char_char_consumer<_CharT> __c(__pattern); _S_apply_to_pieces(__c, this->_M_tree_ptr, __start, size()); size_type __result_pos = __start + __c._M_count; #ifndef __STL_OLD_ROPE_SEMANTICS if (__result_pos == size()) __result_pos = npos; #endif return __result_pos; } template <class _CharT, class _Alloc> _CharT* rope<_CharT, _Alloc>:: _S_flatten(_RopeRep* __r, _CharT* __buffer) { if (0 == __r) return __buffer; switch(__r->_M_tag) { case __detail::_S_concat: { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _RopeRep* __left = __c->_M_left; _RopeRep* __right = __c->_M_right; _CharT* __rest = _S_flatten(__left, __buffer); return _S_flatten(__right, __rest); } case __detail::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; return copy_n(__l->_M_data, __l->_M_size, __buffer).second; } case __detail::_S_function: case __detail::_S_substringfn: // We don't yet do anything with substring nodes. // This needs to be fixed before ropefiles will work well. { _RopeFunction* __f = (_RopeFunction*)__r; (*(__f->_M_fn))(0, __f->_M_size, __buffer); return __buffer + __f->_M_size; } default: return 0; } } // This needs work for _CharT != char template <class _CharT, class _Alloc> void rope<_CharT, _Alloc>:: _S_dump(_RopeRep* __r, int __indent) { for (int __i = 0; __i < __indent; __i++) putchar(' '); if (0 == __r) { printf("NULL\n"); return; } if (__detail::_S_concat == __r->_M_tag) { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _RopeRep* __left = __c->_M_left; _RopeRep* __right = __c->_M_right; #ifdef __GC printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n", __r, __r->_M_depth, __r->_M_size, __r->_M_is_balanced? "" : "not"); #else printf("Concatenation %p (rc = %ld, depth = %d, " "len = %ld, %s balanced)\n", __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size, __r->_M_is_balanced? "" : "not"); #endif _S_dump(__left, __indent + 2); _S_dump(__right, __indent + 2); return; } else { const char* __kind; switch (__r->_M_tag) { case __detail::_S_leaf: __kind = "Leaf"; break; case __detail::_S_function: __kind = "Function"; break; case __detail::_S_substringfn: __kind = "Function representing substring"; break; default: __kind = "(corrupted kind field!)"; } #ifdef __GC printf("%s %p (depth = %d, len = %ld) ", __kind, __r, __r->_M_depth, __r->_M_size); #else printf("%s %p (rc = %ld, depth = %d, len = %ld) ", __kind, __r, __r->_M_ref_count, __r->_M_depth, __r->_M_size); #endif if (_S_is_one_byte_char_type((_CharT*)0)) { const int __max_len = 40; _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len)); _CharT __buffer[__max_len + 1]; bool __too_big = __r->_M_size > __prefix->_M_size; _S_flatten(__prefix, __buffer); __buffer[__prefix->_M_size] = _S_eos((_CharT*)0); printf("%s%s\n", (char*)__buffer, __too_big? "...\n" : "\n"); } else printf("\n"); } } template <class _CharT, class _Alloc> const unsigned long rope<_CharT, _Alloc>:: _S_min_len[int(__detail::_S_max_rope_depth) + 1] = { /* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21, /* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377, /* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181, /* 18 */6765, /* 19 */10946, /* 20 */17711, /* 21 */28657, /* 22 */46368, /* 23 */75025, /* 24 */121393, /* 25 */196418, /* 26 */317811, /* 27 */514229, /* 28 */832040, /* 29 */1346269, /* 30 */2178309, /* 31 */3524578, /* 32 */5702887, /* 33 */9227465, /* 34 */14930352, /* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155, /* 39 */165580141, /* 40 */267914296, /* 41 */433494437, /* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903, /* 45 */2971215073u }; // These are Fibonacci numbers < 2**32. template <class _CharT, class _Alloc> typename rope<_CharT, _Alloc>::_RopeRep* rope<_CharT, _Alloc>:: _S_balance(_RopeRep* __r) { _RopeRep* __forest[int(__detail::_S_max_rope_depth) + 1]; _RopeRep* __result = 0; int __i; // Invariant: // The concatenation of forest in descending order is equal to __r. // __forest[__i]._M_size >= _S_min_len[__i] // __forest[__i]._M_depth = __i // References from forest are included in refcount. for (__i = 0; __i <= int(__detail::_S_max_rope_depth); ++__i) __forest[__i] = 0; __try { _S_add_to_forest(__r, __forest); for (__i = 0; __i <= int(__detail::_S_max_rope_depth); ++__i) if (0 != __forest[__i]) { #ifndef __GC _Self_destruct_ptr __old(__result); #endif __result = _S_concat(__forest[__i], __result); __forest[__i]->_M_unref_nonnil(); #if !defined(__GC) && __cpp_exceptions __forest[__i] = 0; #endif } } __catch(...) { for(__i = 0; __i <= int(__detail::_S_max_rope_depth); __i++) _S_unref(__forest[__i]); __throw_exception_again; } if (__result->_M_depth > int(__detail::_S_max_rope_depth)) __throw_length_error(__N("rope::_S_balance")); return(__result); } template <class _CharT, class _Alloc> void rope<_CharT, _Alloc>:: _S_add_to_forest(_RopeRep* __r, _RopeRep** __forest) { if (__r->_M_is_balanced) { _S_add_leaf_to_forest(__r, __forest); return; } { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _S_add_to_forest(__c->_M_left, __forest); _S_add_to_forest(__c->_M_right, __forest); } } template <class _CharT, class _Alloc> void rope<_CharT, _Alloc>:: _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) { _RopeRep* __insertee; // included in refcount _RopeRep* __too_tiny = 0; // included in refcount int __i; // forest[0..__i-1] is empty size_t __s = __r->_M_size; for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) { if (0 != __forest[__i]) { #ifndef __GC _Self_destruct_ptr __old(__too_tiny); #endif __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny); __forest[__i]->_M_unref_nonnil(); __forest[__i] = 0; } } { #ifndef __GC _Self_destruct_ptr __old(__too_tiny); #endif __insertee = _S_concat_and_set_balanced(__too_tiny, __r); } // Too_tiny dead, and no longer included in refcount. // Insertee is live and included. for (;; ++__i) { if (0 != __forest[__i]) { #ifndef __GC _Self_destruct_ptr __old(__insertee); #endif __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee); __forest[__i]->_M_unref_nonnil(); __forest[__i] = 0; } if (__i == int(__detail::_S_max_rope_depth) || __insertee->_M_size < _S_min_len[__i+1]) { __forest[__i] = __insertee; // refcount is OK since __insertee is now dead. return; } } } template <class _CharT, class _Alloc> _CharT rope<_CharT, _Alloc>:: _S_fetch(_RopeRep* __r, size_type __i) { __GC_CONST _CharT* __cstr = __r->_M_c_string; if (0 != __cstr) return __cstr[__i]; for(;;) { switch(__r->_M_tag) { case __detail::_S_concat: { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _RopeRep* __left = __c->_M_left; size_t __left_len = __left->_M_size; if (__i >= __left_len) { __i -= __left_len; __r = __c->_M_right; } else __r = __left; } break; case __detail::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; return __l->_M_data[__i]; } case __detail::_S_function: case __detail::_S_substringfn: { _RopeFunction* __f = (_RopeFunction*)__r; _CharT __result; (*(__f->_M_fn))(__i, 1, &__result); return __result; } } } } #ifndef __GC // Return a uniquely referenced character slot for the given // position, or 0 if that's not possible. template <class _CharT, class _Alloc> _CharT* rope<_CharT, _Alloc>:: _S_fetch_ptr(_RopeRep* __r, size_type __i) { _RopeRep* __clrstack[__detail::_S_max_rope_depth]; size_t __csptr = 0; for(;;) { if (__r->_M_ref_count > 1) return 0; switch(__r->_M_tag) { case __detail::_S_concat: { _RopeConcatenation* __c = (_RopeConcatenation*)__r; _RopeRep* __left = __c->_M_left; size_t __left_len = __left->_M_size; if (__c->_M_c_string != 0) __clrstack[__csptr++] = __c; if (__i >= __left_len) { __i -= __left_len; __r = __c->_M_right; } else __r = __left; } break; case __detail::_S_leaf: { _RopeLeaf* __l = (_RopeLeaf*)__r; if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0) __clrstack[__csptr++] = __l; while (__csptr > 0) { -- __csptr; _RopeRep* __d = __clrstack[__csptr]; __d->_M_free_c_string(); __d->_M_c_string = 0; } return __l->_M_data + __i; } case __detail::_S_function: case __detail::_S_substringfn: return 0; } } } #endif /* __GC */ // The following could be implemented trivially using // lexicographical_compare_3way. // We do a little more work to avoid dealing with rope iterators for // flat strings. template <class _CharT, class _Alloc> int rope<_CharT, _Alloc>:: _S_compare (const _RopeRep* __left, const _RopeRep* __right) { size_t __left_len; size_t __right_len; if (0 == __right) return 0 != __left; if (0 == __left) return -1; __left_len = __left->_M_size; __right_len = __right->_M_size; if (__detail::_S_leaf == __left->_M_tag) { _RopeLeaf* __l = (_RopeLeaf*) __left; if (__detail::_S_leaf == __right->_M_tag) { _RopeLeaf* __r = (_RopeLeaf*) __right; return lexicographical_compare_3way(__l->_M_data, __l->_M_data + __left_len, __r->_M_data, __r->_M_data + __right_len); } else { const_iterator __rstart(__right, 0); const_iterator __rend(__right, __right_len); return lexicographical_compare_3way(__l->_M_data, __l->_M_data + __left_len, __rstart, __rend); } } else { const_iterator __lstart(__left, 0); const_iterator __lend(__left, __left_len); if (__detail::_S_leaf == __right->_M_tag) { _RopeLeaf* __r = (_RopeLeaf*) __right; return lexicographical_compare_3way(__lstart, __lend, __r->_M_data, __r->_M_data + __right_len); } else { const_iterator __rstart(__right, 0); const_iterator __rend(__right, __right_len); return lexicographical_compare_3way(__lstart, __lend, __rstart, __rend); } } } // Assignment to reference proxies. template <class _CharT, class _Alloc> _Rope_char_ref_proxy<_CharT, _Alloc>& _Rope_char_ref_proxy<_CharT, _Alloc>:: operator=(_CharT __c) { _RopeRep* __old = _M_root->_M_tree_ptr; #ifndef __GC // First check for the case in which everything is uniquely // referenced. In that case we can do this destructively. _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos); if (0 != __ptr) { *__ptr = __c; return *this; } #endif _Self_destruct_ptr __left(_My_rope::_S_substring(__old, 0, _M_pos)); _Self_destruct_ptr __right(_My_rope::_S_substring(__old, _M_pos + 1, __old->_M_size)); _Self_destruct_ptr __result_left(_My_rope:: _S_destr_concat_char_iter(__left, &__c, 1)); _RopeRep* __result = _My_rope::_S_concat(__result_left, __right); #ifndef __GC _RopeRep::_S_unref(__old); #endif _M_root->_M_tree_ptr = __result; return *this; } template <class _CharT, class _Alloc> inline _Rope_char_ref_proxy<_CharT, _Alloc>:: operator _CharT() const { if (_M_current_valid) return _M_current; else return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos); } template <class _CharT, class _Alloc> _Rope_char_ptr_proxy<_CharT, _Alloc> _Rope_char_ref_proxy<_CharT, _Alloc>:: operator&() const { return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); } template <class _CharT, class _Alloc> rope<_CharT, _Alloc>:: rope(size_t __n, _CharT __c, const allocator_type& __a) : _Base(__a) { rope<_CharT,_Alloc> __result; const size_t __exponentiate_threshold = 32; size_t __exponent; size_t __rest; _CharT* __rest_buffer; _RopeRep* __remainder; rope<_CharT, _Alloc> __remainder_rope; if (0 == __n) return; __exponent = __n / __exponentiate_threshold; __rest = __n % __exponentiate_threshold; if (0 == __rest) __remainder = 0; else { __rest_buffer = this->_Data_allocate(_S_rounded_up_size(__rest)); __uninitialized_fill_n_a(__rest_buffer, __rest, __c, _M_get_allocator()); _S_cond_store_eos(__rest_buffer[__rest]); __try { __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, _M_get_allocator()); } __catch(...) { _RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, _M_get_allocator()); __throw_exception_again; } } __remainder_rope._M_tree_ptr = __remainder; if (__exponent != 0) { _CharT* __base_buffer = this->_Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); _RopeLeaf* __base_leaf; rope __base_rope; __uninitialized_fill_n_a(__base_buffer, __exponentiate_threshold, __c, _M_get_allocator()); _S_cond_store_eos(__base_buffer[__exponentiate_threshold]); __try { __base_leaf = _S_new_RopeLeaf(__base_buffer, __exponentiate_threshold, _M_get_allocator()); } __catch(...) { _RopeRep::__STL_FREE_STRING(__base_buffer, __exponentiate_threshold, _M_get_allocator()); __throw_exception_again; } __base_rope._M_tree_ptr = __base_leaf; if (1 == __exponent) __result = __base_rope; else __result = power(__base_rope, __exponent, _Rope_Concat_fn<_CharT, _Alloc>()); if (0 != __remainder) __result += __remainder_rope; } else __result = __remainder_rope; this->_M_tree_ptr = __result._M_tree_ptr; this->_M_tree_ptr->_M_ref_nonnil(); } template<class _CharT, class _Alloc> _CharT rope<_CharT, _Alloc>::_S_empty_c_str[1]; template<class _CharT, class _Alloc> const _CharT* rope<_CharT, _Alloc>:: c_str() const { if (0 == this->_M_tree_ptr) { _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, // but probably fast. return _S_empty_c_str; } __gthread_mutex_lock (&this->_M_tree_ptr->_M_c_string_lock); __GC_CONST _CharT* __result = this->_M_tree_ptr->_M_c_string; if (0 == __result) { size_t __s = size(); __result = this->_Data_allocate(__s + 1); _S_flatten(this->_M_tree_ptr, __result); __result[__s] = _S_eos((_CharT*)0); this->_M_tree_ptr->_M_c_string = __result; } __gthread_mutex_unlock (&this->_M_tree_ptr->_M_c_string_lock); return(__result); } template<class _CharT, class _Alloc> const _CharT* rope<_CharT, _Alloc>:: replace_with_c_str() { if (0 == this->_M_tree_ptr) { _S_empty_c_str[0] = _S_eos((_CharT*)0); return _S_empty_c_str; } __GC_CONST _CharT* __old_c_string = this->_M_tree_ptr->_M_c_string; if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag && 0 != __old_c_string) return(__old_c_string); size_t __s = size(); _CharT* __result = this->_Data_allocate(_S_rounded_up_size(__s)); _S_flatten(this->_M_tree_ptr, __result); __result[__s] = _S_eos((_CharT*)0); this->_M_tree_ptr->_M_unref_nonnil(); this->_M_tree_ptr = _S_new_RopeLeaf(__result, __s, this->_M_get_allocator()); return(__result); } // Algorithm specializations. More should be added. template<class _Rope_iterator> // was templated on CharT and Alloc void // VC++ workaround _Rope_rotate(_Rope_iterator __first, _Rope_iterator __middle, _Rope_iterator __last) { typedef typename _Rope_iterator::value_type _CharT; typedef typename _Rope_iterator::_allocator_type _Alloc; rope<_CharT, _Alloc>& __r(__first.container()); rope<_CharT, _Alloc> __prefix = __r.substr(0, __first.index()); rope<_CharT, _Alloc> __suffix = __r.substr(__last.index(), __r.size() - __last.index()); rope<_CharT, _Alloc> __part1 = __r.substr(__middle.index(), __last.index() - __middle.index()); rope<_CharT, _Alloc> __part2 = __r.substr(__first.index(), __middle.index() - __first.index()); __r = __prefix; __r += __part1; __r += __part2; __r += __suffix; } #if !defined(__GNUC__) // Appears to confuse g++ inline void rotate(_Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __first, _Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __middle, _Rope_iterator<char, __STL_DEFAULT_ALLOCATOR(char)> __last) { _Rope_rotate(__first, __middle, __last); } #endif # if 0 // Probably not useful for several reasons: // - for SGIs 7.1 compiler and probably some others, // this forces lots of rope<wchar_t, ...> instantiations, creating a // code bloat and compile time problem. (Fixed in 7.2.) // - wchar_t is 4 bytes wide on most UNIX platforms, making it // unattractive for unicode strings. Unsigned short may be a better // character type. inline void rotate(_Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __first, _Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __middle, _Rope_iterator<wchar_t, __STL_DEFAULT_ALLOCATOR(char)> __last) { _Rope_rotate(__first, __middle, __last); } # endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/ext/malloc_allocator.h 0000644 00000011736 15146341150 0011553 0 ustar 00 // Allocator that wraps "C" malloc -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/malloc_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _MALLOC_ALLOCATOR_H #define _MALLOC_ALLOCATOR_H 1 #include <cstdlib> #include <cstddef> #include <new> #include <bits/functexcept.h> #include <bits/move.h> #if __cplusplus >= 201103L #include <type_traits> #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; /** * @brief An allocator that uses malloc. * @ingroup allocators * * This is precisely the allocator defined in the C++ Standard. * - all allocation calls malloc * - all deallocation calls free */ template<typename _Tp> class malloc_allocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; template<typename _Tp1> struct rebind { typedef malloc_allocator<_Tp1> other; }; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; #endif malloc_allocator() _GLIBCXX_USE_NOEXCEPT { } malloc_allocator(const malloc_allocator&) _GLIBCXX_USE_NOEXCEPT { } template<typename _Tp1> malloc_allocator(const malloc_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } ~malloc_allocator() _GLIBCXX_USE_NOEXCEPT { } pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } // NB: __n is permitted to be 0. The C++ standard says nothing // about what the return value is when __n == 0. pointer allocate(size_type __n, const void* = 0) { if (__n > this->max_size()) std::__throw_bad_alloc(); pointer __ret = 0; #if __cpp_aligned_new #if __cplusplus > 201402L && _GLIBCXX_HAVE_ALIGNED_ALLOC if (alignof(_Tp) > alignof(std::max_align_t)) { __ret = static_cast<_Tp*>(::aligned_alloc(alignof(_Tp), __n * sizeof(_Tp))); } #else # define _GLIBCXX_CHECK_MALLOC_RESULT #endif #endif if (!__ret) __ret = static_cast<_Tp*>(std::malloc(__n * sizeof(_Tp))); if (!__ret) std::__throw_bad_alloc(); #ifdef _GLIBCXX_CHECK_MALLOC_RESULT #undef _GLIBCXX_CHECK_MALLOC_RESULT if (reinterpret_cast<std::size_t>(__ret) % alignof(_Tp)) { // Memory returned by malloc is not suitably aligned for _Tp. deallocate(__ret, __n); std::__throw_bad_alloc(); } #endif return __ret; } // __p is not permitted to be a null pointer. void deallocate(pointer __p, size_type) { std::free(static_cast<void*>(__p)); } size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return size_t(-1) / sizeof(_Tp); } #if __cplusplus >= 201103L template<typename _Up, typename... _Args> void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template<typename _Up> void destroy(_Up* __p) { __p->~_Up(); } #else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) value_type(__val); } void destroy(pointer __p) { __p->~_Tp(); } #endif }; template<typename _Tp> inline bool operator==(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&) { return true; } template<typename _Tp> inline bool operator!=(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&) { return false; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/atomicity.h 0000644 00000006665 15146341150 0010253 0 ustar 00 // Support for atomic operations -*- C++ -*- // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/atomicity.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _GLIBCXX_ATOMICITY_H #define _GLIBCXX_ATOMICITY_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/gthr.h> #include <bits/atomic_word.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Functions for portable atomic access. // To abstract locking primitives across all thread policies, use: // __exchange_and_add_dispatch // __atomic_add_dispatch #ifdef _GLIBCXX_ATOMIC_BUILTINS static inline _Atomic_word __exchange_and_add(volatile _Atomic_word* __mem, int __val) { return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); } static inline void __atomic_add(volatile _Atomic_word* __mem, int __val) { __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); } #else _Atomic_word __attribute__ ((__unused__)) __exchange_and_add(volatile _Atomic_word*, int) throw (); void __attribute__ ((__unused__)) __atomic_add(volatile _Atomic_word*, int) throw (); #endif static inline _Atomic_word __exchange_and_add_single(_Atomic_word* __mem, int __val) { _Atomic_word __result = *__mem; *__mem += __val; return __result; } static inline void __atomic_add_single(_Atomic_word* __mem, int __val) { *__mem += __val; } static inline _Atomic_word __attribute__ ((__unused__)) __exchange_and_add_dispatch(_Atomic_word* __mem, int __val) { #ifdef __GTHREADS if (__gthread_active_p()) return __exchange_and_add(__mem, __val); else return __exchange_and_add_single(__mem, __val); #else return __exchange_and_add_single(__mem, __val); #endif } static inline void __attribute__ ((__unused__)) __atomic_add_dispatch(_Atomic_word* __mem, int __val) { #ifdef __GTHREADS if (__gthread_active_p()) __atomic_add(__mem, __val); else __atomic_add_single(__mem, __val); #else __atomic_add_single(__mem, __val); #endif } _GLIBCXX_END_NAMESPACE_VERSION } // namespace // Even if the CPU doesn't need a memory barrier, we need to ensure // that the compiler doesn't reorder memory accesses across the // barriers. #ifndef _GLIBCXX_READ_MEM_BARRIER #define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE) #endif #ifndef _GLIBCXX_WRITE_MEM_BARRIER #define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE) #endif #endif c++/8/ext/numeric_traits.h 0000644 00000010737 15146341150 0011274 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, or (at your option) any later // version. // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/numeric_traits.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_NUMERIC_TRAITS #define _EXT_NUMERIC_TRAITS 1 #pragma GCC system_header #include <bits/cpp_type_traits.h> #include <ext/type_traits.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Compile time constants for builtin types. // Sadly std::numeric_limits member functions cannot be used for this. #define __glibcxx_signed(_Tp) ((_Tp)(-1) < 0) #define __glibcxx_digits(_Tp) \ (sizeof(_Tp) * __CHAR_BIT__ - __glibcxx_signed(_Tp)) #define __glibcxx_min(_Tp) \ (__glibcxx_signed(_Tp) ? (_Tp)1 << __glibcxx_digits(_Tp) : (_Tp)0) #define __glibcxx_max(_Tp) \ (__glibcxx_signed(_Tp) ? \ (((((_Tp)1 << (__glibcxx_digits(_Tp) - 1)) - 1) << 1) + 1) : ~(_Tp)0) template<typename _Value> struct __numeric_traits_integer { // Only integers for initialization of member constant. static const _Value __min = __glibcxx_min(_Value); static const _Value __max = __glibcxx_max(_Value); // NB: these two also available in std::numeric_limits as compile // time constants, but <limits> is big and we avoid including it. static const bool __is_signed = __glibcxx_signed(_Value); static const int __digits = __glibcxx_digits(_Value); }; template<typename _Value> const _Value __numeric_traits_integer<_Value>::__min; template<typename _Value> const _Value __numeric_traits_integer<_Value>::__max; template<typename _Value> const bool __numeric_traits_integer<_Value>::__is_signed; template<typename _Value> const int __numeric_traits_integer<_Value>::__digits; #undef __glibcxx_signed #undef __glibcxx_digits #undef __glibcxx_min #undef __glibcxx_max #define __glibcxx_floating(_Tp, _Fval, _Dval, _LDval) \ (std::__are_same<_Tp, float>::__value ? _Fval \ : std::__are_same<_Tp, double>::__value ? _Dval : _LDval) #define __glibcxx_max_digits10(_Tp) \ (2 + __glibcxx_floating(_Tp, __FLT_MANT_DIG__, __DBL_MANT_DIG__, \ __LDBL_MANT_DIG__) * 643L / 2136) #define __glibcxx_digits10(_Tp) \ __glibcxx_floating(_Tp, __FLT_DIG__, __DBL_DIG__, __LDBL_DIG__) #define __glibcxx_max_exponent10(_Tp) \ __glibcxx_floating(_Tp, __FLT_MAX_10_EXP__, __DBL_MAX_10_EXP__, \ __LDBL_MAX_10_EXP__) template<typename _Value> struct __numeric_traits_floating { // Only floating point types. See N1822. static const int __max_digits10 = __glibcxx_max_digits10(_Value); // See above comment... static const bool __is_signed = true; static const int __digits10 = __glibcxx_digits10(_Value); static const int __max_exponent10 = __glibcxx_max_exponent10(_Value); }; template<typename _Value> const int __numeric_traits_floating<_Value>::__max_digits10; template<typename _Value> const bool __numeric_traits_floating<_Value>::__is_signed; template<typename _Value> const int __numeric_traits_floating<_Value>::__digits10; template<typename _Value> const int __numeric_traits_floating<_Value>::__max_exponent10; template<typename _Value> struct __numeric_traits : public __conditional_type<std::__is_integer<_Value>::__value, __numeric_traits_integer<_Value>, __numeric_traits_floating<_Value> >::__type { }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #undef __glibcxx_floating #undef __glibcxx_max_digits10 #undef __glibcxx_digits10 #undef __glibcxx_max_exponent10 #endif c++/8/ext/typelist.h 0000644 00000040140 15146341150 0010110 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice and // this permission notice appear in supporting documentation. None of // the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied warranty. /** * @file ext/typelist.h * This file is a GNU extension to the Standard C++ Library. * * Contains typelist_chain definitions. * Typelists are an idea by Andrei Alexandrescu. */ #ifndef _TYPELIST_H #define _TYPELIST_H 1 #include <ext/type_traits.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** @namespace __gnu_cxx::typelist * @brief GNU typelist extensions for public compile-time use. */ namespace typelist { struct null_type { }; template<typename Root> struct node { typedef Root root; }; // Forward declarations of functors. template<typename Hd, typename Typelist> struct chain { typedef Hd head; typedef Typelist tail; }; // Apply all typelist types to unary functor. template<typename Fn, typename Typelist> void apply(Fn&, Typelist); /// Apply all typelist types to generator functor. template<typename Gn, typename Typelist> void apply_generator(Gn&, Typelist); // Apply all typelist types and values to generator functor. template<typename Gn, typename TypelistT, typename TypelistV> void apply_generator(Gn&, TypelistT, TypelistV); template<typename Typelist0, typename Typelist1> struct append; template<typename Typelist_Typelist> struct append_typelist; template<typename Typelist, typename T> struct contains; template<typename Typelist, template<typename T> class Pred> struct filter; template<typename Typelist, int i> struct at_index; template<typename Typelist, template<typename T> class Transform> struct transform; template<typename Typelist_Typelist> struct flatten; template<typename Typelist> struct from_first; template<typename T1> struct create1; template<typename T1, typename T2> struct create2; template<typename T1, typename T2, typename T3> struct create3; template<typename T1, typename T2, typename T3, typename T4> struct create4; template<typename T1, typename T2, typename T3, typename T4, typename T5> struct create5; template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> struct create6; namespace detail { template<typename Fn, typename Typelist_Chain> struct apply_; template<typename Fn, typename Hd, typename Tl> struct apply_<Fn, chain<Hd, Tl> > { void operator()(Fn& f) { f.operator()(Hd()); apply_<Fn, Tl> next; next(f); } }; template<typename Fn> struct apply_<Fn, null_type> { void operator()(Fn&) { } }; template<typename Gn, typename Typelist_Chain> struct apply_generator1_; template<typename Gn, typename Hd, typename Tl> struct apply_generator1_<Gn, chain<Hd, Tl> > { void operator()(Gn& g) { g.template operator()<Hd>(); apply_generator1_<Gn, Tl> next; next(g); } }; template<typename Gn> struct apply_generator1_<Gn, null_type> { void operator()(Gn&) { } }; template<typename Gn, typename TypelistT_Chain, typename TypelistV_Chain> struct apply_generator2_; template<typename Gn, typename Hd1, typename TlT, typename Hd2, typename TlV> struct apply_generator2_<Gn, chain<Hd1, TlT>, chain<Hd2, TlV> > { void operator()(Gn& g) { g.template operator()<Hd1, Hd2>(); apply_generator2_<Gn, TlT, TlV> next; next(g); } }; template<typename Gn> struct apply_generator2_<Gn, null_type, null_type> { void operator()(Gn&) { } }; template<typename Typelist_Chain0, typename Typelist_Chain1> struct append_; template<typename Hd, typename Tl, typename Typelist_Chain> struct append_<chain<Hd, Tl>, Typelist_Chain> { private: typedef append_<Tl, Typelist_Chain> append_type; public: typedef chain<Hd, typename append_type::type> type; }; template<typename Typelist_Chain> struct append_<null_type, Typelist_Chain> { typedef Typelist_Chain type; }; template<typename Typelist_Chain> struct append_<Typelist_Chain, null_type> { typedef Typelist_Chain type; }; template<> struct append_<null_type, null_type> { typedef null_type type; }; template<typename Typelist_Typelist_Chain> struct append_typelist_; template<typename Hd> struct append_typelist_<chain<Hd, null_type> > { typedef chain<Hd, null_type> type; }; template<typename Hd, typename Tl> struct append_typelist_<chain< Hd, Tl> > { private: typedef typename append_typelist_<Tl>::type rest_type; public: typedef typename append<Hd, node<rest_type> >::type::root type; }; template<typename Typelist_Chain, typename T> struct contains_; template<typename T> struct contains_<null_type, T> { enum { value = false }; }; template<typename Hd, typename Tl, typename T> struct contains_<chain<Hd, Tl>, T> { enum { value = contains_<Tl, T>::value }; }; template<typename Tl, typename T> struct contains_<chain<T, Tl>, T> { enum { value = true }; }; template<typename Typelist_Chain, template<typename T> class Pred> struct chain_filter_; template<template<typename T> class Pred> struct chain_filter_<null_type, Pred> { typedef null_type type; }; template<typename Hd, typename Tl, template<typename T> class Pred> struct chain_filter_<chain<Hd, Tl>, Pred> { private: enum { include_hd = Pred<Hd>::value }; typedef typename chain_filter_<Tl, Pred>::type rest_type; typedef chain<Hd, rest_type> chain_type; public: typedef typename __conditional_type<include_hd, chain_type, rest_type>::__type type; }; template<typename Typelist_Chain, int i> struct chain_at_index_; template<typename Hd, typename Tl> struct chain_at_index_<chain<Hd, Tl>, 0> { typedef Hd type; }; template<typename Hd, typename Tl, int i> struct chain_at_index_<chain<Hd, Tl>, i> { typedef typename chain_at_index_<Tl, i - 1>::type type; }; template<class Typelist_Chain, template<typename T> class Transform> struct chain_transform_; template<template<typename T> class Transform> struct chain_transform_<null_type, Transform> { typedef null_type type; }; template<class Hd, class Tl, template<typename T> class Transform> struct chain_transform_<chain<Hd, Tl>, Transform> { private: typedef typename chain_transform_<Tl, Transform>::type rest_type; typedef typename Transform<Hd>::type transform_type; public: typedef chain<transform_type, rest_type> type; }; template<typename Typelist_Typelist_Chain> struct chain_flatten_; template<typename Hd_Tl> struct chain_flatten_<chain<Hd_Tl, null_type> > { typedef typename Hd_Tl::root type; }; template<typename Hd_Typelist, class Tl_Typelist> struct chain_flatten_<chain<Hd_Typelist, Tl_Typelist> > { private: typedef typename chain_flatten_<Tl_Typelist>::type rest_type; typedef append<Hd_Typelist, node<rest_type> > append_type; public: typedef typename append_type::type::root type; }; } // namespace detail #define _GLIBCXX_TYPELIST_CHAIN1(X0) __gnu_cxx::typelist::chain<X0, __gnu_cxx::typelist::null_type> #define _GLIBCXX_TYPELIST_CHAIN2(X0, X1) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN1(X1) > #define _GLIBCXX_TYPELIST_CHAIN3(X0, X1, X2) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN2(X1, X2) > #define _GLIBCXX_TYPELIST_CHAIN4(X0, X1, X2, X3) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN3(X1, X2, X3) > #define _GLIBCXX_TYPELIST_CHAIN5(X0, X1, X2, X3, X4) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN4(X1, X2, X3, X4) > #define _GLIBCXX_TYPELIST_CHAIN6(X0, X1, X2, X3, X4, X5) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN5(X1, X2, X3, X4, X5) > #define _GLIBCXX_TYPELIST_CHAIN7(X0, X1, X2, X3, X4, X5, X6) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN6(X1, X2, X3, X4, X5, X6) > #define _GLIBCXX_TYPELIST_CHAIN8(X0, X1, X2, X3, X4, X5, X6, X7) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN7(X1, X2, X3, X4, X5, X6, X7) > #define _GLIBCXX_TYPELIST_CHAIN9(X0, X1, X2, X3, X4, X5, X6, X7, X8) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN8(X1, X2, X3, X4, X5, X6, X7, X8) > #define _GLIBCXX_TYPELIST_CHAIN10(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN9(X1, X2, X3, X4, X5, X6, X7, X8, X9) > #define _GLIBCXX_TYPELIST_CHAIN11(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN10(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) > #define _GLIBCXX_TYPELIST_CHAIN12(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN11(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) > #define _GLIBCXX_TYPELIST_CHAIN13(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN12(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) > #define _GLIBCXX_TYPELIST_CHAIN14(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN13(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) > #define _GLIBCXX_TYPELIST_CHAIN15(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN14(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) > #define _GLIBCXX_TYPELIST_CHAIN16(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN15(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15) > #define _GLIBCXX_TYPELIST_CHAIN17(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN16(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16) > #define _GLIBCXX_TYPELIST_CHAIN18(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN17(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17) > #define _GLIBCXX_TYPELIST_CHAIN19(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN18(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18) > #define _GLIBCXX_TYPELIST_CHAIN20(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN19(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19) > template<typename Fn, typename Typelist> void apply(Fn& fn, Typelist) { detail::apply_<Fn, typename Typelist::root> a; a(fn); } template<typename Fn, typename Typelist> void apply_generator(Fn& fn, Typelist) { detail::apply_generator1_<Fn, typename Typelist::root> a; a(fn); } template<typename Fn, typename TypelistT, typename TypelistV> void apply_generator(Fn& fn, TypelistT, TypelistV) { typedef typename TypelistT::root rootT; typedef typename TypelistV::root rootV; detail::apply_generator2_<Fn, rootT, rootV> a; a(fn); } template<typename Typelist0, typename Typelist1> struct append { private: typedef typename Typelist0::root root0_type; typedef typename Typelist1::root root1_type; typedef detail::append_<root0_type, root1_type> append_type; public: typedef node<typename append_type::type> type; }; template<typename Typelist_Typelist> struct append_typelist { private: typedef typename Typelist_Typelist::root root_type; typedef detail::append_typelist_<root_type> append_type; public: typedef node<typename append_type::type> type; }; template<typename Typelist, typename T> struct contains { private: typedef typename Typelist::root root_type; public: enum { value = detail::contains_<root_type, T>::value }; }; template<typename Typelist, template<typename T> class Pred> struct filter { private: typedef typename Typelist::root root_type; typedef detail::chain_filter_<root_type, Pred> filter_type; public: typedef node<typename filter_type::type> type; }; template<typename Typelist, int i> struct at_index { private: typedef typename Typelist::root root_type; typedef detail::chain_at_index_<root_type, i> index_type; public: typedef typename index_type::type type; }; template<typename Typelist, template<typename T> class Transform> struct transform { private: typedef typename Typelist::root root_type; typedef detail::chain_transform_<root_type, Transform> transform_type; public: typedef node<typename transform_type::type> type; }; template<typename Typelist_Typelist> struct flatten { private: typedef typename Typelist_Typelist::root root_type; typedef typename detail::chain_flatten_<root_type>::type flatten_type; public: typedef node<flatten_type> type; }; template<typename Typelist> struct from_first { private: typedef typename at_index<Typelist, 0>::type first_type; public: typedef node<chain<first_type, null_type> > type; }; template<typename T1> struct create1 { typedef node<_GLIBCXX_TYPELIST_CHAIN1(T1)> type; }; template<typename T1, typename T2> struct create2 { typedef node<_GLIBCXX_TYPELIST_CHAIN2(T1,T2)> type; }; template<typename T1, typename T2, typename T3> struct create3 { typedef node<_GLIBCXX_TYPELIST_CHAIN3(T1,T2,T3)> type; }; template<typename T1, typename T2, typename T3, typename T4> struct create4 { typedef node<_GLIBCXX_TYPELIST_CHAIN4(T1,T2,T3,T4)> type; }; template<typename T1, typename T2, typename T3, typename T4, typename T5> struct create5 { typedef node<_GLIBCXX_TYPELIST_CHAIN5(T1,T2,T3,T4,T5)> type; }; template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> struct create6 { typedef node<_GLIBCXX_TYPELIST_CHAIN6(T1,T2,T3,T4,T5,T6)> type; }; } // namespace typelist _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/random.tcc 0000644 00000165527 15146341150 0010056 0 ustar 00 // Random number extensions -*- C++ -*- // Copyright (C) 2012-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/random.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/random} */ #ifndef _EXT_RANDOM_TCC #define _EXT_RANDOM_TCC 1 #pragma GCC system_header namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: seed(_UIntType __seed) { _M_state32[0] = static_cast<uint32_t>(__seed); for (size_t __i = 1; __i < _M_nstate32; ++__i) _M_state32[__i] = (1812433253UL * (_M_state32[__i - 1] ^ (_M_state32[__i - 1] >> 30)) + __i); _M_pos = state_size; _M_period_certification(); } namespace { inline uint32_t _Func1(uint32_t __x) { return (__x ^ (__x >> 27)) * UINT32_C(1664525); } inline uint32_t _Func2(uint32_t __x) { return (__x ^ (__x >> 27)) * UINT32_C(1566083941); } } template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> template<typename _Sseq> typename std::enable_if<std::is_class<_Sseq>::value>::type simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: seed(_Sseq& __q) { size_t __lag; if (_M_nstate32 >= 623) __lag = 11; else if (_M_nstate32 >= 68) __lag = 7; else if (_M_nstate32 >= 39) __lag = 5; else __lag = 3; const size_t __mid = (_M_nstate32 - __lag) / 2; std::fill(_M_state32, _M_state32 + _M_nstate32, UINT32_C(0x8b8b8b8b)); uint32_t __arr[_M_nstate32]; __q.generate(__arr + 0, __arr + _M_nstate32); uint32_t __r = _Func1(_M_state32[0] ^ _M_state32[__mid] ^ _M_state32[_M_nstate32 - 1]); _M_state32[__mid] += __r; __r += _M_nstate32; _M_state32[__mid + __lag] += __r; _M_state32[0] = __r; for (size_t __i = 1, __j = 0; __j < _M_nstate32; ++__j) { __r = _Func1(_M_state32[__i] ^ _M_state32[(__i + __mid) % _M_nstate32] ^ _M_state32[(__i + _M_nstate32 - 1) % _M_nstate32]); _M_state32[(__i + __mid) % _M_nstate32] += __r; __r += __arr[__j] + __i; _M_state32[(__i + __mid + __lag) % _M_nstate32] += __r; _M_state32[__i] = __r; __i = (__i + 1) % _M_nstate32; } for (size_t __j = 0; __j < _M_nstate32; ++__j) { const size_t __i = (__j + 1) % _M_nstate32; __r = _Func2(_M_state32[__i] + _M_state32[(__i + __mid) % _M_nstate32] + _M_state32[(__i + _M_nstate32 - 1) % _M_nstate32]); _M_state32[(__i + __mid) % _M_nstate32] ^= __r; __r -= __i; _M_state32[(__i + __mid + __lag) % _M_nstate32] ^= __r; _M_state32[__i] = __r; } _M_pos = state_size; _M_period_certification(); } template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: _M_period_certification(void) { static const uint32_t __parity[4] = { __parity1, __parity2, __parity3, __parity4 }; uint32_t __inner = 0; for (size_t __i = 0; __i < 4; ++__i) if (__parity[__i] != 0) __inner ^= _M_state32[__i] & __parity[__i]; if (__builtin_parity(__inner) & 1) return; for (size_t __i = 0; __i < 4; ++__i) if (__parity[__i] != 0) { _M_state32[__i] ^= 1 << (__builtin_ffs(__parity[__i]) - 1); return; } __builtin_unreachable(); } template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: discard(unsigned long long __z) { while (__z > state_size - _M_pos) { __z -= state_size - _M_pos; _M_gen_rand(); } _M_pos += __z; } #ifndef _GLIBCXX_OPT_HAVE_RANDOM_SFMT_GEN_READ namespace { template<size_t __shift> inline void __rshift(uint32_t *__out, const uint32_t *__in) { uint64_t __th = ((static_cast<uint64_t>(__in[3]) << 32) | static_cast<uint64_t>(__in[2])); uint64_t __tl = ((static_cast<uint64_t>(__in[1]) << 32) | static_cast<uint64_t>(__in[0])); uint64_t __oh = __th >> (__shift * 8); uint64_t __ol = __tl >> (__shift * 8); __ol |= __th << (64 - __shift * 8); __out[1] = static_cast<uint32_t>(__ol >> 32); __out[0] = static_cast<uint32_t>(__ol); __out[3] = static_cast<uint32_t>(__oh >> 32); __out[2] = static_cast<uint32_t>(__oh); } template<size_t __shift> inline void __lshift(uint32_t *__out, const uint32_t *__in) { uint64_t __th = ((static_cast<uint64_t>(__in[3]) << 32) | static_cast<uint64_t>(__in[2])); uint64_t __tl = ((static_cast<uint64_t>(__in[1]) << 32) | static_cast<uint64_t>(__in[0])); uint64_t __oh = __th << (__shift * 8); uint64_t __ol = __tl << (__shift * 8); __oh |= __tl >> (64 - __shift * 8); __out[1] = static_cast<uint32_t>(__ol >> 32); __out[0] = static_cast<uint32_t>(__ol); __out[3] = static_cast<uint32_t>(__oh >> 32); __out[2] = static_cast<uint32_t>(__oh); } template<size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4> inline void __recursion(uint32_t *__r, const uint32_t *__a, const uint32_t *__b, const uint32_t *__c, const uint32_t *__d) { uint32_t __x[4]; uint32_t __y[4]; __lshift<__sl2>(__x, __a); __rshift<__sr2>(__y, __c); __r[0] = (__a[0] ^ __x[0] ^ ((__b[0] >> __sr1) & __msk1) ^ __y[0] ^ (__d[0] << __sl1)); __r[1] = (__a[1] ^ __x[1] ^ ((__b[1] >> __sr1) & __msk2) ^ __y[1] ^ (__d[1] << __sl1)); __r[2] = (__a[2] ^ __x[2] ^ ((__b[2] >> __sr1) & __msk3) ^ __y[2] ^ (__d[2] << __sl1)); __r[3] = (__a[3] ^ __x[3] ^ ((__b[3] >> __sr1) & __msk4) ^ __y[3] ^ (__d[3] << __sl1)); } } template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: _M_gen_rand(void) { const uint32_t *__r1 = &_M_state32[_M_nstate32 - 8]; const uint32_t *__r2 = &_M_state32[_M_nstate32 - 4]; static constexpr size_t __pos1_32 = __pos1 * 4; size_t __i; for (__i = 0; __i < _M_nstate32 - __pos1_32; __i += 4) { __recursion<__sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4> (&_M_state32[__i], &_M_state32[__i], &_M_state32[__i + __pos1_32], __r1, __r2); __r1 = __r2; __r2 = &_M_state32[__i]; } for (; __i < _M_nstate32; __i += 4) { __recursion<__sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4> (&_M_state32[__i], &_M_state32[__i], &_M_state32[__i + __pos1_32 - _M_nstate32], __r1, __r2); __r1 = __r2; __r2 = &_M_state32[__i]; } _M_pos = 0; } #endif #ifndef _GLIBCXX_OPT_HAVE_RANDOM_SFMT_OPERATOREQUAL template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> bool operator==(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) { typedef __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4> __engine; return (std::equal(__lhs._M_stateT, __lhs._M_stateT + __engine::state_size, __rhs._M_stateT) && __lhs._M_pos == __rhs._M_pos); } #endif template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); __os.fill(__space); for (size_t __i = 0; __i < __x._M_nstate32; ++__i) __os << __x._M_state32[__i] << __space; __os << __x._M_pos; __os.flags(__flags); __os.fill(__fill); return __os; } template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); for (size_t __i = 0; __i < __x._M_nstate32; ++__i) __is >> __x._M_state32[__i]; __is >> __x._M_pos; __is.flags(__flags); return __is; } #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /** * Iteration method due to M.D. J<o:>hnk. * * M.D. J<o:>hnk, Erzeugung von betaverteilten und gammaverteilten * Zufallszahlen, Metrika, Volume 8, 1964 */ template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename beta_distribution<_RealType>::result_type beta_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __x, __y; do { __x = std::exp(std::log(__aurng()) / __param.alpha()); __y = std::exp(std::log(__aurng()) / __param.beta()); } while (__x + __y > result_type(1)); return __x / (__x + __y); } template<typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void beta_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); while (__f != __t) { result_type __x, __y; do { __x = std::exp(std::log(__aurng()) / __param.alpha()); __y = std::exp(std::log(__aurng()) / __param.beta()); } while (__x + __y > result_type(1)); *__f++ = __x / (__x + __y); } } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::beta_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.alpha() << __space << __x.beta(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::beta_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __alpha_val, __beta_val; __is >> __alpha_val >> __beta_val; __x.param(typename __gnu_cxx::beta_distribution<_RealType>:: param_type(__alpha_val, __beta_val)); __is.flags(__flags); return __is; } template<std::size_t _Dimen, typename _RealType> template<typename _InputIterator1, typename _InputIterator2> void normal_mv_distribution<_Dimen, _RealType>::param_type:: _M_init_full(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend) { __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) std::fill(std::copy(__meanbegin, __meanend, _M_mean.begin()), _M_mean.end(), _RealType(0)); // Perform the Cholesky decomposition auto __w = _M_t.begin(); for (size_t __j = 0; __j < _Dimen; ++__j) { _RealType __sum = _RealType(0); auto __slitbegin = __w; auto __cit = _M_t.begin(); for (size_t __i = 0; __i < __j; ++__i) { auto __slit = __slitbegin; _RealType __s = *__varcovbegin++; for (size_t __k = 0; __k < __i; ++__k) __s -= *__slit++ * *__cit++; *__w++ = __s /= *__cit++; __sum += __s * __s; } __sum = *__varcovbegin - __sum; if (__builtin_expect(__sum <= _RealType(0), 0)) std::__throw_runtime_error(__N("normal_mv_distribution::" "param_type::_M_init_full")); *__w++ = std::sqrt(__sum); std::advance(__varcovbegin, _Dimen - __j); } } template<std::size_t _Dimen, typename _RealType> template<typename _InputIterator1, typename _InputIterator2> void normal_mv_distribution<_Dimen, _RealType>::param_type:: _M_init_lower(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend) { __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) std::fill(std::copy(__meanbegin, __meanend, _M_mean.begin()), _M_mean.end(), _RealType(0)); // Perform the Cholesky decomposition auto __w = _M_t.begin(); for (size_t __j = 0; __j < _Dimen; ++__j) { _RealType __sum = _RealType(0); auto __slitbegin = __w; auto __cit = _M_t.begin(); for (size_t __i = 0; __i < __j; ++__i) { auto __slit = __slitbegin; _RealType __s = *__varcovbegin++; for (size_t __k = 0; __k < __i; ++__k) __s -= *__slit++ * *__cit++; *__w++ = __s /= *__cit++; __sum += __s * __s; } __sum = *__varcovbegin++ - __sum; if (__builtin_expect(__sum <= _RealType(0), 0)) std::__throw_runtime_error(__N("normal_mv_distribution::" "param_type::_M_init_full")); *__w++ = std::sqrt(__sum); } } template<std::size_t _Dimen, typename _RealType> template<typename _InputIterator1, typename _InputIterator2> void normal_mv_distribution<_Dimen, _RealType>::param_type:: _M_init_diagonal(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varbegin, _InputIterator2 __varend) { __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) std::fill(std::copy(__meanbegin, __meanend, _M_mean.begin()), _M_mean.end(), _RealType(0)); auto __w = _M_t.begin(); size_t __step = 0; while (__varbegin != __varend) { std::fill_n(__w, __step, _RealType(0)); __w += __step++; if (__builtin_expect(*__varbegin < _RealType(0), 0)) std::__throw_runtime_error(__N("normal_mv_distribution::" "param_type::_M_init_diagonal")); *__w++ = std::sqrt(*__varbegin++); } } template<std::size_t _Dimen, typename _RealType> template<typename _UniformRandomNumberGenerator> typename normal_mv_distribution<_Dimen, _RealType>::result_type normal_mv_distribution<_Dimen, _RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { result_type __ret; _M_nd.__generate(__ret.begin(), __ret.end(), __urng); auto __t_it = __param._M_t.crbegin(); for (size_t __i = _Dimen; __i > 0; --__i) { _RealType __sum = _RealType(0); for (size_t __j = __i; __j > 0; --__j) __sum += __ret[__j - 1] * *__t_it++; __ret[__i - 1] = __sum; } return __ret; } template<std::size_t _Dimen, typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void normal_mv_distribution<_Dimen, _RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template<size_t _Dimen, typename _RealType> bool operator==(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d2) { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; } template<size_t _Dimen, typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); auto __mean = __x._M_param.mean(); for (auto __it : __mean) __os << __it << __space; auto __t = __x._M_param.varcov(); for (auto __it : __t) __os << __it << __space; __os << __x._M_nd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<size_t _Dimen, typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); std::array<_RealType, _Dimen> __mean; for (auto& __it : __mean) __is >> __it; std::array<_RealType, _Dimen * (_Dimen + 1) / 2> __varcov; for (auto& __it : __varcov) __is >> __it; __is >> __x._M_nd; __x.param(typename normal_mv_distribution<_Dimen, _RealType>:: param_type(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end())); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void rice_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) { typename std::normal_distribution<result_type>::param_type __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); result_type __x = this->_M_ndx(__px, __urng); result_type __y = this->_M_ndy(__py, __urng); #if _GLIBCXX_USE_C99_MATH_TR1 *__f++ = std::hypot(__x, __y); #else *__f++ = std::sqrt(__x * __x + __y * __y); #endif } } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const rice_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.nu() << __space << __x.sigma(); __os << __space << __x._M_ndx; __os << __space << __x._M_ndy; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, rice_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __nu_val, __sigma_val; __is >> __nu_val >> __sigma_val; __is >> __x._M_ndx; __is >> __x._M_ndy; __x.param(typename rice_distribution<_RealType>:: param_type(__nu_val, __sigma_val)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void nakagami_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) typename std::gamma_distribution<result_type>::param_type __pg(__p.mu(), __p.omega() / __p.mu()); while (__f != __t) *__f++ = std::sqrt(this->_M_gd(__pg, __urng)); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const nakagami_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.mu() << __space << __x.omega(); __os << __space << __x._M_gd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, nakagami_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __mu_val, __omega_val; __is >> __mu_val >> __omega_val; __is >> __x._M_gd; __x.param(typename nakagami_distribution<_RealType>:: param_type(__mu_val, __omega_val)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void pareto_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) result_type __mu_val = __p.mu(); result_type __malphinv = -result_type(1) / __p.alpha(); while (__f != __t) *__f++ = __mu_val * std::pow(this->_M_ud(__urng), __malphinv); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const pareto_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.alpha() << __space << __x.mu(); __os << __space << __x._M_ud; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, pareto_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __alpha_val, __mu_val; __is >> __alpha_val >> __mu_val; __is >> __x._M_ud; __x.param(typename pareto_distribution<_RealType>:: param_type(__alpha_val, __mu_val)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename k_distribution<_RealType>::result_type k_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = this->_M_gd1(__urng); result_type __y = this->_M_gd2(__urng); return std::sqrt(__x * __y); } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename k_distribution<_RealType>::result_type k_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::gamma_distribution<result_type>::param_type __p1(__p.lambda(), result_type(1) / __p.lambda()), __p2(__p.nu(), __p.mu() / __p.nu()); result_type __x = this->_M_gd1(__p1, __urng); result_type __y = this->_M_gd2(__p2, __urng); return std::sqrt(__x * __y); } template<typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void k_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) typename std::gamma_distribution<result_type>::param_type __p1(__p.lambda(), result_type(1) / __p.lambda()), __p2(__p.nu(), __p.mu() / __p.nu()); while (__f != __t) { result_type __x = this->_M_gd1(__p1, __urng); result_type __y = this->_M_gd2(__p2, __urng); *__f++ = std::sqrt(__x * __y); } } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const k_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.lambda() << __space << __x.mu() << __space << __x.nu(); __os << __space << __x._M_gd1; __os << __space << __x._M_gd2; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, k_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __lambda_val, __mu_val, __nu_val; __is >> __lambda_val >> __mu_val >> __nu_val; __is >> __x._M_gd1; __is >> __x._M_gd2; __x.param(typename k_distribution<_RealType>:: param_type(__lambda_val, __mu_val, __nu_val)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void arcsine_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) result_type __dif = __p.b() - __p.a(); result_type __sum = __p.a() + __p.b(); while (__f != __t) { result_type __x = std::sin(this->_M_ud(__urng)); *__f++ = (__x * __dif + __sum) / result_type(2); } } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const arcsine_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b(); __os << __space << __x._M_ud; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, arcsine_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b; __is >> __a >> __b; __is >> __x._M_ud; __x.param(typename arcsine_distribution<_RealType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename hoyt_distribution<_RealType>::result_type hoyt_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = this->_M_ad(__urng); result_type __y = this->_M_ed(__urng); return (result_type(2) * this->q() / (result_type(1) + this->q() * this->q())) * std::sqrt(this->omega() * __x * __y); } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename hoyt_distribution<_RealType>::result_type hoyt_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { result_type __q2 = __p.q() * __p.q(); result_type __num = result_type(0.5L) * (result_type(1) + __q2); typename __gnu_cxx::arcsine_distribution<result_type>::param_type __pa(__num, __num / __q2); result_type __x = this->_M_ad(__pa, __urng); result_type __y = this->_M_ed(__urng); return (result_type(2) * __p.q() / (result_type(1) + __q2)) * std::sqrt(__p.omega() * __x * __y); } template<typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void hoyt_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) result_type __2q = result_type(2) * __p.q(); result_type __q2 = __p.q() * __p.q(); result_type __q2p1 = result_type(1) + __q2; result_type __num = result_type(0.5L) * __q2p1; result_type __omega = __p.omega(); typename __gnu_cxx::arcsine_distribution<result_type>::param_type __pa(__num, __num / __q2); while (__f != __t) { result_type __x = this->_M_ad(__pa, __urng); result_type __y = this->_M_ed(__urng); *__f++ = (__2q / __q2p1) * std::sqrt(__omega * __x * __y); } } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const hoyt_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.q() << __space << __x.omega(); __os << __space << __x._M_ad; __os << __space << __x._M_ed; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, hoyt_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __q, __omega; __is >> __q >> __omega; __is >> __x._M_ad; __is >> __x._M_ed; __x.param(typename hoyt_distribution<_RealType>:: param_type(__q, __omega)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void triangular_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::triangular_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b() << __space << __x.c(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::triangular_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b, __c; __is >> __a >> __b >> __c; __x.param(typename __gnu_cxx::triangular_distribution<_RealType>:: param_type(__a, __b, __c)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename von_mises_distribution<_RealType>::result_type von_mises_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { const result_type __pi = __gnu_cxx::__math_constants<result_type>::__pi; std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __f; while (1) { result_type __rnd = std::cos(__pi * __aurng()); __f = (result_type(1) + __p._M_r * __rnd) / (__p._M_r + __rnd); result_type __c = __p._M_kappa * (__p._M_r - __f); result_type __rnd2 = __aurng(); if (__c * (result_type(2) - __c) > __rnd2) break; if (std::log(__c / __rnd2) >= __c - result_type(1)) break; } result_type __res = std::acos(__f); #if _GLIBCXX_USE_C99_MATH_TR1 __res = std::copysign(__res, __aurng() - result_type(0.5)); #else if (__aurng() < result_type(0.5)) __res = -__res; #endif __res += __p._M_mu; if (__res > __pi) __res -= result_type(2) * __pi; else if (__res < -__pi) __res += result_type(2) * __pi; return __res; } template<typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void von_mises_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::von_mises_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.mu() << __space << __x.kappa(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::von_mises_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __mu, __kappa; __is >> __mu >> __kappa; __x.param(typename __gnu_cxx::von_mises_distribution<_RealType>:: param_type(__mu, __kappa)); __is.flags(__flags); return __is; } template<typename _UIntType> template<typename _UniformRandomNumberGenerator> typename hypergeometric_distribution<_UIntType>::result_type hypergeometric_distribution<_UIntType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); result_type __a = __param.successful_size(); result_type __b = __param.total_size(); result_type __k = 0; if (__param.total_draws() < __param.total_size() / 2) { for (result_type __i = 0; __i < __param.total_draws(); ++__i) { if (__b * __aurng() < __a) { ++__k; if (__k == __param.successful_size()) return __k; --__a; } --__b; } return __k; } else { for (result_type __i = 0; __i < __param.unsuccessful_size(); ++__i) { if (__b * __aurng() < __a) { ++__k; if (__k == __param.successful_size()) return __param.successful_size() - __k; --__a; } --__b; } return __param.successful_size() - __k; } } template<typename _UIntType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void hypergeometric_distribution<_UIntType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng); } template<typename _UIntType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::hypergeometric_distribution<_UIntType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_UIntType>::max_digits10); __os << __x.total_size() << __space << __x.successful_size() << __space << __x.total_draws(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _UIntType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::hypergeometric_distribution<_UIntType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _UIntType __total_size, __successful_size, __total_draws; __is >> __total_size >> __successful_size >> __total_draws; __x.param(typename __gnu_cxx::hypergeometric_distribution<_UIntType>:: param_type(__total_size, __successful_size, __total_draws)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename logistic_distribution<_RealType>::result_type logistic_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __arg = result_type(1); while (__arg == result_type(1) || __arg == result_type(0)) __arg = __aurng(); return __p.a() + __p.b() * std::log(__arg / (result_type(1) - __arg)); } template<typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void logistic_distribution<_RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); while (__f != __t) { result_type __arg = result_type(1); while (__arg == result_type(1) || __arg == result_type(0)) __arg = __aurng(); *__f++ = __p.a() + __p.b() * std::log(__arg / (result_type(1) - __arg)); } } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const logistic_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, logistic_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b; __is >> __a >> __b; __x.param(typename logistic_distribution<_RealType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } namespace { // Helper class for the uniform_on_sphere_distribution generation // function. template<std::size_t _Dimen, typename _RealType> class uniform_on_sphere_helper { typedef typename uniform_on_sphere_distribution<_Dimen, _RealType>:: result_type result_type; public: template<typename _NormalDistribution, typename _UniformRandomNumberGenerator> result_type operator()(_NormalDistribution& __nd, _UniformRandomNumberGenerator& __urng) { result_type __ret; typename result_type::value_type __norm; do { auto __sum = _RealType(0); std::generate(__ret.begin(), __ret.end(), [&__nd, &__urng, &__sum](){ _RealType __t = __nd(__urng); __sum += __t * __t; return __t; }); __norm = std::sqrt(__sum); } while (__norm == _RealType(0) || ! __builtin_isfinite(__norm)); std::transform(__ret.begin(), __ret.end(), __ret.begin(), [__norm](_RealType __val){ return __val / __norm; }); return __ret; } }; template<typename _RealType> class uniform_on_sphere_helper<2, _RealType> { typedef typename uniform_on_sphere_distribution<2, _RealType>:: result_type result_type; public: template<typename _NormalDistribution, typename _UniformRandomNumberGenerator> result_type operator()(_NormalDistribution&, _UniformRandomNumberGenerator& __urng) { result_type __ret; _RealType __sq; std::__detail::_Adaptor<_UniformRandomNumberGenerator, _RealType> __aurng(__urng); do { __ret[0] = _RealType(2) * __aurng() - _RealType(1); __ret[1] = _RealType(2) * __aurng() - _RealType(1); __sq = __ret[0] * __ret[0] + __ret[1] * __ret[1]; } while (__sq == _RealType(0) || __sq > _RealType(1)); #if _GLIBCXX_USE_C99_MATH_TR1 // Yes, we do not just use sqrt(__sq) because hypot() is more // accurate. auto __norm = std::hypot(__ret[0], __ret[1]); #else auto __norm = std::sqrt(__sq); #endif __ret[0] /= __norm; __ret[1] /= __norm; return __ret; } }; } template<std::size_t _Dimen, typename _RealType> template<typename _UniformRandomNumberGenerator> typename uniform_on_sphere_distribution<_Dimen, _RealType>::result_type uniform_on_sphere_distribution<_Dimen, _RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { uniform_on_sphere_helper<_Dimen, _RealType> __helper; return __helper(_M_nd, __urng); } template<std::size_t _Dimen, typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void uniform_on_sphere_distribution<_Dimen, _RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template<std::size_t _Dimen, typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __x) { return __os << __x._M_nd; } template<std::size_t _Dimen, typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __x) { return __is >> __x._M_nd; } namespace { // Helper class for the uniform_inside_sphere_distribution generation // function. template<std::size_t _Dimen, bool _SmallDimen, typename _RealType> class uniform_inside_sphere_helper; template<std::size_t _Dimen, typename _RealType> class uniform_inside_sphere_helper<_Dimen, false, _RealType> { using result_type = typename uniform_inside_sphere_distribution<_Dimen, _RealType>:: result_type; public: template<typename _UniformOnSphereDistribution, typename _UniformRandomNumberGenerator> result_type operator()(_UniformOnSphereDistribution& __uosd, _UniformRandomNumberGenerator& __urng, _RealType __radius) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, _RealType> __aurng(__urng); _RealType __pow = 1 / _RealType(_Dimen); _RealType __urt = __radius * std::pow(__aurng(), __pow); result_type __ret = __uosd(__aurng); std::transform(__ret.begin(), __ret.end(), __ret.begin(), [__urt](_RealType __val) { return __val * __urt; }); return __ret; } }; // Helper class for the uniform_inside_sphere_distribution generation // function specialized for small dimensions. template<std::size_t _Dimen, typename _RealType> class uniform_inside_sphere_helper<_Dimen, true, _RealType> { using result_type = typename uniform_inside_sphere_distribution<_Dimen, _RealType>:: result_type; public: template<typename _UniformOnSphereDistribution, typename _UniformRandomNumberGenerator> result_type operator()(_UniformOnSphereDistribution&, _UniformRandomNumberGenerator& __urng, _RealType __radius) { result_type __ret; _RealType __sq; _RealType __radsq = __radius * __radius; std::__detail::_Adaptor<_UniformRandomNumberGenerator, _RealType> __aurng(__urng); do { __sq = _RealType(0); for (int i = 0; i < _Dimen; ++i) { __ret[i] = _RealType(2) * __aurng() - _RealType(1); __sq += __ret[i] * __ret[i]; } } while (__sq > _RealType(1)); for (int i = 0; i < _Dimen; ++i) __ret[i] *= __radius; return __ret; } }; } // namespace // // Experiments have shown that rejection is more efficient than transform // for dimensions less than 8. // template<std::size_t _Dimen, typename _RealType> template<typename _UniformRandomNumberGenerator> typename uniform_inside_sphere_distribution<_Dimen, _RealType>::result_type uniform_inside_sphere_distribution<_Dimen, _RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { uniform_inside_sphere_helper<_Dimen, _Dimen < 8, _RealType> __helper; return __helper(_M_uosd, __urng, __p.radius()); } template<std::size_t _Dimen, typename _RealType> template<typename _OutputIterator, typename _UniformRandomNumberGenerator> void uniform_inside_sphere_distribution<_Dimen, _RealType>:: __generate_impl(_OutputIterator __f, _OutputIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, result_type>) while (__f != __t) *__f++ = this->operator()(__urng, __param); } template<std::size_t _Dimen, typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.radius() << __space << __x._M_uosd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<std::size_t _Dimen, typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __radius_val; __is >> __radius_val >> __x._M_uosd; __x.param(typename uniform_inside_sphere_distribution<_Dimen, _RealType>:: param_type(__radius_val)); __is.flags(__flags); return __is; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #endif // _EXT_RANDOM_TCC c++/8/ext/pool_allocator.h 0000644 00000021165 15146341150 0011252 0 ustar 00 // Allocators -*- C++ -*- // Copyright (C) 2001-2018 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 ext/pool_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _POOL_ALLOCATOR_H #define _POOL_ALLOCATOR_H 1 #include <bits/c++config.h> #include <cstdlib> #include <new> #include <bits/functexcept.h> #include <ext/atomicity.h> #include <ext/concurrence.h> #include <bits/move.h> #if __cplusplus >= 201103L #include <type_traits> #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; /** * @brief Base class for __pool_alloc. * * Uses various allocators to fulfill underlying requests (and makes as * few requests as possible when in default high-speed pool mode). * * Important implementation properties: * 0. If globally mandated, then allocate objects from new * 1. If the clients request an object of size > _S_max_bytes, the resulting * object will be obtained directly from new * 2. In all other cases, we allocate an object of size exactly * _S_round_up(requested_size). Thus the client has enough size * information that we can return the object to the proper free list * without permanently losing part of the object. */ class __pool_alloc_base { protected: enum { _S_align = 8 }; enum { _S_max_bytes = 128 }; enum { _S_free_list_size = (size_t)_S_max_bytes / (size_t)_S_align }; union _Obj { union _Obj* _M_free_list_link; char _M_client_data[1]; // The client sees this. }; static _Obj* volatile _S_free_list[_S_free_list_size]; // Chunk allocation state. static char* _S_start_free; static char* _S_end_free; static size_t _S_heap_size; size_t _M_round_up(size_t __bytes) { return ((__bytes + (size_t)_S_align - 1) & ~((size_t)_S_align - 1)); } _GLIBCXX_CONST _Obj* volatile* _M_get_free_list(size_t __bytes) throw (); __mutex& _M_get_mutex() throw (); // Returns an object of size __n, and optionally adds to size __n // free list. void* _M_refill(size_t __n); // Allocates a chunk for nobjs of size size. nobjs may be reduced // if it is inconvenient to allocate the requested number. char* _M_allocate_chunk(size_t __n, int& __nobjs); }; /** * @brief Allocator using a memory pool with a single lock. * @ingroup allocators */ template<typename _Tp> class __pool_alloc : private __pool_alloc_base { private: static _Atomic_word _S_force_new; public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; template<typename _Tp1> struct rebind { typedef __pool_alloc<_Tp1> other; }; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; #endif __pool_alloc() _GLIBCXX_USE_NOEXCEPT { } __pool_alloc(const __pool_alloc&) _GLIBCXX_USE_NOEXCEPT { } template<typename _Tp1> __pool_alloc(const __pool_alloc<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } ~__pool_alloc() _GLIBCXX_USE_NOEXCEPT { } pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return size_t(-1) / sizeof(_Tp); } #if __cplusplus >= 201103L template<typename _Up, typename... _Args> void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template<typename _Up> void destroy(_Up* __p) { __p->~_Up(); } #else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) _Tp(__val); } void destroy(pointer __p) { __p->~_Tp(); } #endif pointer allocate(size_type __n, const void* = 0); void deallocate(pointer __p, size_type __n); }; template<typename _Tp> inline bool operator==(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) { return true; } template<typename _Tp> inline bool operator!=(const __pool_alloc<_Tp>&, const __pool_alloc<_Tp>&) { return false; } template<typename _Tp> _Atomic_word __pool_alloc<_Tp>::_S_force_new; template<typename _Tp> _Tp* __pool_alloc<_Tp>::allocate(size_type __n, const void*) { pointer __ret = 0; if (__builtin_expect(__n != 0, true)) { if (__n > this->max_size()) std::__throw_bad_alloc(); const size_t __bytes = __n * sizeof(_Tp); #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { std::align_val_t __al = std::align_val_t(alignof(_Tp)); return static_cast<_Tp*>(::operator new(__bytes, __al)); } #endif // If there is a race through here, assume answer from getenv // will resolve in same direction. Inspired by techniques // to efficiently support threading found in basic_string.h. if (_S_force_new == 0) { if (std::getenv("GLIBCXX_FORCE_NEW")) __atomic_add_dispatch(&_S_force_new, 1); else __atomic_add_dispatch(&_S_force_new, -1); } if (__bytes > size_t(_S_max_bytes) || _S_force_new > 0) __ret = static_cast<_Tp*>(::operator new(__bytes)); else { _Obj* volatile* __free_list = _M_get_free_list(__bytes); __scoped_lock sentry(_M_get_mutex()); _Obj* __restrict__ __result = *__free_list; if (__builtin_expect(__result == 0, 0)) __ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes))); else { *__free_list = __result->_M_free_list_link; __ret = reinterpret_cast<_Tp*>(__result); } if (__ret == 0) std::__throw_bad_alloc(); } } return __ret; } template<typename _Tp> void __pool_alloc<_Tp>::deallocate(pointer __p, size_type __n) { if (__builtin_expect(__n != 0 && __p != 0, true)) { #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { ::operator delete(__p, std::align_val_t(alignof(_Tp))); return; } #endif const size_t __bytes = __n * sizeof(_Tp); if (__bytes > static_cast<size_t>(_S_max_bytes) || _S_force_new > 0) ::operator delete(__p); else { _Obj* volatile* __free_list = _M_get_free_list(__bytes); _Obj* __q = reinterpret_cast<_Obj*>(__p); __scoped_lock sentry(_M_get_mutex()); __q ->_M_free_list_link = *__free_list; *__free_list = __q; } } } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/vstring.h 0000644 00000327760 15146341150 0007747 0 ustar 00 // Versatile string -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/vstring.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _VSTRING_H #define _VSTRING_H 1 #pragma GCC system_header #if __cplusplus >= 201103L #include <initializer_list> #endif #include <ext/vstring_util.h> #include <ext/rc_string_base.h> #include <ext/sso_string_base.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @class __versa_string vstring.h * @brief Template class __versa_string. * @ingroup extensions * * Data structure managing sequences of characters and * character-like objects. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> class __versa_string : private _Base<_CharT, _Traits, _Alloc> { typedef _Base<_CharT, _Traits, _Alloc> __vstring_base; typedef typename __vstring_base::_CharT_alloc_type _CharT_alloc_type; // Types: public: typedef _Traits traits_type; typedef typename _Traits::char_type value_type; typedef _Alloc allocator_type; typedef typename _CharT_alloc_type::size_type size_type; typedef typename _CharT_alloc_type::difference_type difference_type; typedef value_type& reference; typedef const value_type& const_reference; typedef typename _CharT_alloc_type::pointer pointer; typedef typename _CharT_alloc_type::const_pointer const_pointer; typedef __gnu_cxx::__normal_iterator<pointer, __versa_string> iterator; typedef __gnu_cxx::__normal_iterator<const_pointer, __versa_string> const_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; // Data Member (public): /// Value returned by various member functions when they fail. static const size_type npos = static_cast<size_type>(-1); private: size_type _M_check(size_type __pos, const char* __s) const { if (__pos > this->size()) std::__throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > " "this->size() (which is %zu)"), __s, __pos, this->size()); return __pos; } void _M_check_length(size_type __n1, size_type __n2, const char* __s) const { if (this->max_size() - (this->size() - __n1) < __n2) std::__throw_length_error(__N(__s)); } // NB: _M_limit doesn't check for a bad __pos value. size_type _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT { const bool __testoff = __off < this->size() - __pos; return __testoff ? __off : this->size() - __pos; } // True if _Rep and source do not overlap. bool _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT { return (std::less<const _CharT*>()(__s, this->_M_data()) || std::less<const _CharT*>()(this->_M_data() + this->size(), __s)); } // For the internal use we have functions similar to `begin'/`end' // but they do not call _M_leak. iterator _M_ibegin() const _GLIBCXX_NOEXCEPT { return iterator(this->_M_data()); } iterator _M_iend() const _GLIBCXX_NOEXCEPT { return iterator(this->_M_data() + this->_M_length()); } public: // Construct/copy/destroy: // NB: We overload ctors in some cases instead of using default // arguments, per 17.4.4.4 para. 2 item 2. /** * @brief Construct an empty string using allocator @a a. */ explicit __versa_string(const _Alloc& __a = _Alloc()) _GLIBCXX_NOEXCEPT : __vstring_base(__a) { } // NB: per LWG issue 42, semantics different from IS: /** * @brief Construct string with copy of value of @a __str. * @param __str Source string. */ __versa_string(const __versa_string& __str) : __vstring_base(__str) { } #if __cplusplus >= 201103L /** * @brief String move constructor. * @param __str Source string. * * The newly-constructed %string contains the exact contents of * @a __str. The contents of @a __str are a valid, but unspecified * string. */ __versa_string(__versa_string&& __str) noexcept : __vstring_base(std::move(__str)) { } /** * @brief Construct string from an initializer list. * @param __l std::initializer_list of characters. * @param __a Allocator to use (default is default allocator). */ __versa_string(std::initializer_list<_CharT> __l, const _Alloc& __a = _Alloc()) : __vstring_base(__l.begin(), __l.end(), __a) { } #endif /** * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. * @param __n Number of characters to copy (default remainder). */ __versa_string(const __versa_string& __str, size_type __pos, size_type __n = npos) : __vstring_base(__str._M_data() + __str._M_check(__pos, "__versa_string::__versa_string"), __str._M_data() + __str._M_limit(__pos, __n) + __pos, _Alloc()) { } /** * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. * @param __n Number of characters to copy. * @param __a Allocator to use. */ __versa_string(const __versa_string& __str, size_type __pos, size_type __n, const _Alloc& __a) : __vstring_base(__str._M_data() + __str._M_check(__pos, "__versa_string::__versa_string"), __str._M_data() + __str._M_limit(__pos, __n) + __pos, __a) { } /** * @brief Construct string initialized by a character array. * @param __s Source character array. * @param __n Number of characters to copy. * @param __a Allocator to use (default is default allocator). * * NB: @a __s must have at least @a __n characters, '\\0' has no special * meaning. */ __versa_string(const _CharT* __s, size_type __n, const _Alloc& __a = _Alloc()) : __vstring_base(__s, __s + __n, __a) { } /** * @brief Construct string as copy of a C string. * @param __s Source C string. * @param __a Allocator to use (default is default allocator). */ __versa_string(const _CharT* __s, const _Alloc& __a = _Alloc()) : __vstring_base(__s, __s ? __s + traits_type::length(__s) : __s + npos, __a) { } /** * @brief Construct string as multiple characters. * @param __n Number of characters. * @param __c Character to use. * @param __a Allocator to use (default is default allocator). */ __versa_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()) : __vstring_base(__n, __c, __a) { } /** * @brief Construct string as copy of a range. * @param __beg Start of range. * @param __end End of range. * @param __a Allocator to use (default is default allocator). */ #if __cplusplus >= 201103L template<class _InputIterator, typename = std::_RequireInputIter<_InputIterator>> #else template<class _InputIterator> #endif __versa_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc()) : __vstring_base(__beg, __end, __a) { } /** * @brief Destroy the string instance. */ ~__versa_string() _GLIBCXX_NOEXCEPT { } /** * @brief Assign the value of @a str to this string. * @param __str Source string. */ __versa_string& operator=(const __versa_string& __str) { return this->assign(__str); } #if __cplusplus >= 201103L /** * @brief String move assignment operator. * @param __str Source string. * * The contents of @a __str are moved into this string (without * copying). @a __str is a valid, but unspecified string. */ __versa_string& operator=(__versa_string&& __str) noexcept { // NB: DR 1204. this->swap(__str); return *this; } /** * @brief Set value to string constructed from initializer list. * @param __l std::initializer_list. */ __versa_string& operator=(std::initializer_list<_CharT> __l) { this->assign(__l.begin(), __l.end()); return *this; } #endif /** * @brief Copy contents of @a __s into this string. * @param __s Source null-terminated string. */ __versa_string& operator=(const _CharT* __s) { return this->assign(__s); } /** * @brief Set value to string of length 1. * @param __c Source character. * * Assigning to a character makes this string length 1 and * (*this)[0] == @a __c. */ __versa_string& operator=(_CharT __c) { this->assign(1, __c); return *this; } // Iterators: /** * Returns a read/write iterator that points to the first character in * the %string. Unshares the string. */ iterator begin() _GLIBCXX_NOEXCEPT { this->_M_leak(); return iterator(this->_M_data()); } /** * Returns a read-only (constant) iterator that points to the first * character in the %string. */ const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(this->_M_data()); } /** * Returns a read/write iterator that points one past the last * character in the %string. Unshares the string. */ iterator end() _GLIBCXX_NOEXCEPT { this->_M_leak(); return iterator(this->_M_data() + this->size()); } /** * Returns a read-only (constant) iterator that points one past the * last character in the %string. */ const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(this->_M_data() + this->size()); } /** * Returns a read/write reverse iterator that points to the last * character in the %string. Iteration is done in reverse element * order. Unshares the string. */ reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return reverse_iterator(this->end()); } /** * Returns a read-only (constant) reverse iterator that points * to the last character in the %string. Iteration is done in * reverse element order. */ const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(this->end()); } /** * Returns a read/write reverse iterator that points to one before the * first character in the %string. Iteration is done in reverse * element order. Unshares the string. */ reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(this->begin()); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first character in the %string. Iteration * is done in reverse element order. */ const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(this->begin()); } #if __cplusplus >= 201103L /** * Returns a read-only (constant) iterator that points to the first * character in the %string. */ const_iterator cbegin() const noexcept { return const_iterator(this->_M_data()); } /** * Returns a read-only (constant) iterator that points one past the * last character in the %string. */ const_iterator cend() const noexcept { return const_iterator(this->_M_data() + this->size()); } /** * Returns a read-only (constant) reverse iterator that points * to the last character in the %string. Iteration is done in * reverse element order. */ const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(this->end()); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first character in the %string. Iteration * is done in reverse element order. */ const_reverse_iterator crend() const noexcept { return const_reverse_iterator(this->begin()); } #endif public: // Capacity: /// Returns the number of characters in the string, not including any /// null-termination. size_type size() const _GLIBCXX_NOEXCEPT { return this->_M_length(); } /// Returns the number of characters in the string, not including any /// null-termination. size_type length() const _GLIBCXX_NOEXCEPT { return this->_M_length(); } /// Returns the size() of the largest possible %string. size_type max_size() const _GLIBCXX_NOEXCEPT { return this->_M_max_size(); } /** * @brief Resizes the %string to the specified number of characters. * @param __n Number of characters the %string should contain. * @param __c Character to fill any new elements. * * This function will %resize the %string to the specified * number of characters. If the number is smaller than the * %string's current size the %string is truncated, otherwise * the %string is extended and new elements are set to @a __c. */ void resize(size_type __n, _CharT __c); /** * @brief Resizes the %string to the specified number of characters. * @param __n Number of characters the %string should contain. * * This function will resize the %string to the specified * length. If the new size is smaller than the %string's * current size the %string is truncated, otherwise the %string * is extended and new characters are default-constructed. For * basic types such as char, this means setting them to 0. */ void resize(size_type __n) { this->resize(__n, _CharT()); } #if __cplusplus >= 201103L /// A non-binding request to reduce capacity() to size(). void shrink_to_fit() noexcept { if (capacity() > size()) { __try { this->reserve(0); } __catch(...) { } } } #endif /** * Returns the total number of characters that the %string can * hold before needing to allocate more memory. */ size_type capacity() const _GLIBCXX_NOEXCEPT { return this->_M_capacity(); } /** * @brief Attempt to preallocate enough memory for specified number of * characters. * @param __res_arg Number of characters required. * @throw std::length_error If @a __res_arg exceeds @c max_size(). * * This function attempts to reserve enough memory for the * %string to hold the specified number of characters. If the * number requested is more than max_size(), length_error is * thrown. * * The advantage of this function is that if optimal code is a * necessity and the user can determine the string length that * will be required, the user can reserve the memory in * %advance, and thus prevent a possible reallocation of memory * and copying of %string data. */ void reserve(size_type __res_arg = 0) { this->_M_reserve(__res_arg); } /** * Erases the string, making it empty. */ void clear() _GLIBCXX_NOEXCEPT { this->_M_clear(); } /** * Returns true if the %string is empty. Equivalent to * <code>*this == ""</code>. */ bool empty() const _GLIBCXX_NOEXCEPT { return this->size() == 0; } // Element access: /** * @brief Subscript access to the data contained in the %string. * @param __pos The index of the character to access. * @return Read-only (constant) reference to the character. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ const_reference operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT { __glibcxx_assert(__pos <= this->size()); return this->_M_data()[__pos]; } /** * @brief Subscript access to the data contained in the %string. * @param __pos The index of the character to access. * @return Read/write reference to the character. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) Unshares the string. */ reference operator[](size_type __pos) _GLIBCXX_NOEXCEPT { // Allow pos == size() both in C++98 mode, as v3 extension, // and in C++11 mode. __glibcxx_assert(__pos <= this->size()); // In pedantic mode be strict in C++98 mode. _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < this->size()); this->_M_leak(); return this->_M_data()[__pos]; } /** * @brief Provides access to the data contained in the %string. * @param __n The index of the character to access. * @return Read-only (const) reference to the character. * @throw std::out_of_range If @a __n is an invalid index. * * This function provides for safer data access. The parameter * is first checked that it is in the range of the string. The * function throws out_of_range if the check fails. */ const_reference at(size_type __n) const { if (__n >= this->size()) std::__throw_out_of_range_fmt(__N("__versa_string::at: __n " "(which is %zu) >= this->size() " "(which is %zu)"), __n, this->size()); return this->_M_data()[__n]; } /** * @brief Provides access to the data contained in the %string. * @param __n The index of the character to access. * @return Read/write reference to the character. * @throw std::out_of_range If @a __n is an invalid index. * * This function provides for safer data access. The parameter * is first checked that it is in the range of the string. The * function throws out_of_range if the check fails. Success * results in unsharing the string. */ reference at(size_type __n) { if (__n >= this->size()) std::__throw_out_of_range_fmt(__N("__versa_string::at: __n " "(which is %zu) >= this->size() " "(which is %zu)"), __n, this->size()); this->_M_leak(); return this->_M_data()[__n]; } #if __cplusplus >= 201103L /** * Returns a read/write reference to the data at the first * element of the %string. */ reference front() noexcept { return operator[](0); } /** * Returns a read-only (constant) reference to the data at the first * element of the %string. */ const_reference front() const noexcept { return operator[](0); } /** * Returns a read/write reference to the data at the last * element of the %string. */ reference back() noexcept { return operator[](this->size() - 1); } /** * Returns a read-only (constant) reference to the data at the * last element of the %string. */ const_reference back() const noexcept { return operator[](this->size() - 1); } #endif // Modifiers: /** * @brief Append a string to this string. * @param __str The string to append. * @return Reference to this string. */ __versa_string& operator+=(const __versa_string& __str) { return this->append(__str); } /** * @brief Append a C string. * @param __s The C string to append. * @return Reference to this string. */ __versa_string& operator+=(const _CharT* __s) { return this->append(__s); } /** * @brief Append a character. * @param __c The character to append. * @return Reference to this string. */ __versa_string& operator+=(_CharT __c) { this->push_back(__c); return *this; } #if __cplusplus >= 201103L /** * @brief Append an initializer_list of characters. * @param __l The initializer_list of characters to be appended. * @return Reference to this string. */ __versa_string& operator+=(std::initializer_list<_CharT> __l) { return this->append(__l.begin(), __l.end()); } #endif // C++11 /** * @brief Append a string to this string. * @param __str The string to append. * @return Reference to this string. */ __versa_string& append(const __versa_string& __str) { return _M_append(__str._M_data(), __str.size()); } /** * @brief Append a substring. * @param __str The string to append. * @param __pos Index of the first character of str to append. * @param __n The number of characters to append. * @return Reference to this string. * @throw std::out_of_range if @a pos is not a valid index. * * This function appends @a __n characters from @a __str * starting at @a __pos to this string. If @a __n is is larger * than the number of available characters in @a __str, the * remainder of @a __str is appended. */ __versa_string& append(const __versa_string& __str, size_type __pos, size_type __n) { return _M_append(__str._M_data() + __str._M_check(__pos, "__versa_string::append"), __str._M_limit(__pos, __n)); } /** * @brief Append a C substring. * @param __s The C string to append. * @param __n The number of characters to append. * @return Reference to this string. */ __versa_string& append(const _CharT* __s, size_type __n) { __glibcxx_requires_string_len(__s, __n); _M_check_length(size_type(0), __n, "__versa_string::append"); return _M_append(__s, __n); } /** * @brief Append a C string. * @param __s The C string to append. * @return Reference to this string. */ __versa_string& append(const _CharT* __s) { __glibcxx_requires_string(__s); const size_type __n = traits_type::length(__s); _M_check_length(size_type(0), __n, "__versa_string::append"); return _M_append(__s, __n); } /** * @brief Append multiple characters. * @param __n The number of characters to append. * @param __c The character to use. * @return Reference to this string. * * Appends n copies of c to this string. */ __versa_string& append(size_type __n, _CharT __c) { return _M_replace_aux(this->size(), size_type(0), __n, __c); } #if __cplusplus >= 201103L /** * @brief Append an initializer_list of characters. * @param __l The initializer_list of characters to append. * @return Reference to this string. */ __versa_string& append(std::initializer_list<_CharT> __l) { return this->append(__l.begin(), __l.end()); } #endif // C++11 /** * @brief Append a range of characters. * @param __first Iterator referencing the first character to append. * @param __last Iterator marking the end of the range. * @return Reference to this string. * * Appends characters in the range [first,last) to this string. */ #if __cplusplus >= 201103L template<class _InputIterator, typename = std::_RequireInputIter<_InputIterator>> #else template<class _InputIterator> #endif __versa_string& append(_InputIterator __first, _InputIterator __last) { return this->replace(_M_iend(), _M_iend(), __first, __last); } /** * @brief Append a single character. * @param __c Character to append. */ void push_back(_CharT __c) { const size_type __size = this->size(); if (__size + 1 > this->capacity() || this->_M_is_shared()) this->_M_mutate(__size, size_type(0), 0, size_type(1)); traits_type::assign(this->_M_data()[__size], __c); this->_M_set_length(__size + 1); } /** * @brief Set value to contents of another string. * @param __str Source string to use. * @return Reference to this string. */ __versa_string& assign(const __versa_string& __str) { this->_M_assign(__str); return *this; } #if __cplusplus >= 201103L /** * @brief Set value to contents of another string. * @param __str Source string to use. * @return Reference to this string. * * This function sets this string to the exact contents of @a __str. * @a __str is a valid, but unspecified string. */ __versa_string& assign(__versa_string&& __str) noexcept { this->swap(__str); return *this; } #endif // C++11 /** * @brief Set value to a substring of a string. * @param __str The string to use. * @param __pos Index of the first character of str. * @param __n Number of characters to use. * @return Reference to this string. * @throw std::out_of_range if @a __pos is not a valid index. * * This function sets this string to the substring of @a __str * consisting of @a __n characters at @a __pos. If @a __n is * is larger than the number of available characters in @a * __str, the remainder of @a __str is used. */ __versa_string& assign(const __versa_string& __str, size_type __pos, size_type __n) { return _M_replace(size_type(0), this->size(), __str._M_data() + __str._M_check(__pos, "__versa_string::assign"), __str._M_limit(__pos, __n)); } /** * @brief Set value to a C substring. * @param __s The C string to use. * @param __n Number of characters to use. * @return Reference to this string. * * This function sets the value of this string to the first @a * __n characters of @a __s. If @a __n is is larger than the * number of available characters in @a __s, the remainder of * @a __s is used. */ __versa_string& assign(const _CharT* __s, size_type __n) { __glibcxx_requires_string_len(__s, __n); return _M_replace(size_type(0), this->size(), __s, __n); } /** * @brief Set value to contents of a C string. * @param __s The C string to use. * @return Reference to this string. * * This function sets the value of this string to the value of * @a __s. The data is copied, so there is no dependence on @a * __s once the function returns. */ __versa_string& assign(const _CharT* __s) { __glibcxx_requires_string(__s); return _M_replace(size_type(0), this->size(), __s, traits_type::length(__s)); } /** * @brief Set value to multiple characters. * @param __n Length of the resulting string. * @param __c The character to use. * @return Reference to this string. * * This function sets the value of this string to @a __n copies of * character @a __c. */ __versa_string& assign(size_type __n, _CharT __c) { return _M_replace_aux(size_type(0), this->size(), __n, __c); } /** * @brief Set value to a range of characters. * @param __first Iterator referencing the first character to append. * @param __last Iterator marking the end of the range. * @return Reference to this string. * * Sets value of string to characters in the range * [first,last). */ #if __cplusplus >= 201103L template<class _InputIterator, typename = std::_RequireInputIter<_InputIterator>> #else template<class _InputIterator> #endif __versa_string& assign(_InputIterator __first, _InputIterator __last) { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } #if __cplusplus >= 201103L /** * @brief Set value to an initializer_list of characters. * @param __l The initializer_list of characters to assign. * @return Reference to this string. */ __versa_string& assign(std::initializer_list<_CharT> __l) { return this->assign(__l.begin(), __l.end()); } #endif // C++11 #if __cplusplus >= 201103L /** * @brief Insert multiple characters. * @param __p Const_iterator referencing location in string to * insert at. * @param __n Number of characters to insert * @param __c The character to insert. * @return Iterator referencing the first inserted char. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts @a __n copies of character @a __c starting at the * position referenced by iterator @a __p. If adding * characters causes the length to exceed max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ iterator insert(const_iterator __p, size_type __n, _CharT __c) { _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); const size_type __pos = __p - _M_ibegin(); this->replace(__p, __p, __n, __c); return iterator(this->_M_data() + __pos); } #else /** * @brief Insert multiple characters. * @param __p Iterator referencing location in string to insert at. * @param __n Number of characters to insert * @param __c The character to insert. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts @a __n copies of character @a __c starting at the * position referenced by iterator @a __p. If adding * characters causes the length to exceed max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ void insert(iterator __p, size_type __n, _CharT __c) { this->replace(__p, __p, __n, __c); } #endif #if __cplusplus >= 201103L /** * @brief Insert a range of characters. * @param __p Const_iterator referencing location in string to * insert at. * @param __beg Start of range. * @param __end End of range. * @return Iterator referencing the first inserted char. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts characters in range [beg,end). If adding characters * causes the length to exceed max_size(), length_error is * thrown. The value of the string doesn't change if an error * is thrown. */ template<class _InputIterator, typename = std::_RequireInputIter<_InputIterator>> iterator insert(const_iterator __p, _InputIterator __beg, _InputIterator __end) { _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); const size_type __pos = __p - _M_ibegin(); this->replace(__p, __p, __beg, __end); return iterator(this->_M_data() + __pos); } #else /** * @brief Insert a range of characters. * @param __p Iterator referencing location in string to insert at. * @param __beg Start of range. * @param __end End of range. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts characters in range [beg,end). If adding characters * causes the length to exceed max_size(), length_error is * thrown. The value of the string doesn't change if an error * is thrown. */ template<class _InputIterator> void insert(iterator __p, _InputIterator __beg, _InputIterator __end) { this->replace(__p, __p, __beg, __end); } #endif #if __cplusplus >= 201103L /** * @brief Insert an initializer_list of characters. * @param __p Const_iterator referencing location in string to * insert at. * @param __l The initializer_list of characters to insert. * @return Iterator referencing the first inserted char. * @throw std::length_error If new length exceeds @c max_size(). */ iterator insert(const_iterator __p, std::initializer_list<_CharT> __l) { return this->insert(__p, __l.begin(), __l.end()); } #endif // C++11 /** * @brief Insert value of a string. * @param __pos1 Iterator referencing location in string to insert at. * @param __str The string to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts value of @a __str starting at @a __pos1. If adding * characters causes the length to exceed max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ __versa_string& insert(size_type __pos1, const __versa_string& __str) { return this->replace(__pos1, size_type(0), __str._M_data(), __str.size()); } /** * @brief Insert a substring. * @param __pos1 Iterator referencing location in string to insert at. * @param __str The string to insert. * @param __pos2 Start of characters in str to insert. * @param __n Number of characters to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a __pos1 > size() or * @a __pos2 > @a __str.size(). * * Starting at @a __pos1, insert @a __n character of @a __str * beginning with @a __pos2. If adding characters causes the * length to exceed max_size(), length_error is thrown. If @a * __pos1 is beyond the end of this string or @a __pos2 is * beyond the end of @a __str, out_of_range is thrown. The * value of the string doesn't change if an error is thrown. */ __versa_string& insert(size_type __pos1, const __versa_string& __str, size_type __pos2, size_type __n) { return this->replace(__pos1, size_type(0), __str._M_data() + __str._M_check(__pos2, "__versa_string::insert"), __str._M_limit(__pos2, __n)); } /** * @brief Insert a C substring. * @param __pos Iterator referencing location in string to insert at. * @param __s The C string to insert. * @param __n The number of characters to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a __pos is beyond the end of this * string. * * Inserts the first @a __n characters of @a __s starting at @a * __pos. If adding characters causes the length to exceed * max_size(), length_error is thrown. If @a __pos is beyond * end(), out_of_range is thrown. The value of the string * doesn't change if an error is thrown. */ __versa_string& insert(size_type __pos, const _CharT* __s, size_type __n) { return this->replace(__pos, size_type(0), __s, __n); } /** * @brief Insert a C string. * @param __pos Iterator referencing location in string to insert at. * @param __s The C string to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a __pos is beyond the end of this * string. * * Inserts the first @a __n characters of @a __s starting at @a * __pos. If adding characters causes the length to exceed * max_size(), length_error is thrown. If @a __pos is beyond * end(), out_of_range is thrown. The value of the string * doesn't change if an error is thrown. */ __versa_string& insert(size_type __pos, const _CharT* __s) { __glibcxx_requires_string(__s); return this->replace(__pos, size_type(0), __s, traits_type::length(__s)); } /** * @brief Insert multiple characters. * @param __pos Index in string to insert at. * @param __n Number of characters to insert * @param __c The character to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a __pos is beyond the end of this * string. * * Inserts @a __n copies of character @a __c starting at index * @a __pos. If adding characters causes the length to exceed * max_size(), length_error is thrown. If @a __pos > length(), * out_of_range is thrown. The value of the string doesn't * change if an error is thrown. */ __versa_string& insert(size_type __pos, size_type __n, _CharT __c) { return _M_replace_aux(_M_check(__pos, "__versa_string::insert"), size_type(0), __n, __c); } /** * @brief Insert one character. * @param __p Iterator referencing position in string to insert at. * @param __c The character to insert. * @return Iterator referencing newly inserted char. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts character @a __c at position referenced by @a __p. * If adding character causes the length to exceed max_size(), * length_error is thrown. If @a __p is beyond end of string, * out_of_range is thrown. The value of the string doesn't * change if an error is thrown. */ iterator #if __cplusplus >= 201103L insert(const_iterator __p, _CharT __c) #else insert(iterator __p, _CharT __c) #endif { _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); const size_type __pos = __p - _M_ibegin(); _M_replace_aux(__pos, size_type(0), size_type(1), __c); this->_M_set_leaked(); return iterator(this->_M_data() + __pos); } /** * @brief Remove characters. * @param __pos Index of first character to remove (default 0). * @param __n Number of characters to remove (default remainder). * @return Reference to this string. * @throw std::out_of_range If @a __pos is beyond the end of this * string. * * Removes @a __n characters from this string starting at @a * __pos. The length of the string is reduced by @a __n. If * there are < @a __n characters to remove, the remainder of * the string is truncated. If @a __p is beyond end of string, * out_of_range is thrown. The value of the string doesn't * change if an error is thrown. */ __versa_string& erase(size_type __pos = 0, size_type __n = npos) { this->_M_erase(_M_check(__pos, "__versa_string::erase"), _M_limit(__pos, __n)); return *this; } /** * @brief Remove one character. * @param __position Iterator referencing the character to remove. * @return iterator referencing same location after removal. * * Removes the character at @a __position from this string. The * value of the string doesn't change if an error is thrown. */ iterator #if __cplusplus >= 201103L erase(const_iterator __position) #else erase(iterator __position) #endif { _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() && __position < _M_iend()); const size_type __pos = __position - _M_ibegin(); this->_M_erase(__pos, size_type(1)); this->_M_set_leaked(); return iterator(this->_M_data() + __pos); } /** * @brief Remove a range of characters. * @param __first Iterator referencing the first character to remove. * @param __last Iterator referencing the end of the range. * @return Iterator referencing location of first after removal. * * Removes the characters in the range [first,last) from this * string. The value of the string doesn't change if an error * is thrown. */ iterator #if __cplusplus >= 201103L erase(const_iterator __first, const_iterator __last) #else erase(iterator __first, iterator __last) #endif { _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last && __last <= _M_iend()); const size_type __pos = __first - _M_ibegin(); this->_M_erase(__pos, __last - __first); this->_M_set_leaked(); return iterator(this->_M_data() + __pos); } #if __cplusplus >= 201103L /** * @brief Remove the last character. * * The string must be non-empty. */ void pop_back() { this->_M_erase(size()-1, 1); } #endif // C++11 /** * @brief Replace characters with value from another string. * @param __pos Index of first character to replace. * @param __n Number of characters to be replaced. * @param __str String to insert. * @return Reference to this string. * @throw std::out_of_range If @a __pos is beyond the end of this * string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [pos,pos+n) from this * string. In place, the value of @a __str is inserted. If @a * __pos is beyond end of string, out_of_range is thrown. If * the length of the result exceeds max_size(), length_error is * thrown. The value of the string doesn't change if an error * is thrown. */ __versa_string& replace(size_type __pos, size_type __n, const __versa_string& __str) { return this->replace(__pos, __n, __str._M_data(), __str.size()); } /** * @brief Replace characters with value from another string. * @param __pos1 Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __str String to insert. * @param __pos2 Index of first character of str to use. * @param __n2 Number of characters from str to use. * @return Reference to this string. * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 > * str.size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [pos1,pos1 + n) from * this string. In place, the value of @a __str is inserted. * If @a __pos is beyond end of string, out_of_range is thrown. * If the length of the result exceeds max_size(), length_error * is thrown. The value of the string doesn't change if an * error is thrown. */ __versa_string& replace(size_type __pos1, size_type __n1, const __versa_string& __str, size_type __pos2, size_type __n2) { return this->replace(__pos1, __n1, __str._M_data() + __str._M_check(__pos2, "__versa_string::replace"), __str._M_limit(__pos2, __n2)); } /** * @brief Replace characters with value of a C substring. * @param __pos Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __s C string to insert. * @param __n2 Number of characters from @a __s to use. * @return Reference to this string. * @throw std::out_of_range If @a __pos1 > size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [pos,pos + n1) from this * string. In place, the first @a __n2 characters of @a __s * are inserted, or all of @a __s if @a __n2 is too large. If * @a __pos is beyond end of string, out_of_range is thrown. * If the length of result exceeds max_size(), length_error is * thrown. The value of the string doesn't change if an error * is thrown. */ __versa_string& replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) { __glibcxx_requires_string_len(__s, __n2); return _M_replace(_M_check(__pos, "__versa_string::replace"), _M_limit(__pos, __n1), __s, __n2); } /** * @brief Replace characters with value of a C string. * @param __pos Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __s C string to insert. * @return Reference to this string. * @throw std::out_of_range If @a __pos > size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [pos,pos + n1) from this * string. In place, the characters of @a __s are inserted. If * @a pos is beyond end of string, out_of_range is thrown. If * the length of result exceeds max_size(), length_error is thrown. * The value of the string doesn't change if an error is thrown. */ __versa_string& replace(size_type __pos, size_type __n1, const _CharT* __s) { __glibcxx_requires_string(__s); return this->replace(__pos, __n1, __s, traits_type::length(__s)); } /** * @brief Replace characters with multiple characters. * @param __pos Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __n2 Number of characters to insert. * @param __c Character to insert. * @return Reference to this string. * @throw std::out_of_range If @a __pos > size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [pos,pos + n1) from this * string. In place, @a __n2 copies of @a __c are inserted. * If @a __pos is beyond end of string, out_of_range is thrown. * If the length of result exceeds max_size(), length_error is * thrown. The value of the string doesn't change if an error * is thrown. */ __versa_string& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) { return _M_replace_aux(_M_check(__pos, "__versa_string::replace"), _M_limit(__pos, __n1), __n2, __c); } /** * @brief Replace range of characters with string. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __str String value to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [i1,i2). In place, the * value of @a __str is inserted. If the length of result * exceeds max_size(), length_error is thrown. The value of * the string doesn't change if an error is thrown. */ __versa_string& #if __cplusplus >= 201103L replace(const_iterator __i1, const_iterator __i2, const __versa_string& __str) #else replace(iterator __i1, iterator __i2, const __versa_string& __str) #endif { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } /** * @brief Replace range of characters with C substring. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __s C string value to insert. * @param __n Number of characters from s to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [i1,i2). In place, the * first @a n characters of @a __s are inserted. If the length * of result exceeds max_size(), length_error is thrown. The * value of the string doesn't change if an error is thrown. */ __versa_string& #if __cplusplus >= 201103L replace(const_iterator __i1, const_iterator __i2, const _CharT* __s, size_type __n) #else replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) #endif { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); } /** * @brief Replace range of characters with C string. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __s C string value to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [i1,i2). In place, the * characters of @a __s are inserted. If the length of result * exceeds max_size(), length_error is thrown. The value of * the string doesn't change if an error is thrown. */ __versa_string& #if __cplusplus >= 201103L replace(const_iterator __i1, const_iterator __i2, const _CharT* __s) #else replace(iterator __i1, iterator __i2, const _CharT* __s) #endif { __glibcxx_requires_string(__s); return this->replace(__i1, __i2, __s, traits_type::length(__s)); } /** * @brief Replace range of characters with multiple characters * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __n Number of characters to insert. * @param __c Character to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [i1,i2). In place, @a * __n copies of @a __c are inserted. If the length of result * exceeds max_size(), length_error is thrown. The value of * the string doesn't change if an error is thrown. */ __versa_string& #if __cplusplus >= 201103L replace(const_iterator __i1, const_iterator __i2, size_type __n, _CharT __c) #else replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) #endif { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c); } /** * @brief Replace range of characters with range. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __k1 Iterator referencing start of range to insert. * @param __k2 Iterator referencing end of range to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [i1,i2). In place, * characters in the range [k1,k2) are inserted. If the length * of result exceeds max_size(), length_error is thrown. The * value of the string doesn't change if an error is thrown. */ #if __cplusplus >= 201103L template<class _InputIterator, typename = std::_RequireInputIter<_InputIterator>> __versa_string& replace(const_iterator __i1, const_iterator __i2, _InputIterator __k1, _InputIterator __k2) { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); return this->_M_replace_dispatch(__i1, __i2, __k1, __k2, std::__false_type()); } #else template<class _InputIterator> __versa_string& replace(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2) { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); typedef typename std::__is_integer<_InputIterator>::__type _Integral; return this->_M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); } #endif // Specializations for the common case of pointer and iterator: // useful to avoid the overhead of temporary buffering in _M_replace. __versa_string& #if __cplusplus >= 201103L replace(const_iterator __i1, const_iterator __i2, _CharT* __k1, _CharT* __k2) #else replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) #endif { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1, __k2 - __k1); } __versa_string& #if __cplusplus >= 201103L replace(const_iterator __i1, const_iterator __i2, const _CharT* __k1, const _CharT* __k2) #else replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2) #endif { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1, __k2 - __k1); } __versa_string& #if __cplusplus >= 201103L replace(const_iterator __i1, const_iterator __i2, iterator __k1, iterator __k2) #else replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) #endif { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1.base(), __k2 - __k1); } __versa_string& #if __cplusplus >= 201103L replace(const_iterator __i1, const_iterator __i2, const_iterator __k1, const_iterator __k2) #else replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2) #endif { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1.base(), __k2 - __k1); } #if __cplusplus >= 201103L /** * @brief Replace range of characters with initializer_list. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __l The initializer_list of characters to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [i1,i2). In place, * characters in the range [k1,k2) are inserted. If the length * of result exceeds max_size(), length_error is thrown. The * value of the string doesn't change if an error is thrown. */ __versa_string& replace(const_iterator __i1, const_iterator __i2, std::initializer_list<_CharT> __l) { return this->replace(__i1, __i2, __l.begin(), __l.end()); } #endif // C++11 private: template<class _Integer> __versa_string& _M_replace_dispatch(const_iterator __i1, const_iterator __i2, _Integer __n, _Integer __val, std::__true_type) { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); } template<class _InputIterator> __versa_string& _M_replace_dispatch(const_iterator __i1, const_iterator __i2, _InputIterator __k1, _InputIterator __k2, std::__false_type); __versa_string& _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, _CharT __c); __versa_string& _M_replace(size_type __pos, size_type __len1, const _CharT* __s, const size_type __len2); __versa_string& _M_append(const _CharT* __s, size_type __n); public: /** * @brief Copy substring into C string. * @param __s C string to copy value into. * @param __n Number of characters to copy. * @param __pos Index of first character to copy. * @return Number of characters actually copied * @throw std::out_of_range If pos > size(). * * Copies up to @a __n characters starting at @a __pos into the * C string @a s. If @a __pos is greater than size(), * out_of_range is thrown. */ size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const; /** * @brief Swap contents with another string. * @param __s String to swap with. * * Exchanges the contents of this string with that of @a __s in * constant time. */ void swap(__versa_string& __s) _GLIBCXX_NOEXCEPT { this->_M_swap(__s); } // String operations: /** * @brief Return const pointer to null-terminated contents. * * This is a handle to internal data. Do not modify or dire things may * happen. */ const _CharT* c_str() const _GLIBCXX_NOEXCEPT { return this->_M_data(); } /** * @brief Return const pointer to contents. * * This is a handle to internal data. Do not modify or dire things may * happen. */ const _CharT* data() const _GLIBCXX_NOEXCEPT { return this->_M_data(); } /** * @brief Return copy of allocator used to construct this string. */ allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(this->_M_get_allocator()); } /** * @brief Find position of a C substring. * @param __s C string to locate. * @param __pos Index of character to search from. * @param __n Number of characters from @a __s to search for. * @return Index of start of first occurrence. * * Starting from @a __pos, searches forward for the first @a * __n characters in @a __s within this string. If found, * returns the index where it begins. If not found, returns * npos. */ size_type find(const _CharT* __s, size_type __pos, size_type __n) const; /** * @brief Find position of a string. * @param __str String to locate. * @param __pos Index of character to search from (default 0). * @return Index of start of first occurrence. * * Starting from @a __pos, searches forward for value of @a * __str within this string. If found, returns the index where * it begins. If not found, returns npos. */ size_type find(const __versa_string& __str, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find(__str.data(), __pos, __str.size()); } /** * @brief Find position of a C string. * @param __s C string to locate. * @param __pos Index of character to search from (default 0). * @return Index of start of first occurrence. * * Starting from @a __pos, searches forward for the value of @a * __s within this string. If found, returns the index where * it begins. If not found, returns npos. */ size_type find(const _CharT* __s, size_type __pos = 0) const { __glibcxx_requires_string(__s); return this->find(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a character. * @param __c Character to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for @a __c within * this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT; /** * @brief Find last position of a string. * @param __str String to locate. * @param __pos Index of character to search back from (default end). * @return Index of start of last occurrence. * * Starting from @a __pos, searches backward for value of @a * __str within this string. If found, returns the index where * it begins. If not found, returns npos. */ size_type rfind(const __versa_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->rfind(__str.data(), __pos, __str.size()); } /** * @brief Find last position of a C substring. * @param __s C string to locate. * @param __pos Index of character to search back from. * @param __n Number of characters from s to search for. * @return Index of start of last occurrence. * * Starting from @a __pos, searches backward for the first @a * __n characters in @a __s within this string. If found, * returns the index where it begins. If not found, returns * npos. */ size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const; /** * @brief Find last position of a C string. * @param __s C string to locate. * @param __pos Index of character to start search at (default end). * @return Index of start of last occurrence. * * Starting from @a __pos, searches backward for the value of * @a __s within this string. If found, returns the index * where it begins. If not found, returns npos. */ size_type rfind(const _CharT* __s, size_type __pos = npos) const { __glibcxx_requires_string(__s); return this->rfind(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a character. * @param __c Character to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for @a __c within * this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT; /** * @brief Find position of a character of string. * @param __str String containing characters to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for one of the characters of * @a __str within this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type find_first_of(const __versa_string& __str, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find_first_of(__str.data(), __pos, __str.size()); } /** * @brief Find position of a character of C substring. * @param __s String containing characters to locate. * @param __pos Index of character to search from. * @param __n Number of characters from s to search for. * @return Index of first occurrence. * * Starting from @a __pos, searches forward for one of the * first @a __n characters of @a __s within this string. If * found, returns the index where it was found. If not found, * returns npos. */ size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; /** * @brief Find position of a character of C string. * @param __s String containing characters to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for one of the * characters of @a __s within this string. If found, returns * the index where it was found. If not found, returns npos. */ size_type find_first_of(const _CharT* __s, size_type __pos = 0) const { __glibcxx_requires_string(__s); return this->find_first_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a character. * @param __c Character to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for the character * @a __c within this string. If found, returns the index * where it was found. If not found, returns npos. * * Note: equivalent to find(c, pos). */ size_type find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find(__c, __pos); } /** * @brief Find last position of a character of string. * @param __str String containing characters to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for one of the * characters of @a __str within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_last_of(const __versa_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->find_last_of(__str.data(), __pos, __str.size()); } /** * @brief Find last position of a character of C substring. * @param __s C string containing characters to locate. * @param __pos Index of character to search back from. * @param __n Number of characters from s to search for. * @return Index of last occurrence. * * Starting from @a __pos, searches backward for one of the * first @a __n characters of @a __s within this string. If * found, returns the index where it was found. If not found, * returns npos. */ size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; /** * @brief Find last position of a character of C string. * @param __s C string containing characters to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for one of the * characters of @a __s within this string. If found, returns * the index where it was found. If not found, returns npos. */ size_type find_last_of(const _CharT* __s, size_type __pos = npos) const { __glibcxx_requires_string(__s); return this->find_last_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a character. * @param __c Character to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for @a __c within * this string. If found, returns the index where it was * found. If not found, returns npos. * * Note: equivalent to rfind(c, pos). */ size_type find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->rfind(__c, __pos); } /** * @brief Find position of a character not in string. * @param __str String containing characters to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character not * contained in @a __str within this string. If found, returns * the index where it was found. If not found, returns npos. */ size_type find_first_not_of(const __versa_string& __str, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find_first_not_of(__str.data(), __pos, __str.size()); } /** * @brief Find position of a character not in C substring. * @param __s C string containing characters to avoid. * @param __pos Index of character to search from. * @param __n Number of characters from s to consider. * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character not * contained in the first @a __n characters of @a __s within * this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const; /** * @brief Find position of a character not in C string. * @param __s C string containing characters to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character not * contained in @a __s within this string. If found, returns * the index where it was found. If not found, returns npos. */ size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const { __glibcxx_requires_string(__s); return this->find_first_not_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a different character. * @param __c Character to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character * other than @a __c within this string. If found, returns the * index where it was found. If not found, returns npos. */ size_type find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT; /** * @brief Find last position of a character not in string. * @param __str String containing characters to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character * not contained in @a __str within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_last_not_of(const __versa_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->find_last_not_of(__str.data(), __pos, __str.size()); } /** * @brief Find last position of a character not in C substring. * @param __s C string containing characters to avoid. * @param __pos Index of character to search back from. * @param __n Number of characters from s to consider. * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character * not contained in the first @a __n characters of @a __s * within this string. If found, returns the index where it * was found. If not found, returns npos. */ size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const; /** * @brief Find last position of a character not in C string. * @param __s C string containing characters to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character * not contained in @a __s within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const { __glibcxx_requires_string(__s); return this->find_last_not_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a different character. * @param __c Character to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character * other than @a __c within this string. If found, returns the * index where it was found. If not found, returns npos. */ size_type find_last_not_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT; /** * @brief Get a substring. * @param __pos Index of first character (default 0). * @param __n Number of characters in substring (default remainder). * @return The new string. * @throw std::out_of_range If pos > size(). * * Construct and return a new string using the @a __n * characters starting at @a __pos. If the string is too * short, use the remainder of the characters. If @a __pos is * beyond the end of the string, out_of_range is thrown. */ __versa_string substr(size_type __pos = 0, size_type __n = npos) const { return __versa_string(*this, _M_check(__pos, "__versa_string::substr"), __n); } /** * @brief Compare to a string. * @param __str String to compare against. * @return Integer < 0, 0, or > 0. * * Returns an integer < 0 if this string is ordered before @a * __str, 0 if their values are equivalent, or > 0 if this * string is ordered after @a __str. Determines the effective * length rlen of the strings to compare as the smallest of * size() and str.size(). The function then compares the two * strings by calling traits::compare(data(), str.data(),rlen). * If the result of the comparison is nonzero returns it, * otherwise the shorter one is ordered first. */ int compare(const __versa_string& __str) const { if (this->_M_compare(__str)) return 0; const size_type __size = this->size(); const size_type __osize = __str.size(); const size_type __len = std::min(__size, __osize); int __r = traits_type::compare(this->_M_data(), __str.data(), __len); if (!__r) __r = this->_S_compare(__size, __osize); return __r; } /** * @brief Compare substring to a string. * @param __pos Index of first character of substring. * @param __n Number of characters in substring. * @param __str String to compare against. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n characters * starting at @a __pos. Returns an integer < 0 if the * substring is ordered before @a __str, 0 if their values are * equivalent, or > 0 if the substring is ordered after @a * __str. Determines the effective length rlen of the strings * to compare as the smallest of the length of the substring * and @a __str.size(). The function then compares the two * strings by calling * traits::compare(substring.data(),str.data(),rlen). If the * result of the comparison is nonzero returns it, otherwise * the shorter one is ordered first. */ int compare(size_type __pos, size_type __n, const __versa_string& __str) const; /** * @brief Compare substring to a substring. * @param __pos1 Index of first character of substring. * @param __n1 Number of characters in substring. * @param __str String to compare against. * @param __pos2 Index of first character of substring of str. * @param __n2 Number of characters in substring of str. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n1 * characters starting at @a __pos1. Form the substring of @a * __str from the @a __n2 characters starting at @a __pos2. * Returns an integer < 0 if this substring is ordered before * the substring of @a __str, 0 if their values are equivalent, * or > 0 if this substring is ordered after the substring of * @a __str. Determines the effective length rlen of the * strings to compare as the smallest of the lengths of the * substrings. The function then compares the two strings by * calling * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). * If the result of the comparison is nonzero returns it, * otherwise the shorter one is ordered first. */ int compare(size_type __pos1, size_type __n1, const __versa_string& __str, size_type __pos2, size_type __n2) const; /** * @brief Compare to a C string. * @param __s C string to compare against. * @return Integer < 0, 0, or > 0. * * Returns an integer < 0 if this string is ordered before @a * __s, 0 if their values are equivalent, or > 0 if this string * is ordered after @a __s. Determines the effective length * rlen of the strings to compare as the smallest of size() and * the length of a string constructed from @a __s. The * function then compares the two strings by calling * traits::compare(data(),s,rlen). If the result of the * comparison is nonzero returns it, otherwise the shorter one * is ordered first. */ int compare(const _CharT* __s) const; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 5 String::compare specification questionable /** * @brief Compare substring to a C string. * @param __pos Index of first character of substring. * @param __n1 Number of characters in substring. * @param __s C string to compare against. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n1 * characters starting at @a __pos. Returns an integer < 0 if * the substring is ordered before @a __s, 0 if their values * are equivalent, or > 0 if the substring is ordered after @a * __s. Determines the effective length rlen of the strings to * compare as the smallest of the length of the substring and * the length of a string constructed from @a __s. The * function then compares the two string by calling * traits::compare(substring.data(),s,rlen). If the result of * the comparison is nonzero returns it, otherwise the shorter * one is ordered first. */ int compare(size_type __pos, size_type __n1, const _CharT* __s) const; /** * @brief Compare substring against a character array. * @param __pos Index of first character of substring. * @param __n1 Number of characters in substring. * @param __s character array to compare against. * @param __n2 Number of characters of s. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n1 * characters starting at @a __pos. Form a string from the * first @a __n2 characters of @a __s. Returns an integer < 0 * if this substring is ordered before the string from @a __s, * 0 if their values are equivalent, or > 0 if this substring * is ordered after the string from @a __s. Determines the * effective length rlen of the strings to compare as the * smallest of the length of the substring and @a __n2. The * function then compares the two strings by calling * traits::compare(substring.data(),__s,rlen). If the result of * the comparison is nonzero returns it, otherwise the shorter * one is ordered first. * * NB: __s must have at least n2 characters, <em>\\0</em> has no special * meaning. */ int compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const; }; // operator+ /** * @brief Concatenate two strings. * @param __lhs First string. * @param __rhs Last string. * @return New string with value of @a __lhs followed by @a __rhs. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs); /** * @brief Concatenate C string and string. * @param __lhs First string. * @param __rhs Last string. * @return New string with value of @a __lhs followed by @a __rhs. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(const _CharT* __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs); /** * @brief Concatenate character and string. * @param __lhs First string. * @param __rhs Last string. * @return New string with @a __lhs followed by @a __rhs. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(_CharT __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs); /** * @brief Concatenate string and C string. * @param __lhs First string. * @param __rhs Last string. * @return New string with @a __lhs followed by @a __rhs. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const _CharT* __rhs); /** * @brief Concatenate string and character. * @param __lhs First string. * @param __rhs Last string. * @return New string with @a __lhs followed by @a __rhs. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, _CharT __rhs); #if __cplusplus >= 201103L template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(__versa_string<_CharT, _Traits, _Alloc, _Base>&& __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return std::move(__lhs.append(__rhs)); } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, __versa_string<_CharT, _Traits, _Alloc, _Base>&& __rhs) { return std::move(__rhs.insert(0, __lhs)); } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(__versa_string<_CharT, _Traits, _Alloc, _Base>&& __lhs, __versa_string<_CharT, _Traits, _Alloc, _Base>&& __rhs) { const auto __size = __lhs.size() + __rhs.size(); const bool __cond = (__size > __lhs.capacity() && __size <= __rhs.capacity()); return __cond ? std::move(__rhs.insert(0, __lhs)) : std::move(__lhs.append(__rhs)); } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(const _CharT* __lhs, __versa_string<_CharT, _Traits, _Alloc, _Base>&& __rhs) { return std::move(__rhs.insert(0, __lhs)); } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(_CharT __lhs, __versa_string<_CharT, _Traits, _Alloc, _Base>&& __rhs) { return std::move(__rhs.insert(0, 1, __lhs)); } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(__versa_string<_CharT, _Traits, _Alloc, _Base>&& __lhs, const _CharT* __rhs) { return std::move(__lhs.append(__rhs)); } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(__versa_string<_CharT, _Traits, _Alloc, _Base>&& __lhs, _CharT __rhs) { return std::move(__lhs.append(1, __rhs)); } #endif // operator == /** * @brief Test equivalence of two strings. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator==(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return __lhs.compare(__rhs) == 0; } template<typename _CharT, template <typename, typename, typename> class _Base> inline typename __enable_if<std::__is_char<_CharT>::__value, bool>::__type operator==(const __versa_string<_CharT, std::char_traits<_CharT>, std::allocator<_CharT>, _Base>& __lhs, const __versa_string<_CharT, std::char_traits<_CharT>, std::allocator<_CharT>, _Base>& __rhs) { return (__lhs.size() == __rhs.size() && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(), __lhs.size())); } /** * @brief Test equivalence of C string and string. * @param __lhs C string. * @param __rhs String. * @return True if @a __rhs.compare(@a __lhs) == 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator==(const _CharT* __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return __rhs.compare(__lhs) == 0; } /** * @brief Test equivalence of string and C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator==(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) == 0; } // operator != /** * @brief Test difference of two strings. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return !(__lhs == __rhs); } /** * @brief Test difference of C string and string. * @param __lhs C string. * @param __rhs String. * @return True if @a __rhs.compare(@a __lhs) != 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator!=(const _CharT* __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return !(__lhs == __rhs); } /** * @brief Test difference of string and C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const _CharT* __rhs) { return !(__lhs == __rhs); } // operator < /** * @brief Test if string precedes string. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs precedes @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator<(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return __lhs.compare(__rhs) < 0; } /** * @brief Test if string precedes C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs precedes @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator<(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) < 0; } /** * @brief Test if C string precedes string. * @param __lhs C string. * @param __rhs String. * @return True if @a __lhs precedes @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator<(const _CharT* __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return __rhs.compare(__lhs) > 0; } // operator > /** * @brief Test if string follows string. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs follows @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator>(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return __lhs.compare(__rhs) > 0; } /** * @brief Test if string follows C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs follows @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator>(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) > 0; } /** * @brief Test if C string follows string. * @param __lhs C string. * @param __rhs String. * @return True if @a __lhs follows @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator>(const _CharT* __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return __rhs.compare(__lhs) < 0; } // operator <= /** * @brief Test if string doesn't follow string. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs doesn't follow @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator<=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return __lhs.compare(__rhs) <= 0; } /** * @brief Test if string doesn't follow C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs doesn't follow @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator<=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) <= 0; } /** * @brief Test if C string doesn't follow string. * @param __lhs C string. * @param __rhs String. * @return True if @a __lhs doesn't follow @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator<=(const _CharT* __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return __rhs.compare(__lhs) >= 0; } // operator >= /** * @brief Test if string doesn't precede string. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs doesn't precede @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator>=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return __lhs.compare(__rhs) >= 0; } /** * @brief Test if string doesn't precede C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs doesn't precede @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator>=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) >= 0; } /** * @brief Test if C string doesn't precede string. * @param __lhs C string. * @param __rhs String. * @return True if @a __lhs doesn't precede @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline bool operator>=(const _CharT* __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { return __rhs.compare(__lhs) <= 0; } /** * @brief Swap contents of two strings. * @param __lhs First string. * @param __rhs Second string. * * Exchanges the contents of @a __lhs and @a __rhs in constant time. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline void swap(__versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { __lhs.swap(__rhs); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Read stream into a string. * @param __is Input stream. * @param __str Buffer to store into. * @return Reference to the input stream. * * Stores characters from @a __is into @a __str until whitespace is * found, the end of the stream is encountered, or str.max_size() * is reached. If is.width() is non-zero, that is the limit on the * number of characters stored into @a __str. Any previous * contents of @a __str are erased. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str); /** * @brief Write string to a stream. * @param __os Output stream. * @param __str String to write out. * @return Reference to the output stream. * * Output characters of @a __str into os following the same rules as for * writing a C string. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 586. string inserter not a formatted function return __ostream_insert(__os, __str.data(), __str.size()); } /** * @brief Read a line from stream into a string. * @param __is Input stream. * @param __str Buffer to store into. * @param __delim Character marking end of line. * @return Reference to the input stream. * * Stores characters from @a __is into @a __str until @a __delim is * found, the end of the stream is encountered, or str.max_size() * is reached. If is.width() is non-zero, that is the limit on the * number of characters stored into @a __str. Any previous * contents of @a __str are erased. If @a delim was encountered, * it is extracted but not stored into @a __str. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>& __is, __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str, _CharT __delim); /** * @brief Read a line from stream into a string. * @param __is Input stream. * @param __str Buffer to store into. * @return Reference to the input stream. * * Stores characters from is into @a __str until '\n' is * found, the end of the stream is encountered, or str.max_size() * is reached. If is.width() is non-zero, that is the limit on the * number of characters stored into @a __str. Any previous * contents of @a __str are erased. If end of line was * encountered, it is extracted but not stored into @a __str. */ template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> inline basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>& __is, __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str) { return getline(__is, __str, __is.widen('\n')); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if __cplusplus >= 201103L #include <ext/string_conversions.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if _GLIBCXX_USE_C99_STDLIB // 21.4 Numeric Conversions [string.conversions]. inline int stoi(const __vstring& __str, std::size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(), __idx, __base); } inline long stol(const __vstring& __str, std::size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(), __idx, __base); } inline unsigned long stoul(const __vstring& __str, std::size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(), __idx, __base); } inline long long stoll(const __vstring& __str, std::size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(), __idx, __base); } inline unsigned long long stoull(const __vstring& __str, std::size_t* __idx, int __base = 10) { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(), __idx, __base); } // NB: strtof vs strtod. inline float stof(const __vstring& __str, std::size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); } inline double stod(const __vstring& __str, std::size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); } inline long double stold(const __vstring& __str, std::size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); } #endif // _GLIBCXX_USE_C99_STDLIB #if _GLIBCXX_USE_C99_STDIO // NB: (v)snprintf vs sprintf. // DR 1261. inline __vstring to_string(int __val) { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, 4 * sizeof(int), "%d", __val); } inline __vstring to_string(unsigned __val) { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, 4 * sizeof(unsigned), "%u", __val); } inline __vstring to_string(long __val) { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, 4 * sizeof(long), "%ld", __val); } inline __vstring to_string(unsigned long __val) { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, 4 * sizeof(unsigned long), "%lu", __val); } inline __vstring to_string(long long __val) { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, 4 * sizeof(long long), "%lld", __val); } inline __vstring to_string(unsigned long long __val) { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, 4 * sizeof(unsigned long long), "%llu", __val); } inline __vstring to_string(float __val) { const int __n = __numeric_traits<float>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, __n, "%f", __val); } inline __vstring to_string(double __val) { const int __n = __numeric_traits<double>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, __n, "%f", __val); } inline __vstring to_string(long double __val) { const int __n = __numeric_traits<long double>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, __n, "%Lf", __val); } #endif // _GLIBCXX_USE_C99_STDIO #if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_WCHAR inline int stoi(const __wvstring& __str, std::size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa<long, int>(&std::wcstol, "stoi", __str.c_str(), __idx, __base); } inline long stol(const __wvstring& __str, std::size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::wcstol, "stol", __str.c_str(), __idx, __base); } inline unsigned long stoul(const __wvstring& __str, std::size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::wcstoul, "stoul", __str.c_str(), __idx, __base); } inline long long stoll(const __wvstring& __str, std::size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(), __idx, __base); } inline unsigned long long stoull(const __wvstring& __str, std::size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(), __idx, __base); } // NB: wcstof vs wcstod. inline float stof(const __wvstring& __str, std::size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); } inline double stod(const __wvstring& __str, std::size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::wcstod, "stod", __str.c_str(), __idx); } inline long double stold(const __wvstring& __str, std::size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); } #ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF // DR 1261. inline __wvstring to_wstring(int __val) { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, 4 * sizeof(int), L"%d", __val); } inline __wvstring to_wstring(unsigned __val) { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, 4 * sizeof(unsigned), L"%u", __val); } inline __wvstring to_wstring(long __val) { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, 4 * sizeof(long), L"%ld", __val); } inline __wvstring to_wstring(unsigned long __val) { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, 4 * sizeof(unsigned long), L"%lu", __val); } inline __wvstring to_wstring(long long __val) { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, 4 * sizeof(long long), L"%lld", __val); } inline __wvstring to_wstring(unsigned long long __val) { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, 4 * sizeof(unsigned long long), L"%llu", __val); } inline __wvstring to_wstring(float __val) { const int __n = __numeric_traits<float>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, __n, L"%f", __val); } inline __wvstring to_wstring(double __val) { const int __n = __numeric_traits<double>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, __n, L"%f", __val); } inline __wvstring to_wstring(long double __val) { const int __n = __numeric_traits<long double>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, __n, L"%Lf", __val); } #endif // _GLIBCXX_HAVE_BROKEN_VSWPRINTF #endif // _GLIBCXX_USE_WCHAR_T && _GLIBCXX_USE_C99_WCHAR _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif #if __cplusplus >= 201103L #include <bits/functional_hash.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// std::hash specialization for __vstring. template<> struct hash<__gnu_cxx::__vstring> : public __hash_base<size_t, __gnu_cxx::__vstring> { size_t operator()(const __gnu_cxx::__vstring& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length()); } }; #ifdef _GLIBCXX_USE_WCHAR_T /// std::hash specialization for __wvstring. template<> struct hash<__gnu_cxx::__wvstring> : public __hash_base<size_t, __gnu_cxx::__wvstring> { size_t operator()(const __gnu_cxx::__wvstring& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); } }; #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 /// std::hash specialization for __u16vstring. template<> struct hash<__gnu_cxx::__u16vstring> : public __hash_base<size_t, __gnu_cxx::__u16vstring> { size_t operator()(const __gnu_cxx::__u16vstring& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(char16_t)); } }; /// std::hash specialization for __u32vstring. template<> struct hash<__gnu_cxx::__u32vstring> : public __hash_base<size_t, __gnu_cxx::__u32vstring> { size_t operator()(const __gnu_cxx::__u32vstring& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(char32_t)); } }; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #include <ext/vstring.tcc> #endif /* _VSTRING_H */ c++/8/ext/array_allocator.h 0000644 00000012412 15146341150 0011412 0 ustar 00 // array allocator -*- C++ -*- // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/array_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _ARRAY_ALLOCATOR_H #define _ARRAY_ALLOCATOR_H 1 #include <bits/c++config.h> #include <new> #include <bits/functexcept.h> #include <tr1/array> #include <bits/move.h> #if __cplusplus >= 201103L #include <type_traits> #endif // Suppress deprecated warning for this file. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; /// Base class. template<typename _Tp> class array_allocator_base { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } void deallocate(pointer, size_type) { // Does nothing. } size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return size_t(-1) / sizeof(_Tp); } #if __cplusplus >= 201103L template<typename _Up, typename... _Args> void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template<typename _Up> void destroy(_Up* __p) { __p->~_Up(); } #else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) value_type(__val); } void destroy(pointer __p) { __p->~_Tp(); } #endif } _GLIBCXX_DEPRECATED; /** * @brief An allocator that uses previously allocated memory. * This memory can be externally, globally, or otherwise allocated. * @ingroup allocators */ template<typename _Tp, typename _Array = std::tr1::array<_Tp, 1> > class array_allocator : public array_allocator_base<_Tp> { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; typedef _Array array_type; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; typedef std::true_type is_always_equal; #endif private: array_type* _M_array; size_type _M_used; public: template<typename _Tp1, typename _Array1 = _Array> struct rebind { typedef array_allocator<_Tp1, _Array1> other _GLIBCXX_DEPRECATED; } _GLIBCXX_DEPRECATED; array_allocator(array_type* __array = 0) _GLIBCXX_USE_NOEXCEPT : _M_array(__array), _M_used(size_type()) { } array_allocator(const array_allocator& __o) _GLIBCXX_USE_NOEXCEPT : _M_array(__o._M_array), _M_used(__o._M_used) { } template<typename _Tp1, typename _Array1> array_allocator(const array_allocator<_Tp1, _Array1>&) _GLIBCXX_USE_NOEXCEPT : _M_array(0), _M_used(size_type()) { } ~array_allocator() _GLIBCXX_USE_NOEXCEPT { } pointer allocate(size_type __n, const void* = 0) { if (_M_array == 0 || _M_used + __n > _M_array->size()) std::__throw_bad_alloc(); pointer __ret = _M_array->begin() + _M_used; _M_used += __n; return __ret; } } _GLIBCXX_DEPRECATED; template<typename _Tp, typename _Array> inline bool operator==(const array_allocator<_Tp, _Array>&, const array_allocator<_Tp, _Array>&) { return true; } template<typename _Tp, typename _Array> inline bool operator!=(const array_allocator<_Tp, _Array>&, const array_allocator<_Tp, _Array>&) { return false; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #pragma GCC diagnostic pop #endif c++/8/ext/enc_filebuf.h 0000644 00000004307 15146341150 0010501 0 ustar 00 // filebuf with encoding state type -*- C++ -*- // Copyright (C) 2002-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/enc_filebuf.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_ENC_FILEBUF_H #define _EXT_ENC_FILEBUF_H 1 #include <fstream> #include <locale> #include <ext/codecvt_specializations.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// class enc_filebuf. template<typename _CharT> class enc_filebuf : public std::basic_filebuf<_CharT, encoding_char_traits<_CharT> > { public: typedef encoding_char_traits<_CharT> traits_type; typedef typename traits_type::state_type state_type; typedef typename traits_type::pos_type pos_type; enc_filebuf(state_type& __state) : std::basic_filebuf<_CharT, encoding_char_traits<_CharT> >() { this->_M_state_beg = __state; } private: // concept requirements: // Set state type to something useful. // Something more than copyconstructible is needed here, so // require default and copy constructible + assignment operator. __glibcxx_class_requires(state_type, _SGIAssignableConcept) }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/extptr_allocator.h 0000644 00000014055 15146341150 0011627 0 ustar 00 // <extptr_allocator.h> -*- C++ -*- // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** * @file ext/extptr_allocator.h * This file is a GNU extension to the Standard C++ Library. * * @author Bob Walters * * An example allocator which uses an alternative pointer type from * bits/pointer.h. Supports test cases which confirm container support * for alternative pointers. */ #ifndef _EXTPTR_ALLOCATOR_H #define _EXTPTR_ALLOCATOR_H 1 #include <memory> #include <ext/numeric_traits.h> #include <ext/pointer.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief An example allocator which uses a non-standard pointer type. * @ingroup allocators * * This allocator specifies that containers use a 'relative pointer' as it's * pointer type. (See ext/pointer.h) Memory allocation in this example * is still performed using std::allocator. */ template<typename _Tp> class _ExtPtr_allocator { public: typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; // Note the non-standard pointer types. typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> > pointer; typedef _Pointer_adapter<_Relative_pointer_impl<const _Tp> > const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; template<typename _Up> struct rebind { typedef _ExtPtr_allocator<_Up> other; }; _ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT : _M_real_alloc() { } _ExtPtr_allocator(const _ExtPtr_allocator& __rarg) _GLIBCXX_USE_NOEXCEPT : _M_real_alloc(__rarg._M_real_alloc) { } template<typename _Up> _ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg) _GLIBCXX_USE_NOEXCEPT : _M_real_alloc(__rarg._M_getUnderlyingImp()) { } ~_ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT { } pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } pointer allocate(size_type __n, void* __hint = 0) { return _M_real_alloc.allocate(__n,__hint); } void deallocate(pointer __p, size_type __n) { _M_real_alloc.deallocate(__p.get(), __n); } size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return __numeric_traits<size_type>::__max / sizeof(_Tp); } #if __cplusplus >= 201103L template<typename _Up, typename... _Args> void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template<typename... _Args> void construct(pointer __p, _Args&&... __args) { construct(__p.get(), std::forward<_Args>(__args)...); } template<typename _Up> void destroy(_Up* __p) { __p->~_Up(); } void destroy(pointer __p) { destroy(__p.get()); } #else void construct(pointer __p, const _Tp& __val) { ::new(__p.get()) _Tp(__val); } void destroy(pointer __p) { __p->~_Tp(); } #endif template<typename _Up> inline bool operator==(const _ExtPtr_allocator<_Up>& __rarg) { return _M_real_alloc == __rarg._M_getUnderlyingImp(); } inline bool operator==(const _ExtPtr_allocator& __rarg) { return _M_real_alloc == __rarg._M_real_alloc; } template<typename _Up> inline bool operator!=(const _ExtPtr_allocator<_Up>& __rarg) { return _M_real_alloc != __rarg._M_getUnderlyingImp(); } inline bool operator!=(const _ExtPtr_allocator& __rarg) { return _M_real_alloc != __rarg._M_real_alloc; } template<typename _Up> inline friend void swap(_ExtPtr_allocator<_Up>&, _ExtPtr_allocator<_Up>&); // A method specific to this implementation. const std::allocator<_Tp>& _M_getUnderlyingImp() const { return _M_real_alloc; } private: std::allocator<_Tp> _M_real_alloc; }; // _ExtPtr_allocator<void> specialization. template<> class _ExtPtr_allocator<void> { public: typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef void value_type; // Note the non-standard pointer types typedef _Pointer_adapter<_Relative_pointer_impl<void> > pointer; typedef _Pointer_adapter<_Relative_pointer_impl<const void> > const_pointer; template<typename _Up> struct rebind { typedef _ExtPtr_allocator<_Up> other; }; private: std::allocator<void> _M_real_alloc; }; template<typename _Tp> inline void swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg) { std::allocator<_Tp> __tmp( __rarg._M_real_alloc ); __rarg._M_real_alloc = __larg._M_real_alloc; __larg._M_real_alloc = __tmp; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _EXTPTR_ALLOCATOR_H */ c++/8/ext/type_traits.h 0000644 00000013432 15146341150 0010606 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, or (at your option) any later // version. // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/type_traits.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_TYPE_TRAITS #define _EXT_TYPE_TRAITS 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/cpp_type_traits.h> extern "C++" { namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Define a nested type if some predicate holds. template<bool, typename> struct __enable_if { }; template<typename _Tp> struct __enable_if<true, _Tp> { typedef _Tp __type; }; // Conditional expression for types. If true, first, if false, second. template<bool _Cond, typename _Iftrue, typename _Iffalse> struct __conditional_type { typedef _Iftrue __type; }; template<typename _Iftrue, typename _Iffalse> struct __conditional_type<false, _Iftrue, _Iffalse> { typedef _Iffalse __type; }; // Given an integral builtin type, return the corresponding unsigned type. template<typename _Tp> struct __add_unsigned { private: typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; public: typedef typename __if_type::__type __type; }; template<> struct __add_unsigned<char> { typedef unsigned char __type; }; template<> struct __add_unsigned<signed char> { typedef unsigned char __type; }; template<> struct __add_unsigned<short> { typedef unsigned short __type; }; template<> struct __add_unsigned<int> { typedef unsigned int __type; }; template<> struct __add_unsigned<long> { typedef unsigned long __type; }; template<> struct __add_unsigned<long long> { typedef unsigned long long __type; }; // Declare but don't define. template<> struct __add_unsigned<bool>; template<> struct __add_unsigned<wchar_t>; // Given an integral builtin type, return the corresponding signed type. template<typename _Tp> struct __remove_unsigned { private: typedef __enable_if<std::__is_integer<_Tp>::__value, _Tp> __if_type; public: typedef typename __if_type::__type __type; }; template<> struct __remove_unsigned<char> { typedef signed char __type; }; template<> struct __remove_unsigned<unsigned char> { typedef signed char __type; }; template<> struct __remove_unsigned<unsigned short> { typedef short __type; }; template<> struct __remove_unsigned<unsigned int> { typedef int __type; }; template<> struct __remove_unsigned<unsigned long> { typedef long __type; }; template<> struct __remove_unsigned<unsigned long long> { typedef long long __type; }; // Declare but don't define. template<> struct __remove_unsigned<bool>; template<> struct __remove_unsigned<wchar_t>; // For use in string and vstring. template<typename _Type> inline bool __is_null_pointer(_Type* __ptr) { return __ptr == 0; } template<typename _Type> inline bool __is_null_pointer(_Type) { return false; } #if __cplusplus >= 201103L inline bool __is_null_pointer(std::nullptr_t) { return true; } #endif // For complex and cmath template<typename _Tp, bool = std::__is_integer<_Tp>::__value> struct __promote { typedef double __type; }; // No nested __type member for non-integer non-floating point types, // allows this type to be used for SFINAE to constrain overloads in // <cmath> and <complex> to only the intended types. template<typename _Tp> struct __promote<_Tp, false> { }; template<> struct __promote<long double> { typedef long double __type; }; template<> struct __promote<double> { typedef double __type; }; template<> struct __promote<float> { typedef float __type; }; template<typename _Tp, typename _Up, typename _Tp2 = typename __promote<_Tp>::__type, typename _Up2 = typename __promote<_Up>::__type> struct __promote_2 { typedef __typeof__(_Tp2() + _Up2()) __type; }; template<typename _Tp, typename _Up, typename _Vp, typename _Tp2 = typename __promote<_Tp>::__type, typename _Up2 = typename __promote<_Up>::__type, typename _Vp2 = typename __promote<_Vp>::__type> struct __promote_3 { typedef __typeof__(_Tp2() + _Up2() + _Vp2()) __type; }; template<typename _Tp, typename _Up, typename _Vp, typename _Wp, typename _Tp2 = typename __promote<_Tp>::__type, typename _Up2 = typename __promote<_Up>::__type, typename _Vp2 = typename __promote<_Vp>::__type, typename _Wp2 = typename __promote<_Wp>::__type> struct __promote_4 { typedef __typeof__(_Tp2() + _Up2() + _Vp2() + _Wp2()) __type; }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace } // extern "C++" #endif c++/8/ext/vstring.tcc 0000644 00000056076 15146341150 0010270 0 ustar 00 // Versatile string -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/vstring.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/vstring.h} */ #ifndef _VSTRING_TCC #define _VSTRING_TCC 1 #pragma GCC system_header #include <bits/cxxabi_forced.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> const typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>::npos; template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> void __versa_string<_CharT, _Traits, _Alloc, _Base>:: resize(size_type __n, _CharT __c) { const size_type __size = this->size(); if (__size < __n) this->append(__n - __size, __c); else if (__n < __size) this->_M_erase(__n, __size - __n); } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base>& __versa_string<_CharT, _Traits, _Alloc, _Base>:: _M_append(const _CharT* __s, size_type __n) { const size_type __len = __n + this->size(); if (__len <= this->capacity() && !this->_M_is_shared()) { if (__n) this->_S_copy(this->_M_data() + this->size(), __s, __n); } else this->_M_mutate(this->size(), size_type(0), __s, __n); this->_M_set_length(__len); return *this; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> template<typename _InputIterator> __versa_string<_CharT, _Traits, _Alloc, _Base>& __versa_string<_CharT, _Traits, _Alloc, _Base>:: _M_replace_dispatch(const_iterator __i1, const_iterator __i2, _InputIterator __k1, _InputIterator __k2, std::__false_type) { const __versa_string __s(__k1, __k2); const size_type __n1 = __i2 - __i1; return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(), __s.size()); } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base>& __versa_string<_CharT, _Traits, _Alloc, _Base>:: _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, _CharT __c) { _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux"); const size_type __old_size = this->size(); const size_type __new_size = __old_size + __n2 - __n1; if (__new_size <= this->capacity() && !this->_M_is_shared()) { _CharT* __p = this->_M_data() + __pos1; const size_type __how_much = __old_size - __pos1 - __n1; if (__how_much && __n1 != __n2) this->_S_move(__p + __n2, __p + __n1, __how_much); } else this->_M_mutate(__pos1, __n1, 0, __n2); if (__n2) this->_S_assign(this->_M_data() + __pos1, __n2, __c); this->_M_set_length(__new_size); return *this; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base>& __versa_string<_CharT, _Traits, _Alloc, _Base>:: _M_replace(size_type __pos, size_type __len1, const _CharT* __s, const size_type __len2) { _M_check_length(__len1, __len2, "__versa_string::_M_replace"); const size_type __old_size = this->size(); const size_type __new_size = __old_size + __len2 - __len1; if (__new_size <= this->capacity() && !this->_M_is_shared()) { _CharT* __p = this->_M_data() + __pos; const size_type __how_much = __old_size - __pos - __len1; if (_M_disjunct(__s)) { if (__how_much && __len1 != __len2) this->_S_move(__p + __len2, __p + __len1, __how_much); if (__len2) this->_S_copy(__p, __s, __len2); } else { // Work in-place. if (__len2 && __len2 <= __len1) this->_S_move(__p, __s, __len2); if (__how_much && __len1 != __len2) this->_S_move(__p + __len2, __p + __len1, __how_much); if (__len2 > __len1) { if (__s + __len2 <= __p + __len1) this->_S_move(__p, __s, __len2); else if (__s >= __p + __len1) this->_S_copy(__p, __s + __len2 - __len1, __len2); else { const size_type __nleft = (__p + __len1) - __s; this->_S_move(__p, __s, __nleft); this->_S_copy(__p + __nleft, __p + __len2, __len2 - __nleft); } } } } else this->_M_mutate(__pos, __len1, __s, __len2); this->_M_set_length(__new_size); return *this; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { __versa_string<_CharT, _Traits, _Alloc, _Base> __str; __str.reserve(__lhs.size() + __rhs.size()); __str.append(__lhs); __str.append(__rhs); return __str; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(const _CharT* __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { __glibcxx_requires_string(__lhs); typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; typedef typename __string_type::size_type __size_type; const __size_type __len = _Traits::length(__lhs); __string_type __str; __str.reserve(__len + __rhs.size()); __str.append(__lhs, __len); __str.append(__rhs); return __str; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(_CharT __lhs, const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) { __versa_string<_CharT, _Traits, _Alloc, _Base> __str; __str.reserve(__rhs.size() + 1); __str.push_back(__lhs); __str.append(__rhs); return __str; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, const _CharT* __rhs) { __glibcxx_requires_string(__rhs); typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; typedef typename __string_type::size_type __size_type; const __size_type __len = _Traits::length(__rhs); __string_type __str; __str.reserve(__lhs.size() + __len); __str.append(__lhs); __str.append(__rhs, __len); return __str; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> __versa_string<_CharT, _Traits, _Alloc, _Base> operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, _CharT __rhs) { __versa_string<_CharT, _Traits, _Alloc, _Base> __str; __str.reserve(__lhs.size() + 1); __str.append(__lhs); __str.push_back(__rhs); return __str; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: copy(_CharT* __s, size_type __n, size_type __pos) const { _M_check(__pos, "__versa_string::copy"); __n = _M_limit(__pos, __n); __glibcxx_requires_string_len(__s, __n); if (__n) this->_S_copy(__s, this->_M_data() + __pos, __n); // 21.3.5.7 par 3: do not append null. (good.) return __n; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: find(const _CharT* __s, size_type __pos, size_type __n) const { __glibcxx_requires_string_len(__s, __n); const size_type __size = this->size(); const _CharT* __data = this->_M_data(); if (__n == 0) return __pos <= __size ? __pos : npos; if (__n <= __size) { for (; __pos <= __size - __n; ++__pos) if (traits_type::eq(__data[__pos], __s[0]) && traits_type::compare(__data + __pos + 1, __s + 1, __n - 1) == 0) return __pos; } return npos; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT { size_type __ret = npos; const size_type __size = this->size(); if (__pos < __size) { const _CharT* __data = this->_M_data(); const size_type __n = __size - __pos; const _CharT* __p = traits_type::find(__data + __pos, __n, __c); if (__p) __ret = __p - __data; } return __ret; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: rfind(const _CharT* __s, size_type __pos, size_type __n) const { __glibcxx_requires_string_len(__s, __n); const size_type __size = this->size(); if (__n <= __size) { __pos = std::min(size_type(__size - __n), __pos); const _CharT* __data = this->_M_data(); do { if (traits_type::compare(__data + __pos, __s, __n) == 0) return __pos; } while (__pos-- > 0); } return npos; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT { size_type __size = this->size(); if (__size) { if (--__size > __pos) __size = __pos; for (++__size; __size-- > 0; ) if (traits_type::eq(this->_M_data()[__size], __c)) return __size; } return npos; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: find_first_of(const _CharT* __s, size_type __pos, size_type __n) const { __glibcxx_requires_string_len(__s, __n); for (; __n && __pos < this->size(); ++__pos) { const _CharT* __p = traits_type::find(__s, __n, this->_M_data()[__pos]); if (__p) return __pos; } return npos; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: find_last_of(const _CharT* __s, size_type __pos, size_type __n) const { __glibcxx_requires_string_len(__s, __n); size_type __size = this->size(); if (__size && __n) { if (--__size > __pos) __size = __pos; do { if (traits_type::find(__s, __n, this->_M_data()[__size])) return __size; } while (__size-- != 0); } return npos; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const { __glibcxx_requires_string_len(__s, __n); for (; __pos < this->size(); ++__pos) if (!traits_type::find(__s, __n, this->_M_data()[__pos])) return __pos; return npos; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT { for (; __pos < this->size(); ++__pos) if (!traits_type::eq(this->_M_data()[__pos], __c)) return __pos; return npos; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const { __glibcxx_requires_string_len(__s, __n); size_type __size = this->size(); if (__size) { if (--__size > __pos) __size = __pos; do { if (!traits_type::find(__s, __n, this->_M_data()[__size])) return __size; } while (__size--); } return npos; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> typename __versa_string<_CharT, _Traits, _Alloc, _Base>::size_type __versa_string<_CharT, _Traits, _Alloc, _Base>:: find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT { size_type __size = this->size(); if (__size) { if (--__size > __pos) __size = __pos; do { if (!traits_type::eq(this->_M_data()[__size], __c)) return __size; } while (__size--); } return npos; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> int __versa_string<_CharT, _Traits, _Alloc, _Base>:: compare(size_type __pos, size_type __n, const __versa_string& __str) const { _M_check(__pos, "__versa_string::compare"); __n = _M_limit(__pos, __n); const size_type __osize = __str.size(); const size_type __len = std::min(__n, __osize); int __r = traits_type::compare(this->_M_data() + __pos, __str.data(), __len); if (!__r) __r = this->_S_compare(__n, __osize); return __r; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> int __versa_string<_CharT, _Traits, _Alloc, _Base>:: compare(size_type __pos1, size_type __n1, const __versa_string& __str, size_type __pos2, size_type __n2) const { _M_check(__pos1, "__versa_string::compare"); __str._M_check(__pos2, "__versa_string::compare"); __n1 = _M_limit(__pos1, __n1); __n2 = __str._M_limit(__pos2, __n2); const size_type __len = std::min(__n1, __n2); int __r = traits_type::compare(this->_M_data() + __pos1, __str.data() + __pos2, __len); if (!__r) __r = this->_S_compare(__n1, __n2); return __r; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> int __versa_string<_CharT, _Traits, _Alloc, _Base>:: compare(const _CharT* __s) const { __glibcxx_requires_string(__s); const size_type __size = this->size(); const size_type __osize = traits_type::length(__s); const size_type __len = std::min(__size, __osize); int __r = traits_type::compare(this->_M_data(), __s, __len); if (!__r) __r = this->_S_compare(__size, __osize); return __r; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> int __versa_string <_CharT, _Traits, _Alloc, _Base>:: compare(size_type __pos, size_type __n1, const _CharT* __s) const { __glibcxx_requires_string(__s); _M_check(__pos, "__versa_string::compare"); __n1 = _M_limit(__pos, __n1); const size_type __osize = traits_type::length(__s); const size_type __len = std::min(__n1, __osize); int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); if (!__r) __r = this->_S_compare(__n1, __osize); return __r; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> int __versa_string <_CharT, _Traits, _Alloc, _Base>:: compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const { __glibcxx_requires_string_len(__s, __n2); _M_check(__pos, "__versa_string::compare"); __n1 = _M_limit(__pos, __n1); const size_type __len = std::min(__n1, __n2); int __r = traits_type::compare(this->_M_data() + __pos, __s, __len); if (!__r) __r = this->_S_compare(__n1, __n2); return __r; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __in, __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str) { typedef basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; typedef typename __istream_type::int_type __int_type; typedef typename __string_type::size_type __size_type; typedef ctype<_CharT> __ctype_type; typedef typename __ctype_type::ctype_base __ctype_base; __size_type __extracted = 0; typename __ios_base::iostate __err = __ios_base::goodbit; typename __istream_type::sentry __cerb(__in, false); if (__cerb) { __try { // Avoid reallocation for common case. __str.erase(); _CharT __buf[128]; __size_type __len = 0; const streamsize __w = __in.width(); const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size(); const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); const __int_type __eof = _Traits::eof(); __int_type __c = __in.rdbuf()->sgetc(); while (__extracted < __n && !_Traits::eq_int_type(__c, __eof) && !__ct.is(__ctype_base::space, _Traits::to_char_type(__c))) { if (__len == sizeof(__buf) / sizeof(_CharT)) { __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); __len = 0; } __buf[__len++] = _Traits::to_char_type(__c); ++__extracted; __c = __in.rdbuf()->snextc(); } __str.append(__buf, __len); if (_Traits::eq_int_type(__c, __eof)) __err |= __ios_base::eofbit; __in.width(0); } __catch(__cxxabiv1::__forced_unwind&) { __in._M_setstate(__ios_base::badbit); __throw_exception_again; } __catch(...) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 91. Description of operator>> and getline() for string<> // might cause endless loop __in._M_setstate(__ios_base::badbit); } } // 211. operator>>(istream&, string&) doesn't set failbit if (!__extracted) __err |= __ios_base::failbit; if (__err) __in.setstate(__err); return __in; } template<typename _CharT, typename _Traits, typename _Alloc, template <typename, typename, typename> class _Base> basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>& __in, __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str, _CharT __delim) { typedef basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; typedef __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base> __string_type; typedef typename __istream_type::int_type __int_type; typedef typename __string_type::size_type __size_type; __size_type __extracted = 0; const __size_type __n = __str.max_size(); typename __ios_base::iostate __err = __ios_base::goodbit; typename __istream_type::sentry __cerb(__in, true); if (__cerb) { __try { // Avoid reallocation for common case. __str.erase(); _CharT __buf[128]; __size_type __len = 0; const __int_type __idelim = _Traits::to_int_type(__delim); const __int_type __eof = _Traits::eof(); __int_type __c = __in.rdbuf()->sgetc(); while (__extracted < __n && !_Traits::eq_int_type(__c, __eof) && !_Traits::eq_int_type(__c, __idelim)) { if (__len == sizeof(__buf) / sizeof(_CharT)) { __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); __len = 0; } __buf[__len++] = _Traits::to_char_type(__c); ++__extracted; __c = __in.rdbuf()->snextc(); } __str.append(__buf, __len); if (_Traits::eq_int_type(__c, __eof)) __err |= __ios_base::eofbit; else if (_Traits::eq_int_type(__c, __idelim)) { ++__extracted; __in.rdbuf()->sbumpc(); } else __err |= __ios_base::failbit; } __catch(__cxxabiv1::__forced_unwind&) { __in._M_setstate(__ios_base::badbit); __throw_exception_again; } __catch(...) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 91. Description of operator>> and getline() for string<> // might cause endless loop __in._M_setstate(__ios_base::badbit); } } if (!__extracted) __err |= __ios_base::failbit; if (__err) __in.setstate(__err); return __in; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _VSTRING_TCC c++/8/ext/rope 0000644 00000253125 15146341150 0006763 0 ustar 00 // SGI's rope class -*- C++ -*- // Copyright (C) 2001-2018 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) 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 ext/rope * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _ROPE #define _ROPE 1 #pragma GCC system_header #include <algorithm> #include <iosfwd> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> #include <bits/stl_function.h> #include <bits/stl_numeric.h> #include <bits/allocator.h> #include <bits/gthr.h> #include <tr1/functional> # ifdef __GC # define __GC_CONST const # else # define __GC_CONST // constant except for deallocation # endif #include <ext/memory> // For uninitialized_copy_n namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { enum { _S_max_rope_depth = 45 }; enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; } // namespace __detail using std::size_t; using std::ptrdiff_t; using std::allocator; using std::_Destroy; // See libstdc++/36832. template<typename _ForwardIterator, typename _Allocator> void _Destroy_const(_ForwardIterator __first, _ForwardIterator __last, _Allocator __alloc) { for (; __first != __last; ++__first) __alloc.destroy(&*__first); } template<typename _ForwardIterator, typename _Tp> inline void _Destroy_const(_ForwardIterator __first, _ForwardIterator __last, allocator<_Tp>) { _Destroy(__first, __last); } // The _S_eos function is used for those functions that // convert to/from C-like strings to detect the end of the string. // The end-of-C-string character. // This is what the draft standard says it should be. template <class _CharT> inline _CharT _S_eos(_CharT*) { return _CharT(); } // Test for basic character types. // For basic character types leaves having a trailing eos. template <class _CharT> inline bool _S_is_basic_char_type(_CharT*) { return false; } template <class _CharT> inline bool _S_is_one_byte_char_type(_CharT*) { return false; } inline bool _S_is_basic_char_type(char*) { return true; } inline bool _S_is_one_byte_char_type(char*) { return true; } inline bool _S_is_basic_char_type(wchar_t*) { return true; } // Store an eos iff _CharT is a basic character type. // Do not reference _S_eos if it isn't. template <class _CharT> inline void _S_cond_store_eos(_CharT&) { } inline void _S_cond_store_eos(char& __c) { __c = 0; } inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; } // char_producers are logically functions that generate a section of // a string. These can be converted to ropes. The resulting rope // invokes the char_producer on demand. This allows, for example, // files to be viewed as ropes without reading the entire file. template <class _CharT> class char_producer { public: virtual ~char_producer() { } virtual void operator()(size_t __start_pos, size_t __len, _CharT* __buffer) = 0; // Buffer should really be an arbitrary output iterator. // That way we could flatten directly into an ostream, etc. // This is thoroughly impossible, since iterator types don't // have runtime descriptions. }; // Sequence buffers: // // Sequence must provide an append operation that appends an // array to the sequence. Sequence buffers are useful only if // appending an entire array is cheaper than appending element by element. // This is true for many string representations. // This should perhaps inherit from ostream<sequence::value_type> // and be implemented correspondingly, so that they can be used // for formatted. For the sake of portability, we don't do this yet. // // For now, sequence buffers behave as output iterators. But they also // behave a little like basic_ostringstream<sequence::value_type> and a // little like containers. template<class _Sequence, size_t _Buf_sz = 100> class sequence_buffer : public std::iterator<std::output_iterator_tag, void, void, void, void> { public: typedef typename _Sequence::value_type value_type; protected: _Sequence* _M_prefix; value_type _M_buffer[_Buf_sz]; size_t _M_buf_count; public: void flush() { _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count); _M_buf_count = 0; } ~sequence_buffer() { flush(); } sequence_buffer() : _M_prefix(0), _M_buf_count(0) { } sequence_buffer(const sequence_buffer& __x) { _M_prefix = __x._M_prefix; _M_buf_count = __x._M_buf_count; std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); } sequence_buffer(sequence_buffer& __x) { __x.flush(); _M_prefix = __x._M_prefix; _M_buf_count = 0; } sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) { } sequence_buffer& operator=(sequence_buffer& __x) { __x.flush(); _M_prefix = __x._M_prefix; _M_buf_count = 0; return *this; } sequence_buffer& operator=(const sequence_buffer& __x) { _M_prefix = __x._M_prefix; _M_buf_count = __x._M_buf_count; std::copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); return *this; } void push_back(value_type __x) { if (_M_buf_count < _Buf_sz) { _M_buffer[_M_buf_count] = __x; ++_M_buf_count; } else { flush(); _M_buffer[0] = __x; _M_buf_count = 1; } } void append(value_type* __s, size_t __len) { if (__len + _M_buf_count <= _Buf_sz) { size_t __i = _M_buf_count; for (size_t __j = 0; __j < __len; __i++, __j++) _M_buffer[__i] = __s[__j]; _M_buf_count += __len; } else if (0 == _M_buf_count) _M_prefix->append(__s, __s + __len); else { flush(); append(__s, __len); } } sequence_buffer& write(value_type* __s, size_t __len) { append(__s, __len); return *this; } sequence_buffer& put(value_type __x) { push_back(__x); return *this; } sequence_buffer& operator=(const value_type& __rhs) { push_back(__rhs); return *this; } sequence_buffer& operator*() { return *this; } sequence_buffer& operator++() { return *this; } sequence_buffer operator++(int) { return *this; } }; // The following should be treated as private, at least for now. template<class _CharT> class _Rope_char_consumer { public: // If we had member templates, these should not be virtual. // For now we need to use run-time parametrization where // compile-time would do. Hence this should all be private // for now. // The symmetry with char_producer is accidental and temporary. virtual ~_Rope_char_consumer() { } virtual bool operator()(const _CharT* __buffer, size_t __len) = 0; }; // First a lot of forward declarations. The standard seems to require // much stricter "declaration before use" than many of the implementations // that preceded it. template<class _CharT, class _Alloc = allocator<_CharT> > class rope; template<class _CharT, class _Alloc> struct _Rope_RopeConcatenation; template<class _CharT, class _Alloc> struct _Rope_RopeLeaf; template<class _CharT, class _Alloc> struct _Rope_RopeFunction; template<class _CharT, class _Alloc> struct _Rope_RopeSubstring; template<class _CharT, class _Alloc> class _Rope_iterator; template<class _CharT, class _Alloc> class _Rope_const_iterator; template<class _CharT, class _Alloc> class _Rope_char_ref_proxy; template<class _CharT, class _Alloc> class _Rope_char_ptr_proxy; template<class _CharT, class _Alloc> bool operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> _Rope_const_iterator<_CharT, _Alloc> operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); template<class _CharT, class _Alloc> _Rope_const_iterator<_CharT, _Alloc> operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); template<class _CharT, class _Alloc> _Rope_const_iterator<_CharT, _Alloc> operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT, _Alloc>& __x); template<class _CharT, class _Alloc> bool operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> bool operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> ptrdiff_t operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> _Rope_iterator<_CharT, _Alloc> operator-(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); template<class _CharT, class _Alloc> _Rope_iterator<_CharT, _Alloc> operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n); template<class _CharT, class _Alloc> _Rope_iterator<_CharT, _Alloc> operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x); template<class _CharT, class _Alloc> bool operator==(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> bool operator<(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> ptrdiff_t operator-(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y); template<class _CharT, class _Alloc> rope<_CharT, _Alloc> operator+(const rope<_CharT, _Alloc>& __left, const rope<_CharT, _Alloc>& __right); template<class _CharT, class _Alloc> rope<_CharT, _Alloc> operator+(const rope<_CharT, _Alloc>& __left, const _CharT* __right); template<class _CharT, class _Alloc> rope<_CharT, _Alloc> operator+(const rope<_CharT, _Alloc>& __left, _CharT __right); // Some helpers, so we can use power on ropes. // See below for why this isn't local to the implementation. // This uses a nonstandard refcount convention. // The result has refcount 0. template<class _CharT, class _Alloc> struct _Rope_Concat_fn : public std::binary_function<rope<_CharT, _Alloc>, rope<_CharT, _Alloc>, rope<_CharT, _Alloc> > { rope<_CharT, _Alloc> operator()(const rope<_CharT, _Alloc>& __x, const rope<_CharT, _Alloc>& __y) { return __x + __y; } }; template <class _CharT, class _Alloc> inline rope<_CharT, _Alloc> identity_element(_Rope_Concat_fn<_CharT, _Alloc>) { return rope<_CharT, _Alloc>(); } // Class _Refcount_Base provides a type, _RC_t, a data member, // _M_ref_count, and member functions _M_incr and _M_decr, which perform // atomic preincrement/predecrement. The constructor initializes // _M_ref_count. struct _Refcount_Base { // The type _RC_t typedef size_t _RC_t; // The data member _M_ref_count volatile _RC_t _M_ref_count; // Constructor #ifdef __GTHREAD_MUTEX_INIT __gthread_mutex_t _M_ref_count_lock = __GTHREAD_MUTEX_INIT; #else __gthread_mutex_t _M_ref_count_lock; #endif _Refcount_Base(_RC_t __n) : _M_ref_count(__n) { #ifndef __GTHREAD_MUTEX_INIT #ifdef __GTHREAD_MUTEX_INIT_FUNCTION __GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock); #else #error __GTHREAD_MUTEX_INIT or __GTHREAD_MUTEX_INIT_FUNCTION should be defined by gthr.h abstraction layer, report problem to libstdc++@gcc.gnu.org. #endif #endif } #ifndef __GTHREAD_MUTEX_INIT ~_Refcount_Base() { __gthread_mutex_destroy(&_M_ref_count_lock); } #endif void _M_incr() { __gthread_mutex_lock(&_M_ref_count_lock); ++_M_ref_count; __gthread_mutex_unlock(&_M_ref_count_lock); } _RC_t _M_decr() { __gthread_mutex_lock(&_M_ref_count_lock); volatile _RC_t __tmp = --_M_ref_count; __gthread_mutex_unlock(&_M_ref_count_lock); return __tmp; } }; // // What follows should really be local to rope. Unfortunately, // that doesn't work, since it makes it impossible to define generic // equality on rope iterators. According to the draft standard, the // template parameters for such an equality operator cannot be inferred // from the occurrence of a member class as a parameter. // (SGI compilers in fact allow this, but the __result wouldn't be // portable.) // Similarly, some of the static member functions are member functions // only to avoid polluting the global namespace, and to circumvent // restrictions on type inference for template functions. // // // The internal data structure for representing a rope. This is // private to the implementation. A rope is really just a pointer // to one of these. // // A few basic functions for manipulating this data structure // are members of _RopeRep. Most of the more complex algorithms // are implemented as rope members. // // Some of the static member functions of _RopeRep have identically // named functions in rope that simply invoke the _RopeRep versions. #define __ROPE_DEFINE_ALLOCS(__a) \ __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \ typedef _Rope_RopeConcatenation<_CharT,__a> __C; \ __ROPE_DEFINE_ALLOC(__C,_C) \ typedef _Rope_RopeLeaf<_CharT,__a> __L; \ __ROPE_DEFINE_ALLOC(__L,_L) \ typedef _Rope_RopeFunction<_CharT,__a> __F; \ __ROPE_DEFINE_ALLOC(__F,_F) \ typedef _Rope_RopeSubstring<_CharT,__a> __S; \ __ROPE_DEFINE_ALLOC(__S,_S) // Internal rope nodes potentially store a copy of the allocator // instance used to allocate them. This is mostly redundant. // But the alternative would be to pass allocator instances around // in some form to nearly all internal functions, since any pointer // assignment may result in a zero reference count and thus require // deallocation. #define __STATIC_IF_SGI_ALLOC /* not static */ template <class _CharT, class _Alloc> struct _Rope_rep_base : public _Alloc { typedef _Alloc allocator_type; allocator_type get_allocator() const { return *static_cast<const _Alloc*>(this); } allocator_type& _M_get_allocator() { return *static_cast<_Alloc*>(this); } const allocator_type& _M_get_allocator() const { return *static_cast<const _Alloc*>(this); } _Rope_rep_base(size_t __size, const allocator_type&) : _M_size(__size) { } size_t _M_size; # define __ROPE_DEFINE_ALLOC(_Tp, __name) \ typedef typename \ _Alloc::template rebind<_Tp>::other __name##Alloc; \ static _Tp* __name##_allocate(size_t __n) \ { return __name##Alloc().allocate(__n); } \ static void __name##_deallocate(_Tp *__p, size_t __n) \ { __name##Alloc().deallocate(__p, __n); } __ROPE_DEFINE_ALLOCS(_Alloc) # undef __ROPE_DEFINE_ALLOC }; template<class _CharT, class _Alloc> struct _Rope_RopeRep : public _Rope_rep_base<_CharT, _Alloc> # ifndef __GC , _Refcount_Base # endif { public: __detail::_Tag _M_tag:8; bool _M_is_balanced:8; unsigned char _M_depth; __GC_CONST _CharT* _M_c_string; #ifdef __GTHREAD_MUTEX_INIT __gthread_mutex_t _M_c_string_lock = __GTHREAD_MUTEX_INIT; #else __gthread_mutex_t _M_c_string_lock; #endif /* Flattened version of string, if needed. */ /* typically 0. */ /* If it's not 0, then the memory is owned */ /* by this node. */ /* In the case of a leaf, this may point to */ /* the same memory as the data field. */ typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type allocator_type; using _Rope_rep_base<_CharT, _Alloc>::get_allocator; using _Rope_rep_base<_CharT, _Alloc>::_M_get_allocator; _Rope_RopeRep(__detail::_Tag __t, int __d, bool __b, size_t __size, const allocator_type& __a) : _Rope_rep_base<_CharT, _Alloc>(__size, __a), #ifndef __GC _Refcount_Base(1), #endif _M_tag(__t), _M_is_balanced(__b), _M_depth(__d), _M_c_string(0) #ifdef __GTHREAD_MUTEX_INIT { } #else { __GTHREAD_MUTEX_INIT_FUNCTION (&_M_c_string_lock); } ~_Rope_RopeRep() { __gthread_mutex_destroy (&_M_c_string_lock); } #endif #ifdef __GC void _M_incr () { } #endif static void _S_free_string(__GC_CONST _CharT*, size_t __len, allocator_type& __a); #define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a); // Deallocate data section of a leaf. // This shouldn't be a member function. // But its hard to do anything else at the // moment, because it's templatized w.r.t. // an allocator. // Does nothing if __GC is defined. #ifndef __GC void _M_free_c_string(); void _M_free_tree(); // Deallocate t. Assumes t is not 0. void _M_unref_nonnil() { if (0 == _M_decr()) _M_free_tree(); } void _M_ref_nonnil() { _M_incr(); } static void _S_unref(_Rope_RopeRep* __t) { if (0 != __t) __t->_M_unref_nonnil(); } static void _S_ref(_Rope_RopeRep* __t) { if (0 != __t) __t->_M_incr(); } static void _S_free_if_unref(_Rope_RopeRep* __t) { if (0 != __t && 0 == __t->_M_ref_count) __t->_M_free_tree(); } # else /* __GC */ void _M_unref_nonnil() { } void _M_ref_nonnil() { } static void _S_unref(_Rope_RopeRep*) { } static void _S_ref(_Rope_RopeRep*) { } static void _S_free_if_unref(_Rope_RopeRep*) { } # endif protected: _Rope_RopeRep& operator=(const _Rope_RopeRep&); _Rope_RopeRep(const _Rope_RopeRep&); }; template<class _CharT, class _Alloc> struct _Rope_RopeLeaf : public _Rope_RopeRep<_CharT, _Alloc> { public: // Apparently needed by VC++ // The data fields of leaves are allocated with some // extra space, to accommodate future growth and for basic // character types, to hold a trailing eos character. enum { _S_alloc_granularity = 8 }; static size_t _S_rounded_up_size(size_t __n) { size_t __size_with_eos; if (_S_is_basic_char_type((_CharT*)0)) __size_with_eos = __n + 1; else __size_with_eos = __n; #ifdef __GC return __size_with_eos; #else // Allow slop for in-place expansion. return ((__size_with_eos + size_t(_S_alloc_granularity) - 1) &~ (size_t(_S_alloc_granularity) - 1)); #endif } __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */ /* The allocated size is */ /* _S_rounded_up_size(size), except */ /* in the GC case, in which it */ /* doesn't matter. */ typedef typename _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, const allocator_type& __a) : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_leaf, 0, true, __size, __a), _M_data(__d) { if (_S_is_basic_char_type((_CharT *)0)) { // already eos terminated. this->_M_c_string = __d; } } // The constructor assumes that d has been allocated with // the proper allocator and the properly padded size. // In contrast, the destructor deallocates the data: #ifndef __GC ~_Rope_RopeLeaf() throw() { if (_M_data != this->_M_c_string) this->_M_free_c_string(); this->__STL_FREE_STRING(_M_data, this->_M_size, this->_M_get_allocator()); } #endif protected: _Rope_RopeLeaf& operator=(const _Rope_RopeLeaf&); _Rope_RopeLeaf(const _Rope_RopeLeaf&); }; template<class _CharT, class _Alloc> struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT, _Alloc> { public: _Rope_RopeRep<_CharT, _Alloc>* _M_left; _Rope_RopeRep<_CharT, _Alloc>* _M_right; typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type allocator_type; _Rope_RopeConcatenation(_Rope_RopeRep<_CharT, _Alloc>* __l, _Rope_RopeRep<_CharT, _Alloc>* __r, const allocator_type& __a) : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_concat, std::max(__l->_M_depth, __r->_M_depth) + 1, false, __l->_M_size + __r->_M_size, __a), _M_left(__l), _M_right(__r) { } #ifndef __GC ~_Rope_RopeConcatenation() throw() { this->_M_free_c_string(); _M_left->_M_unref_nonnil(); _M_right->_M_unref_nonnil(); } #endif protected: _Rope_RopeConcatenation& operator=(const _Rope_RopeConcatenation&); _Rope_RopeConcatenation(const _Rope_RopeConcatenation&); }; template<class _CharT, class _Alloc> struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT, _Alloc> { public: char_producer<_CharT>* _M_fn; #ifndef __GC bool _M_delete_when_done; // Char_producer is owned by the // rope and should be explicitly // deleted when the rope becomes // inaccessible. #else // In the GC case, we either register the rope for // finalization, or not. Thus the field is unnecessary; // the information is stored in the collector data structures. // We do need a finalization procedure to be invoked by the // collector. static void _S_fn_finalization_proc(void * __tree, void *) { delete ((_Rope_RopeFunction *)__tree) -> _M_fn; } #endif typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type allocator_type; _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, bool __d, const allocator_type& __a) : _Rope_RopeRep<_CharT, _Alloc>(__detail::_S_function, 0, true, __size, __a) , _M_fn(__f) #ifndef __GC , _M_delete_when_done(__d) #endif { #ifdef __GC if (__d) { GC_REGISTER_FINALIZER(this, _Rope_RopeFunction:: _S_fn_finalization_proc, 0, 0, 0); } #endif } #ifndef __GC ~_Rope_RopeFunction() throw() { this->_M_free_c_string(); if (_M_delete_when_done) delete _M_fn; } # endif protected: _Rope_RopeFunction& operator=(const _Rope_RopeFunction&); _Rope_RopeFunction(const _Rope_RopeFunction&); }; // Substring results are usually represented using just // concatenation nodes. But in the case of very long flat ropes // or ropes with a functional representation that isn't practical. // In that case, we represent the __result as a special case of // RopeFunction, whose char_producer points back to the rope itself. // In all cases except repeated substring operations and // deallocation, we treat the __result as a RopeFunction. template<class _CharT, class _Alloc> struct _Rope_RopeSubstring : public _Rope_RopeFunction<_CharT, _Alloc>, public char_producer<_CharT> { public: // XXX this whole class should be rewritten. _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0 size_t _M_start; virtual void operator()(size_t __start_pos, size_t __req_len, _CharT* __buffer) { switch(_M_base->_M_tag) { case __detail::_S_function: case __detail::_S_substringfn: { char_producer<_CharT>* __fn = ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; (*__fn)(__start_pos + _M_start, __req_len, __buffer); } break; case __detail::_S_leaf: { __GC_CONST _CharT* __s = ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data; uninitialized_copy_n(__s + __start_pos + _M_start, __req_len, __buffer); } break; default: break; } } typedef typename _Rope_rep_base<_CharT, _Alloc>::allocator_type allocator_type; _Rope_RopeSubstring(_Rope_RopeRep<_CharT, _Alloc>* __b, size_t __s, size_t __l, const allocator_type& __a) : _Rope_RopeFunction<_CharT, _Alloc>(this, __l, false, __a), char_producer<_CharT>(), _M_base(__b), _M_start(__s) { #ifndef __GC _M_base->_M_ref_nonnil(); #endif this->_M_tag = __detail::_S_substringfn; } virtual ~_Rope_RopeSubstring() throw() { #ifndef __GC _M_base->_M_unref_nonnil(); // _M_free_c_string(); -- done by parent class #endif } }; // Self-destructing pointers to Rope_rep. // These are not conventional smart pointers. Their // only purpose in life is to ensure that unref is called // on the pointer either at normal exit or if an exception // is raised. It is the caller's responsibility to // adjust reference counts when these pointers are initialized // or assigned to. (This convention significantly reduces // the number of potentially expensive reference count // updates.) #ifndef __GC template<class _CharT, class _Alloc> struct _Rope_self_destruct_ptr { _Rope_RopeRep<_CharT, _Alloc>* _M_ptr; ~_Rope_self_destruct_ptr() { _Rope_RopeRep<_CharT, _Alloc>::_S_unref(_M_ptr); } #if __cpp_exceptions _Rope_self_destruct_ptr() : _M_ptr(0) { } #else _Rope_self_destruct_ptr() { } #endif _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT, _Alloc>* __p) : _M_ptr(__p) { } _Rope_RopeRep<_CharT, _Alloc>& operator*() { return *_M_ptr; } _Rope_RopeRep<_CharT, _Alloc>* operator->() { return _M_ptr; } operator _Rope_RopeRep<_CharT, _Alloc>*() { return _M_ptr; } _Rope_self_destruct_ptr& operator=(_Rope_RopeRep<_CharT, _Alloc>* __x) { _M_ptr = __x; return *this; } }; #endif // Dereferencing a nonconst iterator has to return something // that behaves almost like a reference. It's not possible to // return an actual reference since assignment requires extra // work. And we would get into the same problems as with the // CD2 version of basic_string. template<class _CharT, class _Alloc> class _Rope_char_ref_proxy { friend class rope<_CharT, _Alloc>; friend class _Rope_iterator<_CharT, _Alloc>; friend class _Rope_char_ptr_proxy<_CharT, _Alloc>; #ifdef __GC typedef _Rope_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr; #else typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr; #endif typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; typedef rope<_CharT, _Alloc> _My_rope; size_t _M_pos; _CharT _M_current; bool _M_current_valid; _My_rope* _M_root; // The whole rope. public: _Rope_char_ref_proxy(_My_rope* __r, size_t __p) : _M_pos(__p), _M_current(), _M_current_valid(false), _M_root(__r) { } _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) : _M_pos(__x._M_pos), _M_current(__x._M_current), _M_current_valid(false), _M_root(__x._M_root) { } // Don't preserve cache if the reference can outlive the // expression. We claim that's not possible without calling // a copy constructor or generating reference to a proxy // reference. We declare the latter to have undefined semantics. _Rope_char_ref_proxy(_My_rope* __r, size_t __p, _CharT __c) : _M_pos(__p), _M_current(__c), _M_current_valid(true), _M_root(__r) { } inline operator _CharT () const; _Rope_char_ref_proxy& operator=(_CharT __c); _Rope_char_ptr_proxy<_CharT, _Alloc> operator&() const; _Rope_char_ref_proxy& operator=(const _Rope_char_ref_proxy& __c) { return operator=((_CharT)__c); } }; template<class _CharT, class __Alloc> inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, _Rope_char_ref_proxy <_CharT, __Alloc > __b) { _CharT __tmp = __a; __a = __b; __b = __tmp; } template<class _CharT, class _Alloc> class _Rope_char_ptr_proxy { // XXX this class should be rewritten. friend class _Rope_char_ref_proxy<_CharT, _Alloc>; size_t _M_pos; rope<_CharT,_Alloc>* _M_root; // The whole rope. public: _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) : _M_pos(__x._M_pos), _M_root(__x._M_root) { } _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x) : _M_pos(__x._M_pos), _M_root(__x._M_root) { } _Rope_char_ptr_proxy() { } _Rope_char_ptr_proxy(_CharT* __x) : _M_root(0), _M_pos(0) { } _Rope_char_ptr_proxy& operator=(const _Rope_char_ptr_proxy& __x) { _M_pos = __x._M_pos; _M_root = __x._M_root; return *this; } template<class _CharT2, class _Alloc2> friend bool operator==(const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __x, const _Rope_char_ptr_proxy<_CharT2, _Alloc2>& __y); _Rope_char_ref_proxy<_CharT, _Alloc> operator*() const { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root, _M_pos); } }; // Rope iterators: // Unlike in the C version, we cache only part of the stack // for rope iterators, since they must be efficiently copyable. // When we run out of cache, we have to reconstruct the iterator // value. // Pointers from iterators are not included in reference counts. // Iterators are assumed to be thread private. Ropes can // be shared. template<class _CharT, class _Alloc> class _Rope_iterator_base : public std::iterator<std::random_access_iterator_tag, _CharT> { friend class rope<_CharT, _Alloc>; public: typedef _Alloc _allocator_type; // used in _Rope_rotate, VC++ workaround typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; // Borland doesn't want this to be protected. protected: enum { _S_path_cache_len = 4 }; // Must be <= 9. enum { _S_iterator_buf_len = 15 }; size_t _M_current_pos; _RopeRep* _M_root; // The whole rope. size_t _M_leaf_pos; // Starting position for current leaf __GC_CONST _CharT* _M_buf_start; // Buffer possibly // containing current char. __GC_CONST _CharT* _M_buf_ptr; // Pointer to current char in buffer. // != 0 ==> buffer valid. __GC_CONST _CharT* _M_buf_end; // One past __last valid char in buffer. // What follows is the path cache. We go out of our // way to make this compact. // Path_end contains the bottom section of the path from // the root to the current leaf. const _RopeRep* _M_path_end[_S_path_cache_len]; int _M_leaf_index; // Last valid __pos in path_end; // _M_path_end[0] ... _M_path_end[leaf_index-1] // point to concatenation nodes. unsigned char _M_path_directions; // (path_directions >> __i) & 1 is 1 // iff we got from _M_path_end[leaf_index - __i - 1] // to _M_path_end[leaf_index - __i] by going to the // __right. Assumes path_cache_len <= 9. _CharT _M_tmp_buf[_S_iterator_buf_len]; // Short buffer for surrounding chars. // This is useful primarily for // RopeFunctions. We put the buffer // here to avoid locking in the // multithreaded case. // The cached path is generally assumed to be valid // only if the buffer is valid. static void _S_setbuf(_Rope_iterator_base& __x); // Set buffer contents given // path cache. static void _S_setcache(_Rope_iterator_base& __x); // Set buffer contents and // path cache. static void _S_setcache_for_incr(_Rope_iterator_base& __x); // As above, but assumes path // cache is valid for previous posn. _Rope_iterator_base() { } _Rope_iterator_base(_RopeRep* __root, size_t __pos) : _M_current_pos(__pos), _M_root(__root), _M_buf_ptr(0) { } void _M_incr(size_t __n); void _M_decr(size_t __n); public: size_t index() const { return _M_current_pos; } _Rope_iterator_base(const _Rope_iterator_base& __x) { if (0 != __x._M_buf_ptr) *this = __x; else { _M_current_pos = __x._M_current_pos; _M_root = __x._M_root; _M_buf_ptr = 0; } } }; template<class _CharT, class _Alloc> class _Rope_iterator; template<class _CharT, class _Alloc> class _Rope_const_iterator : public _Rope_iterator_base<_CharT, _Alloc> { friend class rope<_CharT, _Alloc>; protected: typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; // The one from the base class may not be directly visible. _Rope_const_iterator(const _RopeRep* __root, size_t __pos) : _Rope_iterator_base<_CharT, _Alloc>(const_cast<_RopeRep*>(__root), __pos) // Only nonconst iterators modify root ref count { } public: typedef _CharT reference; // Really a value. Returning a reference // Would be a mess, since it would have // to be included in refcount. typedef const _CharT* pointer; public: _Rope_const_iterator() { } _Rope_const_iterator(const _Rope_const_iterator& __x) : _Rope_iterator_base<_CharT,_Alloc>(__x) { } _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x); _Rope_const_iterator(const rope<_CharT, _Alloc>& __r, size_t __pos) : _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) { } _Rope_const_iterator& operator=(const _Rope_const_iterator& __x) { if (0 != __x._M_buf_ptr) *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x; else { this->_M_current_pos = __x._M_current_pos; this->_M_root = __x._M_root; this->_M_buf_ptr = 0; } return(*this); } reference operator*() { if (0 == this->_M_buf_ptr) this->_S_setcache(*this); return *this->_M_buf_ptr; } // Without this const version, Rope iterators do not meet the // requirements of an Input Iterator. reference operator*() const { return *const_cast<_Rope_const_iterator&>(*this); } _Rope_const_iterator& operator++() { __GC_CONST _CharT* __next; if (0 != this->_M_buf_ptr && (__next = this->_M_buf_ptr + 1) < this->_M_buf_end) { this->_M_buf_ptr = __next; ++this->_M_current_pos; } else this->_M_incr(1); return *this; } _Rope_const_iterator& operator+=(ptrdiff_t __n) { if (__n >= 0) this->_M_incr(__n); else this->_M_decr(-__n); return *this; } _Rope_const_iterator& operator--() { this->_M_decr(1); return *this; } _Rope_const_iterator& operator-=(ptrdiff_t __n) { if (__n >= 0) this->_M_decr(__n); else this->_M_incr(-__n); return *this; } _Rope_const_iterator operator++(int) { size_t __old_pos = this->_M_current_pos; this->_M_incr(1); return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos); // This makes a subsequent dereference expensive. // Perhaps we should instead copy the iterator // if it has a valid cache? } _Rope_const_iterator operator--(int) { size_t __old_pos = this->_M_current_pos; this->_M_decr(1); return _Rope_const_iterator<_CharT,_Alloc>(this->_M_root, __old_pos); } template<class _CharT2, class _Alloc2> friend _Rope_const_iterator<_CharT2, _Alloc2> operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n); template<class _CharT2, class _Alloc2> friend _Rope_const_iterator<_CharT2, _Alloc2> operator+(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n); template<class _CharT2, class _Alloc2> friend _Rope_const_iterator<_CharT2, _Alloc2> operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT2, _Alloc2>& __x); reference operator[](size_t __n) { return rope<_CharT, _Alloc>::_S_fetch(this->_M_root, this->_M_current_pos + __n); } template<class _CharT2, class _Alloc2> friend bool operator==(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, const _Rope_const_iterator<_CharT2, _Alloc2>& __y); template<class _CharT2, class _Alloc2> friend bool operator<(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, const _Rope_const_iterator<_CharT2, _Alloc2>& __y); template<class _CharT2, class _Alloc2> friend ptrdiff_t operator-(const _Rope_const_iterator<_CharT2, _Alloc2>& __x, const _Rope_const_iterator<_CharT2, _Alloc2>& __y); }; template<class _CharT, class _Alloc> class _Rope_iterator : public _Rope_iterator_base<_CharT, _Alloc> { friend class rope<_CharT, _Alloc>; protected: typedef typename _Rope_iterator_base<_CharT, _Alloc>::_RopeRep _RopeRep; rope<_CharT, _Alloc>* _M_root_rope; // root is treated as a cached version of this, and is used to // detect changes to the underlying rope. // Root is included in the reference count. This is necessary // so that we can detect changes reliably. Unfortunately, it // requires careful bookkeeping for the nonGC case. _Rope_iterator(rope<_CharT, _Alloc>* __r, size_t __pos) : _Rope_iterator_base<_CharT, _Alloc>(__r->_M_tree_ptr, __pos), _M_root_rope(__r) { _RopeRep::_S_ref(this->_M_root); if (!(__r -> empty())) this->_S_setcache(*this); } void _M_check(); public: typedef _Rope_char_ref_proxy<_CharT, _Alloc> reference; typedef _Rope_char_ref_proxy<_CharT, _Alloc>* pointer; rope<_CharT, _Alloc>& container() { return *_M_root_rope; } _Rope_iterator() { this->_M_root = 0; // Needed for reference counting. } _Rope_iterator(const _Rope_iterator& __x) : _Rope_iterator_base<_CharT, _Alloc>(__x) { _M_root_rope = __x._M_root_rope; _RopeRep::_S_ref(this->_M_root); } _Rope_iterator(rope<_CharT, _Alloc>& __r, size_t __pos); ~_Rope_iterator() { _RopeRep::_S_unref(this->_M_root); } _Rope_iterator& operator=(const _Rope_iterator& __x) { _RopeRep* __old = this->_M_root; _RopeRep::_S_ref(__x._M_root); if (0 != __x._M_buf_ptr) { _M_root_rope = __x._M_root_rope; *(static_cast<_Rope_iterator_base<_CharT, _Alloc>*>(this)) = __x; } else { this->_M_current_pos = __x._M_current_pos; this->_M_root = __x._M_root; _M_root_rope = __x._M_root_rope; this->_M_buf_ptr = 0; } _RopeRep::_S_unref(__old); return(*this); } reference operator*() { _M_check(); if (0 == this->_M_buf_ptr) return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, this->_M_current_pos); else return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, this->_M_current_pos, *this->_M_buf_ptr); } // See above comment. reference operator*() const { return *const_cast<_Rope_iterator&>(*this); } _Rope_iterator& operator++() { this->_M_incr(1); return *this; } _Rope_iterator& operator+=(ptrdiff_t __n) { if (__n >= 0) this->_M_incr(__n); else this->_M_decr(-__n); return *this; } _Rope_iterator& operator--() { this->_M_decr(1); return *this; } _Rope_iterator& operator-=(ptrdiff_t __n) { if (__n >= 0) this->_M_decr(__n); else this->_M_incr(-__n); return *this; } _Rope_iterator operator++(int) { size_t __old_pos = this->_M_current_pos; this->_M_incr(1); return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); } _Rope_iterator operator--(int) { size_t __old_pos = this->_M_current_pos; this->_M_decr(1); return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); } reference operator[](ptrdiff_t __n) { return _Rope_char_ref_proxy<_CharT, _Alloc>(_M_root_rope, this->_M_current_pos + __n); } template<class _CharT2, class _Alloc2> friend bool operator==(const _Rope_iterator<_CharT2, _Alloc2>& __x, const _Rope_iterator<_CharT2, _Alloc2>& __y); template<class _CharT2, class _Alloc2> friend bool operator<(const _Rope_iterator<_CharT2, _Alloc2>& __x, const _Rope_iterator<_CharT2, _Alloc2>& __y); template<class _CharT2, class _Alloc2> friend ptrdiff_t operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x, const _Rope_iterator<_CharT2, _Alloc2>& __y); template<class _CharT2, class _Alloc2> friend _Rope_iterator<_CharT2, _Alloc2> operator-(const _Rope_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n); template<class _CharT2, class _Alloc2> friend _Rope_iterator<_CharT2, _Alloc2> operator+(const _Rope_iterator<_CharT2, _Alloc2>& __x, ptrdiff_t __n); template<class _CharT2, class _Alloc2> friend _Rope_iterator<_CharT2, _Alloc2> operator+(ptrdiff_t __n, const _Rope_iterator<_CharT2, _Alloc2>& __x); }; template <class _CharT, class _Alloc> struct _Rope_base : public _Alloc { typedef _Alloc allocator_type; allocator_type get_allocator() const { return *static_cast<const _Alloc*>(this); } allocator_type& _M_get_allocator() { return *static_cast<_Alloc*>(this); } const allocator_type& _M_get_allocator() const { return *static_cast<const _Alloc*>(this); } typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; // The one in _Base may not be visible due to template rules. _Rope_base(_RopeRep* __t, const allocator_type&) : _M_tree_ptr(__t) { } _Rope_base(const allocator_type&) { } // The only data member of a rope: _RopeRep *_M_tree_ptr; #define __ROPE_DEFINE_ALLOC(_Tp, __name) \ typedef typename \ _Alloc::template rebind<_Tp>::other __name##Alloc; \ static _Tp* __name##_allocate(size_t __n) \ { return __name##Alloc().allocate(__n); } \ static void __name##_deallocate(_Tp *__p, size_t __n) \ { __name##Alloc().deallocate(__p, __n); } __ROPE_DEFINE_ALLOCS(_Alloc) #undef __ROPE_DEFINE_ALLOC protected: _Rope_base& operator=(const _Rope_base&); _Rope_base(const _Rope_base&); }; /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template <class _CharT, class _Alloc> class rope : public _Rope_base<_CharT, _Alloc> { public: typedef _CharT value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; typedef _CharT const_reference; typedef const _CharT* const_pointer; typedef _Rope_iterator<_CharT, _Alloc> iterator; typedef _Rope_const_iterator<_CharT, _Alloc> const_iterator; typedef _Rope_char_ref_proxy<_CharT, _Alloc> reference; typedef _Rope_char_ptr_proxy<_CharT, _Alloc> pointer; friend class _Rope_iterator<_CharT, _Alloc>; friend class _Rope_const_iterator<_CharT, _Alloc>; friend struct _Rope_RopeRep<_CharT, _Alloc>; friend class _Rope_iterator_base<_CharT, _Alloc>; friend class _Rope_char_ptr_proxy<_CharT, _Alloc>; friend class _Rope_char_ref_proxy<_CharT, _Alloc>; friend struct _Rope_RopeSubstring<_CharT, _Alloc>; protected: typedef _Rope_base<_CharT, _Alloc> _Base; typedef typename _Base::allocator_type allocator_type; using _Base::_M_tree_ptr; using _Base::get_allocator; using _Base::_M_get_allocator; typedef __GC_CONST _CharT* _Cstrptr; static _CharT _S_empty_c_str[1]; static bool _S_is0(_CharT __c) { return __c == _S_eos((_CharT*)0); } enum { _S_copy_max = 23 }; // For strings shorter than _S_copy_max, we copy to // concatenate. typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; typedef _Rope_RopeConcatenation<_CharT, _Alloc> _RopeConcatenation; typedef _Rope_RopeLeaf<_CharT, _Alloc> _RopeLeaf; typedef _Rope_RopeFunction<_CharT, _Alloc> _RopeFunction; typedef _Rope_RopeSubstring<_CharT, _Alloc> _RopeSubstring; // Retrieve a character at the indicated position. static _CharT _S_fetch(_RopeRep* __r, size_type __pos); #ifndef __GC // Obtain a pointer to the character at the indicated position. // The pointer can be used to change the character. // If such a pointer cannot be produced, as is frequently the // case, 0 is returned instead. // (Returns nonzero only if all nodes in the path have a refcount // of 1.) static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos); #endif static bool _S_apply_to_pieces(// should be template parameter _Rope_char_consumer<_CharT>& __c, const _RopeRep* __r, size_t __begin, size_t __end); // begin and end are assumed to be in range. #ifndef __GC static void _S_unref(_RopeRep* __t) { _RopeRep::_S_unref(__t); } static void _S_ref(_RopeRep* __t) { _RopeRep::_S_ref(__t); } #else /* __GC */ static void _S_unref(_RopeRep*) { } static void _S_ref(_RopeRep*) { } #endif #ifdef __GC typedef _Rope_RopeRep<_CharT, _Alloc>* _Self_destruct_ptr; #else typedef _Rope_self_destruct_ptr<_CharT, _Alloc> _Self_destruct_ptr; #endif // _Result is counted in refcount. static _RopeRep* _S_substring(_RopeRep* __base, size_t __start, size_t __endp1); static _RopeRep* _S_concat_char_iter(_RopeRep* __r, const _CharT* __iter, size_t __slen); // Concatenate rope and char ptr, copying __s. // Should really take an arbitrary iterator. // Result is counted in refcount. static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r, const _CharT* __iter, size_t __slen) // As above, but one reference to __r is about to be // destroyed. Thus the pieces may be recycled if all // relevant reference counts are 1. #ifdef __GC // We can't really do anything since refcounts are unavailable. { return _S_concat_char_iter(__r, __iter, __slen); } #else ; #endif static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right); // General concatenation on _RopeRep. _Result // has refcount of 1. Adjusts argument refcounts. public: void apply_to_pieces(size_t __begin, size_t __end, _Rope_char_consumer<_CharT>& __c) const { _S_apply_to_pieces(__c, this->_M_tree_ptr, __begin, __end); } protected: static size_t _S_rounded_up_size(size_t __n) { return _RopeLeaf::_S_rounded_up_size(__n); } static size_t _S_allocated_capacity(size_t __n) { if (_S_is_basic_char_type((_CharT*)0)) return _S_rounded_up_size(__n) - 1; else return _S_rounded_up_size(__n); } // Allocate and construct a RopeLeaf using the supplied allocator // Takes ownership of s instead of copying. static _RopeLeaf* _S_new_RopeLeaf(__GC_CONST _CharT *__s, size_t __size, allocator_type& __a) { _RopeLeaf* __space = typename _Base::_LAlloc(__a).allocate(1); return new(__space) _RopeLeaf(__s, __size, __a); } static _RopeConcatenation* _S_new_RopeConcatenation(_RopeRep* __left, _RopeRep* __right, allocator_type& __a) { _RopeConcatenation* __space = typename _Base::_CAlloc(__a).allocate(1); return new(__space) _RopeConcatenation(__left, __right, __a); } static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, size_t __size, bool __d, allocator_type& __a) { _RopeFunction* __space = typename _Base::_FAlloc(__a).allocate(1); return new(__space) _RopeFunction(__f, __size, __d, __a); } static _RopeSubstring* _S_new_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, size_t __l, allocator_type& __a) { _RopeSubstring* __space = typename _Base::_SAlloc(__a).allocate(1); return new(__space) _RopeSubstring(__b, __s, __l, __a); } static _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s, size_t __size, allocator_type& __a) #define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a) { if (0 == __size) return 0; _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); __uninitialized_copy_n_a(__s, __size, __buf, __a); _S_cond_store_eos(__buf[__size]); __try { return _S_new_RopeLeaf(__buf, __size, __a); } __catch(...) { _RopeRep::__STL_FREE_STRING(__buf, __size, __a); __throw_exception_again; } } // Concatenation of nonempty strings. // Always builds a concatenation node. // Rebalances if the result is too deep. // Result has refcount 1. // Does not increment left and right ref counts even though // they are referenced. static _RopeRep* _S_tree_concat(_RopeRep* __left, _RopeRep* __right); // Concatenation helper functions static _RopeLeaf* _S_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, size_t __slen); // Concatenate by copying leaf. // should take an arbitrary iterator // result has refcount 1. #ifndef __GC static _RopeLeaf* _S_destr_leaf_concat_char_iter(_RopeLeaf* __r, const _CharT* __iter, size_t __slen); // A version that potentially clobbers __r if __r->_M_ref_count == 1. #endif private: static size_t _S_char_ptr_len(const _CharT* __s); // slightly generalized strlen rope(_RopeRep* __t, const allocator_type& __a = allocator_type()) : _Base(__t, __a) { } // Copy __r to the _CharT buffer. // Returns __buffer + __r->_M_size. // Assumes that buffer is uninitialized. static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer); // Again, with explicit starting position and length. // Assumes that buffer is uninitialized. static _CharT* _S_flatten(_RopeRep* __r, size_t __start, size_t __len, _CharT* __buffer); static const unsigned long _S_min_len[__detail::_S_max_rope_depth + 1]; static bool _S_is_balanced(_RopeRep* __r) { return (__r->_M_size >= _S_min_len[__r->_M_depth]); } static bool _S_is_almost_balanced(_RopeRep* __r) { return (__r->_M_depth == 0 || __r->_M_size >= _S_min_len[__r->_M_depth - 1]); } static bool _S_is_roughly_balanced(_RopeRep* __r) { return (__r->_M_depth <= 1 || __r->_M_size >= _S_min_len[__r->_M_depth - 2]); } // Assumes the result is not empty. static _RopeRep* _S_concat_and_set_balanced(_RopeRep* __left, _RopeRep* __right) { _RopeRep* __result = _S_concat(__left, __right); if (_S_is_balanced(__result)) __result->_M_is_balanced = true; return __result; } // The basic rebalancing operation. Logically copies the // rope. The result has refcount of 1. The client will // usually decrement the reference count of __r. // The result is within height 2 of balanced by the above // definition. static _RopeRep* _S_balance(_RopeRep* __r); // Add all unbalanced subtrees to the forest of balanced trees. // Used only by balance. static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest); // Add __r to forest, assuming __r is already balanced. static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest); // Print to stdout, exposing structure static void _S_dump(_RopeRep* __r, int __indent = 0); // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp. static int _S_compare(const _RopeRep* __x, const _RopeRep* __y); public: bool empty() const { return 0 == this->_M_tree_ptr; } // Comparison member function. This is public only for those // clients that need a ternary comparison. Others // should use the comparison operators below. int compare(const rope& __y) const { return _S_compare(this->_M_tree_ptr, __y._M_tree_ptr); } rope(const _CharT* __s, const allocator_type& __a = allocator_type()) : _Base(__a) { this->_M_tree_ptr = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s), _M_get_allocator()); } rope(const _CharT* __s, size_t __len, const allocator_type& __a = allocator_type()) : _Base(__a) { this->_M_tree_ptr = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, _M_get_allocator()); } // Should perhaps be templatized with respect to the iterator type // and use Sequence_buffer. (It should perhaps use sequence_buffer // even now.) rope(const _CharT* __s, const _CharT* __e, const allocator_type& __a = allocator_type()) : _Base(__a) { this->_M_tree_ptr = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, _M_get_allocator()); } rope(const const_iterator& __s, const const_iterator& __e, const allocator_type& __a = allocator_type()) : _Base(_S_substring(__s._M_root, __s._M_current_pos, __e._M_current_pos), __a) { } rope(const iterator& __s, const iterator& __e, const allocator_type& __a = allocator_type()) : _Base(_S_substring(__s._M_root, __s._M_current_pos, __e._M_current_pos), __a) { } rope(_CharT __c, const allocator_type& __a = allocator_type()) : _Base(__a) { _CharT* __buf = this->_Data_allocate(_S_rounded_up_size(1)); _M_get_allocator().construct(__buf, __c); __try { this->_M_tree_ptr = _S_new_RopeLeaf(__buf, 1, _M_get_allocator()); } __catch(...) { _RopeRep::__STL_FREE_STRING(__buf, 1, _M_get_allocator()); __throw_exception_again; } } rope(size_t __n, _CharT __c, const allocator_type& __a = allocator_type()); rope(const allocator_type& __a = allocator_type()) : _Base(0, __a) { } // Construct a rope from a function that can compute its members rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn, const allocator_type& __a = allocator_type()) : _Base(__a) { this->_M_tree_ptr = (0 == __len) ? 0 : _S_new_RopeFunction(__fn, __len, __delete_fn, _M_get_allocator()); } rope(const rope& __x, const allocator_type& __a = allocator_type()) : _Base(__x._M_tree_ptr, __a) { _S_ref(this->_M_tree_ptr); } ~rope() throw() { _S_unref(this->_M_tree_ptr); } rope& operator=(const rope& __x) { _RopeRep* __old = this->_M_tree_ptr; this->_M_tree_ptr = __x._M_tree_ptr; _S_ref(this->_M_tree_ptr); _S_unref(__old); return *this; } void clear() { _S_unref(this->_M_tree_ptr); this->_M_tree_ptr = 0; } void push_back(_CharT __x) { _RopeRep* __old = this->_M_tree_ptr; this->_M_tree_ptr = _S_destr_concat_char_iter(this->_M_tree_ptr, &__x, 1); _S_unref(__old); } void pop_back() { _RopeRep* __old = this->_M_tree_ptr; this->_M_tree_ptr = _S_substring(this->_M_tree_ptr, 0, this->_M_tree_ptr->_M_size - 1); _S_unref(__old); } _CharT back() const { return _S_fetch(this->_M_tree_ptr, this->_M_tree_ptr->_M_size - 1); } void push_front(_CharT __x) { _RopeRep* __old = this->_M_tree_ptr; _RopeRep* __left = __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, _M_get_allocator()); __try { this->_M_tree_ptr = _S_concat(__left, this->_M_tree_ptr); _S_unref(__old); _S_unref(__left); } __catch(...) { _S_unref(__left); __throw_exception_again; } } void pop_front() { _RopeRep* __old = this->_M_tree_ptr; this->_M_tree_ptr = _S_substring(this->_M_tree_ptr, 1, this->_M_tree_ptr->_M_size); _S_unref(__old); } _CharT front() const { return _S_fetch(this->_M_tree_ptr, 0); } void balance() { _RopeRep* __old = this->_M_tree_ptr; this->_M_tree_ptr = _S_balance(this->_M_tree_ptr); _S_unref(__old); } void copy(_CharT* __buffer) const { _Destroy_const(__buffer, __buffer + size(), _M_get_allocator()); _S_flatten(this->_M_tree_ptr, __buffer); } // This is the copy function from the standard, but // with the arguments reordered to make it consistent with the // rest of the interface. // Note that this guaranteed not to compile if the draft standard // order is assumed. size_type copy(size_type __pos, size_type __n, _CharT* __buffer) const { size_t __size = size(); size_t __len = (__pos + __n > __size? __size - __pos : __n); _Destroy_const(__buffer, __buffer + __len, _M_get_allocator()); _S_flatten(this->_M_tree_ptr, __pos, __len, __buffer); return __len; } // Print to stdout, exposing structure. May be useful for // performance debugging. void dump() { _S_dump(this->_M_tree_ptr); } // Convert to 0 terminated string in new allocated memory. // Embedded 0s in the input do not terminate the copy. const _CharT* c_str() const; // As above, but also use the flattened representation as // the new rope representation. const _CharT* replace_with_c_str(); // Reclaim memory for the c_str generated flattened string. // Intentionally undocumented, since it's hard to say when this // is safe for multiple threads. void delete_c_str () { if (0 == this->_M_tree_ptr) return; if (__detail::_S_leaf == this->_M_tree_ptr->_M_tag && ((_RopeLeaf*)this->_M_tree_ptr)->_M_data == this->_M_tree_ptr->_M_c_string) { // Representation shared return; } #ifndef __GC this->_M_tree_ptr->_M_free_c_string(); #endif this->_M_tree_ptr->_M_c_string = 0; } _CharT operator[] (size_type __pos) const { return _S_fetch(this->_M_tree_ptr, __pos); } _CharT at(size_type __pos) const { // if (__pos >= size()) throw out_of_range; // XXX return (*this)[__pos]; } const_iterator begin() const { return(const_iterator(this->_M_tree_ptr, 0)); } // An easy way to get a const iterator from a non-const container. const_iterator const_begin() const { return(const_iterator(this->_M_tree_ptr, 0)); } const_iterator end() const { return(const_iterator(this->_M_tree_ptr, size())); } const_iterator const_end() const { return(const_iterator(this->_M_tree_ptr, size())); } size_type size() const { return(0 == this->_M_tree_ptr? 0 : this->_M_tree_ptr->_M_size); } size_type length() const { return size(); } size_type max_size() const { return _S_min_len[int(__detail::_S_max_rope_depth) - 1] - 1; // Guarantees that the result can be sufficiently // balanced. Longer ropes will probably still work, // but it's harder to make guarantees. } typedef std::reverse_iterator<const_iterator> const_reverse_iterator; const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator const_rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } const_reverse_iterator const_rend() const { return const_reverse_iterator(begin()); } template<class _CharT2, class _Alloc2> friend rope<_CharT2, _Alloc2> operator+(const rope<_CharT2, _Alloc2>& __left, const rope<_CharT2, _Alloc2>& __right); template<class _CharT2, class _Alloc2> friend rope<_CharT2, _Alloc2> operator+(const rope<_CharT2, _Alloc2>& __left, const _CharT2* __right); template<class _CharT2, class _Alloc2> friend rope<_CharT2, _Alloc2> operator+(const rope<_CharT2, _Alloc2>& __left, _CharT2 __right); // The symmetric cases are intentionally omitted, since they're // presumed to be less common, and we don't handle them as well. // The following should really be templatized. The first // argument should be an input iterator or forward iterator with // value_type _CharT. rope& append(const _CharT* __iter, size_t __n) { _RopeRep* __result = _S_destr_concat_char_iter(this->_M_tree_ptr, __iter, __n); _S_unref(this->_M_tree_ptr); this->_M_tree_ptr = __result; return *this; } rope& append(const _CharT* __c_string) { size_t __len = _S_char_ptr_len(__c_string); append(__c_string, __len); return(*this); } rope& append(const _CharT* __s, const _CharT* __e) { _RopeRep* __result = _S_destr_concat_char_iter(this->_M_tree_ptr, __s, __e - __s); _S_unref(this->_M_tree_ptr); this->_M_tree_ptr = __result; return *this; } rope& append(const_iterator __s, const_iterator __e) { _Self_destruct_ptr __appendee(_S_substring(__s._M_root, __s._M_current_pos, __e._M_current_pos)); _RopeRep* __result = _S_concat(this->_M_tree_ptr, (_RopeRep*)__appendee); _S_unref(this->_M_tree_ptr); this->_M_tree_ptr = __result; return *this; } rope& append(_CharT __c) { _RopeRep* __result = _S_destr_concat_char_iter(this->_M_tree_ptr, &__c, 1); _S_unref(this->_M_tree_ptr); this->_M_tree_ptr = __result; return *this; } rope& append() { return append(_CharT()); } // XXX why? rope& append(const rope& __y) { _RopeRep* __result = _S_concat(this->_M_tree_ptr, __y._M_tree_ptr); _S_unref(this->_M_tree_ptr); this->_M_tree_ptr = __result; return *this; } rope& append(size_t __n, _CharT __c) { rope<_CharT,_Alloc> __last(__n, __c); return append(__last); } void swap(rope& __b) { _RopeRep* __tmp = this->_M_tree_ptr; this->_M_tree_ptr = __b._M_tree_ptr; __b._M_tree_ptr = __tmp; } protected: // Result is included in refcount. static _RopeRep* replace(_RopeRep* __old, size_t __pos1, size_t __pos2, _RopeRep* __r) { if (0 == __old) { _S_ref(__r); return __r; } _Self_destruct_ptr __left(_S_substring(__old, 0, __pos1)); _Self_destruct_ptr __right(_S_substring(__old, __pos2, __old->_M_size)); _RopeRep* __result; if (0 == __r) __result = _S_concat(__left, __right); else { _Self_destruct_ptr __left_result(_S_concat(__left, __r)); __result = _S_concat(__left_result, __right); } return __result; } public: void insert(size_t __p, const rope& __r) { _RopeRep* __result = replace(this->_M_tree_ptr, __p, __p, __r._M_tree_ptr); _S_unref(this->_M_tree_ptr); this->_M_tree_ptr = __result; } void insert(size_t __p, size_t __n, _CharT __c) { rope<_CharT,_Alloc> __r(__n,__c); insert(__p, __r); } void insert(size_t __p, const _CharT* __i, size_t __n) { _Self_destruct_ptr __left(_S_substring(this->_M_tree_ptr, 0, __p)); _Self_destruct_ptr __right(_S_substring(this->_M_tree_ptr, __p, size())); _Self_destruct_ptr __left_result(_S_concat_char_iter(__left, __i, __n)); // _S_ destr_concat_char_iter should be safe here. // But as it stands it's probably not a win, since __left // is likely to have additional references. _RopeRep* __result = _S_concat(__left_result, __right); _S_unref(this->_M_tree_ptr); this->_M_tree_ptr = __result; } void insert(size_t __p, const _CharT* __c_string) { insert(__p, __c_string, _S_char_ptr_len(__c_string)); } void insert(size_t __p, _CharT __c) { insert(__p, &__c, 1); } void insert(size_t __p) { _CharT __c = _CharT(); insert(__p, &__c, 1); } void insert(size_t __p, const _CharT* __i, const _CharT* __j) { rope __r(__i, __j); insert(__p, __r); } void insert(size_t __p, const const_iterator& __i, const const_iterator& __j) { rope __r(__i, __j); insert(__p, __r); } void insert(size_t __p, const iterator& __i, const iterator& __j) { rope __r(__i, __j); insert(__p, __r); } // (position, length) versions of replace operations: void replace(size_t __p, size_t __n, const rope& __r) { _RopeRep* __result = replace(this->_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); _S_unref(this->_M_tree_ptr); this->_M_tree_ptr = __result; } void replace(size_t __p, size_t __n, const _CharT* __i, size_t __i_len) { rope __r(__i, __i_len); replace(__p, __n, __r); } void replace(size_t __p, size_t __n, _CharT __c) { rope __r(__c); replace(__p, __n, __r); } void replace(size_t __p, size_t __n, const _CharT* __c_string) { rope __r(__c_string); replace(__p, __n, __r); } void replace(size_t __p, size_t __n, const _CharT* __i, const _CharT* __j) { rope __r(__i, __j); replace(__p, __n, __r); } void replace(size_t __p, size_t __n, const const_iterator& __i, const const_iterator& __j) { rope __r(__i, __j); replace(__p, __n, __r); } void replace(size_t __p, size_t __n, const iterator& __i, const iterator& __j) { rope __r(__i, __j); replace(__p, __n, __r); } // Single character variants: void replace(size_t __p, _CharT __c) { iterator __i(this, __p); *__i = __c; } void replace(size_t __p, const rope& __r) { replace(__p, 1, __r); } void replace(size_t __p, const _CharT* __i, size_t __i_len) { replace(__p, 1, __i, __i_len); } void replace(size_t __p, const _CharT* __c_string) { replace(__p, 1, __c_string); } void replace(size_t __p, const _CharT* __i, const _CharT* __j) { replace(__p, 1, __i, __j); } void replace(size_t __p, const const_iterator& __i, const const_iterator& __j) { replace(__p, 1, __i, __j); } void replace(size_t __p, const iterator& __i, const iterator& __j) { replace(__p, 1, __i, __j); } // Erase, (position, size) variant. void erase(size_t __p, size_t __n) { _RopeRep* __result = replace(this->_M_tree_ptr, __p, __p + __n, 0); _S_unref(this->_M_tree_ptr); this->_M_tree_ptr = __result; } // Erase, single character void erase(size_t __p) { erase(__p, __p + 1); } // Insert, iterator variants. iterator insert(const iterator& __p, const rope& __r) { insert(__p.index(), __r); return __p; } iterator insert(const iterator& __p, size_t __n, _CharT __c) { insert(__p.index(), __n, __c); return __p; } iterator insert(const iterator& __p, _CharT __c) { insert(__p.index(), __c); return __p; } iterator insert(const iterator& __p ) { insert(__p.index()); return __p; } iterator insert(const iterator& __p, const _CharT* c_string) { insert(__p.index(), c_string); return __p; } iterator insert(const iterator& __p, const _CharT* __i, size_t __n) { insert(__p.index(), __i, __n); return __p; } iterator insert(const iterator& __p, const _CharT* __i, const _CharT* __j) { insert(__p.index(), __i, __j); return __p; } iterator insert(const iterator& __p, const const_iterator& __i, const const_iterator& __j) { insert(__p.index(), __i, __j); return __p; } iterator insert(const iterator& __p, const iterator& __i, const iterator& __j) { insert(__p.index(), __i, __j); return __p; } // Replace, range variants. void replace(const iterator& __p, const iterator& __q, const rope& __r) { replace(__p.index(), __q.index() - __p.index(), __r); } void replace(const iterator& __p, const iterator& __q, _CharT __c) { replace(__p.index(), __q.index() - __p.index(), __c); } void replace(const iterator& __p, const iterator& __q, const _CharT* __c_string) { replace(__p.index(), __q.index() - __p.index(), __c_string); } void replace(const iterator& __p, const iterator& __q, const _CharT* __i, size_t __n) { replace(__p.index(), __q.index() - __p.index(), __i, __n); } void replace(const iterator& __p, const iterator& __q, const _CharT* __i, const _CharT* __j) { replace(__p.index(), __q.index() - __p.index(), __i, __j); } void replace(const iterator& __p, const iterator& __q, const const_iterator& __i, const const_iterator& __j) { replace(__p.index(), __q.index() - __p.index(), __i, __j); } void replace(const iterator& __p, const iterator& __q, const iterator& __i, const iterator& __j) { replace(__p.index(), __q.index() - __p.index(), __i, __j); } // Replace, iterator variants. void replace(const iterator& __p, const rope& __r) { replace(__p.index(), __r); } void replace(const iterator& __p, _CharT __c) { replace(__p.index(), __c); } void replace(const iterator& __p, const _CharT* __c_string) { replace(__p.index(), __c_string); } void replace(const iterator& __p, const _CharT* __i, size_t __n) { replace(__p.index(), __i, __n); } void replace(const iterator& __p, const _CharT* __i, const _CharT* __j) { replace(__p.index(), __i, __j); } void replace(const iterator& __p, const_iterator __i, const_iterator __j) { replace(__p.index(), __i, __j); } void replace(const iterator& __p, iterator __i, iterator __j) { replace(__p.index(), __i, __j); } // Iterator and range variants of erase iterator erase(const iterator& __p, const iterator& __q) { size_t __p_index = __p.index(); erase(__p_index, __q.index() - __p_index); return iterator(this, __p_index); } iterator erase(const iterator& __p) { size_t __p_index = __p.index(); erase(__p_index, 1); return iterator(this, __p_index); } rope substr(size_t __start, size_t __len = 1) const { return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, __start, __start + __len)); } rope substr(iterator __start, iterator __end) const { return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, __start.index(), __end.index())); } rope substr(iterator __start) const { size_t __pos = __start.index(); return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, __pos, __pos + 1)); } rope substr(const_iterator __start, const_iterator __end) const { // This might eventually take advantage of the cache in the // iterator. return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, __start.index(), __end.index())); } rope<_CharT, _Alloc> substr(const_iterator __start) { size_t __pos = __start.index(); return rope<_CharT, _Alloc>(_S_substring(this->_M_tree_ptr, __pos, __pos + 1)); } static const size_type npos; size_type find(_CharT __c, size_type __pos = 0) const; size_type find(const _CharT* __s, size_type __pos = 0) const { size_type __result_pos; const_iterator __result = std::search(const_begin() + __pos, const_end(), __s, __s + _S_char_ptr_len(__s)); __result_pos = __result.index(); #ifndef __STL_OLD_ROPE_SEMANTICS if (__result_pos == size()) __result_pos = npos; #endif return __result_pos; } iterator mutable_begin() { return(iterator(this, 0)); } iterator mutable_end() { return(iterator(this, size())); } typedef std::reverse_iterator<iterator> reverse_iterator; reverse_iterator mutable_rbegin() { return reverse_iterator(mutable_end()); } reverse_iterator mutable_rend() { return reverse_iterator(mutable_begin()); } reference mutable_reference_at(size_type __pos) { return reference(this, __pos); } #ifdef __STD_STUFF reference operator[] (size_type __pos) { return _char_ref_proxy(this, __pos); } reference at(size_type __pos) { // if (__pos >= size()) throw out_of_range; // XXX return (*this)[__pos]; } void resize(size_type __n, _CharT __c) { } void resize(size_type __n) { } void reserve(size_type __res_arg = 0) { } size_type capacity() const { return max_size(); } // Stuff below this line is dangerous because it's error prone. // I would really like to get rid of it. // copy function with funny arg ordering. size_type copy(_CharT* __buffer, size_type __n, size_type __pos = 0) const { return copy(__pos, __n, __buffer); } iterator end() { return mutable_end(); } iterator begin() { return mutable_begin(); } reverse_iterator rend() { return mutable_rend(); } reverse_iterator rbegin() { return mutable_rbegin(); } #else const_iterator end() { return const_end(); } const_iterator begin() { return const_begin(); } const_reverse_iterator rend() { return const_rend(); } const_reverse_iterator rbegin() { return const_rbegin(); } #endif }; template <class _CharT, class _Alloc> const typename rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = (size_type)(-1); template <class _CharT, class _Alloc> inline bool operator==(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y) { return (__x._M_current_pos == __y._M_current_pos && __x._M_root == __y._M_root); } template <class _CharT, class _Alloc> inline bool operator<(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y) { return (__x._M_current_pos < __y._M_current_pos); } template <class _CharT, class _Alloc> inline bool operator!=(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y) { return !(__x == __y); } template <class _CharT, class _Alloc> inline bool operator>(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y) { return __y < __x; } template <class _CharT, class _Alloc> inline bool operator<=(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y) { return !(__y < __x); } template <class _CharT, class _Alloc> inline bool operator>=(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y) { return !(__x < __y); } template <class _CharT, class _Alloc> inline ptrdiff_t operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, const _Rope_const_iterator<_CharT, _Alloc>& __y) { return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; } template <class _CharT, class _Alloc> inline _Rope_const_iterator<_CharT, _Alloc> operator-(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, __x._M_current_pos - __n); } template <class _CharT, class _Alloc> inline _Rope_const_iterator<_CharT, _Alloc> operator+(const _Rope_const_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, __x._M_current_pos + __n); } template <class _CharT, class _Alloc> inline _Rope_const_iterator<_CharT, _Alloc> operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT, _Alloc>& __x) { return _Rope_const_iterator<_CharT, _Alloc>(__x._M_root, __x._M_current_pos + __n); } template <class _CharT, class _Alloc> inline bool operator==(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y) {return (__x._M_current_pos == __y._M_current_pos && __x._M_root_rope == __y._M_root_rope); } template <class _CharT, class _Alloc> inline bool operator<(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y) { return (__x._M_current_pos < __y._M_current_pos); } template <class _CharT, class _Alloc> inline bool operator!=(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y) { return !(__x == __y); } template <class _CharT, class _Alloc> inline bool operator>(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y) { return __y < __x; } template <class _CharT, class _Alloc> inline bool operator<=(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y) { return !(__y < __x); } template <class _CharT, class _Alloc> inline bool operator>=(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y) { return !(__x < __y); } template <class _CharT, class _Alloc> inline ptrdiff_t operator-(const _Rope_iterator<_CharT, _Alloc>& __x, const _Rope_iterator<_CharT, _Alloc>& __y) { return ((ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos); } template <class _CharT, class _Alloc> inline _Rope_iterator<_CharT, _Alloc> operator-(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, __x._M_current_pos - __n); } template <class _CharT, class _Alloc> inline _Rope_iterator<_CharT, _Alloc> operator+(const _Rope_iterator<_CharT, _Alloc>& __x, ptrdiff_t __n) { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, __x._M_current_pos + __n); } template <class _CharT, class _Alloc> inline _Rope_iterator<_CharT, _Alloc> operator+(ptrdiff_t __n, const _Rope_iterator<_CharT, _Alloc>& __x) { return _Rope_iterator<_CharT, _Alloc>(__x._M_root_rope, __x._M_current_pos + __n); } template <class _CharT, class _Alloc> inline rope<_CharT, _Alloc> operator+(const rope<_CharT, _Alloc>& __left, const rope<_CharT, _Alloc>& __right) { // Inlining this should make it possible to keep __left and // __right in registers. typedef rope<_CharT, _Alloc> rope_type; return rope_type(rope_type::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr)); } template <class _CharT, class _Alloc> inline rope<_CharT, _Alloc>& operator+=(rope<_CharT, _Alloc>& __left, const rope<_CharT, _Alloc>& __right) { __left.append(__right); return __left; } template <class _CharT, class _Alloc> inline rope<_CharT, _Alloc> operator+(const rope<_CharT, _Alloc>& __left, const _CharT* __right) { typedef rope<_CharT, _Alloc> rope_type; size_t __rlen = rope_type::_S_char_ptr_len(__right); return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr, __right, __rlen)); } template <class _CharT, class _Alloc> inline rope<_CharT, _Alloc>& operator+=(rope<_CharT, _Alloc>& __left, const _CharT* __right) { __left.append(__right); return __left; } template <class _CharT, class _Alloc> inline rope<_CharT, _Alloc> operator+(const rope<_CharT, _Alloc>& __left, _CharT __right) { typedef rope<_CharT, _Alloc> rope_type; return rope_type(rope_type::_S_concat_char_iter(__left._M_tree_ptr, &__right, 1)); } template <class _CharT, class _Alloc> inline rope<_CharT, _Alloc>& operator+=(rope<_CharT, _Alloc>& __left, _CharT __right) { __left.append(__right); return __left; } template <class _CharT, class _Alloc> bool operator<(const rope<_CharT, _Alloc>& __left, const rope<_CharT, _Alloc>& __right) { return __left.compare(__right) < 0; } template <class _CharT, class _Alloc> bool operator==(const rope<_CharT, _Alloc>& __left, const rope<_CharT, _Alloc>& __right) { return __left.compare(__right) == 0; } template <class _CharT, class _Alloc> inline bool operator==(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y) { return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); } template <class _CharT, class _Alloc> inline bool operator!=(const rope<_CharT, _Alloc>& __x, const rope<_CharT, _Alloc>& __y) { return !(__x == __y); } template <class _CharT, class _Alloc> inline bool operator>(const rope<_CharT, _Alloc>& __x, const rope<_CharT, _Alloc>& __y) { return __y < __x; } template <class _CharT, class _Alloc> inline bool operator<=(const rope<_CharT, _Alloc>& __x, const rope<_CharT, _Alloc>& __y) { return !(__y < __x); } template <class _CharT, class _Alloc> inline bool operator>=(const rope<_CharT, _Alloc>& __x, const rope<_CharT, _Alloc>& __y) { return !(__x < __y); } template <class _CharT, class _Alloc> inline bool operator!=(const _Rope_char_ptr_proxy<_CharT, _Alloc>& __x, const _Rope_char_ptr_proxy<_CharT, _Alloc>& __y) { return !(__x == __y); } template<class _CharT, class _Traits, class _Alloc> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __o, const rope<_CharT, _Alloc>& __r); typedef rope<char> crope; typedef rope<wchar_t> wrope; inline crope::reference __mutable_reference_at(crope& __c, size_t __i) { return __c.mutable_reference_at(__i); } inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i) { return __c.mutable_reference_at(__i); } template <class _CharT, class _Alloc> inline void swap(rope<_CharT, _Alloc>& __x, rope<_CharT, _Alloc>& __y) { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace tr1 { template<> struct hash<__gnu_cxx::crope> { size_t operator()(const __gnu_cxx::crope& __str) const { size_t __size = __str.size(); if (0 == __size) return 0; return 13 * __str[0] + 5 * __str[__size - 1] + __size; } }; template<> struct hash<__gnu_cxx::wrope> { size_t operator()(const __gnu_cxx::wrope& __str) const { size_t __size = __str.size(); if (0 == __size) return 0; return 13 * __str[0] + 5 * __str[__size - 1] + __size; } }; } // namespace tr1 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std # include <ext/ropeimpl.h> #endif c++/8/ext/cmath 0000644 00000014652 15146341150 0007112 0 ustar 00 // Math extensions -*- C++ -*- // Copyright (C) 2013-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/cmath * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_CMATH #define _EXT_CMATH 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <cmath> #include <type_traits> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // A class for math constants. template<typename _RealType> struct __math_constants { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); // Constant @f$ \pi @f$. static constexpr _RealType __pi = 3.1415926535897932384626433832795029L; // Constant @f$ \pi / 2 @f$. static constexpr _RealType __pi_half = 1.5707963267948966192313216916397514L; // Constant @f$ \pi / 3 @f$. static constexpr _RealType __pi_third = 1.0471975511965977461542144610931676L; // Constant @f$ \pi / 4 @f$. static constexpr _RealType __pi_quarter = 0.7853981633974483096156608458198757L; // Constant @f$ \sqrt(\pi / 2) @f$. static constexpr _RealType __root_pi_div_2 = 1.2533141373155002512078826424055226L; // Constant @f$ 1 / \pi @f$. static constexpr _RealType __one_div_pi = 0.3183098861837906715377675267450287L; // Constant @f$ 2 / \pi @f$. static constexpr _RealType __two_div_pi = 0.6366197723675813430755350534900574L; // Constant @f$ 2 / \sqrt(\pi) @f$. static constexpr _RealType __two_div_root_pi = 1.1283791670955125738961589031215452L; // Constant Euler's number @f$ e @f$. static constexpr _RealType __e = 2.7182818284590452353602874713526625L; // Constant @f$ 1 / e @f$. static constexpr _RealType __one_div_e = 0.36787944117144232159552377016146087L; // Constant @f$ \log_2(e) @f$. static constexpr _RealType __log2_e = 1.4426950408889634073599246810018921L; // Constant @f$ \log_10(e) @f$. static constexpr _RealType __log10_e = 0.4342944819032518276511289189166051L; // Constant @f$ \ln(2) @f$. static constexpr _RealType __ln_2 = 0.6931471805599453094172321214581766L; // Constant @f$ \ln(3) @f$. static constexpr _RealType __ln_3 = 1.0986122886681096913952452369225257L; // Constant @f$ \ln(10) @f$. static constexpr _RealType __ln_10 = 2.3025850929940456840179914546843642L; // Constant Euler-Mascheroni @f$ \gamma_E @f$. static constexpr _RealType __gamma_e = 0.5772156649015328606065120900824024L; // Constant Golden Ratio @f$ \phi @f$. static constexpr _RealType __phi = 1.6180339887498948482045868343656381L; // Constant @f$ \sqrt(2) @f$. static constexpr _RealType __root_2 = 1.4142135623730950488016887242096981L; // Constant @f$ \sqrt(3) @f$. static constexpr _RealType __root_3 = 1.7320508075688772935274463415058724L; // Constant @f$ \sqrt(5) @f$. static constexpr _RealType __root_5 = 2.2360679774997896964091736687312762L; // Constant @f$ \sqrt(7) @f$. static constexpr _RealType __root_7 = 2.6457513110645905905016157536392604L; // Constant @f$ 1 / \sqrt(2) @f$. static constexpr _RealType __one_div_root_2 = 0.7071067811865475244008443621048490L; }; // And the template definitions for the constants. template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__pi; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__pi_half; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__pi_third; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__pi_quarter; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__root_pi_div_2; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__one_div_pi; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__two_div_pi; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__two_div_root_pi; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__e; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__one_div_e; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__log2_e; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__log10_e; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__ln_2; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__ln_3; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__ln_10; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__gamma_e; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__phi; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__root_2; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__root_3; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__root_5; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__root_7; template<typename _RealType> constexpr _RealType __math_constants<_RealType>::__one_div_root_2; _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #endif // C++11 #endif // _EXT_CMATH c++/8/ext/throw_allocator.h 0000644 00000057731 15146341150 0011454 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** @file ext/throw_allocator.h * This file is a GNU extension to the Standard C++ Library. * * Contains two exception-generating types (throw_value, throw_allocator) * intended to be used as value and allocator types while testing * exception safety in templatized containers and algorithms. The * allocator has additional log and debug features. The exception * generated is of type forced_exception_error. */ #ifndef _THROW_ALLOCATOR_H #define _THROW_ALLOCATOR_H 1 #include <cmath> #include <ctime> #include <map> #include <string> #include <ostream> #include <stdexcept> #include <utility> #include <bits/functexcept.h> #include <bits/move.h> #if __cplusplus >= 201103L # include <functional> # include <random> #else # include <tr1/functional> # include <tr1/random> #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Thown by exception safety machinery. * @ingroup exceptions */ struct forced_error : public std::exception { }; // Substitute for forced_error object when -fno-exceptions. inline void __throw_forced_error() { _GLIBCXX_THROW_OR_ABORT(forced_error()); } /** * @brief Base class for checking address and label information * about allocations. Create a std::map between the allocated * address (void*) and a datum for annotations, which are a pair of * numbers corresponding to label and allocated size. */ struct annotate_base { annotate_base() { label(); map_alloc(); } static void set_label(size_t l) { label() = l; } static size_t get_label() { return label(); } void insert(void* p, size_t size) { if (!p) { std::string error("annotate_base::insert null insert!\n"); log_to_string(error, make_entry(p, size)); std::__throw_logic_error(error.c_str()); } const_iterator found = map_alloc().find(p); if (found != map_alloc().end()) { std::string error("annotate_base::insert double insert!\n"); log_to_string(error, make_entry(p, size)); log_to_string(error, *found); std::__throw_logic_error(error.c_str()); } map_alloc().insert(make_entry(p, size)); } void erase(void* p, size_t size) { check_allocated(p, size); map_alloc().erase(p); } #if __cplusplus >= 201103L void insert_construct(void* p) { if (!p) { std::string error("annotate_base::insert_construct null!\n"); std::__throw_logic_error(error.c_str()); } auto found = map_construct().find(p); if (found != map_construct().end()) { std::string error("annotate_base::insert_construct double insert!\n"); log_to_string(error, std::make_pair(p, get_label())); log_to_string(error, *found); std::__throw_logic_error(error.c_str()); } map_construct().insert(std::make_pair(p, get_label())); } void erase_construct(void* p) { check_constructed(p); map_construct().erase(p); } #endif // See if a particular address and allocation size has been saved. inline void check_allocated(void* p, size_t size) { const_iterator found = map_alloc().find(p); if (found == map_alloc().end()) { std::string error("annotate_base::check_allocated by value " "null erase!\n"); log_to_string(error, make_entry(p, size)); std::__throw_logic_error(error.c_str()); } if (found->second.second != size) { std::string error("annotate_base::check_allocated by value " "wrong-size erase!\n"); log_to_string(error, make_entry(p, size)); log_to_string(error, *found); std::__throw_logic_error(error.c_str()); } } // See if a given label has been allocated. inline void check(size_t label) { std::string found; { const_iterator beg = map_alloc().begin(); const_iterator end = map_alloc().end(); while (beg != end) { if (beg->second.first == label) log_to_string(found, *beg); ++beg; } } #if __cplusplus >= 201103L { auto beg = map_construct().begin(); auto end = map_construct().end(); while (beg != end) { if (beg->second == label) log_to_string(found, *beg); ++beg; } } #endif if (!found.empty()) { std::string error("annotate_base::check by label\n"); error += found; std::__throw_logic_error(error.c_str()); } } // See if there is anything left allocated or constructed. inline static void check() { std::string found; { const_iterator beg = map_alloc().begin(); const_iterator end = map_alloc().end(); while (beg != end) { log_to_string(found, *beg); ++beg; } } #if __cplusplus >= 201103L { auto beg = map_construct().begin(); auto end = map_construct().end(); while (beg != end) { log_to_string(found, *beg); ++beg; } } #endif if (!found.empty()) { std::string error("annotate_base::check \n"); error += found; std::__throw_logic_error(error.c_str()); } } #if __cplusplus >= 201103L inline void check_constructed(void* p) { auto found = map_construct().find(p); if (found == map_construct().end()) { std::string error("annotate_base::check_constructed not " "constructed!\n"); log_to_string(error, std::make_pair(p, get_label())); std::__throw_logic_error(error.c_str()); } } inline void check_constructed(size_t label) { auto beg = map_construct().begin(); auto end = map_construct().end(); std::string found; while (beg != end) { if (beg->second == label) log_to_string(found, *beg); ++beg; } if (!found.empty()) { std::string error("annotate_base::check_constructed by label\n"); error += found; std::__throw_logic_error(error.c_str()); } } #endif private: typedef std::pair<size_t, size_t> data_type; typedef std::map<void*, data_type> map_alloc_type; typedef map_alloc_type::value_type entry_type; typedef map_alloc_type::const_iterator const_iterator; typedef map_alloc_type::const_reference const_reference; #if __cplusplus >= 201103L typedef std::map<void*, size_t> map_construct_type; #endif friend std::ostream& operator<<(std::ostream&, const annotate_base&); entry_type make_entry(void* p, size_t size) { return std::make_pair(p, data_type(get_label(), size)); } static void log_to_string(std::string& s, const_reference ref) { char buf[40]; const char tab('\t'); s += "label: "; unsigned long l = static_cast<unsigned long>(ref.second.first); __builtin_sprintf(buf, "%lu", l); s += buf; s += tab; s += "size: "; l = static_cast<unsigned long>(ref.second.second); __builtin_sprintf(buf, "%lu", l); s += buf; s += tab; s += "address: "; __builtin_sprintf(buf, "%p", ref.first); s += buf; s += '\n'; } #if __cplusplus >= 201103L static void log_to_string(std::string& s, const std::pair<const void*, size_t>& ref) { char buf[40]; const char tab('\t'); s += "label: "; unsigned long l = static_cast<unsigned long>(ref.second); __builtin_sprintf(buf, "%lu", l); s += buf; s += tab; s += "address: "; __builtin_sprintf(buf, "%p", ref.first); s += buf; s += '\n'; } #endif static size_t& label() { static size_t _S_label(std::numeric_limits<size_t>::max()); return _S_label; } static map_alloc_type& map_alloc() { static map_alloc_type _S_map; return _S_map; } #if __cplusplus >= 201103L static map_construct_type& map_construct() { static map_construct_type _S_map; return _S_map; } #endif }; inline std::ostream& operator<<(std::ostream& os, const annotate_base& __b) { std::string error; typedef annotate_base base_type; { base_type::const_iterator beg = __b.map_alloc().begin(); base_type::const_iterator end = __b.map_alloc().end(); for (; beg != end; ++beg) __b.log_to_string(error, *beg); } #if __cplusplus >= 201103L { auto beg = __b.map_construct().begin(); auto end = __b.map_construct().end(); for (; beg != end; ++beg) __b.log_to_string(error, *beg); } #endif return os << error; } /** * @brief Base struct for condition policy. * * Requires a public member function with the signature * void throw_conditionally() */ struct condition_base { virtual ~condition_base() { }; }; /** * @brief Base class for incremental control and throw. */ struct limit_condition : public condition_base { // Scope-level adjustor objects: set limit for throw at the // beginning of a scope block, and restores to previous limit when // object is destroyed on exiting the block. struct adjustor_base { private: const size_t _M_orig; public: adjustor_base() : _M_orig(limit()) { } virtual ~adjustor_base() { set_limit(_M_orig); } }; /// Never enter the condition. struct never_adjustor : public adjustor_base { never_adjustor() { set_limit(std::numeric_limits<size_t>::max()); } }; /// Always enter the condition. struct always_adjustor : public adjustor_base { always_adjustor() { set_limit(count()); } }; /// Enter the nth condition. struct limit_adjustor : public adjustor_base { limit_adjustor(const size_t __l) { set_limit(__l); } }; // Increment _S_count every time called. // If _S_count matches the limit count, throw. static void throw_conditionally() { if (count() == limit()) __throw_forced_error(); ++count(); } static size_t& count() { static size_t _S_count(0); return _S_count; } static size_t& limit() { static size_t _S_limit(std::numeric_limits<size_t>::max()); return _S_limit; } // Zero the throw counter, set limit to argument. static void set_limit(const size_t __l) { limit() = __l; count() = 0; } }; /** * @brief Base class for random probability control and throw. */ struct random_condition : public condition_base { // Scope-level adjustor objects: set probability for throw at the // beginning of a scope block, and restores to previous // probability when object is destroyed on exiting the block. struct adjustor_base { private: const double _M_orig; public: adjustor_base() : _M_orig(probability()) { } virtual ~adjustor_base() { set_probability(_M_orig); } }; /// Group condition. struct group_adjustor : public adjustor_base { group_adjustor(size_t size) { set_probability(1 - std::pow(double(1 - probability()), double(0.5 / (size + 1)))); } }; /// Never enter the condition. struct never_adjustor : public adjustor_base { never_adjustor() { set_probability(0); } }; /// Always enter the condition. struct always_adjustor : public adjustor_base { always_adjustor() { set_probability(1); } }; random_condition() { probability(); engine(); } static void set_probability(double __p) { probability() = __p; } static void throw_conditionally() { if (generate() < probability()) __throw_forced_error(); } void seed(unsigned long __s) { engine().seed(__s); } private: #if __cplusplus >= 201103L typedef std::uniform_real_distribution<double> distribution_type; typedef std::mt19937 engine_type; #else typedef std::tr1::uniform_real<double> distribution_type; typedef std::tr1::mt19937 engine_type; #endif static double generate() { #if __cplusplus >= 201103L const distribution_type distribution(0, 1); static auto generator = std::bind(distribution, engine()); #else // Use variate_generator to get normalized results. typedef std::tr1::variate_generator<engine_type, distribution_type> gen_t; distribution_type distribution(0, 1); static gen_t generator(engine(), distribution); #endif double random = generator(); if (random < distribution.min() || random > distribution.max()) { std::string __s("random_condition::generate"); __s += "\n"; __s += "random number generated is: "; char buf[40]; __builtin_sprintf(buf, "%f", random); __s += buf; std::__throw_out_of_range(__s.c_str()); } return random; } static double& probability() { static double _S_p; return _S_p; } static engine_type& engine() { static engine_type _S_e; return _S_e; } }; /** * @brief Class with exception generation control. Intended to be * used as a value_type in templatized code. * * Note: Destructor not allowed to throw. */ template<typename _Cond> struct throw_value_base : public _Cond { typedef _Cond condition_type; using condition_type::throw_conditionally; std::size_t _M_i; #ifndef _GLIBCXX_IS_AGGREGATE throw_value_base() : _M_i(0) { throw_conditionally(); } throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i) { throw_conditionally(); } #if __cplusplus >= 201103L // Shall not throw. throw_value_base(throw_value_base&&) = default; #endif explicit throw_value_base(const std::size_t __i) : _M_i(__i) { throw_conditionally(); } #endif throw_value_base& operator=(const throw_value_base& __v) { throw_conditionally(); _M_i = __v._M_i; return *this; } #if __cplusplus >= 201103L // Shall not throw. throw_value_base& operator=(throw_value_base&&) = default; #endif throw_value_base& operator++() { throw_conditionally(); ++_M_i; return *this; } }; template<typename _Cond> inline void swap(throw_value_base<_Cond>& __a, throw_value_base<_Cond>& __b) { typedef throw_value_base<_Cond> throw_value; throw_value::throw_conditionally(); throw_value orig(__a); __a = __b; __b = orig; } // General instantiable types requirements. template<typename _Cond> inline bool operator==(const throw_value_base<_Cond>& __a, const throw_value_base<_Cond>& __b) { typedef throw_value_base<_Cond> throw_value; throw_value::throw_conditionally(); bool __ret = __a._M_i == __b._M_i; return __ret; } template<typename _Cond> inline bool operator<(const throw_value_base<_Cond>& __a, const throw_value_base<_Cond>& __b) { typedef throw_value_base<_Cond> throw_value; throw_value::throw_conditionally(); bool __ret = __a._M_i < __b._M_i; return __ret; } // Numeric algorithms instantiable types requirements. template<typename _Cond> inline throw_value_base<_Cond> operator+(const throw_value_base<_Cond>& __a, const throw_value_base<_Cond>& __b) { typedef throw_value_base<_Cond> throw_value; throw_value::throw_conditionally(); throw_value __ret(__a._M_i + __b._M_i); return __ret; } template<typename _Cond> inline throw_value_base<_Cond> operator-(const throw_value_base<_Cond>& __a, const throw_value_base<_Cond>& __b) { typedef throw_value_base<_Cond> throw_value; throw_value::throw_conditionally(); throw_value __ret(__a._M_i - __b._M_i); return __ret; } template<typename _Cond> inline throw_value_base<_Cond> operator*(const throw_value_base<_Cond>& __a, const throw_value_base<_Cond>& __b) { typedef throw_value_base<_Cond> throw_value; throw_value::throw_conditionally(); throw_value __ret(__a._M_i * __b._M_i); return __ret; } /// Type throwing via limit condition. struct throw_value_limit : public throw_value_base<limit_condition> { typedef throw_value_base<limit_condition> base_type; #ifndef _GLIBCXX_IS_AGGREGATE throw_value_limit() { } throw_value_limit(const throw_value_limit& __other) : base_type(__other._M_i) { } #if __cplusplus >= 201103L throw_value_limit(throw_value_limit&&) = default; #endif explicit throw_value_limit(const std::size_t __i) : base_type(__i) { } #endif throw_value_limit& operator=(const throw_value_limit& __other) { base_type::operator=(__other); return *this; } #if __cplusplus >= 201103L throw_value_limit& operator=(throw_value_limit&&) = default; #endif }; /// Type throwing via random condition. struct throw_value_random : public throw_value_base<random_condition> { typedef throw_value_base<random_condition> base_type; #ifndef _GLIBCXX_IS_AGGREGATE throw_value_random() { } throw_value_random(const throw_value_random& __other) : base_type(__other._M_i) { } #if __cplusplus >= 201103L throw_value_random(throw_value_random&&) = default; #endif explicit throw_value_random(const std::size_t __i) : base_type(__i) { } #endif throw_value_random& operator=(const throw_value_random& __other) { base_type::operator=(__other); return *this; } #if __cplusplus >= 201103L throw_value_random& operator=(throw_value_random&&) = default; #endif }; /** * @brief Allocator class with logging and exception generation control. * Intended to be used as an allocator_type in templatized code. * @ingroup allocators * * Note: Deallocate not allowed to throw. */ template<typename _Tp, typename _Cond> class throw_allocator_base : public annotate_base, public _Cond { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; #endif private: typedef _Cond condition_type; std::allocator<value_type> _M_allocator; using condition_type::throw_conditionally; public: size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return _M_allocator.max_size(); } pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } pointer allocate(size_type __n, std::allocator<void>::const_pointer hint = 0) { if (__n > this->max_size()) std::__throw_bad_alloc(); throw_conditionally(); pointer const a = _M_allocator.allocate(__n, hint); insert(a, sizeof(value_type) * __n); return a; } #if __cplusplus >= 201103L template<typename _Up, typename... _Args> void construct(_Up* __p, _Args&&... __args) { _M_allocator.construct(__p, std::forward<_Args>(__args)...); insert_construct(__p); } template<typename _Up> void destroy(_Up* __p) { erase_construct(__p); _M_allocator.destroy(__p); } #else void construct(pointer __p, const value_type& val) { return _M_allocator.construct(__p, val); } void destroy(pointer __p) { _M_allocator.destroy(__p); } #endif void deallocate(pointer __p, size_type __n) { erase(__p, sizeof(value_type) * __n); _M_allocator.deallocate(__p, __n); } void check_allocated(pointer __p, size_type __n) { size_type __t = sizeof(value_type) * __n; annotate_base::check_allocated(__p, __t); } void check(size_type __n) { annotate_base::check(__n); } }; template<typename _Tp, typename _Cond> inline bool operator==(const throw_allocator_base<_Tp, _Cond>&, const throw_allocator_base<_Tp, _Cond>&) { return true; } template<typename _Tp, typename _Cond> inline bool operator!=(const throw_allocator_base<_Tp, _Cond>&, const throw_allocator_base<_Tp, _Cond>&) { return false; } /// Allocator throwing via limit condition. template<typename _Tp> struct throw_allocator_limit : public throw_allocator_base<_Tp, limit_condition> { template<typename _Tp1> struct rebind { typedef throw_allocator_limit<_Tp1> other; }; throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { } throw_allocator_limit(const throw_allocator_limit&) _GLIBCXX_USE_NOEXCEPT { } template<typename _Tp1> throw_allocator_limit(const throw_allocator_limit<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { } }; /// Allocator throwing via random condition. template<typename _Tp> struct throw_allocator_random : public throw_allocator_base<_Tp, random_condition> { template<typename _Tp1> struct rebind { typedef throw_allocator_random<_Tp1> other; }; throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { } throw_allocator_random(const throw_allocator_random&) _GLIBCXX_USE_NOEXCEPT { } template<typename _Tp1> throw_allocator_random(const throw_allocator_random<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if __cplusplus >= 201103L # include <bits/functional_hash.h> namespace std _GLIBCXX_VISIBILITY(default) { /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit. template<> struct hash<__gnu_cxx::throw_value_limit> : public std::unary_function<__gnu_cxx::throw_value_limit, size_t> { size_t operator()(const __gnu_cxx::throw_value_limit& __val) const { __gnu_cxx::throw_value_limit::throw_conditionally(); std::hash<std::size_t> __h; size_t __result = __h(__val._M_i); return __result; } }; /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random. template<> struct hash<__gnu_cxx::throw_value_random> : public std::unary_function<__gnu_cxx::throw_value_random, size_t> { size_t operator()(const __gnu_cxx::throw_value_random& __val) const { __gnu_cxx::throw_value_random::throw_conditionally(); std::hash<std::size_t> __h; size_t __result = __h(__val._M_i); return __result; } }; } // end namespace std #endif #endif c++/8/ext/bitmap_allocator.h 0000644 00000076116 15146341150 0011563 0 ustar 00 // Bitmap Allocator. -*- C++ -*- // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/bitmap_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _BITMAP_ALLOCATOR_H #define _BITMAP_ALLOCATOR_H 1 #include <utility> // For std::pair. #include <bits/functexcept.h> // For __throw_bad_alloc(). #include <functional> // For greater_equal, and less_equal. #include <new> // For operator new. #include <debug/debug.h> // _GLIBCXX_DEBUG_ASSERT #include <ext/concurrence.h> #include <bits/move.h> /** @brief The constant in the expression below is the alignment * required in bytes. */ #define _BALLOC_ALIGN_BYTES 8 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; namespace __detail { /** @class __mini_vector bitmap_allocator.h bitmap_allocator.h * * @brief __mini_vector<> is a stripped down version of the * full-fledged std::vector<>. * * It is to be used only for built-in types or PODs. Notable * differences are: * * 1. Not all accessor functions are present. * 2. Used ONLY for PODs. * 3. No Allocator template argument. Uses ::operator new() to get * memory, and ::operator delete() to free it. * Caveat: The dtor does NOT free the memory allocated, so this a * memory-leaking vector! */ template<typename _Tp> class __mini_vector { __mini_vector(const __mini_vector&); __mini_vector& operator=(const __mini_vector&); public: typedef _Tp value_type; typedef _Tp* pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef pointer iterator; private: pointer _M_start; pointer _M_finish; pointer _M_end_of_storage; size_type _M_space_left() const throw() { return _M_end_of_storage - _M_finish; } pointer allocate(size_type __n) { return static_cast<pointer>(::operator new(__n * sizeof(_Tp))); } void deallocate(pointer __p, size_type) { ::operator delete(__p); } public: // Members used: size(), push_back(), pop_back(), // insert(iterator, const_reference), erase(iterator), // begin(), end(), back(), operator[]. __mini_vector() : _M_start(0), _M_finish(0), _M_end_of_storage(0) { } size_type size() const throw() { return _M_finish - _M_start; } iterator begin() const throw() { return this->_M_start; } iterator end() const throw() { return this->_M_finish; } reference back() const throw() { return *(this->end() - 1); } reference operator[](const size_type __pos) const throw() { return this->_M_start[__pos]; } void insert(iterator __pos, const_reference __x); void push_back(const_reference __x) { if (this->_M_space_left()) { *this->end() = __x; ++this->_M_finish; } else this->insert(this->end(), __x); } void pop_back() throw() { --this->_M_finish; } void erase(iterator __pos) throw(); void clear() throw() { this->_M_finish = this->_M_start; } }; // Out of line function definitions. template<typename _Tp> void __mini_vector<_Tp>:: insert(iterator __pos, const_reference __x) { if (this->_M_space_left()) { size_type __to_move = this->_M_finish - __pos; iterator __dest = this->end(); iterator __src = this->end() - 1; ++this->_M_finish; while (__to_move) { *__dest = *__src; --__dest; --__src; --__to_move; } *__pos = __x; } else { size_type __new_size = this->size() ? this->size() * 2 : 1; iterator __new_start = this->allocate(__new_size); iterator __first = this->begin(); iterator __start = __new_start; while (__first != __pos) { *__start = *__first; ++__start; ++__first; } *__start = __x; ++__start; while (__first != this->end()) { *__start = *__first; ++__start; ++__first; } if (this->_M_start) this->deallocate(this->_M_start, this->size()); this->_M_start = __new_start; this->_M_finish = __start; this->_M_end_of_storage = this->_M_start + __new_size; } } template<typename _Tp> void __mini_vector<_Tp>:: erase(iterator __pos) throw() { while (__pos + 1 != this->end()) { *__pos = __pos[1]; ++__pos; } --this->_M_finish; } template<typename _Tp> struct __mv_iter_traits { typedef typename _Tp::value_type value_type; typedef typename _Tp::difference_type difference_type; }; template<typename _Tp> struct __mv_iter_traits<_Tp*> { typedef _Tp value_type; typedef ptrdiff_t difference_type; }; enum { bits_per_byte = 8, bits_per_block = sizeof(size_t) * size_t(bits_per_byte) }; template<typename _ForwardIterator, typename _Tp, typename _Compare> _ForwardIterator __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { typedef typename __mv_iter_traits<_ForwardIterator>::difference_type _DistanceType; _DistanceType __len = __last - __first; _DistanceType __half; _ForwardIterator __middle; while (__len > 0) { __half = __len >> 1; __middle = __first; __middle += __half; if (__comp(*__middle, __val)) { __first = __middle; ++__first; __len = __len - __half - 1; } else __len = __half; } return __first; } /** @brief The number of Blocks pointed to by the address pair * passed to the function. */ template<typename _AddrPair> inline size_t __num_blocks(_AddrPair __ap) { return (__ap.second - __ap.first) + 1; } /** @brief The number of Bit-maps pointed to by the address pair * passed to the function. */ template<typename _AddrPair> inline size_t __num_bitmaps(_AddrPair __ap) { return __num_blocks(__ap) / size_t(bits_per_block); } // _Tp should be a pointer type. template<typename _Tp> class _Inclusive_between : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> { typedef _Tp pointer; pointer _M_ptr_value; typedef typename std::pair<_Tp, _Tp> _Block_pair; public: _Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr) { } bool operator()(_Block_pair __bp) const throw() { if (std::less_equal<pointer>()(_M_ptr_value, __bp.second) && std::greater_equal<pointer>()(_M_ptr_value, __bp.first)) return true; else return false; } }; // Used to pass a Functor to functions by reference. template<typename _Functor> class _Functor_Ref : public std::unary_function<typename _Functor::argument_type, typename _Functor::result_type> { _Functor& _M_fref; public: typedef typename _Functor::argument_type argument_type; typedef typename _Functor::result_type result_type; _Functor_Ref(_Functor& __fref) : _M_fref(__fref) { } result_type operator()(argument_type __arg) { return _M_fref(__arg); } }; /** @class _Ffit_finder bitmap_allocator.h bitmap_allocator.h * * @brief The class which acts as a predicate for applying the * first-fit memory allocation policy for the bitmap allocator. */ // _Tp should be a pointer type, and _Alloc is the Allocator for // the vector. template<typename _Tp> class _Ffit_finder : public std::unary_function<typename std::pair<_Tp, _Tp>, bool> { typedef typename std::pair<_Tp, _Tp> _Block_pair; typedef typename __detail::__mini_vector<_Block_pair> _BPVector; typedef typename _BPVector::difference_type _Counter_type; size_t* _M_pbitmap; _Counter_type _M_data_offset; public: _Ffit_finder() : _M_pbitmap(0), _M_data_offset(0) { } bool operator()(_Block_pair __bp) throw() { // Set the _rover to the last physical location bitmap, // which is the bitmap which belongs to the first free // block. Thus, the bitmaps are in exact reverse order of // the actual memory layout. So, we count down the bitmaps, // which is the same as moving up the memory. // If the used count stored at the start of the Bit Map headers // is equal to the number of Objects that the current Block can // store, then there is definitely no space for another single // object, so just return false. _Counter_type __diff = __detail::__num_bitmaps(__bp); if (*(reinterpret_cast<size_t*> (__bp.first) - (__diff + 1)) == __detail::__num_blocks(__bp)) return false; size_t* __rover = reinterpret_cast<size_t*>(__bp.first) - 1; for (_Counter_type __i = 0; __i < __diff; ++__i) { _M_data_offset = __i; if (*__rover) { _M_pbitmap = __rover; return true; } --__rover; } return false; } size_t* _M_get() const throw() { return _M_pbitmap; } _Counter_type _M_offset() const throw() { return _M_data_offset * size_t(bits_per_block); } }; /** @class _Bitmap_counter bitmap_allocator.h bitmap_allocator.h * * @brief The bitmap counter which acts as the bitmap * manipulator, and manages the bit-manipulation functions and * the searching and identification functions on the bit-map. */ // _Tp should be a pointer type. template<typename _Tp> class _Bitmap_counter { typedef typename __detail::__mini_vector<typename std::pair<_Tp, _Tp> > _BPVector; typedef typename _BPVector::size_type _Index_type; typedef _Tp pointer; _BPVector& _M_vbp; size_t* _M_curr_bmap; size_t* _M_last_bmap_in_block; _Index_type _M_curr_index; public: // Use the 2nd parameter with care. Make sure that such an // entry exists in the vector before passing that particular // index to this ctor. _Bitmap_counter(_BPVector& Rvbp, long __index = -1) : _M_vbp(Rvbp) { this->_M_reset(__index); } void _M_reset(long __index = -1) throw() { if (__index == -1) { _M_curr_bmap = 0; _M_curr_index = static_cast<_Index_type>(-1); return; } _M_curr_index = __index; _M_curr_bmap = reinterpret_cast<size_t*> (_M_vbp[_M_curr_index].first) - 1; _GLIBCXX_DEBUG_ASSERT(__index <= (long)_M_vbp.size() - 1); _M_last_bmap_in_block = _M_curr_bmap - ((_M_vbp[_M_curr_index].second - _M_vbp[_M_curr_index].first + 1) / size_t(bits_per_block) - 1); } // Dangerous Function! Use with extreme care. Pass to this // function ONLY those values that are known to be correct, // otherwise this will mess up big time. void _M_set_internal_bitmap(size_t* __new_internal_marker) throw() { _M_curr_bmap = __new_internal_marker; } bool _M_finished() const throw() { return(_M_curr_bmap == 0); } _Bitmap_counter& operator++() throw() { if (_M_curr_bmap == _M_last_bmap_in_block) { if (++_M_curr_index == _M_vbp.size()) _M_curr_bmap = 0; else this->_M_reset(_M_curr_index); } else --_M_curr_bmap; return *this; } size_t* _M_get() const throw() { return _M_curr_bmap; } pointer _M_base() const throw() { return _M_vbp[_M_curr_index].first; } _Index_type _M_offset() const throw() { return size_t(bits_per_block) * ((reinterpret_cast<size_t*>(this->_M_base()) - _M_curr_bmap) - 1); } _Index_type _M_where() const throw() { return _M_curr_index; } }; /** @brief Mark a memory address as allocated by re-setting the * corresponding bit in the bit-map. */ inline void __bit_allocate(size_t* __pbmap, size_t __pos) throw() { size_t __mask = 1 << __pos; __mask = ~__mask; *__pbmap &= __mask; } /** @brief Mark a memory address as free by setting the * corresponding bit in the bit-map. */ inline void __bit_free(size_t* __pbmap, size_t __pos) throw() { size_t __mask = 1 << __pos; *__pbmap |= __mask; } } // namespace __detail /** @brief Generic Version of the bsf instruction. */ inline size_t _Bit_scan_forward(size_t __num) { return static_cast<size_t>(__builtin_ctzl(__num)); } /** @class free_list bitmap_allocator.h bitmap_allocator.h * * @brief The free list class for managing chunks of memory to be * given to and returned by the bitmap_allocator. */ class free_list { public: typedef size_t* value_type; typedef __detail::__mini_vector<value_type> vector_type; typedef vector_type::iterator iterator; typedef __mutex __mutex_type; private: struct _LT_pointer_compare { bool operator()(const size_t* __pui, const size_t __cui) const throw() { return *__pui < __cui; } }; #if defined __GTHREADS __mutex_type& _M_get_mutex() { static __mutex_type _S_mutex; return _S_mutex; } #endif vector_type& _M_get_free_list() { static vector_type _S_free_list; return _S_free_list; } /** @brief Performs validation of memory based on their size. * * @param __addr The pointer to the memory block to be * validated. * * Validates the memory block passed to this function and * appropriately performs the action of managing the free list of * blocks by adding this block to the free list or deleting this * or larger blocks from the free list. */ void _M_validate(size_t* __addr) throw() { vector_type& __free_list = _M_get_free_list(); const vector_type::size_type __max_size = 64; if (__free_list.size() >= __max_size) { // Ok, the threshold value has been reached. We determine // which block to remove from the list of free blocks. if (*__addr >= *__free_list.back()) { // Ok, the new block is greater than or equal to the // last block in the list of free blocks. We just free // the new block. ::operator delete(static_cast<void*>(__addr)); return; } else { // Deallocate the last block in the list of free lists, // and insert the new one in its correct position. ::operator delete(static_cast<void*>(__free_list.back())); __free_list.pop_back(); } } // Just add the block to the list of free lists unconditionally. iterator __temp = __detail::__lower_bound (__free_list.begin(), __free_list.end(), *__addr, _LT_pointer_compare()); // We may insert the new free list before _temp; __free_list.insert(__temp, __addr); } /** @brief Decides whether the wastage of memory is acceptable for * the current memory request and returns accordingly. * * @param __block_size The size of the block available in the free * list. * * @param __required_size The required size of the memory block. * * @return true if the wastage incurred is acceptable, else returns * false. */ bool _M_should_i_give(size_t __block_size, size_t __required_size) throw() { const size_t __max_wastage_percentage = 36; if (__block_size >= __required_size && (((__block_size - __required_size) * 100 / __block_size) < __max_wastage_percentage)) return true; else return false; } public: /** @brief This function returns the block of memory to the * internal free list. * * @param __addr The pointer to the memory block that was given * by a call to the _M_get function. */ inline void _M_insert(size_t* __addr) throw() { #if defined __GTHREADS __scoped_lock __bfl_lock(_M_get_mutex()); #endif // Call _M_validate to decide what should be done with // this particular free list. this->_M_validate(reinterpret_cast<size_t*>(__addr) - 1); // See discussion as to why this is 1! } /** @brief This function gets a block of memory of the specified * size from the free list. * * @param __sz The size in bytes of the memory required. * * @return A pointer to the new memory block of size at least * equal to that requested. */ size_t* _M_get(size_t __sz) _GLIBCXX_THROW(std::bad_alloc); /** @brief This function just clears the internal Free List, and * gives back all the memory to the OS. */ void _M_clear(); }; // Forward declare the class. template<typename _Tp> class bitmap_allocator; // Specialize for void: template<> class bitmap_allocator<void> { public: typedef void* pointer; typedef const void* const_pointer; // Reference-to-void members are impossible. typedef void value_type; template<typename _Tp1> struct rebind { typedef bitmap_allocator<_Tp1> other; }; }; /** * @brief Bitmap Allocator, primary template. * @ingroup allocators */ template<typename _Tp> class bitmap_allocator : private free_list { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; typedef free_list::__mutex_type __mutex_type; template<typename _Tp1> struct rebind { typedef bitmap_allocator<_Tp1> other; }; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; #endif private: template<size_t _BSize, size_t _AlignSize> struct aligned_size { enum { modulus = _BSize % _AlignSize, value = _BSize + (modulus ? _AlignSize - (modulus) : 0) }; }; struct _Alloc_block { char __M_unused[aligned_size<sizeof(value_type), _BALLOC_ALIGN_BYTES>::value]; }; typedef typename std::pair<_Alloc_block*, _Alloc_block*> _Block_pair; typedef typename __detail::__mini_vector<_Block_pair> _BPVector; typedef typename _BPVector::iterator _BPiter; template<typename _Predicate> static _BPiter _S_find(_Predicate __p) { _BPiter __first = _S_mem_blocks.begin(); while (__first != _S_mem_blocks.end() && !__p(*__first)) ++__first; return __first; } #if defined _GLIBCXX_DEBUG // Complexity: O(lg(N)). Where, N is the number of block of size // sizeof(value_type). void _S_check_for_free_blocks() throw() { typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF; _BPiter __bpi = _S_find(_FFF()); _GLIBCXX_DEBUG_ASSERT(__bpi == _S_mem_blocks.end()); } #endif /** @brief Responsible for exponentially growing the internal * memory pool. * * @throw std::bad_alloc. If memory can not be allocated. * * Complexity: O(1), but internally depends upon the * complexity of the function free_list::_M_get. The part where * the bitmap headers are written has complexity: O(X),where X * is the number of blocks of size sizeof(value_type) within * the newly acquired block. Having a tight bound. */ void _S_refill_pool() _GLIBCXX_THROW(std::bad_alloc) { #if defined _GLIBCXX_DEBUG _S_check_for_free_blocks(); #endif const size_t __num_bitmaps = (_S_block_size / size_t(__detail::bits_per_block)); const size_t __size_to_allocate = sizeof(size_t) + _S_block_size * sizeof(_Alloc_block) + __num_bitmaps * sizeof(size_t); size_t* __temp = reinterpret_cast<size_t*>(this->_M_get(__size_to_allocate)); *__temp = 0; ++__temp; // The Header information goes at the Beginning of the Block. _Block_pair __bp = std::make_pair(reinterpret_cast<_Alloc_block*> (__temp + __num_bitmaps), reinterpret_cast<_Alloc_block*> (__temp + __num_bitmaps) + _S_block_size - 1); // Fill the Vector with this information. _S_mem_blocks.push_back(__bp); for (size_t __i = 0; __i < __num_bitmaps; ++__i) __temp[__i] = ~static_cast<size_t>(0); // 1 Indicates all Free. _S_block_size *= 2; } static _BPVector _S_mem_blocks; static size_t _S_block_size; static __detail::_Bitmap_counter<_Alloc_block*> _S_last_request; static typename _BPVector::size_type _S_last_dealloc_index; #if defined __GTHREADS static __mutex_type _S_mut; #endif public: /** @brief Allocates memory for a single object of size * sizeof(_Tp). * * @throw std::bad_alloc. If memory can not be allocated. * * Complexity: Worst case complexity is O(N), but that * is hardly ever hit. If and when this particular case is * encountered, the next few cases are guaranteed to have a * worst case complexity of O(1)! That's why this function * performs very well on average. You can consider this * function to have a complexity referred to commonly as: * Amortized Constant time. */ pointer _M_allocate_single_object() _GLIBCXX_THROW(std::bad_alloc) { #if defined __GTHREADS __scoped_lock __bit_lock(_S_mut); #endif // The algorithm is something like this: The last_request // variable points to the last accessed Bit Map. When such a // condition occurs, we try to find a free block in the // current bitmap, or succeeding bitmaps until the last bitmap // is reached. If no free block turns up, we resort to First // Fit method. // WARNING: Do not re-order the condition in the while // statement below, because it relies on C++'s short-circuit // evaluation. The return from _S_last_request->_M_get() will // NOT be dereference able if _S_last_request->_M_finished() // returns true. This would inevitably lead to a NULL pointer // dereference if tinkered with. while (_S_last_request._M_finished() == false && (*(_S_last_request._M_get()) == 0)) _S_last_request.operator++(); if (__builtin_expect(_S_last_request._M_finished() == true, false)) { // Fall Back to First Fit algorithm. typedef typename __detail::_Ffit_finder<_Alloc_block*> _FFF; _FFF __fff; _BPiter __bpi = _S_find(__detail::_Functor_Ref<_FFF>(__fff)); if (__bpi != _S_mem_blocks.end()) { // Search was successful. Ok, now mark the first bit from // the right as 0, meaning Allocated. This bit is obtained // by calling _M_get() on __fff. size_t __nz_bit = _Bit_scan_forward(*__fff._M_get()); __detail::__bit_allocate(__fff._M_get(), __nz_bit); _S_last_request._M_reset(__bpi - _S_mem_blocks.begin()); // Now, get the address of the bit we marked as allocated. pointer __ret = reinterpret_cast<pointer> (__bpi->first + __fff._M_offset() + __nz_bit); size_t* __puse_count = reinterpret_cast<size_t*> (__bpi->first) - (__detail::__num_bitmaps(*__bpi) + 1); ++(*__puse_count); return __ret; } else { // Search was unsuccessful. We Add more memory to the // pool by calling _S_refill_pool(). _S_refill_pool(); // _M_Reset the _S_last_request structure to the first // free block's bit map. _S_last_request._M_reset(_S_mem_blocks.size() - 1); // Now, mark that bit as allocated. } } // _S_last_request holds a pointer to a valid bit map, that // points to a free block in memory. size_t __nz_bit = _Bit_scan_forward(*_S_last_request._M_get()); __detail::__bit_allocate(_S_last_request._M_get(), __nz_bit); pointer __ret = reinterpret_cast<pointer> (_S_last_request._M_base() + _S_last_request._M_offset() + __nz_bit); size_t* __puse_count = reinterpret_cast<size_t*> (_S_mem_blocks[_S_last_request._M_where()].first) - (__detail:: __num_bitmaps(_S_mem_blocks[_S_last_request._M_where()]) + 1); ++(*__puse_count); return __ret; } /** @brief Deallocates memory that belongs to a single object of * size sizeof(_Tp). * * Complexity: O(lg(N)), but the worst case is not hit * often! This is because containers usually deallocate memory * close to each other and this case is handled in O(1) time by * the deallocate function. */ void _M_deallocate_single_object(pointer __p) throw() { #if defined __GTHREADS __scoped_lock __bit_lock(_S_mut); #endif _Alloc_block* __real_p = reinterpret_cast<_Alloc_block*>(__p); typedef typename _BPVector::iterator _Iterator; typedef typename _BPVector::difference_type _Difference_type; _Difference_type __diff; long __displacement; _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0); __detail::_Inclusive_between<_Alloc_block*> __ibt(__real_p); if (__ibt(_S_mem_blocks[_S_last_dealloc_index])) { _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index <= _S_mem_blocks.size() - 1); // Initial Assumption was correct! __diff = _S_last_dealloc_index; __displacement = __real_p - _S_mem_blocks[__diff].first; } else { _Iterator _iter = _S_find(__ibt); _GLIBCXX_DEBUG_ASSERT(_iter != _S_mem_blocks.end()); __diff = _iter - _S_mem_blocks.begin(); __displacement = __real_p - _S_mem_blocks[__diff].first; _S_last_dealloc_index = __diff; } // Get the position of the iterator that has been found. const size_t __rotate = (__displacement % size_t(__detail::bits_per_block)); size_t* __bitmapC = reinterpret_cast<size_t*> (_S_mem_blocks[__diff].first) - 1; __bitmapC -= (__displacement / size_t(__detail::bits_per_block)); __detail::__bit_free(__bitmapC, __rotate); size_t* __puse_count = reinterpret_cast<size_t*> (_S_mem_blocks[__diff].first) - (__detail::__num_bitmaps(_S_mem_blocks[__diff]) + 1); _GLIBCXX_DEBUG_ASSERT(*__puse_count != 0); --(*__puse_count); if (__builtin_expect(*__puse_count == 0, false)) { _S_block_size /= 2; // We can safely remove this block. // _Block_pair __bp = _S_mem_blocks[__diff]; this->_M_insert(__puse_count); _S_mem_blocks.erase(_S_mem_blocks.begin() + __diff); // Reset the _S_last_request variable to reflect the // erased block. We do this to protect future requests // after the last block has been removed from a particular // memory Chunk, which in turn has been returned to the // free list, and hence had been erased from the vector, // so the size of the vector gets reduced by 1. if ((_Difference_type)_S_last_request._M_where() >= __diff--) _S_last_request._M_reset(__diff); // If the Index into the vector of the region of memory // that might hold the next address that will be passed to // deallocated may have been invalidated due to the above // erase procedure being called on the vector, hence we // try to restore this invariant too. if (_S_last_dealloc_index >= _S_mem_blocks.size()) { _S_last_dealloc_index =(__diff != -1 ? __diff : 0); _GLIBCXX_DEBUG_ASSERT(_S_last_dealloc_index >= 0); } } } public: bitmap_allocator() _GLIBCXX_USE_NOEXCEPT { } bitmap_allocator(const bitmap_allocator&) _GLIBCXX_USE_NOEXCEPT { } template<typename _Tp1> bitmap_allocator(const bitmap_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } ~bitmap_allocator() _GLIBCXX_USE_NOEXCEPT { } pointer allocate(size_type __n) { if (__n > this->max_size()) std::__throw_bad_alloc(); #if __cpp_aligned_new if (alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { const size_type __b = __n * sizeof(value_type); std::align_val_t __al = std::align_val_t(alignof(value_type)); return static_cast<pointer>(::operator new(__b, __al)); } #endif if (__builtin_expect(__n == 1, true)) return this->_M_allocate_single_object(); else { const size_type __b = __n * sizeof(value_type); return reinterpret_cast<pointer>(::operator new(__b)); } } pointer allocate(size_type __n, typename bitmap_allocator<void>::const_pointer) { return allocate(__n); } void deallocate(pointer __p, size_type __n) throw() { if (__builtin_expect(__p != 0, true)) { #if __cpp_aligned_new // Types with extended alignment are handled by operator delete. if (alignof(value_type) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { ::operator delete(__p, std::align_val_t(alignof(value_type))); return; } #endif if (__builtin_expect(__n == 1, true)) this->_M_deallocate_single_object(__p); else ::operator delete(__p); } } pointer address(reference __r) const _GLIBCXX_NOEXCEPT { return std::__addressof(__r); } const_pointer address(const_reference __r) const _GLIBCXX_NOEXCEPT { return std::__addressof(__r); } size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return size_type(-1) / sizeof(value_type); } #if __cplusplus >= 201103L template<typename _Up, typename... _Args> void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template<typename _Up> void destroy(_Up* __p) { __p->~_Up(); } #else void construct(pointer __p, const_reference __data) { ::new((void *)__p) value_type(__data); } void destroy(pointer __p) { __p->~value_type(); } #endif }; template<typename _Tp1, typename _Tp2> bool operator==(const bitmap_allocator<_Tp1>&, const bitmap_allocator<_Tp2>&) throw() { return true; } template<typename _Tp1, typename _Tp2> bool operator!=(const bitmap_allocator<_Tp1>&, const bitmap_allocator<_Tp2>&) throw() { return false; } // Static member definitions. template<typename _Tp> typename bitmap_allocator<_Tp>::_BPVector bitmap_allocator<_Tp>::_S_mem_blocks; template<typename _Tp> size_t bitmap_allocator<_Tp>::_S_block_size = 2 * size_t(__detail::bits_per_block); template<typename _Tp> typename bitmap_allocator<_Tp>::_BPVector::size_type bitmap_allocator<_Tp>::_S_last_dealloc_index = 0; template<typename _Tp> __detail::_Bitmap_counter <typename bitmap_allocator<_Tp>::_Alloc_block*> bitmap_allocator<_Tp>::_S_last_request(_S_mem_blocks); #if defined __GTHREADS template<typename _Tp> typename bitmap_allocator<_Tp>::__mutex_type bitmap_allocator<_Tp>::_S_mut; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #endif c++/8/ext/stdio_sync_filebuf.h 0000644 00000021116 15146341150 0012107 0 ustar 00 // Iostreams wrapper for stdio FILE* -*- C++ -*- // Copyright (C) 2003-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/stdio_sync_filebuf.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _STDIO_SYNC_FILEBUF_H #define _STDIO_SYNC_FILEBUF_H 1 #pragma GCC system_header #include <streambuf> #include <unistd.h> #include <cstdio> #include <bits/c++io.h> // For __c_file #include <bits/move.h> // For __exchange #ifdef _GLIBCXX_USE_WCHAR_T #include <cwchar> #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Provides a layer of compatibility for C. * @ingroup io * * This GNU extension provides extensions for working with standard * C FILE*'s. It must be instantiated by the user with the type of * character used in the file stream, e.g., stdio_filebuf<char>. */ template<typename _CharT, typename _Traits = std::char_traits<_CharT> > class stdio_sync_filebuf : public std::basic_streambuf<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; private: typedef std::basic_streambuf<_CharT, _Traits> __streambuf_type; // Underlying stdio FILE std::__c_file* _M_file; // Last character gotten. This is used when pbackfail is // called from basic_streambuf::sungetc() int_type _M_unget_buf; public: explicit stdio_sync_filebuf(std::__c_file* __f) : _M_file(__f), _M_unget_buf(traits_type::eof()) { } #if __cplusplus >= 201103L stdio_sync_filebuf(stdio_sync_filebuf&& __fb) noexcept : __streambuf_type(std::move(__fb)), _M_file(__fb._M_file), _M_unget_buf(__fb._M_unget_buf) { __fb._M_file = nullptr; __fb._M_unget_buf = traits_type::eof(); } stdio_sync_filebuf& operator=(stdio_sync_filebuf&& __fb) noexcept { __streambuf_type::operator=(__fb); _M_file = std::__exchange(__fb._M_file, nullptr); _M_unget_buf = std::__exchange(__fb._M_unget_buf, traits_type::eof()); return *this; } void swap(stdio_sync_filebuf& __fb) { __streambuf_type::swap(__fb); std::swap(_M_file, __fb._M_file); std::swap(_M_unget_buf, __fb._M_unget_buf); } #endif /** * @return The underlying FILE*. * * This function can be used to access the underlying C file pointer. * Note that there is no way for the library to track what you do * with the file, so be careful. */ std::__c_file* file() { return this->_M_file; } protected: int_type syncgetc(); int_type syncungetc(int_type __c); int_type syncputc(int_type __c); virtual int_type underflow() { int_type __c = this->syncgetc(); return this->syncungetc(__c); } virtual int_type uflow() { // Store the gotten character in case we need to unget it. _M_unget_buf = this->syncgetc(); return _M_unget_buf; } virtual int_type pbackfail(int_type __c = traits_type::eof()) { int_type __ret; const int_type __eof = traits_type::eof(); // Check if the unget or putback was requested if (traits_type::eq_int_type(__c, __eof)) // unget { if (!traits_type::eq_int_type(_M_unget_buf, __eof)) __ret = this->syncungetc(_M_unget_buf); else // buffer invalid, fail. __ret = __eof; } else // putback __ret = this->syncungetc(__c); // The buffered character is no longer valid, discard it. _M_unget_buf = __eof; return __ret; } virtual std::streamsize xsgetn(char_type* __s, std::streamsize __n); virtual int_type overflow(int_type __c = traits_type::eof()) { int_type __ret; if (traits_type::eq_int_type(__c, traits_type::eof())) { if (std::fflush(_M_file)) __ret = traits_type::eof(); else __ret = traits_type::not_eof(__c); } else __ret = this->syncputc(__c); return __ret; } virtual std::streamsize xsputn(const char_type* __s, std::streamsize __n); virtual int sync() { return std::fflush(_M_file); } virtual std::streampos seekoff(std::streamoff __off, std::ios_base::seekdir __dir, std::ios_base::openmode = std::ios_base::in | std::ios_base::out) { std::streampos __ret(std::streamoff(-1)); int __whence; if (__dir == std::ios_base::beg) __whence = SEEK_SET; else if (__dir == std::ios_base::cur) __whence = SEEK_CUR; else __whence = SEEK_END; #ifdef _GLIBCXX_USE_LFS if (!fseeko64(_M_file, __off, __whence)) __ret = std::streampos(ftello64(_M_file)); #else if (!fseek(_M_file, __off, __whence)) __ret = std::streampos(std::ftell(_M_file)); #endif return __ret; } virtual std::streampos seekpos(std::streampos __pos, std::ios_base::openmode __mode = std::ios_base::in | std::ios_base::out) { return seekoff(std::streamoff(__pos), std::ios_base::beg, __mode); } }; template<> inline stdio_sync_filebuf<char>::int_type stdio_sync_filebuf<char>::syncgetc() { return std::getc(_M_file); } template<> inline stdio_sync_filebuf<char>::int_type stdio_sync_filebuf<char>::syncungetc(int_type __c) { return std::ungetc(__c, _M_file); } template<> inline stdio_sync_filebuf<char>::int_type stdio_sync_filebuf<char>::syncputc(int_type __c) { return std::putc(__c, _M_file); } template<> inline std::streamsize stdio_sync_filebuf<char>::xsgetn(char* __s, std::streamsize __n) { std::streamsize __ret = std::fread(__s, 1, __n, _M_file); if (__ret > 0) _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); else _M_unget_buf = traits_type::eof(); return __ret; } template<> inline std::streamsize stdio_sync_filebuf<char>::xsputn(const char* __s, std::streamsize __n) { return std::fwrite(__s, 1, __n, _M_file); } #ifdef _GLIBCXX_USE_WCHAR_T template<> inline stdio_sync_filebuf<wchar_t>::int_type stdio_sync_filebuf<wchar_t>::syncgetc() { return std::getwc(_M_file); } template<> inline stdio_sync_filebuf<wchar_t>::int_type stdio_sync_filebuf<wchar_t>::syncungetc(int_type __c) { return std::ungetwc(__c, _M_file); } template<> inline stdio_sync_filebuf<wchar_t>::int_type stdio_sync_filebuf<wchar_t>::syncputc(int_type __c) { return std::putwc(__c, _M_file); } template<> inline std::streamsize stdio_sync_filebuf<wchar_t>::xsgetn(wchar_t* __s, std::streamsize __n) { std::streamsize __ret = 0; const int_type __eof = traits_type::eof(); while (__n--) { int_type __c = this->syncgetc(); if (traits_type::eq_int_type(__c, __eof)) break; __s[__ret] = traits_type::to_char_type(__c); ++__ret; } if (__ret > 0) _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]); else _M_unget_buf = traits_type::eof(); return __ret; } template<> inline std::streamsize stdio_sync_filebuf<wchar_t>::xsputn(const wchar_t* __s, std::streamsize __n) { std::streamsize __ret = 0; const int_type __eof = traits_type::eof(); while (__n--) { if (traits_type::eq_int_type(this->syncputc(*__s++), __eof)) break; ++__ret; } return __ret; } #endif #if _GLIBCXX_EXTERN_TEMPLATE extern template class stdio_sync_filebuf<char>; #ifdef _GLIBCXX_USE_WCHAR_T extern template class stdio_sync_filebuf<wchar_t>; #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/memory 0000644 00000015764 15146341150 0007333 0 ustar 00 // Memory extensions -*- C++ -*- // Copyright (C) 2002-2018 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 * 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 ext/memory * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_MEMORY #define _EXT_MEMORY 1 #pragma GCC system_header #include <memory> #include <bits/stl_tempbuf.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::ptrdiff_t; using std::pair; using std::__iterator_category; using std::_Temporary_buffer; template<typename _InputIter, typename _Size, typename _ForwardIter> pair<_InputIter, _ForwardIter> __uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result, std::input_iterator_tag) { _ForwardIter __cur = __result; __try { for (; __count > 0 ; --__count, ++__first, ++__cur) std::_Construct(&*__cur, *__first); return pair<_InputIter, _ForwardIter>(__first, __cur); } __catch(...) { std::_Destroy(__result, __cur); __throw_exception_again; } } template<typename _RandomAccessIter, typename _Size, typename _ForwardIter> inline pair<_RandomAccessIter, _ForwardIter> __uninitialized_copy_n(_RandomAccessIter __first, _Size __count, _ForwardIter __result, std::random_access_iterator_tag) { _RandomAccessIter __last = __first + __count; return (pair<_RandomAccessIter, _ForwardIter> (__last, std::uninitialized_copy(__first, __last, __result))); } template<typename _InputIter, typename _Size, typename _ForwardIter> inline pair<_InputIter, _ForwardIter> __uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result) { return __gnu_cxx::__uninitialized_copy_n(__first, __count, __result, __iterator_category(__first)); } /** * @brief Copies the range [first,last) into result. * @param __first An input iterator. * @param __count Length * @param __result An output iterator. * @return __result + (__first + __count) * @ingroup SGIextensions * * Like copy(), but does not require an initialized output range. */ template<typename _InputIter, typename _Size, typename _ForwardIter> inline pair<_InputIter, _ForwardIter> uninitialized_copy_n(_InputIter __first, _Size __count, _ForwardIter __result) { return __gnu_cxx::__uninitialized_copy_n(__first, __count, __result, __iterator_category(__first)); } // An alternative version of uninitialized_copy_n that constructs // and destroys objects with a user-provided allocator. template<typename _InputIter, typename _Size, typename _ForwardIter, typename _Allocator> pair<_InputIter, _ForwardIter> __uninitialized_copy_n_a(_InputIter __first, _Size __count, _ForwardIter __result, _Allocator __alloc) { _ForwardIter __cur = __result; __try { for (; __count > 0 ; --__count, ++__first, ++__cur) __alloc.construct(&*__cur, *__first); return pair<_InputIter, _ForwardIter>(__first, __cur); } __catch(...) { std::_Destroy(__result, __cur, __alloc); __throw_exception_again; } } template<typename _InputIter, typename _Size, typename _ForwardIter, typename _Tp> inline pair<_InputIter, _ForwardIter> __uninitialized_copy_n_a(_InputIter __first, _Size __count, _ForwardIter __result, std::allocator<_Tp>) { return __gnu_cxx::uninitialized_copy_n(__first, __count, __result); } /** * This class provides similar behavior and semantics of the standard * functions get_temporary_buffer() and return_temporary_buffer(), but * encapsulated in a type vaguely resembling a standard container. * * By default, a temporary_buffer<Iter> stores space for objects of * whatever type the Iter iterator points to. It is constructed from a * typical [first,last) range, and provides the begin(), end(), size() * functions, as well as requested_size(). For non-trivial types, copies * of *first will be used to initialize the storage. * * @c malloc is used to obtain underlying storage. * * Like get_temporary_buffer(), not all the requested memory may be * available. Ideally, the created buffer will be large enough to hold a * copy of [first,last), but if size() is less than requested_size(), * then this didn't happen. * * @ingroup SGIextensions */ template <class _ForwardIterator, class _Tp = typename std::iterator_traits<_ForwardIterator>::value_type > struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> { /// Requests storage large enough to hold a copy of [first,last). temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) { } /// Destroys objects and frees storage. ~temporary_buffer() { } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/string_conversions.h 0000644 00000007015 15146341150 0012175 0 ustar 00 // String Conversions -*- C++ -*- // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/string_conversions.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _STRING_CONVERSIONS_H #define _STRING_CONVERSIONS_H 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <bits/c++config.h> #include <ext/numeric_traits.h> #include <bits/functexcept.h> #include <cstdlib> #include <cwchar> #include <cstdio> #include <cerrno> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Helper for all the sto* functions. template<typename _TRet, typename _Ret = _TRet, typename _CharT, typename... _Base> _Ret __stoa(_TRet (*__convf) (const _CharT*, _CharT**, _Base...), const char* __name, const _CharT* __str, std::size_t* __idx, _Base... __base) { _Ret __ret; _CharT* __endptr; struct _Save_errno { _Save_errno() : _M_errno(errno) { errno = 0; } ~_Save_errno() { if (errno == 0) errno = _M_errno; } int _M_errno; } const __save_errno; struct _Range_chk { static bool _S_chk(_TRet, std::false_type) { return false; } static bool _S_chk(_TRet __val, std::true_type) // only called when _Ret is int { return __val < _TRet(__numeric_traits<int>::__min) || __val > _TRet(__numeric_traits<int>::__max); } }; const _TRet __tmp = __convf(__str, &__endptr, __base...); if (__endptr == __str) std::__throw_invalid_argument(__name); else if (errno == ERANGE || _Range_chk::_S_chk(__tmp, std::is_same<_Ret, int>{})) std::__throw_out_of_range(__name); else __ret = __tmp; if (__idx) *__idx = __endptr - __str; return __ret; } // Helper for the to_string / to_wstring functions. template<typename _String, typename _CharT = typename _String::value_type> _String __to_xstring(int (*__convf) (_CharT*, std::size_t, const _CharT*, __builtin_va_list), std::size_t __n, const _CharT* __fmt, ...) { // XXX Eventually the result should be constructed in-place in // the __cxx11 string, likely with the help of internal hooks. _CharT* __s = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __n)); __builtin_va_list __args; __builtin_va_start(__args, __fmt); const int __len = __convf(__s, __n, __fmt, __args); __builtin_va_end(__args); return _String(__s, __s + __len); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _STRING_CONVERSIONS_H c++/8/ext/pb_ds/detail/pat_trie_/pat_trie_base.hpp 0000644 00000111401 15146341150 0015672 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/pat_trie_base.hpp * Contains the base class for a patricia tree. */ #ifndef PB_DS_PAT_TRIE_BASE #define PB_DS_PAT_TRIE_BASE #include <debug/debug.h> namespace __gnu_pbds { namespace detail { /// Base type for PATRICIA trees. struct pat_trie_base { /** * @brief Three types of nodes. * * i_node is used by _Inode, leaf_node by _Leaf, and head_node by _Head. */ enum node_type { i_node, leaf_node, head_node }; /// Metadata base primary template. template<typename Metadata, typename _Alloc> struct _Metadata { typedef Metadata metadata_type; typedef _Alloc allocator_type; typedef typename _Alloc::template rebind<Metadata> __rebind_m; typedef typename __rebind_m::other::const_reference const_reference; const_reference get_metadata() const { return m_metadata; } metadata_type m_metadata; }; /// Specialization for null metadata. template<typename _Alloc> struct _Metadata<null_type, _Alloc> { typedef null_type metadata_type; typedef _Alloc allocator_type; }; /// Node base. template<typename _ATraits, typename Metadata> struct _Node_base : public Metadata { private: typedef typename Metadata::allocator_type _Alloc; public: typedef _Alloc allocator_type; typedef _ATraits access_traits; typedef typename _ATraits::type_traits type_traits; typedef typename _Alloc::template rebind<_Node_base> __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; node_pointer m_p_parent; const node_type m_type; _Node_base(node_type type) : m_type(type) { } typedef typename _Alloc::template rebind<_ATraits> __rebind_at; typedef typename __rebind_at::other::const_pointer a_const_pointer; typedef typename _ATraits::const_iterator a_const_iterator; #ifdef _GLIBCXX_DEBUG typedef std::pair<a_const_iterator, a_const_iterator> node_debug_info; void assert_valid(a_const_pointer p_traits, const char* __file, int __line) const { assert_valid_imp(p_traits, __file, __line); } virtual node_debug_info assert_valid_imp(a_const_pointer, const char*, int) const = 0; #endif }; /// Head node for PATRICIA tree. template<typename _ATraits, typename Metadata> struct _Head : public _Node_base<_ATraits, Metadata> { typedef _Node_base<_ATraits, Metadata> base_type; typedef typename base_type::type_traits type_traits; typedef typename base_type::node_pointer node_pointer; node_pointer m_p_min; node_pointer m_p_max; _Head() : base_type(head_node) { } #ifdef _GLIBCXX_DEBUG typedef typename base_type::node_debug_info node_debug_info; typedef typename base_type::a_const_pointer a_const_pointer; virtual node_debug_info assert_valid_imp(a_const_pointer, const char* __file, int __line) const { _GLIBCXX_DEBUG_VERIFY_AT(false, _M_message("Assertion from %1;:%2;") ._M_string(__FILE__)._M_integer(__LINE__), __file, __line); return node_debug_info(); } #endif }; /// Leaf node for PATRICIA tree. template<typename _ATraits, typename Metadata> struct _Leaf : public _Node_base<_ATraits, Metadata> { typedef _Node_base<_ATraits, Metadata> base_type; typedef typename base_type::type_traits type_traits; typedef typename type_traits::value_type value_type; typedef typename type_traits::reference reference; typedef typename type_traits::const_reference const_reference; private: value_type m_value; _Leaf(const _Leaf&); public: _Leaf(const_reference other) : base_type(leaf_node), m_value(other) { } reference value() { return m_value; } const_reference value() const { return m_value; } #ifdef _GLIBCXX_DEBUG typedef typename base_type::node_debug_info node_debug_info; typedef typename base_type::a_const_pointer a_const_pointer; virtual node_debug_info assert_valid_imp(a_const_pointer p_traits, const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(base_type::m_type == leaf_node); node_debug_info ret; const_reference r_val = value(); return std::make_pair(p_traits->begin(p_traits->extract_key(r_val)), p_traits->end(p_traits->extract_key(r_val))); } virtual ~_Leaf() { } #endif }; /// Internal node type, PATRICIA tree. template<typename _ATraits, typename Metadata> struct _Inode : public _Node_base<_ATraits, Metadata> { typedef _Node_base<_ATraits, Metadata> base_type; typedef typename base_type::type_traits type_traits; typedef typename base_type::access_traits access_traits; typedef typename type_traits::value_type value_type; typedef typename base_type::allocator_type _Alloc; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; private: typedef typename base_type::a_const_pointer a_const_pointer; typedef typename base_type::a_const_iterator a_const_iterator; typedef typename base_type::node_pointer node_pointer; typedef typename _Alloc::template rebind<base_type> __rebind_n; typedef typename __rebind_n::other::const_pointer node_const_pointer; typedef _Leaf<_ATraits, Metadata> leaf; typedef typename _Alloc::template rebind<leaf>::other __rebind_l; typedef typename __rebind_l::pointer leaf_pointer; typedef typename __rebind_l::const_pointer leaf_const_pointer; typedef typename _Alloc::template rebind<_Inode>::other __rebind_in; typedef typename __rebind_in::pointer inode_pointer; typedef typename __rebind_in::const_pointer inode_const_pointer; inline size_type get_pref_pos(a_const_iterator, a_const_iterator, a_const_pointer) const; public: typedef typename _Alloc::template rebind<node_pointer>::other __rebind_np; typedef typename __rebind_np::pointer node_pointer_pointer; typedef typename __rebind_np::reference node_pointer_reference; enum { arr_size = _ATraits::max_size + 1 }; PB_DS_STATIC_ASSERT(min_arr_size, arr_size >= 2); /// Constant child iterator. struct const_iterator { node_pointer_pointer m_p_p_cur; node_pointer_pointer m_p_p_end; typedef std::forward_iterator_tag iterator_category; typedef typename _Alloc::difference_type difference_type; typedef node_pointer value_type; typedef node_pointer_pointer pointer; typedef node_pointer_reference reference; const_iterator(node_pointer_pointer p_p_cur = 0, node_pointer_pointer p_p_end = 0) : m_p_p_cur(p_p_cur), m_p_p_end(p_p_end) { } bool operator==(const const_iterator& other) const { return m_p_p_cur == other.m_p_p_cur; } bool operator!=(const const_iterator& other) const { return m_p_p_cur != other.m_p_p_cur; } const_iterator& operator++() { do ++m_p_p_cur; while (m_p_p_cur != m_p_p_end && *m_p_p_cur == 0); return *this; } const_iterator operator++(int) { const_iterator ret_it(*this); operator++(); return ret_it; } const node_pointer_pointer operator->() const { _GLIBCXX_DEBUG_ONLY(assert_referencible();) return m_p_p_cur; } node_const_pointer operator*() const { _GLIBCXX_DEBUG_ONLY(assert_referencible();) return *m_p_p_cur; } protected: #ifdef _GLIBCXX_DEBUG void assert_referencible() const { _GLIBCXX_DEBUG_ASSERT(m_p_p_cur != m_p_p_end && *m_p_p_cur != 0); } #endif }; /// Child iterator. struct iterator : public const_iterator { public: typedef std::forward_iterator_tag iterator_category; typedef typename _Alloc::difference_type difference_type; typedef node_pointer value_type; typedef node_pointer_pointer pointer; typedef node_pointer_reference reference; inline iterator(node_pointer_pointer p_p_cur = 0, node_pointer_pointer p_p_end = 0) : const_iterator(p_p_cur, p_p_end) { } bool operator==(const iterator& other) const { return const_iterator::m_p_p_cur == other.m_p_p_cur; } bool operator!=(const iterator& other) const { return const_iterator::m_p_p_cur != other.m_p_p_cur; } iterator& operator++() { const_iterator::operator++(); return *this; } iterator operator++(int) { iterator ret_it(*this); operator++(); return ret_it; } node_pointer_pointer operator->() { _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();) return const_iterator::m_p_p_cur; } node_pointer operator*() { _GLIBCXX_DEBUG_ONLY(const_iterator::assert_referencible();) return *const_iterator::m_p_p_cur; } }; _Inode(size_type, const a_const_iterator); void update_prefixes(a_const_pointer); const_iterator begin() const; iterator begin(); const_iterator end() const; iterator end(); inline node_pointer get_child_node(a_const_iterator, a_const_iterator, a_const_pointer); inline node_const_pointer get_child_node(a_const_iterator, a_const_iterator, a_const_pointer) const; inline iterator get_child_it(a_const_iterator, a_const_iterator, a_const_pointer); inline node_pointer get_lower_bound_child_node(a_const_iterator, a_const_iterator, size_type, a_const_pointer); inline node_pointer add_child(node_pointer, a_const_iterator, a_const_iterator, a_const_pointer); inline node_const_pointer get_join_child(node_const_pointer, a_const_pointer) const; inline node_pointer get_join_child(node_pointer, a_const_pointer); void remove_child(node_pointer); void remove_child(iterator); void replace_child(node_pointer, a_const_iterator, a_const_iterator, a_const_pointer); inline a_const_iterator pref_b_it() const; inline a_const_iterator pref_e_it() const; bool should_be_mine(a_const_iterator, a_const_iterator, size_type, a_const_pointer) const; leaf_pointer leftmost_descendant(); leaf_const_pointer leftmost_descendant() const; leaf_pointer rightmost_descendant(); leaf_const_pointer rightmost_descendant() const; #ifdef _GLIBCXX_DEBUG typedef typename base_type::node_debug_info node_debug_info; virtual node_debug_info assert_valid_imp(a_const_pointer, const char*, int) const; #endif size_type get_e_ind() const { return m_e_ind; } private: _Inode(const _Inode&); size_type get_begin_pos() const; static __rebind_l s_leaf_alloc; static __rebind_in s_inode_alloc; const size_type m_e_ind; a_const_iterator m_pref_b_it; a_const_iterator m_pref_e_it; node_pointer m_a_p_children[arr_size]; }; #define PB_DS_CONST_IT_C_DEC \ _CIter<Node, Leaf, Head, Inode, Is_Forward_Iterator> #define PB_DS_CONST_ODIR_IT_C_DEC \ _CIter<Node, Leaf, Head, Inode, !Is_Forward_Iterator> #define PB_DS_IT_C_DEC \ _Iter<Node, Leaf, Head, Inode, Is_Forward_Iterator> #define PB_DS_ODIR_IT_C_DEC \ _Iter<Node, Leaf, Head, Inode, !Is_Forward_Iterator> /// Const iterator. template<typename Node, typename Leaf, typename Head, typename Inode, bool Is_Forward_Iterator> class _CIter { public: // These types are all the same for the first four template arguments. typedef typename Node::allocator_type allocator_type; typedef typename Node::type_traits type_traits; typedef std::bidirectional_iterator_tag iterator_category; typedef typename allocator_type::difference_type difference_type; typedef typename type_traits::value_type value_type; typedef typename type_traits::pointer pointer; typedef typename type_traits::reference reference; typedef typename type_traits::const_pointer const_pointer; typedef typename type_traits::const_reference const_reference; typedef allocator_type _Alloc; typedef typename _Alloc::template rebind<Node> __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename _Alloc::template rebind<Leaf> __rebind_l; typedef typename __rebind_l::other::pointer leaf_pointer; typedef typename __rebind_l::other::const_pointer leaf_const_pointer; typedef typename _Alloc::template rebind<Head> __rebind_h; typedef typename __rebind_h::other::pointer head_pointer; typedef typename _Alloc::template rebind<Inode> __rebind_in; typedef typename __rebind_in::other::pointer inode_pointer; typedef typename Inode::iterator inode_iterator; node_pointer m_p_nd; _CIter(node_pointer p_nd = 0) : m_p_nd(p_nd) { } _CIter(const PB_DS_CONST_ODIR_IT_C_DEC& other) : m_p_nd(other.m_p_nd) { } _CIter& operator=(const _CIter& other) { m_p_nd = other.m_p_nd; return *this; } _CIter& operator=(const PB_DS_CONST_ODIR_IT_C_DEC& other) { m_p_nd = other.m_p_nd; return *this; } const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == leaf_node); return &static_cast<leaf_pointer>(m_p_nd)->value(); } const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == leaf_node); return static_cast<leaf_pointer>(m_p_nd)->value(); } bool operator==(const _CIter& other) const { return m_p_nd == other.m_p_nd; } bool operator==(const PB_DS_CONST_ODIR_IT_C_DEC& other) const { return m_p_nd == other.m_p_nd; } bool operator!=(const _CIter& other) const { return m_p_nd != other.m_p_nd; } bool operator!=(const PB_DS_CONST_ODIR_IT_C_DEC& other) const { return m_p_nd != other.m_p_nd; } _CIter& operator++() { inc(integral_constant<int, Is_Forward_Iterator>()); return *this; } _CIter operator++(int) { _CIter ret_it(m_p_nd); operator++(); return ret_it; } _CIter& operator--() { dec(integral_constant<int, Is_Forward_Iterator>()); return *this; } _CIter operator--(int) { _CIter ret_it(m_p_nd); operator--(); return ret_it; } protected: void inc(false_type) { dec(true_type()); } void inc(true_type) { if (m_p_nd->m_type == head_node) { m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_min; return; } node_pointer p_y = m_p_nd->m_p_parent; while (p_y->m_type != head_node && get_larger_sibling(m_p_nd) == 0) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (p_y->m_type == head_node) { m_p_nd = p_y; return; } m_p_nd = leftmost_descendant(get_larger_sibling(m_p_nd)); } void dec(false_type) { inc(true_type()); } void dec(true_type) { if (m_p_nd->m_type == head_node) { m_p_nd = static_cast<head_pointer>(m_p_nd)->m_p_max; return; } node_pointer p_y = m_p_nd->m_p_parent; while (p_y->m_type != head_node && get_smaller_sibling(m_p_nd) == 0) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (p_y->m_type == head_node) { m_p_nd = p_y; return; } m_p_nd = rightmost_descendant(get_smaller_sibling(m_p_nd)); } static node_pointer get_larger_sibling(node_pointer p_nd) { inode_pointer p_parent = static_cast<inode_pointer>(p_nd->m_p_parent); inode_iterator it = p_parent->begin(); while (*it != p_nd) ++it; inode_iterator next_it = it; ++next_it; return (next_it == p_parent->end())? 0 : *next_it; } static node_pointer get_smaller_sibling(node_pointer p_nd) { inode_pointer p_parent = static_cast<inode_pointer>(p_nd->m_p_parent); inode_iterator it = p_parent->begin(); if (*it == p_nd) return 0; inode_iterator prev_it; do { prev_it = it; ++it; if (*it == p_nd) return *prev_it; } while (true); _GLIBCXX_DEBUG_ASSERT(false); return 0; } static leaf_pointer leftmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast<leaf_pointer>(p_nd); return static_cast<inode_pointer>(p_nd)->leftmost_descendant(); } static leaf_pointer rightmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast<leaf_pointer>(p_nd); return static_cast<inode_pointer>(p_nd)->rightmost_descendant(); } }; /// Iterator. template<typename Node, typename Leaf, typename Head, typename Inode, bool Is_Forward_Iterator> class _Iter : public _CIter<Node, Leaf, Head, Inode, Is_Forward_Iterator> { public: typedef _CIter<Node, Leaf, Head, Inode, Is_Forward_Iterator> base_type; typedef typename base_type::allocator_type allocator_type; typedef typename base_type::type_traits type_traits; typedef typename type_traits::value_type value_type; typedef typename type_traits::pointer pointer; typedef typename type_traits::reference reference; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::leaf_pointer leaf_pointer; typedef typename base_type::leaf_const_pointer leaf_const_pointer; typedef typename base_type::head_pointer head_pointer; typedef typename base_type::inode_pointer inode_pointer; _Iter(node_pointer p_nd = 0) : base_type(p_nd) { } _Iter(const PB_DS_ODIR_IT_C_DEC& other) : base_type(other.m_p_nd) { } _Iter& operator=(const _Iter& other) { base_type::m_p_nd = other.m_p_nd; return *this; } _Iter& operator=(const PB_DS_ODIR_IT_C_DEC& other) { base_type::m_p_nd = other.m_p_nd; return *this; } pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == leaf_node); return &static_cast<leaf_pointer>(base_type::m_p_nd)->value(); } reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == leaf_node); return static_cast<leaf_pointer>(base_type::m_p_nd)->value(); } _Iter& operator++() { base_type::operator++(); return *this; } _Iter operator++(int) { _Iter ret(base_type::m_p_nd); operator++(); return ret; } _Iter& operator--() { base_type::operator--(); return *this; } _Iter operator--(int) { _Iter ret(base_type::m_p_nd); operator--(); return ret; } }; #undef PB_DS_CONST_ODIR_IT_C_DEC #undef PB_DS_ODIR_IT_C_DEC #define PB_DS_PAT_TRIE_NODE_CONST_ITERATOR_C_DEC \ _Node_citer<Node, Leaf, Head, Inode, _CIterator, Iterator, _ATraits, _Alloc> #define PB_DS_PAT_TRIE_NODE_ITERATOR_C_DEC \ _Node_iter<Node, Leaf, Head, Inode, _CIterator, Iterator, _ATraits, _Alloc> /// Node const iterator. template<typename Node, typename Leaf, typename Head, typename Inode, typename _CIterator, typename Iterator, typename _Alloc> class _Node_citer { protected: typedef typename _Alloc::template rebind<Node> __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename _Alloc::template rebind<Leaf> __rebind_l; typedef typename __rebind_l::other::pointer leaf_pointer; typedef typename __rebind_l::other::const_pointer leaf_const_pointer; typedef typename _Alloc::template rebind<Inode> __rebind_in; typedef typename __rebind_in::other::pointer inode_pointer; typedef typename __rebind_in::other::const_pointer inode_const_pointer; typedef typename Node::a_const_pointer a_const_pointer; typedef typename Node::a_const_iterator a_const_iterator; private: a_const_iterator pref_begin() const { if (m_p_nd->m_type == leaf_node) { leaf_const_pointer lcp = static_cast<leaf_const_pointer>(m_p_nd); return m_p_traits->begin(m_p_traits->extract_key(lcp->value())); } _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); return static_cast<inode_const_pointer>(m_p_nd)->pref_b_it(); } a_const_iterator pref_end() const { if (m_p_nd->m_type == leaf_node) { leaf_const_pointer lcp = static_cast<leaf_const_pointer>(m_p_nd); return m_p_traits->end(m_p_traits->extract_key(lcp->value())); } _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); return static_cast<inode_const_pointer>(m_p_nd)->pref_e_it(); } public: typedef trivial_iterator_tag iterator_category; typedef trivial_iterator_difference_type difference_type; typedef typename _Alloc::size_type size_type; typedef _CIterator value_type; typedef value_type reference; typedef value_type const_reference; /// Metadata type. typedef typename Node::metadata_type metadata_type; /// Const metadata reference type. typedef typename _Alloc::template rebind<metadata_type> __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename __rebind_ma::const_reference metadata_const_reference; inline _Node_citer(node_pointer p_nd = 0, a_const_pointer p_traits = 0) : m_p_nd(const_cast<node_pointer>(p_nd)), m_p_traits(p_traits) { } /// Subtree valid prefix. std::pair<a_const_iterator, a_const_iterator> valid_prefix() const { return std::make_pair(pref_begin(), pref_end()); } /// Const access; returns the __const iterator* associated with /// the current leaf. const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(num_children() == 0); return _CIterator(m_p_nd); } /// Metadata access. metadata_const_reference get_metadata() const { return m_p_nd->get_metadata(); } /// Returns the number of children in the corresponding node. size_type num_children() const { if (m_p_nd->m_type == leaf_node) return 0; _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); inode_pointer inp = static_cast<inode_pointer>(m_p_nd); return std::distance(inp->begin(), inp->end()); } /// Returns a __const node __iterator to the corresponding node's /// i-th child. _Node_citer get_child(size_type i) const { _GLIBCXX_DEBUG_ASSERT(m_p_nd->m_type == i_node); inode_pointer inp = static_cast<inode_pointer>(m_p_nd); typename Inode::iterator it = inp->begin(); std::advance(it, i); return _Node_citer(*it, m_p_traits); } /// Compares content to a different iterator object. bool operator==(const _Node_citer& other) const { return m_p_nd == other.m_p_nd; } /// Compares content (negatively) to a different iterator object. bool operator!=(const _Node_citer& other) const { return m_p_nd != other.m_p_nd; } node_pointer m_p_nd; a_const_pointer m_p_traits; }; /// Node iterator. template<typename Node, typename Leaf, typename Head, typename Inode, typename _CIterator, typename Iterator, typename _Alloc> class _Node_iter : public _Node_citer<Node, Leaf, Head, Inode, _CIterator, Iterator, _Alloc> { private: typedef _Node_citer<Node, Leaf, Head, Inode, _CIterator, Iterator, _Alloc> base_type; typedef typename _Alloc::template rebind<Node> __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename base_type::inode_pointer inode_pointer; typedef typename base_type::a_const_pointer a_const_pointer; typedef Iterator iterator; public: typedef typename base_type::size_type size_type; typedef Iterator value_type; typedef value_type reference; typedef value_type const_reference; _Node_iter(node_pointer p_nd = 0, a_const_pointer p_traits = 0) : base_type(p_nd, p_traits) { } /// Access; returns the iterator* associated with the current leaf. reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_type::num_children() == 0); return iterator(base_type::m_p_nd); } /// Returns a node __iterator to the corresponding node's i-th child. _Node_iter get_child(size_type i) const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd->m_type == i_node); typename Inode::iterator it = static_cast<inode_pointer>(base_type::m_p_nd)->begin(); std::advance(it, i); return _Node_iter(*it, base_type::m_p_traits); } }; }; #define PB_DS_CLASS_T_DEC \ template<typename _ATraits, typename Metadata> #define PB_DS_CLASS_C_DEC \ pat_trie_base::_Inode<_ATraits, Metadata> PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::__rebind_l PB_DS_CLASS_C_DEC::s_leaf_alloc; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::__rebind_in PB_DS_CLASS_C_DEC::s_inode_alloc; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_pref_pos(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) const { if (static_cast<std::size_t>(std::distance(b_it, e_it)) <= m_e_ind) return 0; std::advance(b_it, m_e_ind); return 1 + p_traits->e_pos(*b_it); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: _Inode(size_type len, const a_const_iterator it) : base_type(i_node), m_e_ind(len), m_pref_b_it(it), m_pref_e_it(it) { std::advance(m_pref_e_it, m_e_ind); std::fill(m_a_p_children, m_a_p_children + arr_size, static_cast<node_pointer>(0)); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: update_prefixes(a_const_pointer p_traits) { node_pointer p_first = *begin(); if (p_first->m_type == leaf_node) { leaf_const_pointer p = static_cast<leaf_const_pointer>(p_first); m_pref_b_it = p_traits->begin(access_traits::extract_key(p->value())); } else { inode_pointer p = static_cast<inode_pointer>(p_first); _GLIBCXX_DEBUG_ASSERT(p_first->m_type == i_node); m_pref_b_it = p->pref_b_it(); } m_pref_e_it = m_pref_b_it; std::advance(m_pref_e_it, m_e_ind); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { typedef node_pointer_pointer pointer_type; pointer_type p = const_cast<pointer_type>(m_a_p_children); return const_iterator(p + get_begin_pos(), p + arr_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return iterator(m_a_p_children + get_begin_pos(), m_a_p_children + arr_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { typedef node_pointer_pointer pointer_type; pointer_type p = const_cast<pointer_type>(m_a_p_children) + arr_size; return const_iterator(p, p); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(m_a_p_children + arr_size, m_a_p_children + arr_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_child_node(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); return m_a_p_children[i]; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: get_child_it(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); _GLIBCXX_DEBUG_ASSERT(m_a_p_children[i] != 0); return iterator(m_a_p_children + i, m_a_p_children + i); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: get_child_node(a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) const { return const_cast<node_pointer>(get_child_node(b_it, e_it, p_traits)); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_lower_bound_child_node(a_const_iterator b_it, a_const_iterator e_it, size_type checked_ind, a_const_pointer p_traits) { if (!should_be_mine(b_it, e_it, checked_ind, p_traits)) { if (p_traits->cmp_prefixes(b_it, e_it, m_pref_b_it, m_pref_e_it, true)) return leftmost_descendant(); return rightmost_descendant(); } size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); if (m_a_p_children[i] != 0) return m_a_p_children[i]; while (++i < arr_size) if (m_a_p_children[i] != 0) { const node_type& __nt = m_a_p_children[i]->m_type; node_pointer ret = m_a_p_children[i]; if (__nt == leaf_node) return ret; _GLIBCXX_DEBUG_ASSERT(__nt == i_node); inode_pointer inp = static_cast<inode_pointer>(ret); return inp->leftmost_descendant(); } return rightmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: add_child(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); if (m_a_p_children[i] == 0) { m_a_p_children[i] = p_nd; p_nd->m_p_parent = this; return p_nd; } return m_a_p_children[i]; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: get_join_child(node_const_pointer p_nd, a_const_pointer p_tr) const { node_pointer p = const_cast<node_pointer>(p_nd); return const_cast<inode_pointer>(this)->get_join_child(p, p_tr); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_join_child(node_pointer p_nd, a_const_pointer p_traits) { size_type i; a_const_iterator b_it; a_const_iterator e_it; if (p_nd->m_type == leaf_node) { leaf_const_pointer p = static_cast<leaf_const_pointer>(p_nd); typedef typename type_traits::key_const_reference kcr; kcr r_key = access_traits::extract_key(p->value()); b_it = p_traits->begin(r_key); e_it = p_traits->end(r_key); } else { b_it = static_cast<inode_pointer>(p_nd)->pref_b_it(); e_it = static_cast<inode_pointer>(p_nd)->pref_e_it(); } i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); return m_a_p_children[i]; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_child(node_pointer p_nd) { size_type i = 0; for (; i < arr_size; ++i) if (m_a_p_children[i] == p_nd) { m_a_p_children[i] = 0; return; } _GLIBCXX_DEBUG_ASSERT(i != arr_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_child(iterator it) { *it.m_p_p_cur = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: replace_child(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it, a_const_pointer p_traits) { const size_type i = get_pref_pos(b_it, e_it, p_traits); _GLIBCXX_DEBUG_ASSERT(i < arr_size); m_a_p_children[i] = p_nd; p_nd->m_p_parent = this; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_b_it() const { return m_pref_b_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_e_it() const { return m_pref_e_it; } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: should_be_mine(a_const_iterator b_it, a_const_iterator e_it, size_type checked_ind, a_const_pointer p_traits) const { if (m_e_ind == 0) return true; const size_type num_es = std::distance(b_it, e_it); if (num_es < m_e_ind) return false; a_const_iterator key_b_it = b_it; std::advance(key_b_it, checked_ind); a_const_iterator key_e_it = b_it; std::advance(key_e_it, m_e_ind); a_const_iterator value_b_it = m_pref_b_it; std::advance(value_b_it, checked_ind); a_const_iterator value_e_it = m_pref_b_it; std::advance(value_e_it, m_e_ind); return p_traits->equal_prefixes(key_b_it, key_e_it, value_b_it, value_e_it); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant() { node_pointer p_pot = *begin(); if (p_pot->m_type == leaf_node) return (static_cast<leaf_pointer>(p_pot)); _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == i_node); return static_cast<inode_pointer>(p_pot)->leftmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant() const { return const_cast<inode_pointer>(this)->leftmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant() { const size_type num_children = std::distance(begin(), end()); _GLIBCXX_DEBUG_ASSERT(num_children >= 2); iterator it = begin(); std::advance(it, num_children - 1); node_pointer p_pot =* it; if (p_pot->m_type == leaf_node) return static_cast<leaf_pointer>(p_pot); _GLIBCXX_DEBUG_ASSERT(p_pot->m_type == i_node); return static_cast<inode_pointer>(p_pot)->rightmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant() const { return const_cast<inode_pointer>(this)->rightmost_descendant(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_begin_pos() const { size_type i = 0; for (; i < arr_size && m_a_p_children[i] == 0; ++i) ; return i; } #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_debug_info PB_DS_CLASS_C_DEC:: assert_valid_imp(a_const_pointer p_traits, const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(base_type::m_type == i_node); PB_DS_DEBUG_VERIFY(static_cast<size_type>(std::distance(pref_b_it(), pref_e_it())) == m_e_ind); PB_DS_DEBUG_VERIFY(std::distance(begin(), end()) >= 2); for (typename _Inode::const_iterator it = begin(); it != end(); ++it) { node_const_pointer p_nd = *it; PB_DS_DEBUG_VERIFY(p_nd->m_p_parent == this); node_debug_info child_ret = p_nd->assert_valid_imp(p_traits, __file, __line); PB_DS_DEBUG_VERIFY(static_cast<size_type>(std::distance(child_ret.first, child_ret.second)) >= m_e_ind); PB_DS_DEBUG_VERIFY(should_be_mine(child_ret.first, child_ret.second, 0, p_traits)); PB_DS_DEBUG_VERIFY(get_pref_pos(child_ret.first, child_ret.second, p_traits) == static_cast<size_type>(it.m_p_p_cur - m_a_p_children)); } return std::make_pair(pref_b_it(), pref_e_it()); } #endif #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp 0000644 00000013120 15146341150 0021631 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/constructors_destructor_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::head_allocator PB_DS_CLASS_C_DEC::s_head_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::inode_allocator PB_DS_CLASS_C_DEC::s_inode_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_allocator PB_DS_CLASS_C_DEC::s_leaf_allocator; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_PAT_TRIE_NAME() : m_p_head(s_head_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_PAT_TRIE_NAME(const access_traits& r_access_traits) : synth_access_traits(r_access_traits), m_p_head(s_head_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_PAT_TRIE_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef _GLIBCXX_DEBUG debug_base(other), #endif synth_access_traits(other), node_update(other), m_p_head(s_head_allocator.allocate(1)), m_size(0) { initialize(); m_size = other.m_size; PB_DS_ASSERT_VALID(other) if (other.m_p_head->m_p_parent == 0) { PB_DS_ASSERT_VALID((*this)) return; } __try { m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); } __catch(...) { s_head_allocator.deallocate(m_p_head, 1); __throw_exception_again; } m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent); m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); m_p_head->m_p_parent->m_p_parent = m_p_head; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) value_swap(other); std::swap((access_traits& )(*this), (access_traits& )other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_p_head, other.m_p_head); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_PAT_TRIE_NAME() { clear(); s_head_allocator.deallocate(m_p_head, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { new (m_p_head) head(); m_p_head->m_p_parent = 0; m_p_head->m_p_min = m_p_head; m_p_head->m_p_max = m_p_head; m_size = 0; } PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: recursive_copy_node(node_const_pointer p_ncp) { _GLIBCXX_DEBUG_ASSERT(p_ncp != 0); if (p_ncp->m_type == leaf_node) { leaf_const_pointer p_other_lf = static_cast<leaf_const_pointer>(p_ncp); leaf_pointer p_new_lf = s_leaf_allocator.allocate(1); cond_dealtor cond(p_new_lf); new (p_new_lf) leaf(p_other_lf->value()); apply_update(p_new_lf, (node_update*)this); cond.set_no_action_dtor(); return (p_new_lf); } _GLIBCXX_DEBUG_ASSERT(p_ncp->m_type == i_node); node_pointer a_p_children[inode::arr_size]; size_type child_i = 0; inode_const_pointer p_icp = static_cast<inode_const_pointer>(p_ncp); typename inode::const_iterator child_it = p_icp->begin(); inode_pointer p_ret; __try { while (child_it != p_icp->end()) { a_p_children[child_i] = recursive_copy_node(*(child_it)); child_i++; child_it++; } p_ret = s_inode_allocator.allocate(1); } __catch(...) { while (child_i-- > 0) clear_imp(a_p_children[child_i]); __throw_exception_again; } new (p_ret) inode(p_icp->get_e_ind(), pref_begin(a_p_children[0])); --child_i; _GLIBCXX_DEBUG_ASSERT(child_i >= 1); do p_ret->add_child(a_p_children[child_i], pref_begin(a_p_children[child_i]), pref_end(a_p_children[child_i]), this); while (child_i-- > 0); apply_update(p_ret, (node_update*)this); return p_ret; } c++/8/ext/pb_ds/detail/pat_trie_/traits.hpp 0000644 00000014241 15146341150 0014403 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/traits.hpp * Contains an implementation class for pat_trie_. */ #ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP #define PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP #include <ext/pb_ds/detail/pat_trie_/pat_trie_base.hpp> #include <ext/pb_ds/detail/pat_trie_/synth_access_traits.hpp> namespace __gnu_pbds { namespace detail { /// Specialization. /// @ingroup traits template<typename Key, typename Mapped, typename _ATraits, template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn_, typename _Alloc_> class Node_Update, typename _Alloc> struct trie_traits<Key, Mapped, _ATraits, Node_Update, pat_trie_tag, _Alloc> { private: typedef pat_trie_base base_type; typedef types_traits<Key, Mapped, _Alloc, false> type_traits; public: typedef typename trie_node_metadata_dispatch<Key, Mapped, _ATraits, Node_Update, _Alloc>::type metadata_type; typedef base_type::_Metadata<metadata_type, _Alloc> metadata; typedef _ATraits access_traits; /// Type for synthesized traits. typedef __gnu_pbds::detail::synth_access_traits<type_traits, false, access_traits> synth_access_traits; typedef base_type::_Node_base<synth_access_traits, metadata> node; typedef base_type::_Head<synth_access_traits, metadata> head; typedef base_type::_Leaf<synth_access_traits, metadata> leaf; typedef base_type::_Inode<synth_access_traits, metadata> inode; typedef base_type::_Iter<node, leaf, head, inode, true> iterator; typedef base_type::_CIter<node, leaf, head, inode, true> const_iterator; typedef base_type::_Iter<node, leaf, head, inode, false> reverse_iterator; typedef base_type::_CIter<node, leaf, head, inode, false> const_reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef base_type::_Node_citer<node, leaf, head, inode, const_iterator, iterator, _Alloc> node_const_iterator; typedef base_type::_Node_iter<node, leaf, head, inode, const_iterator, iterator, _Alloc> node_iterator; /// Type for node update. typedef Node_Update<node_const_iterator, node_iterator, _ATraits, _Alloc> node_update; typedef null_node_update<node_const_iterator, node_iterator, _ATraits, _Alloc>* null_node_update_pointer; }; /// Specialization. /// @ingroup traits template<typename Key, typename _ATraits, template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn_, typename _Alloc_> class Node_Update, typename _Alloc> struct trie_traits<Key, null_type, _ATraits, Node_Update, pat_trie_tag, _Alloc> { private: typedef pat_trie_base base_type; typedef types_traits<Key, null_type, _Alloc, false> type_traits; public: typedef typename trie_node_metadata_dispatch<Key, null_type, _ATraits, Node_Update, _Alloc>::type metadata_type; typedef base_type::_Metadata<metadata_type, _Alloc> metadata; typedef _ATraits access_traits; /// Type for synthesized traits. typedef __gnu_pbds::detail::synth_access_traits<type_traits, true, access_traits> synth_access_traits; typedef base_type::_Node_base<synth_access_traits, metadata> node; typedef base_type::_Head<synth_access_traits, metadata> head; typedef base_type::_Leaf<synth_access_traits, metadata> leaf; typedef base_type::_Inode<synth_access_traits, metadata> inode; typedef base_type::_CIter<node, leaf, head, inode, true> const_iterator; typedef const_iterator iterator; typedef base_type::_CIter<node, leaf, head, inode, false> const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef base_type::_Node_citer<node, leaf, head, inode, const_iterator, iterator, _Alloc> node_const_iterator; typedef node_const_iterator node_iterator; /// Type for node update. typedef Node_Update<node_const_iterator, node_iterator, _ATraits, _Alloc> node_update; typedef null_node_update<node_const_iterator, node_const_iterator, _ATraits, _Alloc>* null_node_update_pointer; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_PAT_TRIE_NODE_AND_IT_TRAITS_HPP c++/8/ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp 0000644 00000004010 15146341150 0015534 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/info_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_size == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_inode_allocator.max_size(); } c++/8/ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp 0000644 00000006630 15146341150 0016627 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/iterators_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return iterator(m_p_head->m_p_min); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { return const_iterator(m_p_head->m_p_min); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return const_iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() const { if (empty()) return rend(); return --end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() { if (empty()) return rend(); return --end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rend() { return reverse_iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rend() const { return const_reverse_iterator(m_p_head); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_begin() const { return node_const_iterator(m_p_head->m_p_parent, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_begin() { return node_iterator(m_p_head->m_p_parent, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_end() const { return node_const_iterator(0, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_end() { return node_iterator(0, this); } c++/8/ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp 0000644 00000007317 15146341150 0015704 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/debug_fn_imps.hpp * Contains an implementation class for pat_trie_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { if (m_p_head->m_p_parent != 0) m_p_head->m_p_parent->assert_valid(this, __file, __line); assert_iterators(__file, __line); assert_reverse_iterators(__file, __line); if (m_p_head->m_p_parent == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_min == m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_max == m_p_head); PB_DS_DEBUG_VERIFY(empty()); return; } PB_DS_DEBUG_VERIFY(m_p_head->m_p_min->m_type == leaf_node); PB_DS_DEBUG_VERIFY(m_p_head->m_p_max->m_type == leaf_node); PB_DS_DEBUG_VERIFY(!empty()); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { size_type calc_size = 0; for (const_iterator it = begin(); it != end(); ++it) { ++calc_size; debug_base::check_key_exists(PB_DS_V2F(*it), __file, __line); PB_DS_DEBUG_VERIFY(lower_bound(PB_DS_V2F(*it)) == it); PB_DS_DEBUG_VERIFY(--upper_bound(PB_DS_V2F(*it)) == it); } PB_DS_DEBUG_VERIFY(calc_size == m_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_reverse_iterators(const char* __file, int __line) const { size_type calc_size = 0; for (const_reverse_iterator it = rbegin(); it != rend(); ++it) { ++calc_size; node_const_pointer p_nd = const_cast<PB_DS_CLASS_C_DEC*>(this)->find_imp(PB_DS_V2F(*it)); PB_DS_DEBUG_VERIFY(p_nd == it.m_p_nd); } PB_DS_DEBUG_VERIFY(calc_size == m_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: recursive_count_leafs(node_const_pointer p_nd, const char* __file, int __line) { if (p_nd == 0) return (0); if (p_nd->m_type == leaf_node) return (1); PB_DS_DEBUG_VERIFY(p_nd->m_type == i_node); size_type ret = 0; for (typename inode::const_iterator it = static_cast<inode_const_pointer>(p_nd)->begin(); it != static_cast<inode_const_pointer>(p_nd)->end(); ++it) ret += recursive_count_leafs(*it, __file, __line); return ret; } #endif c++/8/ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp 0000644 00000003772 15146341150 0016101 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/update_fn_imps.hpp * Contains an implementation class for pat_trie_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer, null_node_update_pointer) { } PB_DS_CLASS_T_DEC template<typename Node_Update_> inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer p_nd, Node_Update_*) { Node_Update_::operator()(node_iterator(p_nd, this), node_const_iterator(0, this)); } c++/8/ext/pb_ds/detail/pat_trie_/rotate_fn_imps.hpp 0000644 00000010352 15146341150 0016105 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/rotate_fn_imps.hpp * Contains imps for rotating nodes. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_left(node_pointer p_x) { node_pointer p_y = p_x->m_p_right; p_x->m_p_right = p_y->m_p_left; if (p_y->m_p_left != 0) p_y->m_p_left->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_left) p_x->m_p_parent->m_p_left = p_y; else p_x->m_p_parent->m_p_right = p_y; p_y->m_p_left = p_x; p_x->m_p_parent = p_y; _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) apply_update(p_x, (Node_Update*)this); apply_update(p_x->m_p_parent, (Node_Update*)this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_right(node_pointer p_x) { node_pointer p_y = p_x->m_p_left; p_x->m_p_left = p_y->m_p_right; if (p_y->m_p_right != 0) p_y->m_p_right->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_right) p_x->m_p_parent->m_p_right = p_y; else p_x->m_p_parent->m_p_left = p_y; p_y->m_p_right = p_x; p_x->m_p_parent = p_y; _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_x);) _GLIBCXX_DEBUG_ONLY(assert_node_consistent(p_y);) apply_update(p_x, (Node_Update*)this); apply_update(p_x->m_p_parent, (Node_Update*)this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_parent(node_pointer p_nd) { node_pointer p_parent = p_nd->m_p_parent; if (p_nd == p_parent->m_p_left) rotate_right(p_parent); else rotate_left(p_parent); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || p_nd->m_p_right == p_parent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer /*p_nd*/, __gnu_pbds::null_node_update* /*p_update*/) { } PB_DS_CLASS_T_DEC template<typename Node_Update_> inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer p_nd, Node_Update_* p_update) { p_update->operator()(& PB_DS_V2F(p_nd->m_value),(p_nd->m_p_left == 0) ? 0 : & PB_DS_V2F(p_nd->m_p_left->m_value),(p_nd->m_p_right == 0) ? 0 : & PB_DS_V2F(p_nd->m_p_right->m_value)); } PB_DS_CLASS_T_DEC template<typename Node_Update_> inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer p_nd, Node_Update_* p_update) { while (p_nd != m_p_head) { apply_update(p_nd, p_update); p_nd = p_nd->m_p_parent; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer /*p_nd*/, __gnu_pbds::null_node_update* /*p_update*/) { } c++/8/ext/pb_ds/detail/pat_trie_/synth_access_traits.hpp 0000644 00000015076 15146341150 0017160 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/synth_access_traits.hpp * Contains an implementation class for a patricia tree. */ #ifndef PB_DS_SYNTH_E_ACCESS_TRAITS_HPP #define PB_DS_SYNTH_E_ACCESS_TRAITS_HPP #include <ext/pb_ds/detail/type_utils.hpp> namespace __gnu_pbds { namespace detail { #define PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC \ template<typename Type_Traits, bool Set, typename _ATraits> #define PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC \ synth_access_traits<Type_Traits, Set, _ATraits> /// Synthetic element access traits. template<typename Type_Traits, bool Set, typename _ATraits> struct synth_access_traits : public _ATraits { typedef _ATraits base_type; typedef typename base_type::const_iterator const_iterator; typedef Type_Traits type_traits; typedef typename type_traits::const_reference const_reference; typedef typename type_traits::key_const_reference key_const_reference; synth_access_traits(); synth_access_traits(const base_type&); inline bool equal_prefixes(const_iterator, const_iterator, const_iterator, const_iterator, bool compare_after = true) const; bool equal_keys(key_const_reference, key_const_reference) const; bool cmp_prefixes(const_iterator, const_iterator, const_iterator, const_iterator, bool compare_after = false) const; bool cmp_keys(key_const_reference, key_const_reference) const; inline static key_const_reference extract_key(const_reference); #ifdef _GLIBCXX_DEBUG bool operator()(key_const_reference, key_const_reference); #endif private: inline static key_const_reference extract_key(const_reference, true_type); inline static key_const_reference extract_key(const_reference, false_type); static integral_constant<int, Set> s_set_ind; }; PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC integral_constant<int,Set> PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::s_set_ind; PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: synth_access_traits() { } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: synth_access_traits(const _ATraits& r_traits) : _ATraits(r_traits) { } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: equal_prefixes(const_iterator b_l, const_iterator e_l, const_iterator b_r, const_iterator e_r, bool compare_after /*= false */) const { while (b_l != e_l) { if (b_r == e_r) return false; if (base_type::e_pos(*b_l) != base_type::e_pos(*b_r)) return false; ++b_l; ++b_r; } return (!compare_after || b_r == e_r); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: equal_keys(key_const_reference r_lhs_key, key_const_reference r_rhs_key) const { return equal_prefixes(base_type::begin(r_lhs_key), base_type::end(r_lhs_key), base_type::begin(r_rhs_key), base_type::end(r_rhs_key), true); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: cmp_prefixes(const_iterator b_l, const_iterator e_l, const_iterator b_r, const_iterator e_r, bool compare_after /* = false*/) const { while (b_l != e_l) { if (b_r == e_r) return false; const typename base_type::size_type l_pos = base_type::e_pos(*b_l); const typename base_type::size_type r_pos = base_type::e_pos(*b_r); if (l_pos != r_pos) return l_pos < r_pos; ++b_l; ++b_r; } if (!compare_after) return false; return b_r != e_r; } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: cmp_keys(key_const_reference r_lhs_key, key_const_reference r_rhs_key) const { return cmp_prefixes(base_type::begin(r_lhs_key), base_type::end(r_lhs_key), base_type::begin(r_rhs_key), base_type::end(r_rhs_key), true); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::key_const_reference PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: extract_key(const_reference r_val) { return extract_key(r_val, s_set_ind); } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::key_const_reference PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: extract_key(const_reference r_val, true_type) { return r_val; } PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC inline typename PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC::key_const_reference PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: extract_key(const_reference r_val, false_type) { return r_val.first; } #ifdef _GLIBCXX_DEBUG PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC bool PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC:: operator()(key_const_reference r_lhs, key_const_reference r_rhs) { return cmp_keys(r_lhs, r_rhs); } #endif #undef PB_DS_SYNTH_E_ACCESS_TRAITS_T_DEC #undef PB_DS_SYNTH_E_ACCESS_TRAITS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp 0000644 00000006511 15146341150 0015707 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/trace_fn_imps.hpp * Contains an implementation class for pat_trie_. */ #ifdef PB_DS_PAT_TRIE_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << std::endl; if (m_p_head->m_p_parent == 0) return; trace_node(m_p_head->m_p_parent, 0); std::cerr << std::endl; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node(node_const_pointer p_nd, size_type level) { for (size_type i = 0; i < level; ++i) std::cerr << ' '; std::cerr << p_nd << " "; std::cerr << ((p_nd->m_type == pat_trie_leaf_node_type) ? "l " : "i "); trace_node_metadata(p_nd, type_to_type<typename node::metadata_type>()); typename access_traits::const_iterator el_it = pref_begin(p_nd); while (el_it != pref_end(p_nd)) { std::cerr <<* el_it; ++el_it; } if (p_nd->m_type == pat_trie_leaf_node_type) { std::cerr << std::endl; return; } inode_const_pointer p_internal = static_cast<inode_const_pointer>(p_nd); std::cerr << " " << static_cast<unsigned long>(p_internal->get_e_ind()) << std::endl; const size_type num_children = std::distance(p_internal->begin(), p_internal->end()); for (size_type child_i = 0; child_i < num_children; ++child_i) { typename inode::const_iterator child_it = p_internal->begin(); std::advance(child_it, num_children - child_i - 1); trace_node(*child_it, level + 1); } } PB_DS_CLASS_T_DEC template<typename Metadata_> void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer p_nd, type_to_type<Metadata_>) { std::cerr << "(" << static_cast<unsigned long>(p_nd->get_metadata()) << ") "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer, type_to_type<null_type>) { } #endif c++/8/ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp 0000644 00000034213 15146341150 0017134 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/insert_join_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) branch_bag bag; if (!join_prep(other, bag)) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, other.m_p_head->m_p_parent, 0, bag); m_p_head->m_p_parent->m_p_parent = m_p_head; m_size += other.m_size; other.initialize(); PB_DS_ASSERT_VALID(other) m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent); m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: join_prep(PB_DS_CLASS_C_DEC& other, branch_bag& r_bag) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_size == 0) return false; if (m_size == 0) { value_swap(other); return false; } const bool greater = synth_access_traits::cmp_keys(PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_max)->value()), PB_DS_V2F(static_cast<leaf_const_pointer>(other.m_p_head->m_p_min)->value())); const bool lesser = synth_access_traits::cmp_keys(PB_DS_V2F(static_cast<leaf_const_pointer>(other.m_p_head->m_p_max)->value()), PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_min)->value())); if (!greater && !lesser) __throw_join_error(); rec_join_prep(m_p_head->m_p_parent, other.m_p_head->m_p_parent, r_bag); _GLIBCXX_DEBUG_ONLY(debug_base::join(other, false);) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(node_const_pointer p_l, node_const_pointer p_r, branch_bag& r_bag) { if (p_l->m_type == leaf_node) { if (p_r->m_type == leaf_node) { rec_join_prep(static_cast<leaf_const_pointer>(p_l), static_cast<leaf_const_pointer>(p_r), r_bag); return; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); rec_join_prep(static_cast<leaf_const_pointer>(p_l), static_cast<inode_const_pointer>(p_r), r_bag); return; } _GLIBCXX_DEBUG_ASSERT(p_l->m_type == i_node); if (p_r->m_type == leaf_node) { rec_join_prep(static_cast<inode_const_pointer>(p_l), static_cast<leaf_const_pointer>(p_r), r_bag); return; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); rec_join_prep(static_cast<inode_const_pointer>(p_l), static_cast<inode_const_pointer>(p_r), r_bag); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(leaf_const_pointer /*p_l*/, leaf_const_pointer /*p_r*/, branch_bag& r_bag) { r_bag.add_branch(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(leaf_const_pointer /*p_l*/, inode_const_pointer /*p_r*/, branch_bag& r_bag) { r_bag.add_branch(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(inode_const_pointer /*p_l*/, leaf_const_pointer /*p_r*/, branch_bag& r_bag) { r_bag.add_branch(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: rec_join_prep(inode_const_pointer p_l, inode_const_pointer p_r, branch_bag& r_bag) { if (p_l->get_e_ind() == p_r->get_e_ind() && synth_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(), p_r->pref_b_it(), p_r->pref_e_it())) { for (typename inode::const_iterator it = p_r->begin(); it != p_r->end(); ++ it) { node_const_pointer p_l_join_child = p_l->get_join_child(*it, this); if (p_l_join_child != 0) rec_join_prep(p_l_join_child, * it, r_bag); } return; } if (p_r->get_e_ind() < p_l->get_e_ind() && p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) { node_const_pointer p_r_join_child = p_r->get_join_child(p_l, this); if (p_r_join_child != 0) rec_join_prep(p_r_join_child, p_l, r_bag); return; } if (p_r->get_e_ind() < p_l->get_e_ind() && p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) { node_const_pointer p_r_join_child = p_r->get_join_child(p_l, this); if (p_r_join_child != 0) rec_join_prep(p_r_join_child, p_l, r_bag); return; } r_bag.add_branch(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(node_pointer p_l, node_pointer p_r, size_type checked_ind, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_r != 0); if (p_l == 0) { apply_update(p_r, (node_update*)this); return (p_r); } if (p_l->m_type == leaf_node) { if (p_r->m_type == leaf_node) { node_pointer p_ret = rec_join(static_cast<leaf_pointer>(p_l), static_cast<leaf_pointer>(p_r), r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); node_pointer p_ret = rec_join(static_cast<leaf_pointer>(p_l), static_cast<inode_pointer>(p_r), checked_ind, r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } _GLIBCXX_DEBUG_ASSERT(p_l->m_type == i_node); if (p_r->m_type == leaf_node) { node_pointer p_ret = rec_join(static_cast<inode_pointer>(p_l), static_cast<leaf_pointer>(p_r), checked_ind, r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node); node_pointer p_ret = rec_join(static_cast<inode_pointer>(p_l), static_cast<inode_pointer>(p_r), r_bag); apply_update(p_ret, (node_update*)this); return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(leaf_pointer p_l, leaf_pointer p_r, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_r != 0); if (p_l == 0) return (p_r); node_pointer p_ret = insert_branch(p_l, p_r, r_bag); _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == 2); return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(leaf_pointer p_l, inode_pointer p_r, size_type checked_ind, branch_bag& r_bag) { #ifdef _GLIBCXX_DEBUG const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l); const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r); #endif _GLIBCXX_DEBUG_ASSERT(p_r != 0); node_pointer p_ret = rec_join(p_r, p_l, checked_ind, r_bag); _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs); return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(inode_pointer p_l, leaf_pointer p_r, size_type checked_ind, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_l != 0); _GLIBCXX_DEBUG_ASSERT(p_r != 0); #ifdef _GLIBCXX_DEBUG const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l); const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r); #endif if (!p_l->should_be_mine(pref_begin(p_r), pref_end(p_r), checked_ind, this)) { node_pointer p_ret = insert_branch(p_l, p_r, r_bag); PB_DS_ASSERT_NODE_VALID(p_ret) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs); return p_ret; } node_pointer p_pot_child = p_l->add_child(p_r, pref_begin(p_r), pref_end(p_r), this); if (p_pot_child != p_r) { node_pointer p_new_child = rec_join(p_pot_child, p_r, p_l->get_e_ind(), r_bag); p_l->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); } PB_DS_ASSERT_NODE_VALID(p_l) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_l) == lhs_leafs + rhs_leafs); return p_l; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_join(inode_pointer p_l, inode_pointer p_r, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(p_l != 0); _GLIBCXX_DEBUG_ASSERT(p_r != 0); #ifdef _GLIBCXX_DEBUG const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l); const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r); #endif if (p_l->get_e_ind() == p_r->get_e_ind() && synth_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(), p_r->pref_b_it(), p_r->pref_e_it())) { for (typename inode::iterator it = p_r->begin(); it != p_r->end(); ++ it) { node_pointer p_new_child = rec_join(p_l->get_join_child(*it, this), * it, 0, r_bag); p_l->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); } p_r->~inode(); s_inode_allocator.deallocate(p_r, 1); PB_DS_ASSERT_NODE_VALID(p_l) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_l) == lhs_leafs + rhs_leafs); return p_l; } if (p_l->get_e_ind() < p_r->get_e_ind() && p_l->should_be_mine(p_r->pref_b_it(), p_r->pref_e_it(), 0, this)) { node_pointer p_new_child = rec_join(p_l->get_join_child(p_r, this), p_r, 0, r_bag); p_l->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); PB_DS_ASSERT_NODE_VALID(p_l) return p_l; } if (p_r->get_e_ind() < p_l->get_e_ind() && p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this)) { node_pointer p_new_child = rec_join(p_r->get_join_child(p_l, this), p_l, 0, r_bag); p_r->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); PB_DS_ASSERT_NODE_VALID(p_r) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_r) == lhs_leafs + rhs_leafs); return p_r; } node_pointer p_ret = insert_branch(p_l, p_r, r_bag); PB_DS_ASSERT_NODE_VALID(p_ret) _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs); return p_ret; } PB_DS_CLASS_T_DEC inline std::pair<typename PB_DS_CLASS_C_DEC::iterator, bool> PB_DS_CLASS_C_DEC:: insert(const_reference r_val) { node_pointer p_lf = find_imp(PB_DS_V2F(r_val)); if (p_lf != 0 && p_lf->m_type == leaf_node && synth_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_pointer>(p_lf)->value()), PB_DS_V2F(r_val))) { PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_val)) PB_DS_ASSERT_VALID((*this)) return std::make_pair(iterator(p_lf), false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_val)) leaf_pointer p_new_lf = s_leaf_allocator.allocate(1); cond_dealtor cond(p_new_lf); new (p_new_lf) leaf(r_val); apply_update(p_new_lf, (node_update*)this); cond.set_call_destructor(); branch_bag bag; bag.add_branch(); m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, p_new_lf, 0, bag); m_p_head->m_p_parent->m_p_parent = m_p_head; cond.set_no_action_dtor(); ++m_size; update_min_max_for_inserted_leaf(p_new_lf); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) PB_DS_ASSERT_VALID((*this)) return std::make_pair(point_iterator(p_new_lf), true); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: keys_diff_ind(typename access_traits::const_iterator b_l, typename access_traits::const_iterator e_l, typename access_traits::const_iterator b_r, typename access_traits::const_iterator e_r) { size_type diff_pos = 0; while (b_l != e_l) { if (b_r == e_r) return (diff_pos); if (access_traits::e_pos(*b_l) != access_traits::e_pos(*b_r)) return (diff_pos); ++b_l; ++b_r; ++diff_pos; } _GLIBCXX_DEBUG_ASSERT(b_r != e_r); return diff_pos; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::inode_pointer PB_DS_CLASS_C_DEC:: insert_branch(node_pointer p_l, node_pointer p_r, branch_bag& r_bag) { typename synth_access_traits::const_iterator left_b_it = pref_begin(p_l); typename synth_access_traits::const_iterator left_e_it = pref_end(p_l); typename synth_access_traits::const_iterator right_b_it = pref_begin(p_r); typename synth_access_traits::const_iterator right_e_it = pref_end(p_r); const size_type diff_ind = keys_diff_ind(left_b_it, left_e_it, right_b_it, right_e_it); inode_pointer p_new_nd = r_bag.get_branch(); new (p_new_nd) inode(diff_ind, left_b_it); p_new_nd->add_child(p_l, left_b_it, left_e_it, this); p_new_nd->add_child(p_r, right_b_it, right_e_it, this); p_l->m_p_parent = p_new_nd; p_r->m_p_parent = p_new_nd; PB_DS_ASSERT_NODE_VALID(p_new_nd) return (p_new_nd); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: update_min_max_for_inserted_leaf(leaf_pointer p_new_lf) { if (m_p_head->m_p_min == m_p_head || synth_access_traits::cmp_keys(PB_DS_V2F(p_new_lf->value()), PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_min)->value()))) m_p_head->m_p_min = p_new_lf; if (m_p_head->m_p_max == m_p_head || synth_access_traits::cmp_keys(PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_max)->value()), PB_DS_V2F(p_new_lf->value()))) m_p_head->m_p_max = p_new_lf; } c++/8/ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp 0000644 00000004247 15146341150 0017435 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/policy_access_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::access_traits& PB_DS_CLASS_C_DEC:: get_access_traits() { return *this; } PB_DS_CLASS_T_DEC const typename PB_DS_CLASS_C_DEC::access_traits& PB_DS_CLASS_C_DEC:: get_access_traits() const { return *this; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_update& PB_DS_CLASS_C_DEC:: get_node_update() { return *this; } PB_DS_CLASS_T_DEC const typename PB_DS_CLASS_C_DEC::node_update& PB_DS_CLASS_C_DEC:: get_node_update() const { return *this; } c++/8/ext/pb_ds/detail/pat_trie_/r_erase_fn_imps.hpp 0000644 00000005550 15146341150 0016233 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/r_erase_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_z) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_z->m_value))); p_z->~node(); s_node_allocator.deallocate(p_z, 1); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_node(node_pointer p_z) { if (m_size == 1) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } if (m_p_head->m_p_left == p_z) { iterator it(p_z); ++it; m_p_head->m_p_left = it.m_p_nd; } else if (m_p_head->m_p_right == p_z) { iterator it(p_z); --it; m_p_head->m_p_right = it.m_p_nd; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);) clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) _GLIBCXX_DEBUG_ONLY(assert_valid(true, true);) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd == 0) return; clear_imp(p_nd->m_p_left); clear_imp(p_nd->m_p_right); p_nd->~Node(); s_node_allocator.deallocate(p_nd, 1); } c++/8/ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp 0000644 00000017055 15146341150 0015751 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/split_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) branch_bag bag; leaf_pointer p_split_lf = split_prep(r_key, other, bag); if (p_split_lf == 0) { _GLIBCXX_DEBUG_ASSERT(bag.empty()); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } _GLIBCXX_DEBUG_ASSERT(!bag.empty()); other.clear(); m_p_head->m_p_parent = rec_split(m_p_head->m_p_parent, pref_begin(p_split_lf), pref_end(p_split_lf), other, bag); m_p_head->m_p_parent->m_p_parent = m_p_head; head_pointer __ohead = other.m_p_head; __ohead->m_p_max = m_p_head->m_p_max; m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent); __ohead->m_p_min = other.leftmost_descendant(__ohead->m_p_parent); other.m_size = std::distance(other.PB_DS_CLASS_C_DEC::begin(), other.PB_DS_CLASS_C_DEC::end()); m_size -= other.m_size; PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: split_prep(key_const_reference r_key, PB_DS_CLASS_C_DEC& other, branch_bag& r_bag) { _GLIBCXX_DEBUG_ASSERT(r_bag.empty()); if (m_size == 0) { other.clear(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return 0; } if (synth_access_traits::cmp_keys(r_key, PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_min)->value()))) { other.clear(); value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return 0; } if (!synth_access_traits::cmp_keys(r_key, PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_max)->value()))) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return 0; } iterator it = lower_bound(r_key); if (!synth_access_traits::equal_keys(PB_DS_V2F(*it), r_key)) --it; node_pointer p_nd = it.m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node); leaf_pointer p_ret_l = static_cast<leaf_pointer>(p_nd); while (p_nd->m_type != head_node) { r_bag.add_branch(); p_nd = p_nd->m_p_parent; } _GLIBCXX_DEBUG_ONLY(debug_base::split(r_key,(synth_access_traits&)(*this), other);) return p_ret_l; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: rec_split(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it, PB_DS_CLASS_C_DEC& other, branch_bag& r_bag) { if (p_nd->m_type == leaf_node) { _GLIBCXX_DEBUG_ASSERT(other.m_p_head->m_p_parent == 0); return p_nd; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); inode_pointer p_ind = static_cast<inode_pointer>(p_nd); node_pointer pfirst = p_ind->get_child_node(b_it, e_it, this); node_pointer p_child_ret = rec_split(pfirst, b_it, e_it, other, r_bag); PB_DS_ASSERT_NODE_VALID(p_child_ret) p_ind->replace_child(p_child_ret, b_it, e_it, this); apply_update(p_ind, (node_update*)this); inode_iterator child_it = p_ind->get_child_it(b_it, e_it, this); const size_type lhs_dist = std::distance(p_ind->begin(), child_it); const size_type lhs_num_children = lhs_dist + 1; _GLIBCXX_DEBUG_ASSERT(lhs_num_children > 0); const size_type rhs_dist = std::distance(p_ind->begin(), p_ind->end()); size_type rhs_num_children = rhs_dist - lhs_num_children; if (rhs_num_children == 0) { apply_update(p_ind, (node_update*)this); return p_ind; } other.split_insert_branch(p_ind->get_e_ind(), b_it, child_it, rhs_num_children, r_bag); child_it = p_ind->get_child_it(b_it, e_it, this); while (rhs_num_children != 0) { ++child_it; p_ind->remove_child(child_it); --rhs_num_children; } apply_update(p_ind, (node_update*)this); const size_type int_dist = std::distance(p_ind->begin(), p_ind->end()); _GLIBCXX_DEBUG_ASSERT(int_dist >= 1); if (int_dist > 1) { p_ind->update_prefixes(this); PB_DS_ASSERT_NODE_VALID(p_ind) apply_update(p_ind, (node_update*)this); return p_ind; } node_pointer p_ret = *p_ind->begin(); p_ind->~inode(); s_inode_allocator.deallocate(p_ind, 1); apply_update(p_ret, (node_update*)this); return p_ret; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split_insert_branch(size_type e_ind, a_const_iterator b_it, inode_iterator child_b_it, size_type num_children, branch_bag& r_bag) { #ifdef _GLIBCXX_DEBUG if (m_p_head->m_p_parent != 0) PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) #endif const size_type start = m_p_head->m_p_parent == 0 ? 0 : 1; const size_type total_num_children = start + num_children; if (total_num_children == 0) { _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == 0); return; } if (total_num_children == 1) { if (m_p_head->m_p_parent != 0) { PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) return; } _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == 0); ++child_b_it; m_p_head->m_p_parent = *child_b_it; m_p_head->m_p_parent->m_p_parent = m_p_head; apply_update(m_p_head->m_p_parent, (node_update*)this); PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) return; } _GLIBCXX_DEBUG_ASSERT(total_num_children > 1); inode_pointer p_new_root = r_bag.get_branch(); new (p_new_root) inode(e_ind, b_it); size_type num_inserted = 0; while (num_inserted++ < num_children) { ++child_b_it; PB_DS_ASSERT_NODE_VALID((*child_b_it)) p_new_root->add_child(*child_b_it, pref_begin(*child_b_it), pref_end(*child_b_it), this); } if (m_p_head->m_p_parent != 0) p_new_root->add_child(m_p_head->m_p_parent, pref_begin(m_p_head->m_p_parent), pref_end(m_p_head->m_p_parent), this); m_p_head->m_p_parent = p_new_root; p_new_root->m_p_parent = m_p_head; apply_update(m_p_head->m_p_parent, (node_update*)this); PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent) } c++/8/ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp 0000644 00000017303 15146341150 0015532 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/find_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = find_imp(r_key); if (p_nd == 0 || p_nd->m_type != leaf_node) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } if (synth_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_pointer>(p_nd)->value()), r_key)) { PB_DS_CHECK_KEY_EXISTS(r_key) return iterator(p_nd); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) node_const_pointer p_nd = const_cast<PB_DS_CLASS_C_DEC* >(this)->find_imp(r_key); if (p_nd == 0 || p_nd->m_type != leaf_node) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } if (synth_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_const_pointer>(p_nd)->value()), r_key)) { PB_DS_CHECK_KEY_EXISTS(r_key) return const_iterator(const_cast<node_pointer>(p_nd)); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) { if (empty()) return 0; typename synth_access_traits::const_iterator b_it = synth_access_traits::begin(r_key); typename synth_access_traits::const_iterator e_it = synth_access_traits::end(r_key); node_pointer p_nd = m_p_head->m_p_parent; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); while (p_nd->m_type != leaf_node) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); node_pointer p_next_nd = static_cast<inode_pointer>(p_nd)->get_child_node(b_it, e_it, this); if (p_next_nd == 0) return p_nd; p_nd = p_next_nd; } return p_nd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: lower_bound_imp(key_const_reference r_key) { if (empty()) return (m_p_head); node_pointer p_nd = m_p_head->m_p_parent; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); typename PB_DS_CLASS_C_DEC::a_const_iterator b_it = synth_access_traits::begin(r_key); typename PB_DS_CLASS_C_DEC::a_const_iterator e_it = synth_access_traits::end(r_key); size_type checked_ind = 0; while (true) { if (p_nd->m_type == leaf_node) { if (!synth_access_traits::cmp_keys(PB_DS_V2F(static_cast<leaf_const_pointer>(p_nd)->value()), r_key)) return p_nd; iterator it(p_nd); ++it; return it.m_p_nd; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); const size_type new_checked_ind = static_cast<inode_pointer>(p_nd)->get_e_ind(); p_nd = static_cast<inode_pointer>(p_nd)->get_lower_bound_child_node( b_it, e_it, checked_ind, this); checked_ind = new_checked_ind; } } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) { return point_iterator(lower_bound_imp(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) const { return point_const_iterator(const_cast<PB_DS_CLASS_C_DEC* >(this)->lower_bound_imp(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) { point_iterator l_bound_it = lower_bound(r_key); _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || !synth_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), r_key)); if (l_bound_it == end() || synth_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) return l_bound_it; return ++l_bound_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) const { point_const_iterator l_bound_it = lower_bound(r_key); _GLIBCXX_DEBUG_ASSERT(l_bound_it == end() || !synth_access_traits::cmp_keys(PB_DS_V2F(*l_bound_it), r_key)); if (l_bound_it == end() || synth_access_traits::cmp_keys(r_key, PB_DS_V2F(*l_bound_it))) return l_bound_it; return ++l_bound_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_begin(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return (synth_access_traits::begin(PB_DS_V2F(static_cast<leaf_const_pointer>(p_nd)->value()))); _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); return static_cast<inode_const_pointer>(p_nd)->pref_b_it(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::a_const_iterator PB_DS_CLASS_C_DEC:: pref_end(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return (synth_access_traits::end(PB_DS_V2F(static_cast<leaf_const_pointer>(p_nd)->value()))); _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); return static_cast<inode_const_pointer>(p_nd)->pref_e_it(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast<leaf_const_pointer>(p_nd); return static_cast<inode_const_pointer>(p_nd)->leftmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: leftmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast<leaf_pointer>(p_nd); return static_cast<inode_pointer>(p_nd)->leftmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_const_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant(node_const_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast<leaf_const_pointer>(p_nd); return static_cast<inode_const_pointer>(p_nd)->rightmost_descendant(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::leaf_pointer PB_DS_CLASS_C_DEC:: rightmost_descendant(node_pointer p_nd) { if (p_nd->m_type == leaf_node) return static_cast<leaf_pointer>(p_nd); return static_cast<inode_pointer>(p_nd)->rightmost_descendant(); } c++/8/ext/pb_ds/detail/pat_trie_/pat_trie_.hpp 0000644 00000040745 15146341150 0015053 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/pat_trie_.hpp * Contains an implementation class for a patricia tree. */ #include <iterator> #include <utility> #include <algorithm> #include <functional> #include <assert.h> #include <list> #include <ext/pb_ds/exception.hpp> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/types_traits.hpp> #include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp> #include <ext/pb_ds/detail/pat_trie_/synth_access_traits.hpp> #include <ext/pb_ds/detail/pat_trie_/pat_trie_base.hpp> #ifdef _GLIBCXX_DEBUG #include <ext/pb_ds/detail/debug_map_base.hpp> #endif #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_PAT_TRIE_NAME pat_trie_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_PAT_TRIE_NAME pat_trie_set #endif #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Mapped, typename Node_And_It_Traits, \ typename _Alloc> #define PB_DS_CLASS_C_DEC \ PB_DS_PAT_TRIE_NAME<Key, Mapped, Node_And_It_Traits, _Alloc> #define PB_DS_PAT_TRIE_TRAITS_BASE \ types_traits<Key, Mapped, _Alloc, false> #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base<Key, eq_by_less<Key, std::less<Key> >, \ typename _Alloc::template rebind<Key>::other::const_reference> #endif /** * @brief PATRICIA trie. * @ingroup branch-detail * * This implementation loosely borrows ideas from: * 1) Fast Mergeable Integer Maps, Okasaki, Gill 1998 * 2) Ptset: Sets of integers implemented as Patricia trees, * Jean-Christophe Filliatr, 2000 */ template<typename Key, typename Mapped, typename Node_And_It_Traits, typename _Alloc> class PB_DS_PAT_TRIE_NAME : #ifdef _GLIBCXX_DEBUG public PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public Node_And_It_Traits::synth_access_traits, public Node_And_It_Traits::node_update, public PB_DS_PAT_TRIE_TRAITS_BASE, public pat_trie_base { private: typedef pat_trie_base base_type; typedef PB_DS_PAT_TRIE_TRAITS_BASE traits_base; typedef Node_And_It_Traits traits_type; typedef typename traits_type::synth_access_traits synth_access_traits; typedef typename synth_access_traits::const_iterator a_const_iterator; typedef typename traits_type::node node; typedef typename _Alloc::template rebind<node> __rebind_n; typedef typename __rebind_n::other::const_pointer node_const_pointer; typedef typename __rebind_n::other::pointer node_pointer; typedef typename traits_type::head head; typedef typename _Alloc::template rebind<head> __rebind_h; typedef typename __rebind_h::other head_allocator; typedef typename head_allocator::pointer head_pointer; typedef typename traits_type::leaf leaf; typedef typename _Alloc::template rebind<leaf> __rebind_l; typedef typename __rebind_l::other leaf_allocator; typedef typename leaf_allocator::pointer leaf_pointer; typedef typename leaf_allocator::const_pointer leaf_const_pointer; typedef typename traits_type::inode inode; typedef typename inode::iterator inode_iterator; typedef typename _Alloc::template rebind<inode> __rebind_in; typedef typename __rebind_in::other __rebind_ina; typedef typename __rebind_in::other inode_allocator; typedef typename __rebind_ina::pointer inode_pointer; typedef typename __rebind_ina::const_pointer inode_const_pointer; /// Conditional deallocator. class cond_dealtor { protected: leaf_pointer m_p_nd; bool m_no_action_dtor; bool m_call_destructor; public: cond_dealtor(leaf_pointer p_nd) : m_p_nd(p_nd), m_no_action_dtor(false), m_call_destructor(false) { } void set_no_action_dtor() { m_no_action_dtor = true; } void set_call_destructor() { m_call_destructor = true; } ~cond_dealtor() { if (m_no_action_dtor) return; if (m_call_destructor) m_p_nd->~leaf(); s_leaf_allocator.deallocate(m_p_nd, 1); } }; /// Branch bag, for split-join. class branch_bag { private: typedef inode_pointer __inp; typedef typename _Alloc::template rebind<__inp>::other __rebind_inp; #ifdef _GLIBCXX_DEBUG typedef std::_GLIBCXX_STD_C::list<__inp, __rebind_inp> bag_type; #else typedef std::list<__inp, __rebind_inp> bag_type; #endif bag_type m_bag; public: void add_branch() { inode_pointer p_nd = s_inode_allocator.allocate(1); __try { m_bag.push_back(p_nd); } __catch(...) { s_inode_allocator.deallocate(p_nd, 1); __throw_exception_again; } } inode_pointer get_branch() { _GLIBCXX_DEBUG_ASSERT(!m_bag.empty()); inode_pointer p_nd = *m_bag.begin(); m_bag.pop_front(); return p_nd; } ~branch_bag() { while (!m_bag.empty()) { inode_pointer p_nd = *m_bag.begin(); s_inode_allocator.deallocate(p_nd, 1); m_bag.pop_front(); } } inline bool empty() const { return m_bag.empty(); } }; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif typedef typename traits_type::null_node_update_pointer null_node_update_pointer; public: typedef pat_trie_tag container_category; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; typedef typename traits_type::access_traits access_traits; typedef typename traits_type::const_iterator point_const_iterator; typedef typename traits_type::iterator point_iterator; typedef point_const_iterator const_iterator; typedef point_iterator iterator; typedef typename traits_type::reverse_iterator reverse_iterator; typedef typename traits_type::const_reverse_iterator const_reverse_iterator; typedef typename traits_type::node_const_iterator node_const_iterator; typedef typename traits_type::node_iterator node_iterator; typedef typename traits_type::node_update node_update; PB_DS_PAT_TRIE_NAME(); PB_DS_PAT_TRIE_NAME(const access_traits&); PB_DS_PAT_TRIE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~PB_DS_PAT_TRIE_NAME(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; access_traits& get_access_traits(); const access_traits& get_access_traits() const; node_update& get_node_update(); const node_update& get_node_update() const; inline std::pair<point_iterator, bool> insert(const_reference); inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR return insert(std::make_pair(r_key, mapped_type())).first->second; #else insert(r_key); return traits_base::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline point_iterator lower_bound(key_const_reference); inline point_const_iterator lower_bound(key_const_reference) const; inline point_iterator upper_bound(key_const_reference); inline point_const_iterator upper_bound(key_const_reference) const; void clear(); inline bool erase(key_const_reference); inline const_iterator erase(const_iterator); #ifdef PB_DS_DATA_TRUE_INDICATOR inline iterator erase(iterator); #endif inline const_reverse_iterator erase(const_reverse_iterator); #ifdef PB_DS_DATA_TRUE_INDICATOR inline reverse_iterator erase(reverse_iterator); #endif template<typename Pred> inline size_type erase_if(Pred); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; inline reverse_iterator rbegin(); inline const_reverse_iterator rbegin() const; inline reverse_iterator rend(); inline const_reverse_iterator rend() const; /// Returns a const node_iterator corresponding to the node at the /// root of the tree. inline node_const_iterator node_begin() const; /// Returns a node_iterator corresponding to the node at the /// root of the tree. inline node_iterator node_begin(); /// Returns a const node_iterator corresponding to a node just /// after a leaf of the tree. inline node_const_iterator node_end() const; /// Returns a node_iterator corresponding to a node just /// after a leaf of the tree. inline node_iterator node_end(); #ifdef PB_DS_PAT_TRIE_TRACE_ void trace() const; #endif protected: template<typename It> void copy_from_range(It, It); void value_swap(PB_DS_CLASS_C_DEC&); node_pointer recursive_copy_node(node_const_pointer); private: void initialize(); inline void apply_update(node_pointer, null_node_update_pointer); template<typename Node_Update_> inline void apply_update(node_pointer, Node_Update_*); bool join_prep(PB_DS_CLASS_C_DEC&, branch_bag&); void rec_join_prep(node_const_pointer, node_const_pointer, branch_bag&); void rec_join_prep(leaf_const_pointer, leaf_const_pointer, branch_bag&); void rec_join_prep(leaf_const_pointer, inode_const_pointer, branch_bag&); void rec_join_prep(inode_const_pointer, leaf_const_pointer, branch_bag&); void rec_join_prep(inode_const_pointer, inode_const_pointer, branch_bag&); node_pointer rec_join(node_pointer, node_pointer, size_type, branch_bag&); node_pointer rec_join(leaf_pointer, leaf_pointer, branch_bag&); node_pointer rec_join(leaf_pointer, inode_pointer, size_type, branch_bag&); node_pointer rec_join(inode_pointer, leaf_pointer, size_type, branch_bag&); node_pointer rec_join(inode_pointer, inode_pointer, branch_bag&); size_type keys_diff_ind(typename access_traits::const_iterator, typename access_traits::const_iterator, typename access_traits::const_iterator, typename access_traits::const_iterator); inode_pointer insert_branch(node_pointer, node_pointer, branch_bag&); void update_min_max_for_inserted_leaf(leaf_pointer); void erase_leaf(leaf_pointer); inline void actual_erase_leaf(leaf_pointer); void clear_imp(node_pointer); void erase_fixup(inode_pointer); void update_min_max_for_erased_leaf(leaf_pointer); static inline a_const_iterator pref_begin(node_const_pointer); static inline a_const_iterator pref_end(node_const_pointer); inline node_pointer find_imp(key_const_reference); inline node_pointer lower_bound_imp(key_const_reference); inline node_pointer upper_bound_imp(key_const_reference); inline static leaf_const_pointer leftmost_descendant(node_const_pointer); inline static leaf_pointer leftmost_descendant(node_pointer); inline static leaf_const_pointer rightmost_descendant(node_const_pointer); inline static leaf_pointer rightmost_descendant(node_pointer); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_iterators(const char*, int) const; void assert_reverse_iterators(const char*, int) const; static size_type recursive_count_leafs(node_const_pointer, const char*, int); #endif #ifdef PB_DS_PAT_TRIE_TRACE_ static void trace_node(node_const_pointer, size_type); template<typename Metadata_> static void trace_node_metadata(node_const_pointer, type_to_type<Metadata_>); static void trace_node_metadata(node_const_pointer, type_to_type<null_type>); #endif leaf_pointer split_prep(key_const_reference, PB_DS_CLASS_C_DEC&, branch_bag&); node_pointer rec_split(node_pointer, a_const_iterator, a_const_iterator, PB_DS_CLASS_C_DEC&, branch_bag&); void split_insert_branch(size_type, a_const_iterator, inode_iterator, size_type, branch_bag&); static head_allocator s_head_allocator; static inode_allocator s_inode_allocator; static leaf_allocator s_leaf_allocator; head_pointer m_p_head; size_type m_size; }; #define PB_DS_ASSERT_NODE_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X->assert_valid(this, __FILE__, __LINE__);) #define PB_DS_RECURSIVE_COUNT_LEAFS(X) \ recursive_count_leafs(X, __FILE__, __LINE__) #include <ext/pb_ds/detail/pat_trie_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/pat_trie_/iterators_fn_imps.hpp> #include <ext/pb_ds/detail/pat_trie_/insert_join_fn_imps.hpp> #include <ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/pat_trie_/find_fn_imps.hpp> #include <ext/pb_ds/detail/pat_trie_/info_fn_imps.hpp> #include <ext/pb_ds/detail/pat_trie_/policy_access_fn_imps.hpp> #include <ext/pb_ds/detail/pat_trie_/split_fn_imps.hpp> #include <ext/pb_ds/detail/pat_trie_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/pat_trie_/trace_fn_imps.hpp> #include <ext/pb_ds/detail/pat_trie_/update_fn_imps.hpp> #undef PB_DS_RECURSIVE_COUNT_LEAFS #undef PB_DS_ASSERT_NODE_VALID #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_PAT_TRIE_NAME #undef PB_DS_PAT_TRIE_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/pat_trie_/erase_fn_imps.hpp 0000644 00000017411 15146341150 0015711 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pat_trie_/erase_fn_imps.hpp * Contains an implementation class for pat_trie. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { node_pointer p_nd = find_imp(r_key); if (p_nd == 0 || p_nd->m_type == i_node) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node); if (!synth_access_traits::equal_keys(PB_DS_V2F(reinterpret_cast<leaf_pointer>(p_nd)->value()), r_key)) { PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } PB_DS_CHECK_KEY_EXISTS(r_key) erase_leaf(static_cast<leaf_pointer>(p_nd)); PB_DS_ASSERT_VALID((*this)) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_fixup(inode_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) >= 1); if (std::distance(p_nd->begin(), p_nd->end()) == 1) { node_pointer p_parent = p_nd->m_p_parent; if (p_parent == m_p_head) m_p_head->m_p_parent = *p_nd->begin(); else { _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == i_node); node_pointer p_new_child = *p_nd->begin(); typedef inode_pointer inode_ptr; inode_ptr p_internal = static_cast<inode_ptr>(p_parent); p_internal->replace_child(p_new_child, pref_begin(p_new_child), pref_end(p_new_child), this); } (*p_nd->begin())->m_p_parent = p_nd->m_p_parent; p_nd->~inode(); s_inode_allocator.deallocate(p_nd, 1); if (p_parent == m_p_head) return; _GLIBCXX_DEBUG_ASSERT(p_parent->m_type == i_node); p_nd = static_cast<inode_pointer>(p_parent); } while (true) { _GLIBCXX_DEBUG_ASSERT(std::distance(p_nd->begin(), p_nd->end()) > 1); p_nd->update_prefixes(this); apply_update(p_nd, (node_update*)this); PB_DS_ASSERT_NODE_VALID(p_nd) if (p_nd->m_p_parent->m_type == head_node) return; _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_parent->m_type == i_node); p_nd = static_cast<inode_pointer>(p_nd->m_p_parent); } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_leaf(leaf_pointer p_l) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_l->value()))); p_l->~leaf(); s_leaf_allocator.deallocate(p_l, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { if (!empty()) { clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) PB_DS_ASSERT_VALID((*this)) } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd->m_type == i_node) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node); for (typename inode::iterator it = static_cast<inode_pointer>(p_nd)->begin(); it != static_cast<inode_pointer>(p_nd)->end(); ++it) { node_pointer p_child =* it; clear_imp(p_child); } s_inode_allocator.deallocate(static_cast<inode_pointer>(p_nd), 1); return; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node); static_cast<leaf_pointer>(p_nd)->~leaf(); s_leaf_allocator.deallocate(static_cast<leaf_pointer>(p_nd), 1); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: erase(const_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == end()) return it; const_iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: erase(iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == end()) return it; iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: erase(const_reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == m_p_head) return it; const_reverse_iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: erase(reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == m_p_head) return it; reverse_iterator ret_it = it; ++ret_it; _GLIBCXX_DEBUG_ASSERT(it.m_p_nd->m_type == leaf_node); erase_leaf(static_cast<leaf_pointer>(it.m_p_nd)); PB_DS_ASSERT_VALID((*this)) return ret_it; } #endif // #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_CLASS_T_DEC template<typename Pred> inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { size_type num_ersd = 0; PB_DS_ASSERT_VALID((*this)) iterator it = begin(); while (it != end()) { PB_DS_ASSERT_VALID((*this)) if (pred(*it)) { ++num_ersd; it = erase(it); } else ++it; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_leaf(leaf_pointer p_l) { update_min_max_for_erased_leaf(p_l); if (p_l->m_p_parent->m_type == head_node) { _GLIBCXX_DEBUG_ASSERT(size() == 1); clear(); return; } _GLIBCXX_DEBUG_ASSERT(size() > 1); _GLIBCXX_DEBUG_ASSERT(p_l->m_p_parent->m_type == i_node); inode_pointer p_parent = static_cast<inode_pointer>(p_l->m_p_parent); p_parent->remove_child(p_l); erase_fixup(p_parent); actual_erase_leaf(p_l); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_leaf(leaf_pointer p_l) { if (m_size == 1) { m_p_head->m_p_min = m_p_head; m_p_head->m_p_max = m_p_head; return; } if (p_l == static_cast<leaf_const_pointer>(m_p_head->m_p_min)) { iterator it(p_l); ++it; m_p_head->m_p_min = it.m_p_nd; return; } if (p_l == static_cast<leaf_const_pointer>(m_p_head->m_p_max)) { iterator it(p_l); --it; m_p_head->m_p_max = it.m_p_nd; } } c++/8/ext/pb_ds/detail/standard_policies.hpp 0000644 00000011647 15146341150 0014625 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/standard_policies.hpp * Contains standard policies for containers. */ #ifndef PB_DS_STANDARD_POLICIES_HPP #define PB_DS_STANDARD_POLICIES_HPP #include <memory> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/list_update_policy.hpp> #include <ext/pb_ds/detail/branch_policy/null_node_metadata.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/trie_policy.hpp> #include <ext/pb_ds/tag_and_trait.hpp> #include <tr1/functional> namespace __gnu_pbds { namespace detail { /// Primary template, default_hash_fn. template<typename Key> struct default_hash_fn { /// Dispatched type. typedef std::tr1::hash<Key> type; }; /// Primary template, default_eq_fn. template<typename Key> struct default_eq_fn { /// Dispatched type. typedef std::equal_to<Key> type; }; /// Enumeration for default behavior of stored hash data. enum { default_store_hash = false }; /// Primary template, default_comb_hash_fn. struct default_comb_hash_fn { /// Dispatched type. typedef direct_mask_range_hashing<> type; }; /// Primary template, default_resize_policy. template<typename Comb_Hash_Fn> struct default_resize_policy { private: typedef typename Comb_Hash_Fn::size_type size_type; typedef direct_mask_range_hashing<size_type> default_fn; typedef is_same<default_fn, Comb_Hash_Fn> same_type; typedef hash_exponential_size_policy<size_type> iftrue; typedef hash_prime_size_policy iffalse; typedef __conditional_type<same_type::value, iftrue, iffalse> cond_type; typedef typename cond_type::__type size_policy_type; typedef hash_load_check_resize_trigger<false, size_type> trigger; public: /// Dispatched type. typedef hash_standard_resize_policy<size_policy_type, trigger, false, size_type> type; }; /// Default update policy. struct default_update_policy { /// Dispatched type. typedef lu_move_to_front_policy<> type; }; /// Primary template, default_probe_fn. template<typename Comb_Probe_Fn> struct default_probe_fn { private: typedef typename Comb_Probe_Fn::size_type size_type; typedef direct_mask_range_hashing<size_type> default_fn; typedef is_same<default_fn, Comb_Probe_Fn> same_type; typedef linear_probe_fn<size_type> iftrue; typedef quadratic_probe_fn<size_type> iffalse; typedef __conditional_type<same_type::value, iftrue, iffalse> cond_type; public: /// Dispatched type. typedef typename cond_type::__type type; }; /// Primary template, default_trie_access_traits. template<typename Key> struct default_trie_access_traits; #define __dtrie_alloc std::allocator<char> #define __dtrie_string std::basic_string<Char, Char_Traits, __dtrie_alloc> /// Partial specialization, default_trie_access_traits. template<typename Char, typename Char_Traits> struct default_trie_access_traits<__dtrie_string> { private: typedef __dtrie_string string_type; public: /// Dispatched type. typedef trie_string_access_traits<string_type> type; }; #undef __dtrie_alloc #undef __dtrie_string } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_STANDARD_POLICIES_HPP c++/8/ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp 0000644 00000005125 15146341150 0021724 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/debug_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_array_valid(const entry_array a_entries, true_type, const char* __file, int __line) const { size_type iterated_num_used_e = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { const_entry_pointer p_e =& a_entries[pos]; switch(p_e->m_stat) { case empty_entry_status: case erased_entry_status: break; case valid_entry_status: { key_const_reference r_key = PB_DS_V2F(p_e->m_value); debug_base::check_key_exists(r_key, __file, __line); const comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); PB_DS_DEBUG_VERIFY(p_e->m_hash == pos_hash_pair.second); ++iterated_num_used_e; break; } default: PB_DS_DEBUG_VERIFY(0); }; } PB_DS_DEBUG_VERIFY(iterated_num_used_e == m_num_used_e); } #endif c++/8/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp 0000644 00000014716 15146341150 0023270 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/constructor_destructor_fn_imps.hpp * Contains implementations of gp_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME() : ranged_probe_fn_base(resize_base::get_nearest_larger_size(1)), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn) : ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) : hash_eq_fn_base(r_eq_fn), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Probe_Fn& r_comb_hash_fn) : hash_eq_fn_base(r_eq_fn), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, r_comb_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober) : hash_eq_fn_base(r_eq_fn), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, comb_hash_fn, prober), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Probe_Fn& comb_hash_fn, const Probe_Fn& prober, const Resize_Policy& r_resize_policy) : hash_eq_fn_base(r_eq_fn), resize_base(r_resize_policy), ranged_probe_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, comb_hash_fn, prober), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_GP_HASH_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef _GLIBCXX_DEBUG debug_base(other), #endif hash_eq_fn_base(other), resize_base(other), ranged_probe_fn_base(other), m_num_e(other.m_num_e), m_num_used_e(other.m_num_used_e), m_entries(s_entry_allocator.allocate(m_num_e)) { for (size_type i = 0; i < m_num_e; ++i) m_entries[i].m_stat = (entry_status)empty_entry_status; __try { for (size_type i = 0; i < m_num_e; ++i) { m_entries[i].m_stat = other.m_entries[i].m_stat; if (m_entries[i].m_stat == valid_entry_status) new (m_entries + i) entry(other.m_entries[i]); } } __catch(...) { deallocate_all(); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_GP_HASH_NAME() { deallocate_all(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) std::swap(m_num_e, other.m_num_e); std::swap(m_num_used_e, other.m_num_used_e); std::swap(m_entries, other.m_entries); ranged_probe_fn_base::swap(other); hash_eq_fn_base::swap(other); resize_base::swap(other); _GLIBCXX_DEBUG_ONLY(debug_base::swap(other)); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_all() { clear(); erase_all_valid_entries(m_entries, m_num_e); s_entry_allocator.deallocate(m_entries, m_num_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_all_valid_entries(entry_array a_entries_resized, size_type len) { for (size_type pos = 0; pos < len; ++pos) { entry_pointer p_e = &a_entries_resized[pos]; if (p_e->m_stat == valid_entry_status) p_e->m_value.~value_type(); } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { Resize_Policy::notify_resized(m_num_e); Resize_Policy::notify_cleared(); ranged_probe_fn_base::notify_resized(m_num_e); for (size_type i = 0; i < m_num_e; ++i) m_entries[i].m_stat = empty_entry_status; } c++/8/ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp 0000644 00000004074 15146341150 0017354 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/info_fn_imps.hpp * Contains implementations of gp_ht_map_'s entire container info related * functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_num_used_e; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (size() == 0); } c++/8/ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp 0000644 00000005547 15146341150 0021745 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/erase_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s erase related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_imp(key_const_reference r_key, true_type) { const comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); size_type i; resize_base::notify_erase_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, pos_hash_pair.second, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_erase_search_end(); erase_entry(p_e); do_resize_if_needed_no_throw(); return true; } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_erase_search_collision(); } resize_base::notify_erase_search_end(); return false; } c++/8/ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp 0000644 00000004176 15146341150 0017512 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/debug_fn_imps.hpp * Contains implementations of gp_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { debug_base::check_size(m_num_used_e, __file, __line); assert_entry_array_valid(m_entries, traits_base::m_store_extra_indicator, __file, __line); } #include <ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/debug_store_hash_fn_imps.hpp> #endif c++/8/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp 0000644 00000010075 15146341150 0017720 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/resize_fn_imps.hpp * Contains implementations of gp_ht_map_'s resize related functions. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: do_resize_if_needed() { if (!resize_base::is_resize_needed()) return false; resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type n) { resize_imp(resize_base::get_nearest_larger_size(n)); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: do_resize_if_needed_no_throw() { if (!resize_base::is_resize_needed()) return; __try { resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); } __catch(...) { } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp(size_type new_size) { #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_num_e); #endif if (new_size == m_num_e) return; PB_DS_ASSERT_VALID((*this)) const size_type old_size = m_num_e; entry_array a_entries_resized = 0; // Following line might throw an exception. a_entries_resized = s_entry_allocator.allocate(new_size); ranged_probe_fn_base::notify_resized(new_size); m_num_e = new_size; for (size_type i = 0; i < m_num_e; ++i) a_entries_resized[i].m_stat = empty_entry_status; __try { resize_imp(a_entries_resized, old_size); } __catch(...) { erase_all_valid_entries(a_entries_resized, new_size); m_num_e = old_size; s_entry_allocator.deallocate(a_entries_resized, new_size); ranged_probe_fn_base::notify_resized(old_size); __throw_exception_again; } // At this point no exceptions can be thrown. _GLIBCXX_DEBUG_ONLY(assert_entry_array_valid(a_entries_resized, traits_base::m_store_extra_indicator, __FILE__, __LINE__);) Resize_Policy::notify_resized(new_size); erase_all_valid_entries(m_entries, old_size); s_entry_allocator.deallocate(m_entries, old_size); m_entries = a_entries_resized; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp(entry_array a_entries_resized, size_type old_size) { for (size_type pos = 0; pos < old_size; ++pos) if (m_entries[pos].m_stat == valid_entry_status) resize_imp_reassign(m_entries + pos, a_entries_resized, traits_base::m_store_extra_indicator); } #include <ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp> c++/8/ext/pb_ds/detail/gp_hash_table_map_/find_store_hash_fn_imps.hpp 0000644 00000003364 15146341150 0021561 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/find_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s insert related functions, * when the hash value is stored. */ c++/8/ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp 0000644 00000003550 15146341150 0017723 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/insert_fn_imps.hpp * Contains implementations of gp_ht_map_'s insert related functions. */ #include <ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp> c++/8/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp 0000644 00000004335 15146341150 0025503 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(mapped_const_reference r_val, size_type pos, true_type) { _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); entry* const p_e = m_entries + pos; new (&p_e->m_value) mapped_value_type(r_val); p_e->m_hash = ranged_probe_fn_base::operator()(PB_DS_V2F(r_val)).second; p_e->m_stat = valid_entry_status; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(p_e->m_value.first);) } c++/8/ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp 0000644 00000005505 15146341150 0022433 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s erase related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_imp(key_const_reference r_key, false_type) { PB_DS_ASSERT_VALID((*this)) size_type hash = ranged_probe_fn_base::operator()(r_key); size_type i; resize_base::notify_erase_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return false; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_erase_search_end(); erase_entry(p_e); do_resize_if_needed_no_throw(); return true; } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_erase_search_collision(); } resize_base::notify_erase_search_end(); return false; } c++/8/ext/pb_ds/detail/gp_hash_table_map_/insert_store_hash_fn_imps.hpp 0000644 00000007765 15146341150 0022156 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/insert_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s find related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: find_ins_pos(key_const_reference r_key, true_type) { PB_DS_ASSERT_VALID((*this)) comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(r_key); size_type i; /* The insertion position is initted to a non-legal value to indicate * that it has not been initted yet. */ size_type ins_pos = m_num_e; resize_base::notify_insert_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, pos_hash_pair.second, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return ((ins_pos == m_num_e) ? std::make_pair(pos, pos_hash_pair.second) : std::make_pair(ins_pos, pos_hash_pair.second)); } break; case erased_entry_status: if (ins_pos == m_num_e) ins_pos = pos; break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(pos, pos_hash_pair.second); } break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_insert_search_collision(); } resize_base::notify_insert_search_end(); if (ins_pos == m_num_e) __throw_insert_error(); return std::make_pair(ins_pos, pos_hash_pair.second); } PB_DS_CLASS_T_DEC inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, true_type) { key_const_reference r_key = PB_DS_V2F(r_val); comp_hash pos_hash_pair = find_ins_pos(r_key, traits_base::m_store_extra_indicator); _GLIBCXX_DEBUG_ASSERT(pos_hash_pair.first < m_num_e); entry_pointer p_e =& m_entries[pos_hash_pair.first]; if (p_e->m_stat == valid_entry_status) { PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(&p_e->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return std::make_pair(insert_new_imp(r_val, pos_hash_pair), true); } c++/8/ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp 0000644 00000005073 15146341150 0020252 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/iterator_fn_imps.hpp * Contains implementations of gp_ht_map_'s iterators related functions, e.g., * begin(). */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC::s_end_it; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC::s_const_end_it; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { pointer_ p_value; size_type pos; get_start_it_state(p_value, pos); return iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return s_end_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { const_pointer_ p_value; size_type pos; get_start_it_state(p_value, pos); return const_iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return s_const_end_it; } c++/8/ext/pb_ds/detail/gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp 0000644 00000007301 15146341150 0022634 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/insert_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s insert related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: find_ins_pos(key_const_reference r_key, false_type) { size_type hash = ranged_probe_fn_base::operator()(r_key); size_type i; /* The insertion position is initted to a non-legal value to indicate * that it has not been initted yet. */ size_type ins_pos = m_num_e; resize_base::notify_insert_search_start(); for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); _GLIBCXX_DEBUG_ASSERT(pos < m_num_e); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return (ins_pos == m_num_e) ? pos : ins_pos; } break; case erased_entry_status: if (ins_pos == m_num_e) ins_pos = pos; break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_insert_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) return pos; } break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_insert_search_collision(); } resize_base::notify_insert_search_end(); if (ins_pos == m_num_e) __throw_insert_error(); return ins_pos; } PB_DS_CLASS_T_DEC inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, false_type) { key_const_reference r_key = PB_DS_V2F(r_val); const size_type pos = find_ins_pos(r_key, traits_base::m_store_extra_indicator); if (m_entries[pos].m_stat == valid_entry_status) { PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(&(m_entries + pos)->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return std::make_pair(insert_new_imp(r_val, pos), true); } c++/8/ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp 0000644 00000004570 15146341150 0017520 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/trace_fn_imps.hpp * Contains implementations of gp_ht_map_'s trace-mode functions. */ #ifdef PB_DS_HT_MAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << static_cast<unsigned long>(m_num_e) << " " << static_cast<unsigned long>(m_num_used_e) << std::endl; for (size_type i = 0; i < m_num_e; ++i) { std::cerr << static_cast<unsigned long>(i) << " "; switch(m_entries[i].m_stat) { case empty_entry_status: std::cerr << "<empty>"; break; case erased_entry_status: std::cerr << "<erased>"; break; case valid_entry_status: std::cerr << PB_DS_V2F(m_entries[i].m_value); break; default: _GLIBCXX_DEBUG_ASSERT(0); }; std::cerr << std::endl; } } #endif // #ifdef PB_DS_HT_MAP_TRACE_ c++/8/ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp 0000644 00000005144 15146341150 0021240 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/policy_access_fn_imps.hpp * Contains implementations of gp_ht_map_'s policy agpess * functions. */ PB_DS_CLASS_T_DEC Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() { return *this; } PB_DS_CLASS_T_DEC const Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() const { return *this; } PB_DS_CLASS_T_DEC Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() { return *this; } PB_DS_CLASS_T_DEC const Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() const { return *this; } PB_DS_CLASS_T_DEC Probe_Fn& PB_DS_CLASS_C_DEC:: get_probe_fn() { return *this; } PB_DS_CLASS_T_DEC const Probe_Fn& PB_DS_CLASS_C_DEC:: get_probe_fn() const { return *this; } PB_DS_CLASS_T_DEC Comb_Probe_Fn& PB_DS_CLASS_C_DEC:: get_comb_probe_fn() { return *this; } PB_DS_CLASS_T_DEC const Comb_Probe_Fn& PB_DS_CLASS_C_DEC:: get_comb_probe_fn() const { return *this; } PB_DS_CLASS_T_DEC Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() { return *this; } PB_DS_CLASS_T_DEC const Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() const { return *this; } c++/8/ext/pb_ds/detail/gp_hash_table_map_/resize_store_hash_fn_imps.hpp 0000644 00000005133 15146341150 0022136 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/resize_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s resize related functions, when the * hash value is stored. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_imp_reassign(entry_pointer p_e, entry_array a_entries_resized, true_type) { key_const_reference r_key = PB_DS_V2F(p_e->m_value); size_type hash = ranged_probe_fn_base::operator()(r_key, p_e->m_hash); size_type i; for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); entry_pointer p_new_e = a_entries_resized + pos; switch(p_new_e->m_stat) { case empty_entry_status: new (&p_new_e->m_value) value_type(p_e->m_value); p_new_e->m_hash = hash; p_new_e->m_stat = valid_entry_status; return; case erased_entry_status: _GLIBCXX_DEBUG_ASSERT(0); break; case valid_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; } __throw_insert_error(); } c++/8/ext/pb_ds/detail/gp_hash_table_map_/find_no_store_hash_fn_imps.hpp 0000644 00000003604 15146341150 0022252 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/find_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s find related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::pointer PB_DS_CLASS_C_DEC:: find_key_pointer(key_const_reference r_key, false_type) c++/8/ext/pb_ds/detail/gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp 0000644 00000004711 15146341150 0022420 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/debug_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_array_valid(const entry_array a_entries, false_type, const char* __file, int __line) const { size_type iterated_num_used_e = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { const_entry_pointer p_e = &a_entries[pos]; switch(p_e->m_stat) { case empty_entry_status: case erased_entry_status: break; case valid_entry_status: { key_const_reference r_key = PB_DS_V2F(p_e->m_value); debug_base::check_key_exists(r_key, __file, __line); ++iterated_num_used_e; break; } default: PB_DS_DEBUG_VERIFY(0); }; } PB_DS_DEBUG_VERIFY(iterated_num_used_e == m_num_used_e); } #endif c++/8/ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp 0000644 00000047656 15146341150 0017020 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/gp_ht_map_.hpp * Contains an implementation class for general probing hash. */ #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp> #include <ext/pb_ds/detail/types_traits.hpp> #include <ext/pb_ds/exception.hpp> #include <ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp> #include <utility> #ifdef PB_DS_HT_MAP_TRACE_ #include <iostream> #endif #ifdef _GLIBCXX_DEBUG #include <ext/pb_ds/detail/debug_map_base.hpp> #endif #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_GP_HASH_NAME gp_ht_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_GP_HASH_NAME gp_ht_set #endif #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Mapped, typename Hash_Fn, typename Eq_Fn, \ typename _Alloc, bool Store_Hash, typename Comb_Probe_Fn, \ typename Probe_Fn, typename Resize_Policy> #define PB_DS_CLASS_C_DEC \ PB_DS_GP_HASH_NAME<Key, Mapped, Hash_Fn, Eq_Fn, _Alloc, \ Store_Hash, Comb_Probe_Fn, Probe_Fn, Resize_Policy> #define PB_DS_HASH_EQ_FN_C_DEC \ hash_eq_fn<Key, Eq_Fn, _Alloc, Store_Hash> #define PB_DS_RANGED_PROBE_FN_C_DEC \ ranged_probe_fn<Key, Hash_Fn, _Alloc, Comb_Probe_Fn, Probe_Fn, Store_Hash> #define PB_DS_GP_HASH_TRAITS_BASE \ types_traits<Key, Mapped, _Alloc, Store_Hash> #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base<Key, Eq_Fn, \ typename _Alloc::template rebind<Key>::other::const_reference> #endif /** * A general-probing hash-based container. * * * @ingroup hash-detail * * @tparam Key Key type. * * @tparam Mapped Map type. * * @tparam Hash_Fn Hashing functor. * Default is __gnu_cxx::hash. * * @tparam Eq_Fn Equal functor. * Default std::equal_to<Key> * * @tparam _Alloc Allocator type. * * @tparam Store_Hash If key type stores extra metadata. * Defaults to false. * * @tparam Comb_Probe_Fn Combining probe functor. * If Hash_Fn is not null_type, then this * is the ranged-probe functor; otherwise, * this is the range-hashing functor. * XXX See Design::Hash-Based Containers::Hash Policies. * Default direct_mask_range_hashing. * * @tparam Probe_Fn Probe functor. * Defaults to linear_probe_fn, * also quadratic_probe_fn. * * @tparam Resize_Policy Resizes hash. * Defaults to hash_standard_resize_policy, * using hash_exponential_size_policy and * hash_load_check_resize_trigger. * * * Bases are: detail::hash_eq_fn, Resize_Policy, detail::ranged_probe_fn, * detail::types_traits. (Optional: detail::debug_map_base.) */ template<typename Key, typename Mapped, typename Hash_Fn, typename Eq_Fn, typename _Alloc, bool Store_Hash, typename Comb_Probe_Fn, typename Probe_Fn, typename Resize_Policy> class PB_DS_GP_HASH_NAME : #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public PB_DS_HASH_EQ_FN_C_DEC, public Resize_Policy, public PB_DS_RANGED_PROBE_FN_C_DEC, public PB_DS_GP_HASH_TRAITS_BASE { private: typedef PB_DS_GP_HASH_TRAITS_BASE traits_base; typedef typename traits_base::value_type value_type_; typedef typename traits_base::pointer pointer_; typedef typename traits_base::const_pointer const_pointer_; typedef typename traits_base::reference reference_; typedef typename traits_base::const_reference const_reference_; typedef typename traits_base::comp_hash comp_hash; enum entry_status { empty_entry_status, valid_entry_status, erased_entry_status } __attribute__ ((__packed__)); struct entry : public traits_base::stored_data_type { entry_status m_stat; }; typedef typename _Alloc::template rebind<entry>::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef typename entry_allocator::const_pointer const_entry_pointer; typedef typename entry_allocator::reference entry_reference; typedef typename entry_allocator::const_reference const_entry_reference; typedef typename entry_allocator::pointer entry_array; typedef PB_DS_RANGED_PROBE_FN_C_DEC ranged_probe_fn_base; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; typedef Resize_Policy resize_base; #define PB_DS_GEN_POS typename _Alloc::size_type #include <ext/pb_ds/detail/unordered_iterator/point_const_iterator.hpp> #include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp> #include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp> #include <ext/pb_ds/detail/unordered_iterator/iterator.hpp> #undef PB_DS_GEN_POS public: typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Probe_Fn probe_fn; typedef Comb_Probe_Fn comb_probe_fn; typedef Resize_Policy resize_policy; /// Value stores hash, true or false. enum { store_hash = Store_Hash }; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef point_iterator_ point_iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef point_const_iterator_ point_iterator; #endif typedef point_const_iterator_ point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef iterator_ iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef const_iterator_ iterator; #endif typedef const_iterator_ const_iterator; PB_DS_GP_HASH_NAME(); PB_DS_GP_HASH_NAME(const PB_DS_CLASS_C_DEC&); PB_DS_GP_HASH_NAME(const Hash_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&, const Probe_Fn&); PB_DS_GP_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Probe_Fn&, const Probe_Fn&, const Resize_Policy&); template<typename It> void copy_from_range(It, It); virtual ~PB_DS_GP_HASH_NAME(); void swap(PB_DS_CLASS_C_DEC&); inline size_type size() const; inline size_type max_size() const; /// True if size() == 0. inline bool empty() const; /// Return current hash_fn. Hash_Fn& get_hash_fn(); /// Return current const hash_fn. const Hash_Fn& get_hash_fn() const; /// Return current eq_fn. Eq_Fn& get_eq_fn(); /// Return current const eq_fn. const Eq_Fn& get_eq_fn() const; /// Return current probe_fn. Probe_Fn& get_probe_fn(); /// Return current const probe_fn. const Probe_Fn& get_probe_fn() const; /// Return current comb_probe_fn. Comb_Probe_Fn& get_comb_probe_fn(); /// Return current const comb_probe_fn. const Comb_Probe_Fn& get_comb_probe_fn() const; /// Return current resize_policy. Resize_Policy& get_resize_policy(); /// Return current const resize_policy. const Resize_Policy& get_resize_policy() const; inline std::pair<point_iterator, bool> insert(const_reference r_val) { _GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::assert_valid(__FILE__, __LINE__);) return insert_imp(r_val, traits_base::m_store_extra_indicator); } inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR return subscript_imp(r_key, traits_base::m_store_extra_indicator); #else insert(r_key); return traits_base::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline point_iterator find_end(); inline point_const_iterator find_end() const; inline bool erase(key_const_reference); template<typename Pred> inline size_type erase_if(Pred); void clear(); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_HT_MAP_TRACE_ void trace() const; #endif private: #ifdef PB_DS_DATA_TRUE_INDICATOR friend class iterator_; #endif friend class const_iterator_; void deallocate_all(); void initialize(); void erase_all_valid_entries(entry_array, size_type); inline bool do_resize_if_needed(); inline void do_resize_if_needed_no_throw(); void resize_imp(size_type); virtual void do_resize(size_type); void resize_imp(entry_array, size_type); inline void resize_imp_reassign(entry_pointer, entry_array, false_type); inline void resize_imp_reassign(entry_pointer, entry_array, true_type); inline size_type find_ins_pos(key_const_reference, false_type); inline comp_hash find_ins_pos(key_const_reference, true_type); inline std::pair<point_iterator, bool> insert_imp(const_reference, false_type); inline std::pair<point_iterator, bool> insert_imp(const_reference, true_type); inline pointer insert_new_imp(const_reference r_val, size_type pos) { _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); if (do_resize_if_needed()) pos = find_ins_pos(PB_DS_V2F(r_val), traits_base::m_store_extra_indicator); _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status); entry* const p_e = m_entries + pos; new (&p_e->m_value) value_type(r_val); p_e->m_stat = valid_entry_status; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(p_e->m_value));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } inline pointer insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) { _GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat != valid_entry_status); if (do_resize_if_needed()) r_pos_hash_pair = find_ins_pos(PB_DS_V2F(r_val), traits_base::m_store_extra_indicator); _GLIBCXX_DEBUG_ASSERT(m_entries[r_pos_hash_pair.first].m_stat != valid_entry_status); entry* const p_e = m_entries + r_pos_hash_pair.first; new (&p_e->m_value) value_type(r_val); p_e->m_hash = r_pos_hash_pair.second; p_e->m_stat = valid_entry_status; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(p_e->m_value));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } #ifdef PB_DS_DATA_TRUE_INDICATOR inline mapped_reference subscript_imp(key_const_reference key, false_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) const size_type pos = find_ins_pos(key, traits_base::m_store_extra_indicator); entry_pointer p_e = &m_entries[pos]; if (p_e->m_stat != valid_entry_status) return insert_new_imp(value_type(key, mapped_type()), pos)->second; PB_DS_CHECK_KEY_EXISTS(key) return p_e->m_value.second; } inline mapped_reference subscript_imp(key_const_reference key, true_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) comp_hash pos_hash_pair = find_ins_pos(key, traits_base::m_store_extra_indicator); if (m_entries[pos_hash_pair.first].m_stat != valid_entry_status) return insert_new_imp(value_type(key, mapped_type()), pos_hash_pair)->second; PB_DS_CHECK_KEY_EXISTS(key) return (m_entries + pos_hash_pair.first)->m_value.second; } #endif inline pointer find_key_pointer(key_const_reference key, false_type) { const size_type hash = ranged_probe_fn_base::operator()(key); resize_base::notify_find_search_start(); // Loop until entry is found or until all possible entries accessed. for (size_type i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(key, hash, i); entry* const p_e = m_entries + pos; switch (p_e->m_stat) { case empty_entry_status: { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) return 0; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), key)) { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_EXISTS(key) return pointer(&p_e->m_value); } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_find_search_collision(); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) resize_base::notify_find_search_end(); return 0; } inline pointer find_key_pointer(key_const_reference key, true_type) { comp_hash pos_hash_pair = ranged_probe_fn_base::operator()(key); resize_base::notify_find_search_start(); // Loop until entry is found or until all possible entries accessed. for (size_type i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(key, pos_hash_pair.second, i); entry* const p_e = m_entries + pos; switch(p_e->m_stat) { case empty_entry_status: { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) return 0; } break; case valid_entry_status: if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, key, pos_hash_pair.second)) { resize_base::notify_find_search_end(); PB_DS_CHECK_KEY_EXISTS(key) return pointer(&p_e->m_value); } break; case erased_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; resize_base::notify_find_search_collision(); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) resize_base::notify_find_search_end(); return 0; } inline bool erase_imp(key_const_reference, true_type); inline bool erase_imp(key_const_reference, false_type); inline void erase_entry(entry_pointer); #ifdef PB_DS_DATA_TRUE_INDICATOR void inc_it_state(pointer& r_p_value, size_type& r_pos) const { inc_it_state((mapped_const_pointer& )r_p_value, r_pos); } #endif void inc_it_state(const_pointer& r_p_value, size_type& r_pos) const { _GLIBCXX_DEBUG_ASSERT(r_p_value != 0); for (++r_pos; r_pos < m_num_e; ++r_pos) { const_entry_pointer p_e =& m_entries[r_pos]; if (p_e->m_stat == valid_entry_status) { r_p_value =& p_e->m_value; return; } } r_p_value = 0; } void get_start_it_state(const_pointer& r_p_value, size_type& r_pos) const { for (r_pos = 0; r_pos < m_num_e; ++r_pos) { const_entry_pointer p_e = &m_entries[r_pos]; if (p_e->m_stat == valid_entry_status) { r_p_value = &p_e->m_value; return; } } r_p_value = 0; } void get_start_it_state(pointer& r_p_value, size_type& r_pos) { for (r_pos = 0; r_pos < m_num_e; ++r_pos) { entry_pointer p_e = &m_entries[r_pos]; if (p_e->m_stat == valid_entry_status) { r_p_value = &p_e->m_value; return; } } r_p_value = 0; } #ifdef _GLIBCXX_DEBUG void assert_entry_array_valid(const entry_array, false_type, const char*, int) const; void assert_entry_array_valid(const entry_array, true_type, const char*, int) const; #endif static entry_allocator s_entry_allocator; static iterator s_end_it; static const_iterator s_const_end_it; size_type m_num_e; size_type m_num_used_e; entry_pointer m_entries; enum { store_hash_ok = !Store_Hash || !is_same<Hash_Fn, __gnu_pbds::null_type>::value }; PB_DS_STATIC_ASSERT(sth, store_hash_ok); }; #include <ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/info_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/policy_access_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/iterator_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/trace_fn_imps.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_HASH_EQ_FN_C_DEC #undef PB_DS_RANGED_PROBE_FN_C_DEC #undef PB_DS_GP_HASH_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #undef PB_DS_GP_HASH_NAME } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp 0000644 00000004232 15146341150 0026173 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(mapped_const_reference r_val, size_type pos, false_type) { _GLIBCXX_DEBUG_ASSERT(m_entries[pos].m_stat != valid_entry_status)k; entry* const p_e = m_entries + pos; new (&p_e->m_value) mapped_value_type(r_val); p_e->m_stat = valid_entry_status; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(p_e->m_value.first);) } c++/8/ext/pb_ds/detail/gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp 0000644 00000005072 15146341150 0022634 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/resize_no_store_hash_fn_imps.hpp * Contains implementations of gp_ht_map_'s resize related functions, when the * hash value is not stored. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_imp_reassign(entry_pointer p_e, entry_array a_entries_resized, false_type) { key_const_reference r_key = PB_DS_V2F(p_e->m_value); size_type hash = ranged_probe_fn_base::operator()(r_key); size_type i; for (i = 0; i < m_num_e; ++i) { const size_type pos = ranged_probe_fn_base::operator()(r_key, hash, i); entry_pointer p_new_e = a_entries_resized + pos; switch(p_new_e->m_stat) { case empty_entry_status: new (&p_new_e->m_value) value_type(p_e->m_value); p_new_e->m_stat = valid_entry_status; return; case erased_entry_status: _GLIBCXX_DEBUG_ASSERT(0); break; case valid_entry_status: break; default: _GLIBCXX_DEBUG_ASSERT(0); }; } __throw_insert_error(); } c++/8/ext/pb_ds/detail/gp_hash_table_map_/find_fn_imps.hpp 0000644 00000004656 15146341150 0017347 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/find_fn_imps.hpp * Contains implementations of gp_ht_map_'s find related functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) return find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) return const_cast<PB_DS_CLASS_C_DEC&>(*this).find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find_end() { return 0; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find_end() const { return 0; } c++/8/ext/pb_ds/detail/gp_hash_table_map_/erase_fn_imps.hpp 0000644 00000006204 15146341150 0017515 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file gp_hash_table_map_/erase_fn_imps.hpp * Contains implementations of gp_ht_map_'s erase related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase_entry(entry_pointer p_e) { _GLIBCXX_DEBUG_ASSERT(p_e->m_stat = valid_entry_status); _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_e->m_value));) p_e->m_value.~value_type(); p_e->m_stat = erased_entry_status; _GLIBCXX_DEBUG_ASSERT(m_num_used_e > 0); resize_base::notify_erased(--m_num_used_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { for (size_type pos = 0; pos < m_num_e; ++pos) { entry_pointer p_e = &m_entries[pos]; if (p_e->m_stat == valid_entry_status) erase_entry(p_e); } do_resize_if_needed_no_throw(); resize_base::notify_cleared(); } PB_DS_CLASS_T_DEC template<typename Pred> inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { entry_pointer p_e = &m_entries[pos]; if (p_e->m_stat == valid_entry_status) if (pred(p_e->m_value)) { ++num_ersd; erase_entry(p_e); } } do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { return erase_imp(r_key, traits_base::m_store_extra_indicator); } #include <ext/pb_ds/detail/gp_hash_table_map_/erase_no_store_hash_fn_imps.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/erase_store_hash_fn_imps.hpp> c++/8/ext/pb_ds/detail/cond_dealtor.hpp 0000644 00000005244 15146341150 0013567 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/cond_dealtor.hpp * Contains a conditional deallocator. */ #ifndef PB_DS_COND_DEALTOR_HPP #define PB_DS_COND_DEALTOR_HPP namespace __gnu_pbds { namespace detail { /// Conditional deallocate constructor argument. template<typename Entry, typename _Alloc> class cond_dealtor { typedef typename _Alloc::template rebind<Entry> __rebind_e; public: typedef typename __rebind_e::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; cond_dealtor(entry_pointer p_e) : m_p_e(p_e), m_no_action_destructor(false) { } ~cond_dealtor() { if (m_no_action_destructor) return; s_alloc.deallocate(m_p_e, 1); } void set_no_action() { m_no_action_destructor = true; } private: entry_pointer m_p_e; bool m_no_action_destructor; static entry_allocator s_alloc; }; template<typename Entry, class _Alloc> typename cond_dealtor<Entry, _Alloc>::entry_allocator cond_dealtor<Entry, _Alloc>::s_alloc; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_COND_DEALTOR_HPP c++/8/ext/pb_ds/detail/hash_fn/ranged_probe_fn.hpp 0000644 00000024304 15146341150 0015650 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ranged_probe_fn.hpp * Contains a unified ranged probe functor, allowing the probe tables to deal with * a single class for ranged probeing. */ #ifndef PB_DS_RANGED_PROBE_FN_HPP #define PB_DS_RANGED_PROBE_FN_HPP #include <utility> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { /// Primary template. template<typename Key, typename Hash_Fn, typename _Alloc, typename Comb_Probe_Fn, typename Probe_Fn, bool Store_Hash> class ranged_probe_fn; #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Hash_Fn, typename _Alloc, \ typename Comb_Probe_Fn, typename Probe_Fn> #define PB_DS_CLASS_C_DEC \ ranged_probe_fn<Key, Hash_Fn, _Alloc, Comb_Probe_Fn, Probe_Fn, false> /** * Specialization 1 * The client supplies a probe function and a ranged probe * function, and requests that hash values not be stored. **/ template<typename Key, typename Hash_Fn, typename _Alloc, typename Comb_Probe_Fn, typename Probe_Fn> class ranged_probe_fn<Key, Hash_Fn, _Alloc, Comb_Probe_Fn, Probe_Fn, false> : public Hash_Fn, public Comb_Probe_Fn, public Probe_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Probe_Fn comb_probe_fn_base; typedef Hash_Fn hash_fn_base; typedef Probe_Fn probe_fn_base; typedef typename _Alloc::template rebind<Key>::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_probe_fn(size_type); ranged_probe_fn(size_type, const Hash_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&, const Probe_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline size_type operator()(key_const_reference) const; inline size_type operator()(key_const_reference, size_type, size_type) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn, const Probe_Fn& r_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn), Probe_Fn(r_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_probe_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn&)other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { return comb_probe_fn_base::operator()(hash_fn_base::operator()(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference, size_type hash, size_type i) const { return comb_probe_fn_base::operator()(hash + probe_fn_base::operator()(i)); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Hash_Fn, typename _Alloc, \ typename Comb_Probe_Fn, typename Probe_Fn> #define PB_DS_CLASS_C_DEC \ ranged_probe_fn<Key, Hash_Fn, _Alloc, Comb_Probe_Fn, Probe_Fn, true> /** * Specialization 2- The client supplies a probe function and a ranged * probe function, and requests that hash values not be stored. **/ template<typename Key, typename Hash_Fn, typename _Alloc, typename Comb_Probe_Fn, typename Probe_Fn> class ranged_probe_fn<Key, Hash_Fn, _Alloc, Comb_Probe_Fn, Probe_Fn, true> : public Hash_Fn, public Comb_Probe_Fn, public Probe_Fn { protected: typedef typename _Alloc::size_type size_type; typedef std::pair<size_type, size_type> comp_hash; typedef Comb_Probe_Fn comb_probe_fn_base; typedef Hash_Fn hash_fn_base; typedef Probe_Fn probe_fn_base; typedef typename _Alloc::template rebind<Key>::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_probe_fn(size_type); ranged_probe_fn(size_type, const Hash_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&); ranged_probe_fn(size_type, const Hash_Fn&, const Comb_Probe_Fn&, const Probe_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline comp_hash operator()(key_const_reference) const; inline size_type operator()(key_const_reference, size_type, size_type) const; inline size_type operator()(key_const_reference, size_type) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Probe_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_probe_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Probe_Fn& r_comb_probe_fn, const Probe_Fn& r_probe_fn) : Hash_Fn(r_hash_fn), Comb_Probe_Fn(r_comb_probe_fn), Probe_Fn(r_probe_fn) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_probe_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_probe_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { const size_type hash = hash_fn_base::operator()(r_key); return std::make_pair(comb_probe_fn_base::operator()(hash), hash); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference, size_type hash, size_type i) const { return comb_probe_fn_base::operator()(hash + probe_fn_base::operator()(i)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator() #ifdef _GLIBCXX_DEBUG (key_const_reference r_key, size_type hash) const #else (key_const_reference /*r_key*/, size_type hash) const #endif { _GLIBCXX_DEBUG_ASSERT(hash == hash_fn_base::operator()(r_key)); return hash; } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC /** * Specialization 3 and 4 * The client does not supply a hash function or probe function, * and requests that hash values not be stored. **/ template<typename Key, typename _Alloc, typename Comb_Probe_Fn> class ranged_probe_fn<Key, null_type, _Alloc, Comb_Probe_Fn, null_type, false> : public Comb_Probe_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Probe_Fn comb_probe_fn_base; typedef typename _Alloc::template rebind<Key>::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_probe_fn(size_type size) { Comb_Probe_Fn::notify_resized(size); } ranged_probe_fn(size_type, const Comb_Probe_Fn& r_comb_probe_fn) : Comb_Probe_Fn(r_comb_probe_fn) { } ranged_probe_fn(size_type, const null_type&, const Comb_Probe_Fn& r_comb_probe_fn, const null_type&) : Comb_Probe_Fn(r_comb_probe_fn) { } void swap(ranged_probe_fn& other) { comb_probe_fn_base::swap(other); } }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp 0000644 00000004056 15146341150 0020373 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file direct_mod_range_hashing_imp.hpp * Contains a range-hashing policy implementation */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { mod_based_base::swap(other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type n) { mod_based_base::notify_resized(n); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type hash) const { return mod_based_base::range_hash(hash); } c++/8/ext/pb_ds/detail/hash_fn/sample_ranged_hash_fn.hpp 0000644 00000004645 15146341150 0017033 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_ranged_hash_fn.hpp * Contains a ranged hash policy. */ #ifndef PB_DS_SAMPLE_RANGED_HASH_FN_HPP #define PB_DS_SAMPLE_RANGED_HASH_FN_HPP namespace __gnu_pbds { /// A sample ranged-hash functor. class sample_ranged_hash_fn { public: typedef std::size_t size_type; /// Default constructor. sample_ranged_hash_fn(); /// Copy constructor. sample_ranged_hash_fn(const sample_ranged_hash_fn&); /// Swaps content. inline void swap(sample_ranged_hash_fn&); protected: /// Notifies the policy object that the container's __size has /// changed to size. void notify_resized(size_type); /// Transforms key_const_reference into a position within the table. inline size_type operator()(key_const_reference) const; }; } #endif // #ifndef PB_DS_SAMPLE_RANGED_HASH_FN_HPP c++/8/ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp 0000644 00000004070 15146341150 0020543 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file direct_mask_range_hashing_imp.hpp * Contains a range-hashing policy implementation */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { mask_based_base::swap(other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { mask_based_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type hash) const { return mask_based_base::range_hash(hash); } c++/8/ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp 0000644 00000004527 15146341150 0017335 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file mod_based_range_hashing.hpp * Contains a range hashing policy base. */ #ifndef PB_DS_MOD_BASED_RANGE_HASHING_HPP #define PB_DS_MOD_BASED_RANGE_HASHING_HPP namespace __gnu_pbds { namespace detail { /// Mod based range hashing. template<typename Size_Type> class mod_based_range_hashing { protected: typedef Size_Type size_type; void swap(mod_based_range_hashing& other) { std::swap(m_size, other.m_size); } void notify_resized(size_type s) { m_size = s; } inline size_type range_hash(size_type s) const { return s % m_size; } private: size_type m_size; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_MOD_BASED_RANGE_HASHING_HPP c++/8/ext/pb_ds/detail/hash_fn/sample_range_hashing.hpp 0000644 00000004667 15146341150 0016706 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_range_hashing.hpp * Contains a range hashing policy. */ #ifndef PB_DS_SAMPLE_RANGE_HASHING_HPP #define PB_DS_SAMPLE_RANGE_HASHING_HPP namespace __gnu_pbds { /// A sample range-hashing functor. class sample_range_hashing { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_range_hashing(); /// Copy constructor. sample_range_hashing(const sample_range_hashing& other); /// Swaps content. inline void swap(sample_range_hashing& other); protected: /// Notifies the policy object that the container's size has /// changed to argument's size. void notify_resized(size_type); /// Transforms the __hash value hash into a ranged-hash value. inline size_type operator()(size_type ) const; }; } #endif // #ifndef PB_DS_SAMPLE_RANGE_HASHING_HPP c++/8/ext/pb_ds/detail/hash_fn/probe_fn_base.hpp 0000644 00000003731 15146341150 0015323 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file probe_fn_base.hpp * Contains a probe policy base. */ #ifndef PB_DS_PROBE_FN_BASE_HPP #define PB_DS_PROBE_FN_BASE_HPP #include <functional> namespace __gnu_pbds { namespace detail { /// Probe functor base. template<typename _Alloc> class probe_fn_base { protected: ~probe_fn_base() { } }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/hash_fn/sample_ranged_probe_fn.hpp 0000644 00000005046 15146341150 0017213 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_ranged_probe_fn.hpp * Contains a ranged probe policy. */ #ifndef PB_DS_SAMPLE_RANGED_PROBE_FN_HPP #define PB_DS_SAMPLE_RANGED_PROBE_FN_HPP namespace __gnu_pbds { /// A sample ranged-probe functor. class sample_ranged_probe_fn { public: typedef std::size_t size_type; // Default constructor. sample_ranged_probe_fn(); // Copy constructor. sample_ranged_probe_fn(const sample_ranged_probe_fn&); // Swaps content. inline void swap(sample_ranged_probe_fn&); protected: // Notifies the policy object that the container's __size has // changed to size. void notify_resized(size_type); // Transforms the const key reference r_key into the i-th position // within the table. This method is called for each collision within // the probe sequence. inline size_type operator()(key_const_reference, std::size_t, size_type) const; }; } #endif // #ifndef PB_DS_SAMPLE_RANGED_PROBE_FN_HPP c++/8/ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp 0000644 00000006332 15146341150 0017505 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file mask_based_range_hashing.hpp * Contains a range hashing policy base. */ #ifndef PB_DS_MASK_BASED_RANGE_HASHING_HPP #define PB_DS_MASK_BASED_RANGE_HASHING_HPP namespace __gnu_pbds { namespace detail { /// Range hashing policy. template<typename Size_Type> class mask_based_range_hashing { protected: typedef Size_Type size_type; void swap(mask_based_range_hashing& other) { std::swap(m_mask, other.m_mask); } void notify_resized(size_type size); inline size_type range_hash(size_type hash) const { return size_type(hash & m_mask); } private: size_type m_mask; const static size_type s_num_bits_in_size_type; const static size_type s_highest_bit_1; }; template<typename Size_Type> const typename mask_based_range_hashing<Size_Type>::size_type mask_based_range_hashing<Size_Type>::s_num_bits_in_size_type = sizeof(typename mask_based_range_hashing<Size_Type>::size_type) << 3; template<typename Size_Type> const typename mask_based_range_hashing<Size_Type>::size_type mask_based_range_hashing<Size_Type>::s_highest_bit_1 = static_cast<typename mask_based_range_hashing<Size_Type>::size_type>(1) << (s_num_bits_in_size_type - 1); template<typename Size_Type> void mask_based_range_hashing<Size_Type>:: notify_resized(size_type size) { size_type i = 0; while (size ^ s_highest_bit_1) { size <<= 1; ++i; } m_mask = 1; i += 2; while (i++ < s_num_bits_in_size_type) m_mask = (m_mask << 1) ^ 1; } } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp 0000644 00000024573 15146341150 0015474 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ranged_hash_fn.hpp * Contains a unified ranged hash functor, allowing the hash tables * to deal with a single class for ranged hashing. */ #ifndef PB_DS_RANGED_HASH_FN_HPP #define PB_DS_RANGED_HASH_FN_HPP #include <utility> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { /// Primary template. template<typename Key, typename Hash_Fn, typename _Alloc, typename Comb_Hash_Fn, bool Store_Hash> class ranged_hash_fn; #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Hash_Fn, typename _Alloc, \ typename Comb_Hash_Fn> #define PB_DS_CLASS_C_DEC \ ranged_hash_fn<Key, Hash_Fn, _Alloc, Comb_Hash_Fn, false> /** * Specialization 1 * The client supplies a hash function and a ranged hash function, * and requests that hash values not be stored. **/ template<typename Key, typename Hash_Fn, typename _Alloc, typename Comb_Hash_Fn> class ranged_hash_fn< Key, Hash_Fn, _Alloc, Comb_Hash_Fn, false> : public Hash_Fn, public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Hash_Fn hash_fn_base; typedef Comb_Hash_Fn comb_hash_fn_base; typedef typename _Alloc::template rebind< Key>::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Hash_Fn&); ranged_hash_fn(size_type, const Hash_Fn&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline size_type operator()(key_const_reference) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn) : Hash_Fn(r_hash_fn), Comb_Hash_Fn(r_comb_hash_fn) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { return (comb_hash_fn_base::operator()(hash_fn_base::operator()(r_key)));} #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Hash_Fn, typename _Alloc, \ typename Comb_Hash_Fn> #define PB_DS_CLASS_C_DEC \ ranged_hash_fn<Key,Hash_Fn, _Alloc, Comb_Hash_Fn, true> /** * Specialization 2 * The client supplies a hash function and a ranged hash function, * and requests that hash values be stored. **/ template<typename Key, typename Hash_Fn, typename _Alloc, typename Comb_Hash_Fn> class ranged_hash_fn<Key, Hash_Fn, _Alloc, Comb_Hash_Fn, true> : public Hash_Fn, public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef std::pair<size_type, size_type> comp_hash; typedef Hash_Fn hash_fn_base; typedef Comb_Hash_Fn comb_hash_fn_base; typedef typename _Alloc::template rebind<Key>::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Hash_Fn&); ranged_hash_fn(size_type, const Hash_Fn&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); void notify_resized(size_type); inline comp_hash operator()(key_const_reference) const; inline comp_hash operator()(key_const_reference, size_type) const; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn) : Hash_Fn(r_hash_fn) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Hash_Fn& r_hash_fn, const Comb_Hash_Fn& r_comb_hash_fn) : Hash_Fn(r_hash_fn), Comb_Hash_Fn(r_comb_hash_fn) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); std::swap((Hash_Fn& )(*this), (Hash_Fn& )other); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type size) { comb_hash_fn_base::notify_resized(size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: operator()(key_const_reference r_key) const { const size_type hash = hash_fn_base::operator()(r_key); return std::make_pair(comb_hash_fn_base::operator()(hash), hash); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::comp_hash PB_DS_CLASS_C_DEC:: operator() #ifdef _GLIBCXX_DEBUG (key_const_reference r_key, size_type hash) const #else (key_const_reference /*r_key*/, size_type hash) const #endif { _GLIBCXX_DEBUG_ASSERT(hash == hash_fn_base::operator()(r_key)); return std::make_pair(comb_hash_fn_base::operator()(hash), hash); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template<typename Key, typename _Alloc, typename Comb_Hash_Fn> #define PB_DS_CLASS_C_DEC \ ranged_hash_fn<Key, null_type, _Alloc, Comb_Hash_Fn, false> /** * Specialization 3 * The client does not supply a hash function (by specifying * null_type as the Hash_Fn parameter), and requests that hash * values not be stored. **/ template<typename Key, typename _Alloc, typename Comb_Hash_Fn> class ranged_hash_fn<Key, null_type, _Alloc, Comb_Hash_Fn, false> : public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Hash_Fn comb_hash_fn_base; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Comb_Hash_Fn&); ranged_hash_fn(size_type, const null_type&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const null_type& r_null_type, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template<typename Key, typename _Alloc, typename Comb_Hash_Fn> #define PB_DS_CLASS_C_DEC \ ranged_hash_fn<Key, null_type, _Alloc, Comb_Hash_Fn, true> /** * Specialization 4 * The client does not supply a hash function (by specifying * null_type as the Hash_Fn parameter), and requests that hash * values be stored. **/ template<typename Key, typename _Alloc, typename Comb_Hash_Fn> class ranged_hash_fn<Key, null_type, _Alloc, Comb_Hash_Fn, true> : public Comb_Hash_Fn { protected: typedef typename _Alloc::size_type size_type; typedef Comb_Hash_Fn comb_hash_fn_base; ranged_hash_fn(size_type); ranged_hash_fn(size_type, const Comb_Hash_Fn&); ranged_hash_fn(size_type, const null_type&, const Comb_Hash_Fn&); void swap(PB_DS_CLASS_C_DEC&); }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size) { Comb_Hash_Fn::notify_resized(size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ranged_hash_fn(size_type size, const null_type& r_null_type, const Comb_Hash_Fn& r_comb_hash_fn) : Comb_Hash_Fn(r_comb_hash_fn) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { comb_hash_fn_base::swap(other); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/hash_fn/sample_probe_fn.hpp 0000644 00000004363 15146341150 0015674 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_probe_fn.hpp * Contains a sample probe policy. */ #ifndef PB_DS_SAMPLE_PROBE_FN_HPP #define PB_DS_SAMPLE_PROBE_FN_HPP namespace __gnu_pbds { /// A sample probe policy. class sample_probe_fn { public: typedef std::size_t size_type; /// Default constructor. sample_probe_fn(); /// Copy constructor. sample_probe_fn(const sample_probe_fn&); /// Swaps content. inline void swap(sample_probe_fn&); protected: /// Returns the i-th offset from the hash value of some key r_key. inline size_type operator()(key_const_reference r_key, size_type i) const; }; } #endif // #ifndef PB_DS_SAMPLE_PROBE_FN_HPP c++/8/ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp 0000644 00000003600 15146341150 0017226 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file quadratic_probe_fn_imp.hpp * Contains a probe policy implementation */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type i) const { return (i* i); } c++/8/ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp 0000644 00000003571 15146341150 0016532 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file linear_probe_fn_imp.hpp * Contains a probe policy implementation */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: operator()(size_type i) const { return (i); } c++/8/ext/pb_ds/detail/list_update_policy/lu_counter_metadata.hpp 0000644 00000005442 15146341150 0021045 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file lu_counter_metadata.hpp * Contains implementation of a lu counter policy's metadata. */ namespace __gnu_pbds { namespace detail { template<typename Size_Type> class lu_counter_policy_base; /// A list-update metadata type that moves elements to the front of /// the list based on the counter algorithm. template<typename Size_Type = std::size_t> class lu_counter_metadata { public: typedef Size_Type size_type; private: lu_counter_metadata(size_type init_count) : m_count(init_count) { } friend class lu_counter_policy_base<size_type>; mutable size_type m_count; }; /// Base class for list-update counter policy. template<typename Size_Type> class lu_counter_policy_base { protected: typedef Size_Type size_type; lu_counter_metadata<size_type> operator()(size_type max_size) const { return lu_counter_metadata<Size_Type>(std::rand() % max_size); } template<typename Metadata_Reference> bool operator()(Metadata_Reference r_data, size_type m_max_count) const { if (++r_data.m_count != m_max_count) return false; r_data.m_count = 0; return true; } }; } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/list_update_policy/sample_update_policy.hpp 0000644 00000005160 15146341150 0021225 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_update_policy.hpp * Contains a sample policy for list update containers. */ #ifndef PB_DS_SAMPLE_UPDATE_POLICY_HPP #define PB_DS_SAMPLE_UPDATE_POLICY_HPP namespace __gnu_pbds { /// A sample list-update policy. struct sample_update_policy { /// Default constructor. sample_update_policy(); /// Copy constructor. sample_update_policy(const sample_update_policy&); /// Swaps content. inline void swap(sample_update_policy& other); protected: /// Metadata on which this functor operates. typedef some_metadata_type metadata_type; /// Creates a metadata object. metadata_type operator()() const; /// Decides whether a metadata object should be moved to the front /// of the list. A list-update based containers object will call /// this method to decide whether to move a node to the front of /// the list. The method shoule return true if the node should be /// moved to the front of the list. bool operator()(metadata_reference) const; }; } #endif c++/8/ext/pb_ds/detail/type_utils.hpp 0000644 00000010337 15146341150 0013332 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/type_utils.hpp * Contains utilities for handnling types. All of these classes are based on * Modern C++ by Andrei Alxandrescu. */ #ifndef PB_DS_TYPE_UTILS_HPP #define PB_DS_TYPE_UTILS_HPP #include <cstddef> #include <utility> #include <tr1/type_traits> #include <ext/type_traits.h> #include <ext/numeric_traits.h> namespace __gnu_pbds { namespace detail { using std::tr1::is_same; using std::tr1::is_const; using std::tr1::is_pointer; using std::tr1::is_reference; using std::tr1::is_fundamental; using std::tr1::is_member_object_pointer; using std::tr1::is_member_pointer; using std::tr1::is_base_of; using std::tr1::remove_const; using std::tr1::remove_reference; // Need integral_const<bool, true> <-> integral_const<int, 1>, so // because of this use the following typedefs instead of importing // std::tr1's. using std::tr1::integral_constant; typedef std::tr1::integral_constant<int, 1> true_type; typedef std::tr1::integral_constant<int, 0> false_type; using __gnu_cxx::__conditional_type; using __gnu_cxx::__numeric_traits; template<typename T> struct is_const_pointer { enum { value = is_const<T>::value && is_pointer<T>::value }; }; template<typename T> struct is_const_reference { enum { value = is_const<T>::value && is_reference<T>::value }; }; template<typename T> struct is_simple { enum { value = is_fundamental<typename remove_const<T>::type>::value || is_pointer<typename remove_const<T>::type>::value || is_member_pointer<T>::value }; }; template<typename T> class is_pair { private: template<typename U> struct is_pair_imp { enum { value = 0 }; }; template<typename U, typename V> struct is_pair_imp<std::pair<U,V> > { enum { value = 1 }; }; public: enum { value = is_pair_imp<T>::value }; }; // Use C++11's static_assert if possible. #if __cplusplus >= 201103L #define PB_DS_STATIC_ASSERT(UNIQUE, E) static_assert(E, #UNIQUE) #else template<bool> struct __static_assert; template<> struct __static_assert<true> { }; template<int> struct __static_assert_dumclass { enum { v = 1 }; }; #define PB_DS_STATIC_ASSERT(UNIQUE, E) \ typedef __gnu_pbds::detail::__static_assert_dumclass<sizeof(__gnu_pbds::detail::__static_assert<bool(E)>)> UNIQUE##__static_assert_type #endif template<typename Type> struct type_to_type { typedef Type type; }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/resize_policy/sample_resize_policy.hpp 0000644 00000006772 15146341150 0020242 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_resize_policy.hpp * Contains a sample resize policy for hash tables. */ #ifndef PB_DS_SAMPLE_RESIZE_POLICY_HPP #define PB_DS_SAMPLE_RESIZE_POLICY_HPP namespace __gnu_pbds { /// A sample resize policy. class sample_resize_policy { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_resize_policy(); /// Copy constructor. sample_range_hashing(const sample_resize_policy& other); /// Swaps content. inline void swap(sample_resize_policy& other); protected: /// Notifies a search started. inline void notify_insert_search_start(); /// Notifies a search encountered a collision. inline void notify_insert_search_collision(); /// Notifies a search ended. inline void notify_insert_search_end(); /// Notifies a search started. inline void notify_find_search_start(); /// Notifies a search encountered a collision. inline void notify_find_search_collision(); /// Notifies a search ended. inline void notify_find_search_end(); /// Notifies a search started. inline void notify_erase_search_start(); /// Notifies a search encountered a collision. inline void notify_erase_search_collision(); /// Notifies a search ended. inline void notify_erase_search_end(); /// Notifies an element was inserted. inline void notify_inserted(size_type num_e); /// Notifies an element was erased. inline void notify_erased(size_type num_e); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized to new_size. void notify_resized(size_type new_size); /// Queries whether a resize is needed. inline bool is_resize_needed() const; /// Queries what the new size should be. size_type get_new_size(size_type size, size_type num_used_e) const; }; } #endif c++/8/ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp 0000644 00000014213 15146341150 0022416 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_standard_resize_policy_imp.hpp * Contains a resize policy implementation. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_standard_resize_policy() : m_size(Size_Policy::get_nearest_larger_size(1)) { trigger_policy_base::notify_externally_resized(m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_standard_resize_policy(const Size_Policy& r_size_policy) : Size_Policy(r_size_policy), m_size(Size_Policy::get_nearest_larger_size(1)) { trigger_policy_base::notify_externally_resized(m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_standard_resize_policy(const Size_Policy& r_size_policy, const Trigger_Policy& r_trigger_policy) : Size_Policy(r_size_policy), Trigger_Policy(r_trigger_policy), m_size(Size_Policy::get_nearest_larger_size(1)) { trigger_policy_base::notify_externally_resized(m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~hash_standard_resize_policy() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { trigger_policy_base::swap(other); size_policy_base::swap(other); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_start() { trigger_policy_base::notify_find_search_start(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_collision() { trigger_policy_base::notify_find_search_collision(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_end() { trigger_policy_base::notify_find_search_end(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_start() { trigger_policy_base::notify_insert_search_start(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_collision() { trigger_policy_base::notify_insert_search_collision(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_end() { trigger_policy_base::notify_insert_search_end(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_start() { trigger_policy_base::notify_erase_search_start(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_collision() { trigger_policy_base::notify_erase_search_collision(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_end() { trigger_policy_base::notify_erase_search_end(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_inserted(size_type num_e) { trigger_policy_base::notify_inserted(num_e); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erased(size_type num_e) { trigger_policy_base::notify_erased(num_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_cleared() { trigger_policy_base::notify_cleared(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_resize_needed() const { return trigger_policy_base::is_resize_needed(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_new_size(size_type size, size_type num_used_e) const { if (trigger_policy_base::is_grow_needed(size, num_used_e)) return size_policy_base::get_nearest_larger_size(size); return size_policy_base::get_nearest_smaller_size(size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type new_size) { trigger_policy_base::notify_resized(new_size); m_size = new_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_actual_size() const { PB_DS_STATIC_ASSERT(access, external_size_access); return m_size; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize(size_type new_size) { PB_DS_STATIC_ASSERT(access, external_size_access); size_type actual_size = size_policy_base::get_nearest_larger_size(1); while (actual_size < new_size) { const size_type pot = size_policy_base::get_nearest_larger_size(actual_size); if (pot == actual_size && pot < new_size) __throw_resize_error(); actual_size = pot; } if (actual_size > 0) --actual_size; const size_type old_size = m_size; __try { do_resize(actual_size - 1); } __catch(insert_error& ) { m_size = old_size; __throw_resize_error(); } __catch(...) { m_size = old_size; __throw_exception_again; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type) { // Do nothing } PB_DS_CLASS_T_DEC Trigger_Policy& PB_DS_CLASS_C_DEC:: get_trigger_policy() { return *this; } PB_DS_CLASS_T_DEC const Trigger_Policy& PB_DS_CLASS_C_DEC:: get_trigger_policy() const { return *this; } PB_DS_CLASS_T_DEC Size_Policy& PB_DS_CLASS_C_DEC:: get_size_policy() { return *this; } PB_DS_CLASS_T_DEC const Size_Policy& PB_DS_CLASS_C_DEC:: get_size_policy() const { return *this; } c++/8/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp 0000644 00000013773 15146341150 0021415 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_prime_size_policy_imp.hpp * Contains a resize size policy implementation. */ #pragma GCC system_header namespace detail { enum { num_distinct_sizes_32_bit = 30, num_distinct_sizes_64_bit = 62, num_distinct_sizes = sizeof(std::size_t) != 8 ? num_distinct_sizes_32_bit : num_distinct_sizes_64_bit, }; // Originally taken from the SGI implementation; acknowledged in the docs. // Further modified (for 64 bits) from tr1's hashtable. static const std::size_t g_a_sizes[num_distinct_sizes_64_bit] = { /* 0 */ 5ul, /* 1 */ 11ul, /* 2 */ 23ul, /* 3 */ 47ul, /* 4 */ 97ul, /* 5 */ 199ul, /* 6 */ 409ul, /* 7 */ 823ul, /* 8 */ 1741ul, /* 9 */ 3469ul, /* 10 */ 6949ul, /* 11 */ 14033ul, /* 12 */ 28411ul, /* 13 */ 57557ul, /* 14 */ 116731ul, /* 15 */ 236897ul, /* 16 */ 480881ul, /* 17 */ 976369ul, /* 18 */ 1982627ul, /* 19 */ 4026031ul, /* 20 */ 8175383ul, /* 21 */ 16601593ul, /* 22 */ 33712729ul, /* 23 */ 68460391ul, /* 24 */ 139022417ul, /* 25 */ 282312799ul, /* 26 */ 573292817ul, /* 27 */ 1164186217ul, /* 28 */ 2364114217ul, /* 29 */ 4294967291ul, /* 30 */ (std::size_t)8589934583ull, /* 31 */ (std::size_t)17179869143ull, /* 32 */ (std::size_t)34359738337ull, /* 33 */ (std::size_t)68719476731ull, /* 34 */ (std::size_t)137438953447ull, /* 35 */ (std::size_t)274877906899ull, /* 36 */ (std::size_t)549755813881ull, /* 37 */ (std::size_t)1099511627689ull, /* 38 */ (std::size_t)2199023255531ull, /* 39 */ (std::size_t)4398046511093ull, /* 40 */ (std::size_t)8796093022151ull, /* 41 */ (std::size_t)17592186044399ull, /* 42 */ (std::size_t)35184372088777ull, /* 43 */ (std::size_t)70368744177643ull, /* 44 */ (std::size_t)140737488355213ull, /* 45 */ (std::size_t)281474976710597ull, /* 46 */ (std::size_t)562949953421231ull, /* 47 */ (std::size_t)1125899906842597ull, /* 48 */ (std::size_t)2251799813685119ull, /* 49 */ (std::size_t)4503599627370449ull, /* 50 */ (std::size_t)9007199254740881ull, /* 51 */ (std::size_t)18014398509481951ull, /* 52 */ (std::size_t)36028797018963913ull, /* 53 */ (std::size_t)72057594037927931ull, /* 54 */ (std::size_t)144115188075855859ull, /* 55 */ (std::size_t)288230376151711717ull, /* 56 */ (std::size_t)576460752303423433ull, /* 57 */ (std::size_t)1152921504606846883ull, /* 58 */ (std::size_t)2305843009213693951ull, /* 59 */ (std::size_t)4611686018427387847ull, /* 60 */ (std::size_t)9223372036854775783ull, /* 61 */ (std::size_t)18446744073709551557ull, }; } // namespace detail PB_DS_CLASS_T_DEC inline PB_DS_CLASS_C_DEC:: hash_prime_size_policy(size_type n) : m_start_size(n) { m_start_size = get_nearest_larger_size(n); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_start_size, other.m_start_size); } PB_DS_CLASS_T_DEC inline PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_larger_size(size_type n) const { const std::size_t* const p_upper = std::upper_bound(detail::g_a_sizes, detail::g_a_sizes + detail::num_distinct_sizes, n); if (p_upper == detail::g_a_sizes + detail::num_distinct_sizes) __throw_resize_error(); return *p_upper; } PB_DS_CLASS_T_DEC inline PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_smaller_size(size_type n) const { const std::size_t* p_lower = std::lower_bound(detail::g_a_sizes, detail::g_a_sizes + detail::num_distinct_sizes, n); if (*p_lower >= n && p_lower != detail::g_a_sizes) --p_lower; if (*p_lower < m_start_size) return m_start_size; return *p_lower; } c++/8/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp 0000644 00000005632 15146341150 0024222 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_load_check_resize_trigger_size_base.hpp * Contains an base holding size for some resize policies. */ #ifndef PB_DS_HASH_LOAD_CHECK_RESIZE_TRIGGER_SIZE_BASE_HPP #define PB_DS_HASH_LOAD_CHECK_RESIZE_TRIGGER_SIZE_BASE_HPP namespace __gnu_pbds { namespace detail { /// Primary template. template<typename Size_Type, bool Hold_Size> class hash_load_check_resize_trigger_size_base; /// Specializations. template<typename Size_Type> class hash_load_check_resize_trigger_size_base<Size_Type, true> { protected: typedef Size_Type size_type; hash_load_check_resize_trigger_size_base(): m_size(0) { } inline void swap(hash_load_check_resize_trigger_size_base& other) { std::swap(m_size, other.m_size); } inline void set_size(size_type size) { m_size = size; } inline size_type get_size() const { return m_size; } private: size_type m_size; }; template<typename Size_Type> class hash_load_check_resize_trigger_size_base<Size_Type, false> { protected: typedef Size_Type size_type; protected: inline void swap(hash_load_check_resize_trigger_size_base& other) { } inline void set_size(size_type size) { } }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/resize_policy/sample_size_policy.hpp 0000644 00000004573 15146341150 0017710 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_size_policy.hpp * Contains a sample size resize-policy. */ #ifndef PB_DS_SAMPLE_SIZE_POLICY_HPP #define PB_DS_SAMPLE_SIZE_POLICY_HPP namespace __gnu_pbds { /// A sample size policy. class sample_size_policy { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_size_policy(); /// Copy constructor. sample_range_hashing(const sample_size_policy&); /// Swaps content. inline void swap(sample_size_policy& other); protected: /// Given a __size size, returns a __size that is larger. inline size_type get_nearest_larger_size(size_type size) const; /// Given a __size size, returns a __size that is smaller. inline size_type get_nearest_smaller_size(size_type size) const; }; } #endif c++/8/ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp 0000644 00000005324 15146341150 0022620 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_exponential_size_policy_imp.hpp * Contains a resize size policy implementation. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_exponential_size_policy(size_type start_size, size_type grow_factor) : m_start_size(start_size), m_grow_factor(grow_factor) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_start_size, other.m_start_size); std::swap(m_grow_factor, other.m_grow_factor); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_larger_size(size_type size) const { size_type ret = m_start_size; while (ret <= size) { const size_type next_ret = ret* m_grow_factor; if (next_ret < ret) __throw_insert_error(); ret = next_ret; } return ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: get_nearest_smaller_size(size_type size) const { size_type ret = m_start_size; while (true) { const size_type next_ret = ret* m_grow_factor; if (next_ret < ret) __throw_resize_error(); if (next_ret >= size) return (ret); ret = next_ret; } return ret; } c++/8/ext/pb_ds/detail/resize_policy/sample_resize_trigger.hpp 0000644 00000007512 15146341150 0020377 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file sample_resize_trigger.hpp * Contains a sample resize trigger policy class. */ #ifndef PB_DS_SAMPLE_RESIZE_TRIGGER_HPP #define PB_DS_SAMPLE_RESIZE_TRIGGER_HPP namespace __gnu_pbds { /// A sample resize trigger policy. class sample_resize_trigger { public: /// Size type. typedef std::size_t size_type; /// Default constructor. sample_resize_trigger(); /// Copy constructor. sample_range_hashing(const sample_resize_trigger&); /// Swaps content. inline void swap(sample_resize_trigger&); protected: /// Notifies a search started. inline void notify_insert_search_start(); /// Notifies a search encountered a collision. inline void notify_insert_search_collision(); /// Notifies a search ended. inline void notify_insert_search_end(); /// Notifies a search started. inline void notify_find_search_start(); /// Notifies a search encountered a collision. inline void notify_find_search_collision(); /// Notifies a search ended. inline void notify_find_search_end(); /// Notifies a search started. inline void notify_erase_search_start(); /// Notifies a search encountered a collision. inline void notify_erase_search_collision(); /// Notifies a search ended. inline void notify_erase_search_end(); /// Notifies an element was inserted. the total number of entries in /// the table is num_entries. inline void notify_inserted(size_type num_entries); /// Notifies an element was erased. inline void notify_erased(size_type num_entries); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized as a result of this object's /// signifying that a resize is needed. void notify_resized(size_type new_size); /// Notifies the table was resized externally. void notify_externally_resized(size_type new_size); /// Queries whether a resize is needed. inline bool is_resize_needed() const; /// Queries whether a grow is needed. inline bool is_grow_needed(size_type size, size_type num_entries) const; private: /// Resizes to new_size. virtual void do_resize(size_type); }; } #endif c++/8/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp 0000644 00000017110 15146341150 0023035 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_load_check_resize_trigger_imp.hpp * Contains a resize trigger implementation. */ #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: hash_load_check_resize_trigger(float load_min, float load_max) : m_load_min(load_min), m_load_max(load_max), m_next_shrink_size(0), m_next_grow_size(0), m_resize_needed(false) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_start() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_collision() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_end() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_start() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_collision() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_end() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_start() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_collision() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_end() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_inserted(size_type num_entries) { m_resize_needed = (num_entries >= m_next_grow_size); size_base::set_size(num_entries); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erased(size_type num_entries) { size_base::set_size(num_entries); m_resize_needed = num_entries <= m_next_shrink_size; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_resize_needed() const { PB_DS_ASSERT_VALID((*this)) return m_resize_needed; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_grow_needed(size_type /*size*/, size_type num_entries) const { _GLIBCXX_DEBUG_ASSERT(m_resize_needed); return num_entries >= m_next_grow_size; } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~hash_load_check_resize_trigger() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type new_size) { m_resize_needed = false; m_next_grow_size = size_type(m_load_max * new_size - 1); m_next_shrink_size = size_type(m_load_min * new_size); #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "hlcrt::notify_resized " << std::endl << "1 " << new_size << std::endl << "2 " << m_load_min << std::endl << "3 " << m_load_max << std::endl << "4 " << m_next_shrink_size << std::endl << "5 " << m_next_grow_size << std::endl; #endif PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_externally_resized(size_type new_size) { m_resize_needed = false; size_type new_grow_size = size_type(m_load_max * new_size - 1); size_type new_shrink_size = size_type(m_load_min * new_size); #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "hlcrt::notify_externally_resized " << std::endl << "1 " << new_size << std::endl << "2 " << m_load_min << std::endl << "3 " << m_load_max << std::endl << "4 " << m_next_shrink_size << std::endl << "5 " << m_next_grow_size << std::endl << "6 " << new_shrink_size << std::endl << "7 " << new_grow_size << std::endl; #endif if (new_grow_size >= m_next_grow_size) { _GLIBCXX_DEBUG_ASSERT(new_shrink_size >= m_next_shrink_size); m_next_grow_size = new_grow_size; } else { _GLIBCXX_DEBUG_ASSERT(new_shrink_size <= m_next_shrink_size); m_next_shrink_size = new_shrink_size; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_cleared() { PB_DS_ASSERT_VALID((*this)) size_base::set_size(0); m_resize_needed = (0 < m_next_shrink_size); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) size_base::swap(other); std::swap(m_load_min, other.m_load_min); std::swap(m_load_max, other.m_load_max); std::swap(m_resize_needed, other.m_resize_needed); std::swap(m_next_grow_size, other.m_next_grow_size); std::swap(m_next_shrink_size, other.m_next_shrink_size); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline std::pair<float, float> PB_DS_CLASS_C_DEC:: get_loads() const { PB_DS_STATIC_ASSERT(access, external_load_access); return std::make_pair(m_load_min, m_load_max); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: set_loads(std::pair<float, float> load_pair) { PB_DS_STATIC_ASSERT(access, external_load_access); const float old_load_min = m_load_min; const float old_load_max = m_load_max; const size_type old_next_shrink_size = m_next_shrink_size; const size_type old_next_grow_size = m_next_grow_size; const bool old_resize_needed = m_resize_needed; __try { m_load_min = load_pair.first; m_load_max = load_pair.second; do_resize(static_cast<size_type>(size_base::get_size() / ((m_load_min + m_load_max) / 2))); } __catch(...) { m_load_min = old_load_min; m_load_max = old_load_max; m_next_shrink_size = old_next_shrink_size; m_next_grow_size = old_next_grow_size; m_resize_needed = old_resize_needed; __throw_exception_again; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type) { std::abort(); } #ifdef _GLIBCXX_DEBUG # define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_load_max > m_load_min); PB_DS_DEBUG_VERIFY(m_next_grow_size >= m_next_shrink_size); } # undef PB_DS_DEBUG_VERIFY #endif #undef PB_DS_ASSERT_VALID c++/8/ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp 0000644 00000011443 15146341150 0025426 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_max_collision_check_resize_trigger_imp.hpp * Contains a resize trigger implementation. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: cc_hash_max_collision_check_resize_trigger(float load) : m_load(load), m_size(0), m_num_col(0), m_max_col(0), m_resize_needed(false) { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_start() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_collision() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_find_search_end() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_start() { m_num_col = 0; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_collision() { ++m_num_col; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_insert_search_end() { calc_resize_needed(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_start() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_collision() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erase_search_end() { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_inserted(size_type) { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: notify_erased(size_type) { m_resize_needed = true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_cleared() { m_resize_needed = false; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_resize_needed() const { return m_resize_needed; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_grow_needed(size_type /*size*/, size_type /*num_used_e*/) const { return m_num_col >= m_max_col; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_resized(size_type new_size) { m_size = new_size; #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "chmccrt::notify_resized " << static_cast<unsigned long>(new_size) << std::endl; #endif calc_max_num_coll(); calc_resize_needed(); m_num_col = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: calc_max_num_coll() { // max_col <-- \sqrt{2 load \ln( 2 m \ln( m ) ) } const double ln_arg = 2 * m_size * std::log(double(m_size)); m_max_col = size_type(std::ceil(std::sqrt(2 * m_load * std::log(ln_arg)))); #ifdef PB_DS_HT_MAP_RESIZE_TRACE_ std::cerr << "chmccrt::calc_max_num_coll " << static_cast<unsigned long>(m_size) << " " << static_cast<unsigned long>(m_max_col) << std::endl; #endif } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: notify_externally_resized(size_type new_size) { notify_resized(new_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_load, other.m_load); std::swap(m_size, other.m_size); std::swap(m_num_col, other.m_num_col); std::swap(m_max_col, other.m_max_col); std::swap(m_resize_needed, other.m_resize_needed); } PB_DS_CLASS_T_DEC inline float PB_DS_CLASS_C_DEC:: get_load() const { PB_DS_STATIC_ASSERT(access, external_load_access); return m_load; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: calc_resize_needed() { m_resize_needed = m_resize_needed || m_num_col >= m_max_col; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: set_load(float load) { PB_DS_STATIC_ASSERT(access, external_load_access); m_load = load; calc_max_num_coll(); calc_resize_needed(); } c++/8/ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp 0000644 00000007355 15146341150 0014322 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_eq_fn.hpp * Contains 2 eqivalence functions, one employing a hash value, * and one ignoring it. */ #ifndef PB_DS_HASH_EQ_FN_HPP #define PB_DS_HASH_EQ_FN_HPP #include <utility> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { /// Primary template. template<typename Key, typename Eq_Fn, typename _Alloc, bool Store_Hash> struct hash_eq_fn; /// Specialization 1 - The client requests that hash values not be stored. template<typename Key, typename Eq_Fn, typename _Alloc> struct hash_eq_fn<Key, Eq_Fn, _Alloc, false> : public Eq_Fn { typedef Eq_Fn eq_fn_base; typedef typename _Alloc::template rebind<Key>::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; hash_eq_fn() { } hash_eq_fn(const Eq_Fn& r_eq_fn) : Eq_Fn(r_eq_fn) { } bool operator()(key_const_reference r_lhs_key, key_const_reference r_rhs_key) const { return eq_fn_base::operator()(r_lhs_key, r_rhs_key); } void swap(const hash_eq_fn& other) { std::swap((Eq_Fn&)(*this), (Eq_Fn&)other); } }; /// Specialization 2 - The client requests that hash values be stored. template<typename Key, class Eq_Fn, class _Alloc> struct hash_eq_fn<Key, Eq_Fn, _Alloc, true> : public Eq_Fn { typedef typename _Alloc::size_type size_type; typedef Eq_Fn eq_fn_base; typedef typename _Alloc::template rebind<Key>::other key_allocator; typedef typename key_allocator::const_reference key_const_reference; hash_eq_fn() { } hash_eq_fn(const Eq_Fn& r_eq_fn) : Eq_Fn(r_eq_fn) { } bool operator()(key_const_reference r_lhs_key, size_type lhs_hash, key_const_reference r_rhs_key, size_type rhs_hash) const { _GLIBCXX_DEBUG_ASSERT(!eq_fn_base::operator()(r_lhs_key, r_rhs_key) || lhs_hash == rhs_hash); return (lhs_hash == rhs_hash && eq_fn_base::operator()(r_lhs_key, r_rhs_key)); } void swap(const hash_eq_fn& other) { std::swap((Eq_Fn&)(*this), (Eq_Fn&)(other)); } }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/eq_fn/eq_by_less.hpp 0000644 00000004432 15146341150 0014345 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file eq_by_less.hpp * Contains an equivalence function. */ #ifndef PB_DS_EQ_BY_LESS_HPP #define PB_DS_EQ_BY_LESS_HPP #include <utility> #include <functional> #include <vector> #include <assert.h> #include <ext/pb_ds/detail/types_traits.hpp> namespace __gnu_pbds { namespace detail { /// Equivalence function. template<typename Key, class Cmp_Fn> struct eq_by_less : private Cmp_Fn { bool operator()(const Key& r_lhs, const Key& r_rhs) const { const bool l = Cmp_Fn::operator()(r_lhs, r_rhs); const bool g = Cmp_Fn::operator()(r_rhs, r_lhs); return !(l || g); } }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_EQ_BY_LESS_HPP c++/8/ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp 0000644 00000007172 15146341150 0017606 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/split_join_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC template<typename Pred> void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) other.clear(); if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); while (p_out != 0) { _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); --base_type::m_size; ++other.m_size; node_pointer p_next = p_out->m_p_next_sibling; p_out->m_p_l_child = p_out->m_p_next_sibling = p_out->m_p_prev_or_parent = 0; other.push_imp(p_out); p_out = p_next; } PB_DS_ASSERT_VALID(other) node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = 0; push_imp(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_p_root == 0) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } if (base_type::m_p_root == 0) base_type::m_p_root = other.m_p_root; else if (Cmp_Fn::operator()(base_type::m_p_root->m_value, other.m_p_root->m_value)) { base_type::make_child_of(base_type::m_p_root, other.m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(other.m_p_root, false) base_type::m_p_root = other.m_p_root; } else { base_type::make_child_of(other.m_p_root, base_type::m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(base_type::m_p_root, false) } base_type::m_size += other.m_size; other.m_p_root = 0; other.m_size = 0; PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } c++/8/ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp 0000644 00000004712 15146341150 0022457 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) push(*(first_it++)); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: pairing_heap() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: pairing_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: pairing_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) base_type::swap(other); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~pairing_heap() { } c++/8/ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp 0000644 00000003714 15146341150 0016520 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/debug_fn_imps.hpp * Contains an implementation class for a pairing heap. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(base_type::m_p_root == 0 || base_type::m_p_root->m_p_next_sibling == 0); base_type::assert_valid(__file, __line); } #endif c++/8/ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp 0000644 00000005603 15146341150 0016735 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/insert_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) node_pointer p_new_nd = base_type::get_new_node_for_insert(r_val); push_imp(p_new_nd); PB_DS_ASSERT_VALID((*this)) return point_iterator(p_new_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: push_imp(node_pointer p_nd) { p_nd->m_p_l_child = 0; if (base_type::m_p_root == 0) { p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = 0; base_type::m_p_root = p_nd; } else if (Cmp_Fn::operator()(base_type::m_p_root->m_value, p_nd->m_value)) { p_nd->m_p_next_sibling = p_nd->m_p_prev_or_parent = 0; base_type::make_child_of(base_type::m_p_root, p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_nd, false) base_type::m_p_root = p_nd; } else { base_type::make_child_of(p_nd, base_type::m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(base_type::m_p_root, false) } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) remove_node(it.m_p_nd); it.m_p_nd->m_value = r_new_val; push_imp(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) } c++/8/ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp 0000644 00000003621 15146341150 0016347 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/find_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); return base_type::m_p_root->m_value; } c++/8/ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp 0000644 00000016027 15146341150 0016532 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/erase_fn_imps.hpp * Contains an implementation class for a pairing heap. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); node_pointer p_new_root = join_node_children(base_type::m_p_root); PB_DS_ASSERT_NODE_CONSISTENT(p_new_root, false) if (p_new_root != 0) p_new_root->m_p_prev_or_parent = 0; base_type::actual_erase_node(base_type::m_p_root); base_type::m_p_root = p_new_root; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); remove_node(it.m_p_nd); base_type::actual_erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_node(node_pointer p_nd) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); node_pointer p_new_child = join_node_children(p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_new_child, false) if (p_nd == base_type::m_p_root) { if (p_new_child != 0) p_new_child->m_p_prev_or_parent = 0; base_type::m_p_root = p_new_child; PB_DS_ASSERT_NODE_CONSISTENT(base_type::m_p_root, false) return; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_prev_or_parent != 0); if (p_nd->m_p_prev_or_parent->m_p_l_child == p_nd) { if (p_new_child != 0) { p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_new_child->m_p_next_sibling != 0) p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child; p_nd->m_p_prev_or_parent->m_p_l_child = p_new_child; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) return; } p_nd->m_p_prev_or_parent->m_p_l_child = p_nd->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) return; } if (p_new_child != 0) { p_new_child->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; p_new_child->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_new_child->m_p_next_sibling != 0) p_new_child->m_p_next_sibling->m_p_prev_or_parent = p_new_child; p_new_child->m_p_prev_or_parent->m_p_next_sibling = p_new_child; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) return; } p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; PB_DS_ASSERT_NODE_CONSISTENT(p_nd->m_p_prev_or_parent, false) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: join_node_children(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); node_pointer p_ret = p_nd->m_p_l_child; if (p_ret == 0) return 0; while (p_ret->m_p_next_sibling != 0) p_ret = forward_join(p_ret, p_ret->m_p_next_sibling); while (p_ret->m_p_prev_or_parent != p_nd) p_ret = back_join(p_ret->m_p_prev_or_parent, p_ret); PB_DS_ASSERT_NODE_CONSISTENT(p_ret, false) return p_ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: forward_join(node_pointer p_nd, node_pointer p_next) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling == p_next); if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; base_type::make_child_of(p_nd, p_next); return p_next->m_p_next_sibling == 0 ? p_next : p_next->m_p_next_sibling; } if (p_next->m_p_next_sibling != 0) { p_next->m_p_next_sibling->m_p_prev_or_parent = p_nd; p_nd->m_p_next_sibling = p_next->m_p_next_sibling; base_type::make_child_of(p_next, p_nd); return p_nd->m_p_next_sibling; } p_nd->m_p_next_sibling = 0; base_type::make_child_of(p_next, p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_nd, false) return p_nd; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: back_join(node_pointer p_nd, node_pointer p_next) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_next->m_p_next_sibling == 0); if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; base_type::make_child_of(p_nd, p_next); PB_DS_ASSERT_NODE_CONSISTENT(p_next, false) return p_next; } p_nd->m_p_next_sibling = 0; base_type::make_child_of(p_next, p_nd); PB_DS_ASSERT_NODE_CONSISTENT(p_nd, false) return p_nd; } PB_DS_CLASS_T_DEC template<typename Pred> typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) return 0; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); size_type ersd = 0; while (p_out != 0) { ++ersd; node_pointer p_next = p_out->m_p_next_sibling; base_type::actual_erase_node(p_out); p_out = p_next; } node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_next_sibling = p_cur->m_p_prev_or_parent = 0; push_imp(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) return ersd; } c++/8/ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp 0000644 00000012615 15146341150 0016504 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file pairing_heap_/pairing_heap_.hpp * Contains an implementation class for a pairing heap. */ /* * Pairing heap: * Michael L. Fredman, Robert Sedgewick, Daniel Dominic Sleator, * and Robert Endre Tarjan, The Pairing Heap: * A New Form of Self-Adjusting Heap, Algorithmica, 1(1):111-129, 1986. */ #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> #define PB_DS_CLASS_C_DEC \ pairing_heap<Value_Type, Cmp_Fn, _Alloc> #ifdef _GLIBCXX_DEBUG #define PB_DS_P_HEAP_BASE \ left_child_next_sibling_heap<Value_Type, Cmp_Fn, null_type, _Alloc, false> #else #define PB_DS_P_HEAP_BASE \ left_child_next_sibling_heap<Value_Type, Cmp_Fn, null_type, _Alloc> #endif /** * Pairing heap. * * @ingroup heap-detail */ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> class pairing_heap : public PB_DS_P_HEAP_BASE { private: typedef PB_DS_P_HEAP_BASE base_type; typedef typename base_type::node_pointer node_pointer; typedef typename _Alloc::template rebind<Value_Type>::other __rebind_a; public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename __rebind_a::pointer pointer; typedef typename __rebind_a::const_pointer const_pointer; typedef typename __rebind_a::reference reference; typedef typename __rebind_a::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; pairing_heap(); pairing_heap(const Cmp_Fn&); pairing_heap(const pairing_heap&); void swap(pairing_heap&); ~pairing_heap(); inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; void pop(); void erase(point_iterator); template<typename Pred> size_type erase_if(Pred); template<typename Pred> void split(Pred, pairing_heap&); void join(pairing_heap&); protected: template<typename It> void copy_from_range(It, It); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif private: inline void push_imp(node_pointer); node_pointer join_node_children(node_pointer); node_pointer forward_join(node_pointer, node_pointer); node_pointer back_join(node_pointer, node_pointer); void remove_node(node_pointer); }; #define PB_DS_ASSERT_NODE_CONSISTENT(_Node, _Bool) \ _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(_Node, _Bool, \ __FILE__, __LINE__);) #include <ext/pb_ds/detail/pairing_heap_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/pairing_heap_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/pairing_heap_/find_fn_imps.hpp> #include <ext/pb_ds/detail/pairing_heap_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/pairing_heap_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/pairing_heap_/split_join_fn_imps.hpp> #undef PB_DS_ASSERT_NODE_CONSISTENT #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_P_HEAP_BASE } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp 0000644 00000007000 15146341150 0023011 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/constructor_destructor_fn_imps.hpp */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC Eq_Fn PB_DS_CLASS_C_DEC::s_eq_fn; PB_DS_CLASS_T_DEC null_type PB_DS_CLASS_C_DEC::s_null_type; PB_DS_CLASS_T_DEC Update_Policy PB_DS_CLASS_C_DEC::s_update_policy; PB_DS_CLASS_T_DEC type_to_type< typename PB_DS_CLASS_C_DEC::update_metadata> PB_DS_CLASS_C_DEC::s_metadata_type_indicator; PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_LU_NAME() : m_p_l(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template<typename It> PB_DS_CLASS_C_DEC:: PB_DS_LU_NAME(It first_it, It last_it) : m_p_l(0) { copy_from_range(first_it, last_it); PB_DS_ASSERT_VALID((*this)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_LU_NAME(const PB_DS_CLASS_C_DEC& other) : m_p_l(0) { __try { for (const_iterator it = other.begin(); it != other.end(); ++it) { entry_pointer p_l = allocate_new_entry(*it, traits_base::m_no_throw_copies_indicator); p_l->m_p_next = m_p_l; m_p_l = p_l; } } __catch(...) { deallocate_all(); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_p_l, other.m_p_l); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_all() { entry_pointer p_l = m_p_l; while (p_l != 0) { entry_pointer p_next_l = p_l->m_p_next; actual_erase_entry(p_l); p_l = p_next_l; } m_p_l = 0; } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_LU_NAME() { deallocate_all(); } c++/8/ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp 0000644 00000004105 15146341150 0020431 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/entry_metadata_base.hpp * Contains an implementation for a list update map. */ #ifndef PB_DS_LU_MAP_ENTRY_METADATA_BASE_HPP #define PB_DS_LU_MAP_ENTRY_METADATA_BASE_HPP namespace __gnu_pbds { namespace detail { template<typename Metadata> struct lu_map_entry_metadata_base { Metadata m_update_metadata; }; template<> struct lu_map_entry_metadata_base<null_type> { }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp 0000644 00000004032 15146341150 0017103 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/info_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return std::distance(begin(), end()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_p_l == 0); } c++/8/ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp 0000644 00000004722 15146341150 0020172 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/iterators_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { if (m_p_l == 0) { _GLIBCXX_DEBUG_ASSERT(empty()); return end(); } return iterator(&m_p_l->m_value, m_p_l, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { if (m_p_l == 0) { _GLIBCXX_DEBUG_ASSERT(empty()); return end(); } return iterator(&m_p_l->m_value, m_p_l, const_cast<PB_DS_CLASS_C_DEC* >(this)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(0, 0, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return const_iterator(0, 0, const_cast<PB_DS_CLASS_C_DEC*>(this)); } c++/8/ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp 0000644 00000004057 15146341150 0017245 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/debug_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { size_type calc_size = 0; for (const_iterator it = begin(); it != end(); ++it) { debug_base::check_key_exists(PB_DS_V2F(*it), __file, __line); ++calc_size; } debug_base::check_size(calc_size, __file, __line); } #endif c++/8/ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp 0000644 00000006666 15146341150 0017473 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/insert_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline std::pair< typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) entry_pointer p_l = find_imp(PB_DS_V2F(r_val)); if (p_l != 0) { PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_val)) return std::make_pair(point_iterator(&p_l->m_value), false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_val)) p_l = allocate_new_entry(r_val, traits_base::m_no_throw_copies_indicator); p_l->m_p_next = m_p_l; m_p_l = p_l; PB_DS_ASSERT_VALID((*this)) return std::make_pair(point_iterator(&p_l->m_value), true); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: allocate_new_entry(const_reference r_val, false_type) { entry_pointer p_l = s_entry_allocator.allocate(1); cond_dealtor_t cond(p_l); new (const_cast<void* >(static_cast<const void* >(&p_l->m_value))) value_type(r_val); cond.set_no_action(); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) init_entry_metadata(p_l, s_metadata_type_indicator); return p_l; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: allocate_new_entry(const_reference r_val, true_type) { entry_pointer p_l = s_entry_allocator.allocate(1); new (&p_l->m_value) value_type(r_val); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) init_entry_metadata(p_l, s_metadata_type_indicator); return p_l; } PB_DS_CLASS_T_DEC template<typename Metadata> inline void PB_DS_CLASS_C_DEC:: init_entry_metadata(entry_pointer p_l, type_to_type<Metadata>) { new (&p_l->m_update_metadata) Metadata(s_update_policy()); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: init_entry_metadata(entry_pointer, type_to_type<null_type>) { } c++/8/ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp 0000644 00000003754 15146341150 0017260 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/trace_fn_imps.hpp * Contains implementations of lu_map_. */ #ifdef PB_DS_LU_MAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << m_p_l << std::endl << std::endl; const_entry_pointer p_l = m_p_l; while (p_l != 0) { std::cerr << PB_DS_V2F(p_l->m_value) << std::endl; p_l = p_l->m_p_next; } std::cerr << std::endl; } #endif c++/8/ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp 0000644 00000005455 15146341150 0017102 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/find_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) const { if (m_p_l == 0) return 0; if (s_eq_fn(r_key, PB_DS_V2F(m_p_l->m_value))) { apply_update(m_p_l, s_metadata_type_indicator); PB_DS_CHECK_KEY_EXISTS(r_key) return m_p_l; } entry_pointer p_l = m_p_l; while (p_l->m_p_next != 0) { entry_pointer p_next = p_l->m_p_next; if (s_eq_fn(r_key, PB_DS_V2F(p_next->m_value))) { if (apply_update(p_next, s_metadata_type_indicator)) { p_l->m_p_next = p_next->m_p_next; p_next->m_p_next = m_p_l; m_p_l = p_next; return m_p_l; } return p_next; } else p_l = p_next; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return 0; } PB_DS_CLASS_T_DEC template<typename Metadata> inline bool PB_DS_CLASS_C_DEC:: apply_update(entry_pointer p_l, type_to_type<Metadata>) { return s_update_policy(p_l->m_update_metadata); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: apply_update(entry_pointer, type_to_type<null_type>) { return s_update_policy(s_null_type); } c++/8/ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp 0000644 00000006632 15146341150 0017257 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/erase_fn_imps.hpp * Contains implementations of lu_map_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) if (m_p_l == 0) return false; if (s_eq_fn(r_key, PB_DS_V2F(m_p_l->m_value))) { entry_pointer p_next = m_p_l->m_p_next; actual_erase_entry(m_p_l); m_p_l = p_next; return true; } entry_pointer p_l = m_p_l; while (p_l->m_p_next != 0) if (s_eq_fn(r_key, PB_DS_V2F(p_l->m_p_next->m_value))) { erase_next(p_l); return true; } else p_l = p_l->m_p_next; return false; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { deallocate_all(); } PB_DS_CLASS_T_DEC template<typename Pred> inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; while (m_p_l != 0 && pred(m_p_l->m_value)) { entry_pointer p_next = m_p_l->m_p_next; ++num_ersd; actual_erase_entry(m_p_l); m_p_l = p_next; } if (m_p_l == 0) return num_ersd; entry_pointer p_l = m_p_l; while (p_l->m_p_next != 0) { if (pred(p_l->m_p_next->m_value)) { ++num_ersd; erase_next(p_l); } else p_l = p_l->m_p_next; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_next(entry_pointer p_l) { _GLIBCXX_DEBUG_ASSERT(p_l != 0); _GLIBCXX_DEBUG_ASSERT(p_l->m_p_next != 0); entry_pointer p_next_l = p_l->m_p_next->m_p_next; actual_erase_entry(p_l->m_p_next); p_l->m_p_next = p_next_l; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: actual_erase_entry(entry_pointer p_l) { _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_l->m_value));) p_l->~entry(); s_entry_allocator.deallocate(p_l, 1); } c++/8/ext/pb_ds/detail/list_update_map_/lu_map_.hpp 0000644 00000024231 15146341150 0016054 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_map_/lu_map_.hpp * Contains a list update map. */ #include <utility> #include <iterator> #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/detail/types_traits.hpp> #include <ext/pb_ds/detail/list_update_map_/entry_metadata_base.hpp> #include <ext/pb_ds/exception.hpp> #ifdef _GLIBCXX_DEBUG #include <ext/pb_ds/detail/debug_map_base.hpp> #endif #ifdef PB_DS_LU_MAP_TRACE_ #include <iostream> #endif #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_LU_NAME lu_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_LU_NAME lu_set #endif #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Mapped, typename Eq_Fn, \ typename _Alloc, typename Update_Policy> #define PB_DS_CLASS_C_DEC \ PB_DS_LU_NAME<Key, Mapped, Eq_Fn, _Alloc, Update_Policy> #define PB_DS_LU_TRAITS_BASE \ types_traits<Key, Mapped, _Alloc, false> #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base<Key, Eq_Fn, \ typename _Alloc::template rebind<Key>::other::const_reference> #endif /// list-based (with updates) associative container. /// Skip to the lu, my darling. template<typename Key, typename Mapped, typename Eq_Fn, typename _Alloc, typename Update_Policy> class PB_DS_LU_NAME : #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public PB_DS_LU_TRAITS_BASE { private: typedef PB_DS_LU_TRAITS_BASE traits_base; struct entry : public lu_map_entry_metadata_base<typename Update_Policy::metadata_type> { typename traits_base::value_type m_value; typename _Alloc::template rebind<entry>::other::pointer m_p_next; }; typedef typename _Alloc::template rebind<entry>::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef typename entry_allocator::const_pointer const_entry_pointer; typedef typename entry_allocator::reference entry_reference; typedef typename entry_allocator::const_reference const_entry_reference; typedef typename _Alloc::template rebind<entry_pointer>::other entry_pointer_allocator; typedef typename entry_pointer_allocator::pointer entry_pointer_array; typedef typename traits_base::value_type value_type_; typedef typename traits_base::pointer pointer_; typedef typename traits_base::const_pointer const_pointer_; typedef typename traits_base::reference reference_; typedef typename traits_base::const_reference const_reference_; #define PB_DS_GEN_POS entry_pointer #include <ext/pb_ds/detail/unordered_iterator/point_const_iterator.hpp> #include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp> #include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp> #include <ext/pb_ds/detail/unordered_iterator/iterator.hpp> #undef PB_DS_GEN_POS #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif typedef cond_dealtor<entry, _Alloc> cond_dealtor_t; public: typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Eq_Fn eq_fn; typedef Update_Policy update_policy; typedef typename Update_Policy::metadata_type update_metadata; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef point_iterator_ point_iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef point_const_iterator_ point_iterator; #endif typedef point_const_iterator_ point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef iterator_ iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef const_iterator_ iterator; #endif typedef const_iterator_ const_iterator; public: PB_DS_LU_NAME(); PB_DS_LU_NAME(const PB_DS_CLASS_C_DEC&); virtual ~PB_DS_LU_NAME(); template<typename It> PB_DS_LU_NAME(It, It); void swap(PB_DS_CLASS_C_DEC&); inline size_type size() const; inline size_type max_size() const; inline bool empty() const; inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return insert(std::make_pair(r_key, mapped_type())).first->second; #else insert(r_key); return traits_base::s_null_type; #endif } inline std::pair<point_iterator, bool> insert(const_reference); inline point_iterator find(key_const_reference r_key) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) entry_pointer p_e = find_imp(r_key); return point_iterator(p_e == 0 ? 0: &p_e->m_value); } inline point_const_iterator find(key_const_reference r_key) const { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) entry_pointer p_e = find_imp(r_key); return point_const_iterator(p_e == 0 ? 0: &p_e->m_value); } inline bool erase(key_const_reference); template<typename Pred> inline size_type erase_if(Pred); void clear(); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char* file, int line) const; #endif #ifdef PB_DS_LU_MAP_TRACE_ void trace() const; #endif protected: template<typename It> void copy_from_range(It, It); private: #ifdef PB_DS_DATA_TRUE_INDICATOR friend class iterator_; #endif friend class const_iterator_; inline entry_pointer allocate_new_entry(const_reference, false_type); inline entry_pointer allocate_new_entry(const_reference, true_type); template<typename Metadata> inline static void init_entry_metadata(entry_pointer, type_to_type<Metadata>); inline static void init_entry_metadata(entry_pointer, type_to_type<null_type>); void deallocate_all(); void erase_next(entry_pointer); void actual_erase_entry(entry_pointer); void inc_it_state(const_pointer& r_p_value, entry_pointer& r_pos) const { r_pos = r_pos->m_p_next; r_p_value = (r_pos == 0) ? 0 : &r_pos->m_value; } template<typename Metadata> inline static bool apply_update(entry_pointer, type_to_type<Metadata>); inline static bool apply_update(entry_pointer, type_to_type<null_type>); inline entry_pointer find_imp(key_const_reference) const; static entry_allocator s_entry_allocator; static Eq_Fn s_eq_fn; static Update_Policy s_update_policy; static type_to_type<update_metadata> s_metadata_type_indicator; static null_type s_null_type; mutable entry_pointer m_p_l; }; #include <ext/pb_ds/detail/list_update_map_/constructor_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/list_update_map_/info_fn_imps.hpp> #include <ext/pb_ds/detail/list_update_map_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/list_update_map_/iterators_fn_imps.hpp> #include <ext/pb_ds/detail/list_update_map_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/list_update_map_/find_fn_imps.hpp> #include <ext/pb_ds/detail/list_update_map_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/list_update_map_/trace_fn_imps.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_LU_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #undef PB_DS_LU_NAME } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp 0000644 00000007647 15146341150 0020303 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/split_join_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: join_prep(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_size == 0) return false; if (m_size == 0) { value_swap(other); return false; } const bool greater = Cmp_Fn::operator()(PB_DS_V2F(m_p_head->m_p_right->m_value), PB_DS_V2F(other.m_p_head->m_p_left->m_value)); const bool lesser = Cmp_Fn::operator()(PB_DS_V2F(other.m_p_head->m_p_right->m_value), PB_DS_V2F(m_p_head->m_p_left->m_value)); if (!greater && !lesser) __throw_join_error(); if (lesser) value_swap(other); m_size += other.m_size; _GLIBCXX_DEBUG_ONLY(debug_base::join(other);) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join_finish(PB_DS_CLASS_C_DEC& other) { initialize_min_max(); other.initialize(); } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: split_prep(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) other.clear(); if (m_size == 0) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } if (Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_left->m_value))) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(m_p_head->m_p_right->m_value))) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } if (m_size == 1) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return false; } _GLIBCXX_DEBUG_ONLY(debug_base::split(r_key,(Cmp_Fn& )(*this), other);) return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split_finish(PB_DS_CLASS_C_DEC& other) { other.initialize_min_max(); other.m_size = std::distance(other.begin(), other.end()); m_size -= other.m_size; initialize_min_max(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: recursive_count(node_pointer p) const { if (p == 0) return 0; return 1 + recursive_count(p->m_p_left) + recursive_count(p->m_p_right); } c++/8/ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp 0000644 00000012603 15146341150 0023143 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/constructors_destructor_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_allocator PB_DS_CLASS_C_DEC::s_node_allocator; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME() : m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME(const Cmp_Fn& r_cmp_fn) : Cmp_Fn(r_cmp_fn), m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : Cmp_Fn(r_cmp_fn), node_update(r_node_update), m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_BIN_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef _GLIBCXX_DEBUG debug_base(other), #endif #ifdef PB_DS_TREE_TRACE PB_DS_TREE_TRACE_BASE_C_DEC(other), #endif Cmp_Fn(other), node_update(other), m_p_head(s_node_allocator.allocate(1)), m_size(0) { initialize(); m_size = other.m_size; PB_DS_STRUCT_ONLY_ASSERT_VALID(other) __try { m_p_head->m_p_parent = recursive_copy_node(other.m_p_head->m_p_parent); if (m_p_head->m_p_parent != 0) m_p_head->m_p_parent->m_p_parent = m_p_head; m_size = other.m_size; initialize_min_max(); } __catch(...) { _GLIBCXX_DEBUG_ONLY(debug_base::clear();) s_node_allocator.deallocate(m_p_head, 1); __throw_exception_again; } PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) value_swap(other); std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_p_head, other.m_p_head); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_BIN_TREE_NAME() { clear(); s_node_allocator.deallocate(m_p_head, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { m_p_head->m_p_parent = 0; m_p_head->m_p_left = m_p_head; m_p_head->m_p_right = m_p_head; m_size = 0; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: recursive_copy_node(const node_pointer p_nd) { if (p_nd == 0) return (0); node_pointer p_ret = s_node_allocator.allocate(1); __try { new (p_ret) node(*p_nd); } __catch(...) { s_node_allocator.deallocate(p_ret, 1); __throw_exception_again; } p_ret->m_p_left = p_ret->m_p_right = 0; __try { p_ret->m_p_left = recursive_copy_node(p_nd->m_p_left); p_ret->m_p_right = recursive_copy_node(p_nd->m_p_right); } __catch(...) { clear_imp(p_ret); __throw_exception_again; } if (p_ret->m_p_left != 0) p_ret->m_p_left->m_p_parent = p_ret; if (p_ret->m_p_right != 0) p_ret->m_p_right->m_p_parent = p_ret; PB_DS_ASSERT_NODE_CONSISTENT(p_ret) return p_ret; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize_min_max() { if (m_p_head->m_p_parent == 0) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } { node_pointer p_min = m_p_head->m_p_parent; while (p_min->m_p_left != 0) p_min = p_min->m_p_left; m_p_head->m_p_left = p_min; } { node_pointer p_max = m_p_head->m_p_parent; while (p_max->m_p_right != 0) p_max = p_max->m_p_right; m_p_head->m_p_right = p_max; } } c++/8/ext/pb_ds/detail/bin_search_tree_/traits.hpp 0000644 00000014352 15146341150 0015713 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/traits.hpp * Contains an implementation for bin_search_tree_. */ #ifndef PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP #include <ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp> #include <ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp> namespace __gnu_pbds { namespace detail { /// Binary search tree traits, primary template /// @ingroup traits template<typename Key, typename Mapped, class Cmp_Fn, template<typename Node_CItr, class Node_Itr, class _Cmp_Fn, typename _Alloc> class Node_Update, class Node, typename _Alloc> struct bin_search_tree_traits { private: typedef types_traits<Key, Mapped, _Alloc, false> type_traits; public: typedef Node node; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, true, _Alloc> point_const_iterator; typedef bin_search_tree_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, true, _Alloc> point_iterator; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, false, _Alloc> const_reverse_iterator; typedef bin_search_tree_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, false, _Alloc> reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef bin_search_tree_const_node_it_< Node, point_const_iterator, point_iterator, _Alloc> node_const_iterator; typedef bin_search_tree_node_it_< Node, point_const_iterator, point_iterator, _Alloc> node_iterator; typedef Node_Update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc> node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; /// Specialization. /// @ingroup traits template<typename Key, class Cmp_Fn, template<typename Node_CItr, class Node_Itr, class _Cmp_Fn, typename _Alloc> class Node_Update, class Node, typename _Alloc> struct bin_search_tree_traits<Key, null_type, Cmp_Fn, Node_Update, Node, _Alloc> { private: typedef types_traits<Key, null_type, _Alloc, false> type_traits; public: typedef Node node; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, true, _Alloc> point_const_iterator; typedef point_const_iterator point_iterator; typedef bin_search_tree_const_it_< typename _Alloc::template rebind< node>::other::pointer, typename type_traits::value_type, typename type_traits::pointer, typename type_traits::const_pointer, typename type_traits::reference, typename type_traits::const_reference, false, _Alloc> const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef bin_search_tree_const_node_it_< Node, point_const_iterator, point_iterator, _Alloc> node_const_iterator; typedef node_const_iterator node_iterator; typedef Node_Update<node_const_iterator, node_iterator, Cmp_Fn, _Alloc> node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BIN_SEARCH_TREE_NODE_AND_IT_TRAITS_HPP c++/8/ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp 0000644 00000004040 15146341150 0017044 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/info_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_size == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return (m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return (s_node_allocator.max_size()); } c++/8/ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp 0000644 00000006673 15146341150 0020143 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/iterators_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return (iterator(m_p_head->m_p_left)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { return (const_iterator(m_p_head->m_p_left)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return (iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return (const_iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() const { return (const_reverse_iterator(m_p_head->m_p_right)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rbegin() { return (reverse_iterator(m_p_head->m_p_right)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: rend() { return (reverse_iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reverse_iterator PB_DS_CLASS_C_DEC:: rend() const { return (const_reverse_iterator(m_p_head)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_begin() const { return (node_const_iterator(m_p_head->m_p_parent)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_begin() { return (node_iterator(m_p_head->m_p_parent)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_end() const { return (node_const_iterator(0)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_end() { return (node_iterator(0)); } c++/8/ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp 0000644 00000017607 15146341150 0017214 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/debug_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { structure_only_assert_valid(__file, __line); assert_consistent_with_debug_base(__file, __line); assert_size(__file, __line); assert_iterators(__file, __line); if (m_p_head->m_p_parent == 0) { PB_DS_DEBUG_VERIFY(m_size == 0); } else { PB_DS_DEBUG_VERIFY(m_size > 0); } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: structure_only_assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_p_head != 0); if (m_p_head->m_p_parent == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_left == m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_right == m_p_head); } else { PB_DS_DEBUG_VERIFY(m_p_head->m_p_parent->m_p_parent == m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_left != m_p_head); PB_DS_DEBUG_VERIFY(m_p_head->m_p_right != m_p_head); } if (m_p_head->m_p_parent != 0) assert_node_consistent(m_p_head->m_p_parent, __file, __line); assert_min(__file, __line); assert_max(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(const node_pointer p_nd, const char* __file, int __line) const { assert_node_consistent_(p_nd, __file, __line); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_consistent_t PB_DS_CLASS_C_DEC:: assert_node_consistent_(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return (std::make_pair((const_pointer)0,(const_pointer)0)); assert_node_consistent_with_left(p_nd, __file, __line); assert_node_consistent_with_right(p_nd, __file, __line); const std::pair<const_pointer, const_pointer> l_range = assert_node_consistent_(p_nd->m_p_left, __file, __line); if (l_range.second != 0) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(*l_range.second), PB_DS_V2F(p_nd->m_value))); const std::pair<const_pointer, const_pointer> r_range = assert_node_consistent_(p_nd->m_p_right, __file, __line); if (r_range.first != 0) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(*r_range.first))); return std::make_pair((l_range.first != 0) ? l_range.first : &p_nd->m_value, (r_range.second != 0)? r_range.second : &p_nd->m_value); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent_with_left(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd->m_p_left == 0) return; PB_DS_DEBUG_VERIFY(p_nd->m_p_left->m_p_parent == p_nd); PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(p_nd->m_p_left->m_value))); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent_with_right(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd->m_p_right == 0) return; PB_DS_DEBUG_VERIFY(p_nd->m_p_right->m_p_parent == p_nd); PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_p_right->m_value), PB_DS_V2F(p_nd->m_value))); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_min(const char* __file, int __line) const { assert_min_imp(m_p_head->m_p_parent, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_min_imp(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_left == m_p_head); return; } if (p_nd->m_p_left == 0) { PB_DS_DEBUG_VERIFY(p_nd == m_p_head->m_p_left); return; } assert_min_imp(p_nd->m_p_left, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max(const char* __file, int __line) const { assert_max_imp(m_p_head->m_p_parent, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max_imp(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) { PB_DS_DEBUG_VERIFY(m_p_head->m_p_right == m_p_head); return; } if (p_nd->m_p_right == 0) { PB_DS_DEBUG_VERIFY(p_nd == m_p_head->m_p_right); return; } assert_max_imp(p_nd->m_p_right, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { size_type iterated_num = 0; const_iterator prev_it = end(); for (const_iterator it = begin(); it != end(); ++it) { ++iterated_num; PB_DS_DEBUG_VERIFY(lower_bound(PB_DS_V2F(*it)).m_p_nd == it.m_p_nd); const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it)); --upper_bound_it; PB_DS_DEBUG_VERIFY(upper_bound_it.m_p_nd == it.m_p_nd); if (prev_it != end()) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(*prev_it), PB_DS_V2F(*it))); prev_it = it; } PB_DS_DEBUG_VERIFY(iterated_num == m_size); size_type reverse_iterated_num = 0; const_reverse_iterator reverse_prev_it = rend(); for (const_reverse_iterator reverse_it = rbegin(); reverse_it != rend(); ++reverse_it) { ++reverse_iterated_num; PB_DS_DEBUG_VERIFY(lower_bound( PB_DS_V2F(*reverse_it)).m_p_nd == reverse_it.m_p_nd); const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*reverse_it)); --upper_bound_it; PB_DS_DEBUG_VERIFY(upper_bound_it.m_p_nd == reverse_it.m_p_nd); if (reverse_prev_it != rend()) PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(PB_DS_V2F(*reverse_prev_it), PB_DS_V2F(*reverse_it))); reverse_prev_it = reverse_it; } PB_DS_DEBUG_VERIFY(reverse_iterated_num == m_size); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_consistent_with_debug_base(const char* __file, int __line) const { debug_base::check_size(m_size, __file, __line); assert_consistent_with_debug_base(m_p_head->m_p_parent, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_consistent_with_debug_base(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return; debug_base::check_key_exists(PB_DS_V2F(p_nd->m_value), __file, __line); assert_consistent_with_debug_base(p_nd->m_p_left, __file, __line); assert_consistent_with_debug_base(p_nd->m_p_right, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_size(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(recursive_count(m_p_head->m_p_parent) == m_size); } #endif c++/8/ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp 0000644 00000012551 15146341150 0017423 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/insert_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert_leaf(const_reference r_value) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) if (m_size == 0) return std::make_pair(insert_imp_empty(r_value), true); node_pointer p_nd = m_p_head->m_p_parent; node_pointer p_pot = m_p_head; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; if (p_pot == m_p_head) return std::make_pair(insert_leaf_new(r_value, m_p_head->m_p_right, false), true); if (!Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_pot->m_value))) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_value)) return std::make_pair(p_pot, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_value)) p_nd = p_pot->m_p_left; if (p_nd == 0) return std::make_pair(insert_leaf_new(r_value, p_pot, true), true); while (p_nd->m_p_right != 0) p_nd = p_nd->m_p_right; return std::make_pair(insert_leaf_new(r_value, p_nd, false), true); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: insert_leaf_new(const_reference r_value, node_pointer p_nd, bool left_nd) { node_pointer p_new_nd = get_new_node_for_leaf_insert(r_value, traits_base::m_no_throw_copies_indicator); if (left_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == 0); _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_nd->m_value))); p_nd->m_p_left = p_new_nd; if (m_p_head->m_p_left == p_nd) m_p_head->m_p_left = p_new_nd; } else { _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_right == 0); _GLIBCXX_DEBUG_ASSERT(Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))); p_nd->m_p_right = p_new_nd; if (m_p_head->m_p_right == p_nd) m_p_head->m_p_right = p_new_nd; } p_new_nd->m_p_parent = p_nd; p_new_nd->m_p_left = p_new_nd->m_p_right = 0; PB_DS_ASSERT_NODE_CONSISTENT(p_nd) update_to_top(p_new_nd, (node_update* )this); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value));) return iterator(p_new_nd); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: insert_imp_empty(const_reference r_value) { node_pointer p_new_node = get_new_node_for_leaf_insert(r_value, traits_base::m_no_throw_copies_indicator); m_p_head->m_p_left = m_p_head->m_p_right = m_p_head->m_p_parent = p_new_node; p_new_node->m_p_parent = m_p_head; p_new_node->m_p_left = p_new_node->m_p_right = 0; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value));) update_to_top(m_p_head->m_p_parent, (node_update*)this); return iterator(p_new_node); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_leaf_insert(const_reference r_val, false_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); cond_dealtor_t cond(p_new_nd); new (const_cast<void* >(static_cast<const void* >(&p_new_nd->m_value))) typename node::value_type(r_val); cond.set_no_action(); p_new_nd->m_p_left = p_new_nd->m_p_right = 0; ++m_size; return p_new_nd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_leaf_insert(const_reference r_val, true_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); new (const_cast<void* >(static_cast<const void* >(&p_new_nd->m_value))) typename node::value_type(r_val); p_new_nd->m_p_left = p_new_nd->m_p_right = 0; ++m_size; return p_new_nd; } c++/8/ext/pb_ds/detail/bin_search_tree_/node_iterators.hpp 0000644 00000013555 15146341150 0017432 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/node_iterators.hpp * Contains an implementation class for bin_search_tree_. */ #ifndef PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP #define PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP #include <ext/pb_ds/tag_and_trait.hpp> namespace __gnu_pbds { namespace detail { #define PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC \ bin_search_tree_const_node_it_<Node, Const_Iterator, Iterator, _Alloc> /// Const node iterator. template<typename Node, class Const_Iterator, class Iterator, typename _Alloc> class bin_search_tree_const_node_it_ { private: typedef typename _Alloc::template rebind< Node>::other::pointer node_pointer; public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef Const_Iterator value_type; /// Iterator's reference type. typedef Const_Iterator reference; /// Iterator's __const reference type. typedef Const_Iterator const_reference; /// Metadata type. typedef typename Node::metadata_type metadata_type; /// Const metadata reference type. typedef typename _Alloc::template rebind<metadata_type>::other::const_reference metadata_const_reference; bin_search_tree_const_node_it_(const node_pointer p_nd = 0) : m_p_nd(const_cast<node_pointer>(p_nd)) { } /// Access. const_reference operator*() const { return Const_Iterator(m_p_nd); } /// Metadata access. metadata_const_reference get_metadata() const { return m_p_nd->get_metadata(); } /// Returns the __const node iterator associated with the left node. PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC get_l_child() const { return PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(m_p_nd->m_p_left); } /// Returns the __const node iterator associated with the right node. PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC get_r_child() const { return PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(m_p_nd->m_p_right); } /// Compares to a different iterator object. bool operator==(const PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC& other) const { return m_p_nd == other.m_p_nd; } /// Compares (negatively) to a different iterator object. bool operator!=(const PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC& other) const { return m_p_nd != other.m_p_nd; } node_pointer m_p_nd; }; #define PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC \ bin_search_tree_node_it_<Node, Const_Iterator, Iterator, _Alloc> /// Node iterator. template<typename Node, class Const_Iterator, class Iterator, typename _Alloc> class bin_search_tree_node_it_ : public PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC { private: typedef typename _Alloc::template rebind< Node>::other::pointer node_pointer; public: /// Iterator's value type. typedef Iterator value_type; /// Iterator's reference type. typedef Iterator reference; /// Iterator's __const reference type. typedef Iterator const_reference; inline bin_search_tree_node_it_(const node_pointer p_nd = 0) : PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC(const_cast<node_pointer>(p_nd)) { } /// Access. Iterator operator*() const { return Iterator(PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd); } /// Returns the node iterator associated with the left node. PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC get_l_child() const { return PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC( PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd->m_p_left); } /// Returns the node iterator associated with the right node. PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC get_r_child() const { return PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC( PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC::m_p_nd->m_p_right); } }; #undef PB_DS_TREE_CONST_NODE_ITERATOR_CLASS_C_DEC #undef PB_DS_TREE_NODE_ITERATOR_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BIN_SEARCH_TREE_NODE_ITERATORS_HPP c++/8/ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp 0000644 00000030203 15146341150 0017651 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/bin_search_tree_.hpp * Contains an implementation class for binary search tree. */ #include <ext/pb_ds/exception.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp> #include <ext/pb_ds/detail/types_traits.hpp> #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/tree_trace_base.hpp> #ifdef _GLIBCXX_DEBUG #include <ext/pb_ds/detail/debug_map_base.hpp> #endif #include <utility> #include <functional> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_BIN_TREE_NAME bin_search_tree_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_BIN_TREE_NAME bin_search_tree_set #endif #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Mapped, typename Cmp_Fn, \ typename Node_And_It_Traits, typename _Alloc> #define PB_DS_CLASS_C_DEC \ PB_DS_BIN_TREE_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, _Alloc> #define PB_DS_BIN_TREE_TRAITS_BASE \ types_traits<Key, Mapped, _Alloc, false> #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base<Key, eq_by_less<Key, Cmp_Fn>, \ typename _Alloc::template rebind<Key>::other::const_reference> #endif #ifdef PB_DS_TREE_TRACE #define PB_DS_TREE_TRACE_BASE_C_DEC \ tree_trace_base<typename Node_And_It_Traits::node_const_iterator, \ typename Node_And_It_Traits::node_iterator, \ Cmp_Fn, true, _Alloc> #endif /* * @brief Binary search tree (BST). * * This implementation uses an idea from the SGI STL (using a @a * header node which is needed for efficient iteration). */ template<typename Key, typename Mapped, typename Cmp_Fn, typename Node_And_It_Traits, typename _Alloc> class PB_DS_BIN_TREE_NAME : #ifdef _GLIBCXX_DEBUG public PB_DS_DEBUG_MAP_BASE_C_DEC, #endif #ifdef PB_DS_TREE_TRACE public PB_DS_TREE_TRACE_BASE_C_DEC, #endif public Cmp_Fn, public PB_DS_BIN_TREE_TRAITS_BASE, public Node_And_It_Traits::node_update { typedef Node_And_It_Traits traits_type; protected: typedef PB_DS_BIN_TREE_TRAITS_BASE traits_base; typedef typename _Alloc::template rebind<typename traits_type::node>::other node_allocator; typedef typename node_allocator::value_type node; typedef typename node_allocator::pointer node_pointer; typedef typename traits_type::null_node_update_pointer null_node_update_pointer; private: typedef cond_dealtor<node, _Alloc> cond_dealtor_t; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif public: typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; #endif typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; typedef typename traits_type::point_const_iterator point_const_iterator; typedef point_const_iterator const_iterator; typedef typename traits_type::point_iterator point_iterator; typedef point_iterator iterator; typedef typename traits_type::const_reverse_iterator const_reverse_iterator; typedef typename traits_type::reverse_iterator reverse_iterator; typedef typename traits_type::node_const_iterator node_const_iterator; typedef typename traits_type::node_iterator node_iterator; typedef typename traits_type::node_update node_update; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; PB_DS_BIN_TREE_NAME(); PB_DS_BIN_TREE_NAME(const Cmp_Fn&); PB_DS_BIN_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_BIN_TREE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~PB_DS_BIN_TREE_NAME(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline point_iterator lower_bound(key_const_reference); inline point_const_iterator lower_bound(key_const_reference) const; inline point_iterator upper_bound(key_const_reference); inline point_const_iterator upper_bound(key_const_reference) const; inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; inline reverse_iterator rbegin(); inline const_reverse_iterator rbegin() const; inline reverse_iterator rend(); inline const_reverse_iterator rend() const; /// Returns a const node_iterator corresponding to the node at the /// root of the tree. inline node_const_iterator node_begin() const; /// Returns a node_iterator corresponding to the node at the /// root of the tree. inline node_iterator node_begin(); /// Returns a const node_iterator corresponding to a node just /// after a leaf of the tree. inline node_const_iterator node_end() const; /// Returns a node_iterator corresponding to a node just /// after a leaf of the tree. inline node_iterator node_end(); void clear(); protected: void value_swap(PB_DS_CLASS_C_DEC&); void initialize_min_max(); inline iterator insert_imp_empty(const_reference); inline iterator insert_leaf_new(const_reference, node_pointer, bool); inline node_pointer get_new_node_for_leaf_insert(const_reference, false_type); inline node_pointer get_new_node_for_leaf_insert(const_reference, true_type); inline void actual_erase_node(node_pointer); inline std::pair<node_pointer, bool> erase(node_pointer); inline void update_min_max_for_erased_node(node_pointer); static void clear_imp(node_pointer); inline std::pair<point_iterator, bool> insert_leaf(const_reference); inline void rotate_left(node_pointer); inline void rotate_right(node_pointer); inline void rotate_parent(node_pointer); inline void apply_update(node_pointer, null_node_update_pointer); template<typename Node_Update_> inline void apply_update(node_pointer, Node_Update_*); inline void update_to_top(node_pointer, null_node_update_pointer); template<typename Node_Update_> inline void update_to_top(node_pointer, Node_Update_*); bool join_prep(PB_DS_CLASS_C_DEC&); void join_finish(PB_DS_CLASS_C_DEC&); bool split_prep(key_const_reference, PB_DS_CLASS_C_DEC&); void split_finish(PB_DS_CLASS_C_DEC&); size_type recursive_count(node_pointer) const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void structure_only_assert_valid(const char*, int) const; void assert_node_consistent(const node_pointer, const char*, int) const; #endif private: #ifdef _GLIBCXX_DEBUG void assert_iterators(const char*, int) const; void assert_consistent_with_debug_base(const char*, int) const; void assert_node_consistent_with_left(const node_pointer, const char*, int) const; void assert_node_consistent_with_right(const node_pointer, const char*, int) const; void assert_consistent_with_debug_base(const node_pointer, const char*, int) const; void assert_min(const char*, int) const; void assert_min_imp(const node_pointer, const char*, int) const; void assert_max(const char*, int) const; void assert_max_imp(const node_pointer, const char*, int) const; void assert_size(const char*, int) const; typedef std::pair<const_pointer, const_pointer> node_consistent_t; node_consistent_t assert_node_consistent_(const node_pointer, const char*, int) const; #endif void initialize(); node_pointer recursive_copy_node(const node_pointer); protected: node_pointer m_p_head; size_type m_size; static node_allocator s_node_allocator; }; #define PB_DS_STRUCT_ONLY_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.structure_only_assert_valid(__FILE__, __LINE__);) #define PB_DS_ASSERT_NODE_CONSISTENT(_Node) \ _GLIBCXX_DEBUG_ONLY(assert_node_consistent(_Node, __FILE__, __LINE__);) #include <ext/pb_ds/detail/bin_search_tree_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/bin_search_tree_/iterators_fn_imps.hpp> #include <ext/pb_ds/detail/bin_search_tree_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/bin_search_tree_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp> #include <ext/pb_ds/detail/bin_search_tree_/info_fn_imps.hpp> #include <ext/pb_ds/detail/bin_search_tree_/split_join_fn_imps.hpp> #include <ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp> #include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp> #undef PB_DS_ASSERT_NODE_CONSISTENT #undef PB_DS_STRUCT_ONLY_ASSERT_VALID #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_BIN_TREE_NAME #undef PB_DS_BIN_TREE_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #ifdef PB_DS_TREE_TRACE #undef PB_DS_TREE_TRACE_BASE_C_DEC #endif } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/bin_search_tree_/rotate_fn_imps.hpp 0000644 00000010136 15146341150 0017412 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/rotate_fn_imps.hpp * Contains imps for rotating nodes. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_left(node_pointer p_x) { node_pointer p_y = p_x->m_p_right; p_x->m_p_right = p_y->m_p_left; if (p_y->m_p_left != 0) p_y->m_p_left->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_left) p_x->m_p_parent->m_p_left = p_y; else p_x->m_p_parent->m_p_right = p_y; p_y->m_p_left = p_x; p_x->m_p_parent = p_y; PB_DS_ASSERT_NODE_CONSISTENT(p_x) PB_DS_ASSERT_NODE_CONSISTENT(p_y) apply_update(p_x, (node_update* )this); apply_update(p_x->m_p_parent, (node_update* )this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_right(node_pointer p_x) { node_pointer p_y = p_x->m_p_left; p_x->m_p_left = p_y->m_p_right; if (p_y->m_p_right != 0) p_y->m_p_right->m_p_parent = p_x; p_y->m_p_parent = p_x->m_p_parent; if (p_x == m_p_head->m_p_parent) m_p_head->m_p_parent = p_y; else if (p_x == p_x->m_p_parent->m_p_right) p_x->m_p_parent->m_p_right = p_y; else p_x->m_p_parent->m_p_left = p_y; p_y->m_p_right = p_x; p_x->m_p_parent = p_y; PB_DS_ASSERT_NODE_CONSISTENT(p_x) PB_DS_ASSERT_NODE_CONSISTENT(p_y) apply_update(p_x, (node_update* )this); apply_update(p_x->m_p_parent, (node_update* )this); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rotate_parent(node_pointer p_nd) { node_pointer p_parent = p_nd->m_p_parent; if (p_nd == p_parent->m_p_left) rotate_right(p_parent); else rotate_left(p_parent); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_parent = p_nd); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_left == p_parent || p_nd->m_p_right == p_parent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer /*p_nd*/, null_node_update_pointer /*p_update*/) { } PB_DS_CLASS_T_DEC template<typename Node_Update_> inline void PB_DS_CLASS_C_DEC:: apply_update(node_pointer p_nd, Node_Update_* /*p_update*/) { node_update::operator()(node_iterator(p_nd), node_const_iterator(static_cast<node_pointer>(0))); } PB_DS_CLASS_T_DEC template<typename Node_Update_> inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer p_nd, Node_Update_* p_update) { while (p_nd != m_p_head) { apply_update(p_nd, p_update); p_nd = p_nd->m_p_parent; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_to_top(node_pointer /*p_nd*/, null_node_update_pointer /*p_update*/) { } c++/8/ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp 0000644 00000003561 15146341150 0020740 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/policy_access_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return (*this); } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return (*this); } c++/8/ext/pb_ds/detail/bin_search_tree_/r_erase_fn_imps.hpp 0000644 00000005535 15146341150 0017543 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/r_erase_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_z) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(erase_existing(PB_DS_V2F(p_z->m_value));) p_z->~node(); s_node_allocator.deallocate(p_z, 1); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_node(node_pointer p_z) { if (m_size == 1) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } if (m_p_head->m_p_left == p_z) { iterator it(p_z); ++it; m_p_head->m_p_left = it.m_p_nd; } else if (m_p_head->m_p_right == p_z) { iterator it(p_z); --it; m_p_head->m_p_right = it.m_p_nd; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd == 0) return; clear_imp(p_nd->m_p_left); clear_imp(p_nd->m_p_right); p_nd->~Node(); s_node_allocator.deallocate(p_nd, 1); } c++/8/ext/pb_ds/detail/bin_search_tree_/find_fn_imps.hpp 0000644 00000011107 15146341150 0017033 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/find_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) const { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) p_nd = p_nd->m_p_right; else { p_pot = p_nd; p_nd = p_nd->m_p_left; } return iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: lower_bound(key_const_reference r_key) { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) p_nd = p_nd->m_p_right; else { p_pot = p_nd; p_nd = p_nd->m_p_left; } return iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) const { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return const_iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: upper_bound(key_const_reference r_key) { node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return point_iterator(p_pot); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; node_pointer ret = p_pot; if (p_pot != m_p_head) { const bool __cmp = Cmp_Fn::operator()(r_key, PB_DS_V2F(p_pot->m_value)); if (__cmp) ret = m_p_head; } return point_iterator(ret); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) node_pointer p_pot = m_p_head; node_pointer p_nd = m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; node_pointer ret = p_pot; if (p_pot != m_p_head) { const bool __cmp = Cmp_Fn::operator()(r_key, PB_DS_V2F(p_pot->m_value)); if (__cmp) ret = m_p_head; } return point_const_iterator(ret); } c++/8/ext/pb_ds/detail/bin_search_tree_/point_iterators.hpp 0000644 00000021401 15146341150 0017623 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/point_iterators.hpp * Contains an implementation class for bin_search_tree_. */ #ifndef PB_DS_BIN_SEARCH_TREE_FIND_ITERATORS_HPP #define PB_DS_BIN_SEARCH_TREE_FIND_ITERATORS_HPP #include <ext/pb_ds/tag_and_trait.hpp> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #define PB_DS_TREE_CONST_IT_C_DEC \ bin_search_tree_const_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ Is_Forward_Iterator, \ _Alloc> #define PB_DS_TREE_CONST_ODIR_IT_C_DEC \ bin_search_tree_const_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ !Is_Forward_Iterator, \ _Alloc> #define PB_DS_TREE_IT_C_DEC \ bin_search_tree_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ Is_Forward_Iterator, \ _Alloc> #define PB_DS_TREE_ODIR_IT_C_DEC \ bin_search_tree_it_< \ Node_Pointer, \ Value_Type, \ Pointer, \ Const_Pointer, \ Reference, \ Const_Reference, \ !Is_Forward_Iterator, \ _Alloc> /// Const iterator. template<typename Node_Pointer, typename Value_Type, typename Pointer, typename Const_Pointer, typename Reference, typename Const_Reference, bool Is_Forward_Iterator, typename _Alloc> class bin_search_tree_const_it_ { public: typedef std::bidirectional_iterator_tag iterator_category; typedef typename _Alloc::difference_type difference_type; typedef Value_Type value_type; typedef Pointer pointer; typedef Const_Pointer const_pointer; typedef Reference reference; typedef Const_Reference const_reference; inline bin_search_tree_const_it_(const Node_Pointer p_nd = 0) : m_p_nd(const_cast<Node_Pointer>(p_nd)) { } inline bin_search_tree_const_it_(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) : m_p_nd(other.m_p_nd) { } inline PB_DS_TREE_CONST_IT_C_DEC& operator=(const PB_DS_TREE_CONST_IT_C_DEC& other) { m_p_nd = other.m_p_nd; return *this; } inline PB_DS_TREE_CONST_IT_C_DEC& operator=(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) { m_p_nd = other.m_p_nd; return *this; } inline const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return &m_p_nd->m_value; } inline const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return m_p_nd->m_value; } inline bool operator==(const PB_DS_TREE_CONST_IT_C_DEC & other) const { return m_p_nd == other.m_p_nd; } inline bool operator==(const PB_DS_TREE_CONST_ODIR_IT_C_DEC & other) const { return m_p_nd == other.m_p_nd; } inline bool operator!=(const PB_DS_TREE_CONST_IT_C_DEC& other) const { return m_p_nd != other.m_p_nd; } inline bool operator!=(const PB_DS_TREE_CONST_ODIR_IT_C_DEC& other) const { return m_p_nd != other.m_p_nd; } inline PB_DS_TREE_CONST_IT_C_DEC& operator++() { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); inc(integral_constant<int,Is_Forward_Iterator>()); return *this; } inline PB_DS_TREE_CONST_IT_C_DEC operator++(int) { PB_DS_TREE_CONST_IT_C_DEC ret_it(m_p_nd); operator++(); return ret_it; } inline PB_DS_TREE_CONST_IT_C_DEC& operator--() { dec(integral_constant<int,Is_Forward_Iterator>()); return *this; } inline PB_DS_TREE_CONST_IT_C_DEC operator--(int) { PB_DS_TREE_CONST_IT_C_DEC ret_it(m_p_nd); operator--(); return ret_it; } protected: inline void inc(false_type) { dec(true_type()); } void inc(true_type) { if (m_p_nd->special()&& m_p_nd->m_p_parent->m_p_parent == m_p_nd) { m_p_nd = m_p_nd->m_p_left; return; } if (m_p_nd->m_p_right != 0) { m_p_nd = m_p_nd->m_p_right; while (m_p_nd->m_p_left != 0) m_p_nd = m_p_nd->m_p_left; return; } Node_Pointer p_y = m_p_nd->m_p_parent; while (m_p_nd == p_y->m_p_right) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (m_p_nd->m_p_right != p_y) m_p_nd = p_y; } inline void dec(false_type) { inc(true_type()); } void dec(true_type) { if (m_p_nd->special() && m_p_nd->m_p_parent->m_p_parent == m_p_nd) { m_p_nd = m_p_nd->m_p_right; return; } if (m_p_nd->m_p_left != 0) { Node_Pointer p_y = m_p_nd->m_p_left; while (p_y->m_p_right != 0) p_y = p_y->m_p_right; m_p_nd = p_y; return; } Node_Pointer p_y = m_p_nd->m_p_parent; while (m_p_nd == p_y->m_p_left) { m_p_nd = p_y; p_y = p_y->m_p_parent; } if (m_p_nd->m_p_left != p_y) m_p_nd = p_y; } public: Node_Pointer m_p_nd; }; /// Iterator. template<typename Node_Pointer, typename Value_Type, typename Pointer, typename Const_Pointer, typename Reference, typename Const_Reference, bool Is_Forward_Iterator, typename _Alloc> class bin_search_tree_it_ : public PB_DS_TREE_CONST_IT_C_DEC { public: inline bin_search_tree_it_(const Node_Pointer p_nd = 0) : PB_DS_TREE_CONST_IT_C_DEC((Node_Pointer)p_nd) { } inline bin_search_tree_it_(const PB_DS_TREE_ODIR_IT_C_DEC& other) : PB_DS_TREE_CONST_IT_C_DEC(other.m_p_nd) { } inline PB_DS_TREE_IT_C_DEC& operator=(const PB_DS_TREE_IT_C_DEC& other) { base_it_type::m_p_nd = other.m_p_nd; return *this; } inline PB_DS_TREE_IT_C_DEC& operator=(const PB_DS_TREE_ODIR_IT_C_DEC& other) { base_it_type::m_p_nd = other.m_p_nd; return *this; } inline typename PB_DS_TREE_CONST_IT_C_DEC::pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd != 0); return &base_it_type::m_p_nd->m_value; } inline typename PB_DS_TREE_CONST_IT_C_DEC::reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_it_type::m_p_nd != 0); return base_it_type::m_p_nd->m_value; } inline PB_DS_TREE_IT_C_DEC& operator++() { PB_DS_TREE_CONST_IT_C_DEC:: operator++(); return *this; } inline PB_DS_TREE_IT_C_DEC operator++(int) { PB_DS_TREE_IT_C_DEC ret_it(base_it_type::m_p_nd); operator++(); return ret_it; } inline PB_DS_TREE_IT_C_DEC& operator--() { PB_DS_TREE_CONST_IT_C_DEC:: operator--(); return *this; } inline PB_DS_TREE_IT_C_DEC operator--(int) { PB_DS_TREE_IT_C_DEC ret_it(base_it_type::m_p_nd); operator--(); return ret_it; } protected: typedef PB_DS_TREE_CONST_IT_C_DEC base_it_type; }; #undef PB_DS_TREE_CONST_IT_C_DEC #undef PB_DS_TREE_CONST_ODIR_IT_C_DEC #undef PB_DS_TREE_IT_C_DEC #undef PB_DS_TREE_ODIR_IT_C_DEC } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/bin_search_tree_/erase_fn_imps.hpp 0000644 00000005547 15146341150 0017225 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file bin_search_tree_/erase_fn_imps.hpp * Contains an implementation class for bin_search_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_z) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(p_z->m_value));) p_z->~node(); s_node_allocator.deallocate(p_z, 1); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_min_max_for_erased_node(node_pointer p_z) { if (m_size == 1) { m_p_head->m_p_left = m_p_head->m_p_right = m_p_head; return; } if (m_p_head->m_p_left == p_z) { iterator it(p_z); ++it; m_p_head->m_p_left = it.m_p_nd; } else if (m_p_head->m_p_right == p_z) { iterator it(p_z); --it; m_p_head->m_p_right = it.m_p_nd; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) clear_imp(m_p_head->m_p_parent); m_size = 0; initialize(); _GLIBCXX_DEBUG_ONLY(debug_base::clear();) PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { if (p_nd == 0) return; clear_imp(p_nd->m_p_left); clear_imp(p_nd->m_p_right); p_nd->~node(); s_node_allocator.deallocate(p_nd, 1); } c++/8/ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp 0000644 00000006123 15146341150 0017112 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/split_join_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC template<typename Pred> void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) other.clear(); if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); while (p_out != 0) { _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); --base_type::m_size; ++other.m_size; node_pointer p_next = p_out->m_p_next_sibling; other.make_root_and_link(p_out); p_out = p_next; } PB_DS_ASSERT_VALID(other) node_pointer p_cur = base_type::m_p_root; m_p_max = 0; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; make_root_and_link(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) node_pointer p_other = other.m_p_root; while (p_other != 0) { node_pointer p_next = p_other->m_p_next_sibling; make_root_and_link(p_other); p_other = p_next; } base_type::m_size += other.m_size; other.m_p_root = 0; other.m_size = 0; other.m_p_max = 0; PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } c++/8/ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp 0000644 00000005602 15146341150 0021767 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) push(*(first_it++)); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: thin_heap() : m_p_max(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: thin_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn), m_p_max(0) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: thin_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { initialize(); m_p_max = base_type::m_p_root; for (node_pointer p_nd = base_type::m_p_root; p_nd != 0; p_nd = p_nd->m_p_next_sibling) if (Cmp_Fn::operator()(m_p_max->m_value, p_nd->m_value)) m_p_max = p_nd; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) base_type::swap(other); std::swap(m_p_max, other.m_p_max); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~thin_heap() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { std::fill(m_a_aux, m_a_aux + max_rank, static_cast<node_pointer>(0)); } c++/8/ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp 0000644 00000007432 15146341150 0016032 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/debug_fn_imps.hpp * Contains an implementation for thin_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(__file, __line); assert_node_consistent(base_type::m_p_root, true, __file, __line); assert_max(__file, __line); assert_aux_null(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_aux_null(const char* __file, int __line) const { for (size_type i = 0; i < max_rank; ++i) PB_DS_DEBUG_VERIFY(m_a_aux[i] == 0); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max(const char* __file, int __line) const { if (m_p_max == 0) { PB_DS_DEBUG_VERIFY(base_type::empty()); return; } PB_DS_DEBUG_VERIFY(!base_type::empty()); PB_DS_DEBUG_VERIFY(base_type::parent(m_p_max) == 0); PB_DS_DEBUG_VERIFY(m_p_max->m_p_prev_or_parent == 0); for (const_iterator it = base_type::begin(); it != base_type::end(); ++it) PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value)); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(node_const_pointer p_nd, bool root, const char* __file, int __line) const { base_type::assert_node_consistent(p_nd, root, __file, __line); if (p_nd == 0) return; assert_node_consistent(p_nd->m_p_next_sibling, root, __file, __line); assert_node_consistent(p_nd->m_p_l_child, false, __file, __line); if (!root) { if (p_nd->m_metadata == 0) PB_DS_DEBUG_VERIFY(p_nd->m_p_next_sibling == 0); else PB_DS_DEBUG_VERIFY(p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata + 1); } if (p_nd->m_p_l_child != 0) PB_DS_DEBUG_VERIFY(p_nd->m_p_l_child->m_metadata + 1 == base_type::degree(p_nd)); const bool unmarked_valid = (p_nd->m_p_l_child == 0 && p_nd->m_metadata == 0) || (p_nd->m_p_l_child != 0 && p_nd->m_metadata == p_nd->m_p_l_child->m_metadata + 1); const bool marked_valid = (p_nd->m_p_l_child == 0 && p_nd->m_metadata == 1) || (p_nd->m_p_l_child != 0 && p_nd->m_metadata == p_nd->m_p_l_child->m_metadata + 2); PB_DS_DEBUG_VERIFY(unmarked_valid || marked_valid); if (root) PB_DS_DEBUG_VERIFY(unmarked_valid); } #endif c++/8/ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp 0000644 00000016473 15146341150 0016255 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/insert_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = base_type::get_new_node_for_insert(r_val); p_nd->m_metadata = 0; p_nd->m_p_prev_or_parent = p_nd->m_p_l_child = 0; if (base_type::m_p_root == 0) { p_nd->m_p_next_sibling = 0; m_p_max = base_type::m_p_root = p_nd; PB_DS_ASSERT_VALID((*this)) return point_iterator(p_nd); } p_nd->m_p_next_sibling = base_type::m_p_root; base_type::m_p_root->m_p_prev_or_parent = 0; base_type::m_p_root = p_nd; update_max(p_nd); PB_DS_ASSERT_VALID((*this)) return point_iterator(p_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_root(node_pointer p_nd) { p_nd->m_metadata = p_nd->m_p_l_child == 0 ? 0 : 1 + p_nd->m_p_l_child->m_metadata; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_root_and_link(node_pointer p_nd) { make_root(p_nd); p_nd->m_p_prev_or_parent = 0; p_nd->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = 0; base_type::m_p_root = p_nd; update_max(p_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix(node_pointer p_y) { while (true) { if (p_y->m_p_prev_or_parent == 0) { fix_root(p_y); return; } else if (p_y->m_metadata == 1&& p_y->m_p_next_sibling == 0) { if (p_y->m_p_l_child != 0) { fix_sibling_rank_1_unmarked(p_y); return; } fix_sibling_rank_1_marked(p_y); p_y = p_y->m_p_prev_or_parent; } else if (p_y->m_metadata > p_y->m_p_next_sibling->m_metadata + 1) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_l_child != 0); if (p_y->m_metadata != p_y->m_p_l_child->m_metadata + 2) { fix_sibling_general_unmarked(p_y); return; } fix_sibling_general_marked(p_y); p_y = p_y->m_p_prev_or_parent; } else if ((p_y->m_p_l_child == 0&& p_y->m_metadata == 2) ||(p_y->m_p_l_child != 0&& p_y->m_metadata == p_y->m_p_l_child->m_metadata + 3)) { node_pointer p_z = p_y->m_p_prev_or_parent; fix_child(p_y); p_y = p_z; } else return; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_root(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent == 0); make_root(p_y); PB_DS_ASSERT_NODE_CONSISTENT(p_y, true) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_rank_1_unmarked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); _GLIBCXX_DEBUG_ONLY(node_pointer p_w = p_y->m_p_l_child;) _GLIBCXX_DEBUG_ASSERT(p_w != 0); _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling == 0); _GLIBCXX_DEBUG_ASSERT(p_y->m_p_next_sibling == 0); p_y->m_p_next_sibling = p_y->m_p_l_child; p_y->m_p_next_sibling->m_p_prev_or_parent = p_y; p_y->m_p_l_child = 0; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_rank_1_marked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); _GLIBCXX_DEBUG_ASSERT(p_y->m_p_l_child == 0); p_y->m_metadata = 0; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_general_unmarked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); node_pointer p_w = p_y->m_p_l_child; _GLIBCXX_DEBUG_ASSERT(p_w != 0); _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling != 0); p_y->m_p_l_child = p_w->m_p_next_sibling; p_w->m_p_next_sibling->m_p_prev_or_parent = p_y; p_w->m_p_next_sibling = p_y->m_p_next_sibling; _GLIBCXX_DEBUG_ASSERT(p_w->m_p_next_sibling != 0); p_w->m_p_next_sibling->m_p_prev_or_parent = p_w; p_y->m_p_next_sibling = p_w; p_w->m_p_prev_or_parent = p_y; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_sibling_general_marked(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); --p_y->m_metadata; PB_DS_ASSERT_NODE_CONSISTENT(p_y, false) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: fix_child(node_pointer p_y) { _GLIBCXX_DEBUG_ASSERT(p_y->m_p_prev_or_parent != 0); if (p_y->m_p_next_sibling != 0) p_y->m_p_next_sibling->m_p_prev_or_parent = p_y->m_p_prev_or_parent; if (p_y->m_p_prev_or_parent->m_p_l_child == p_y) p_y->m_p_prev_or_parent->m_p_l_child = p_y->m_p_next_sibling; else p_y->m_p_prev_or_parent->m_p_next_sibling = p_y->m_p_next_sibling; make_root_and_link(p_y); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = it.m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); const bool smaller = Cmp_Fn::operator()(r_new_val, p_nd->m_value); p_nd->m_value = r_new_val; if (smaller) { remove_node(p_nd); p_nd->m_p_l_child = 0; make_root_and_link(p_nd); PB_DS_ASSERT_VALID((*this)) return; } if (p_nd->m_p_prev_or_parent == 0) { update_max(p_nd); PB_DS_ASSERT_VALID((*this)) return; } node_pointer p_y = p_nd->m_p_prev_or_parent; _GLIBCXX_DEBUG_ASSERT(p_y != 0); if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_y; if (p_y->m_p_l_child == p_nd) p_y->m_p_l_child = p_nd->m_p_next_sibling; else p_y->m_p_next_sibling = p_nd->m_p_next_sibling; fix(p_y); make_root_and_link(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update_max(node_pointer p_nd) { if (m_p_max == 0 || Cmp_Fn::operator()(m_p_max->m_value, p_nd->m_value)) m_p_max = p_nd; } c++/8/ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp 0000644 00000003652 15146341150 0016042 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/trace_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ #ifdef PB_DS_THIN_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << std::endl; std::cerr << "m_p_max " << m_p_max << std::endl; base_type::trace(); } #endif // #ifdef PB_DS_THIN_HEAP_TRACE_ c++/8/ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp 0000644 00000003640 15146341150 0015661 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/find_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); return m_p_max->m_value; } c++/8/ext/pb_ds/detail/thin_heap_/thin_heap_.hpp 0000644 00000020324 15146341150 0015322 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/thin_heap_.hpp * Contains an implementation class for a thin heap. */ #ifndef PB_DS_THIN_HEAP_HPP #define PB_DS_THIN_HEAP_HPP #include <algorithm> #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> #define PB_DS_CLASS_C_DEC \ thin_heap<Value_Type, Cmp_Fn, _Alloc> #ifdef _GLIBCXX_DEBUG #define PB_DS_BASE_T_P \ <Value_Type, Cmp_Fn, typename _Alloc::size_type, _Alloc, true> #else #define PB_DS_BASE_T_P \ <Value_Type, Cmp_Fn, typename _Alloc::size_type, _Alloc> #endif /** * Thin heap. * * @ingroup heap-detail * * See Tarjan and Kaplan. */ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> class thin_heap : public left_child_next_sibling_heap PB_DS_BASE_T_P { private: typedef typename _Alloc::template rebind<Value_Type>::other __rebind_a; typedef left_child_next_sibling_heap PB_DS_BASE_T_P base_type; protected: typedef typename base_type::node node; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename __rebind_a::pointer pointer; typedef typename __rebind_a::const_pointer const_pointer; typedef typename __rebind_a::reference reference; typedef typename __rebind_a::const_reference const_reference; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; void pop(); void erase(point_iterator); inline void clear(); template<typename Pred> size_type erase_if(Pred); template<typename Pred> void split(Pred, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&); protected: thin_heap(); thin_heap(const Cmp_Fn&); thin_heap(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~thin_heap(); template<typename It> void copy_from_range(It, It); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_max(const char*, int) const; #endif #ifdef PB_DS_THIN_HEAP_TRACE_ void trace() const; #endif private: enum { max_rank = (sizeof(size_type) << 4) + 2 }; void initialize(); inline void update_max(node_pointer); inline void fix(node_pointer); inline void fix_root(node_pointer); inline void fix_sibling_rank_1_unmarked(node_pointer); inline void fix_sibling_rank_1_marked(node_pointer); inline void fix_sibling_general_unmarked(node_pointer); inline void fix_sibling_general_marked(node_pointer); inline void fix_child(node_pointer); inline static void make_root(node_pointer); inline void make_root_and_link(node_pointer); inline void remove_max_node(); void to_aux_except_max(); inline void add_to_aux(node_pointer); inline void make_from_aux(); inline size_type rank_bound(); inline void make_child_of(node_pointer, node_pointer); inline void remove_node(node_pointer); inline node_pointer join(node_pointer, node_pointer) const; #ifdef _GLIBCXX_DEBUG void assert_node_consistent(node_const_pointer, bool, const char*, int) const; void assert_aux_null(const char*, int) const; #endif node_pointer m_p_max; node_pointer m_a_aux[max_rank]; }; enum { num_distinct_rank_bounds = 48 }; // Taken from the SGI implementation; acknowledged in the docs. static const std::size_t g_a_rank_bounds[num_distinct_rank_bounds] = { /* Dealing cards... */ /* 0 */ 0ul, /* 1 */ 1ul, /* 2 */ 1ul, /* 3 */ 2ul, /* 4 */ 4ul, /* 5 */ 6ul, /* 6 */ 11ul, /* 7 */ 17ul, /* 8 */ 29ul, /* 9 */ 46ul, /* 10 */ 76ul, /* 11 */ 122ul, /* 12 */ 199ul, /* 13 */ 321ul, /* 14 */ 521ul, /* 15 */ 842ul, /* 16 */ 1364ul, /* 17 */ 2206ul, /* 18 */ 3571ul, /* 19 */ 5777ul, /* 20 */ 9349ul, /* 21 */ 15126ul, /* 22 */ 24476ul, /* 23 */ 39602ul, /* 24 */ 64079ul #if __SIZE_MAX__ > 0xfffful , /* 25 */ 103681ul, /* 26 */ 167761ul, /* 27 */ 271442ul, /* 28 */ 439204ul, /* 29 */ 710646ul #if __SIZE_MAX__ > 0xffffful , /* 30 */ 1149851ul, /* 31 */ 1860497ul, /* 32 */ 3010349ul, /* 33 */ 4870846ul, /* 34 */ 7881196ul, /* 35 */ 12752042ul #if __SIZE_MAX__ > 0xfffffful , /* 36 */ 20633239ul, /* 37 */ 33385282ul, /* 38 */ 54018521ul, /* 39 */ 87403803ul, /* 40 */ 141422324ul, /* 41 */ 228826127ul, /* 42 */ 370248451ul, /* 43 */ 599074578ul, /* 44 */ 969323029ul, /* 45 */ 1568397607ul, /* 46 */ 2537720636ul, /* 47 */ 4106118243ul #endif #endif #endif /* Pot's good, let's play */ }; #define PB_DS_ASSERT_NODE_CONSISTENT(_Node, _Bool) \ _GLIBCXX_DEBUG_ONLY(assert_node_consistent(_Node, _Bool, \ __FILE__, __LINE__);) #define PB_DS_ASSERT_AUX_NULL(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_aux_null(__FILE__, __LINE__);) #include <ext/pb_ds/detail/thin_heap_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/thin_heap_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/thin_heap_/trace_fn_imps.hpp> #include <ext/pb_ds/detail/thin_heap_/find_fn_imps.hpp> #include <ext/pb_ds/detail/thin_heap_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/thin_heap_/split_join_fn_imps.hpp> #undef PB_DS_ASSERT_AUX_NULL #undef PB_DS_ASSERT_NODE_CONSISTENT #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_BASE_T_P } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/thin_heap_/erase_fn_imps.hpp 0000644 00000013647 15146341150 0016050 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file thin_heap_/erase_fn_imps.hpp * Contains an implementation for thin_heap_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); node_pointer p_nd = m_p_max; remove_max_node(); base_type::actual_erase_node(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: remove_max_node() { to_aux_except_max(); make_from_aux(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: to_aux_except_max() { node_pointer p_add = base_type::m_p_root; while (p_add != m_p_max) { node_pointer p_next_add = p_add->m_p_next_sibling; add_to_aux(p_add); p_add = p_next_add; } p_add = m_p_max->m_p_l_child; while (p_add != 0) { node_pointer p_next_add = p_add->m_p_next_sibling; p_add->m_metadata = p_add->m_p_l_child == 0 ? 0 : p_add->m_p_l_child->m_metadata + 1; add_to_aux(p_add); p_add = p_next_add; } p_add = m_p_max->m_p_next_sibling; while (p_add != 0) { node_pointer p_next_add = p_add->m_p_next_sibling; add_to_aux(p_add); p_add = p_next_add; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: add_to_aux(node_pointer p_nd) { size_type r = p_nd->m_metadata; while (m_a_aux[r] != 0) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); if (Cmp_Fn::operator()(m_a_aux[r]->m_value, p_nd->m_value)) make_child_of(m_a_aux[r], p_nd); else { make_child_of(p_nd, m_a_aux[r]); p_nd = m_a_aux[r]; } m_a_aux[r] = 0; ++r; } _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < rank_bound()); m_a_aux[r] = p_nd; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_child_of(node_pointer p_nd, node_pointer p_new_parent) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_new_parent->m_metadata); _GLIBCXX_DEBUG_ASSERT(m_a_aux[p_nd->m_metadata] == p_nd || m_a_aux[p_nd->m_metadata] == p_new_parent); ++p_new_parent->m_metadata; base_type::make_child_of(p_nd, p_new_parent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_from_aux() { base_type::m_p_root = m_p_max = 0; const size_type rnk_bnd = rank_bound(); size_type i = 0; while (i < rnk_bnd) { if (m_a_aux[i] != 0) { make_root_and_link(m_a_aux[i]); m_a_aux[i] = 0; } ++i; } PB_DS_ASSERT_AUX_NULL((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: remove_node(node_pointer p_nd) { node_pointer p_parent = p_nd; while (base_type::parent(p_parent) != 0) p_parent = base_type::parent(p_parent); base_type::bubble_to_top(p_nd); m_p_max = p_nd; node_pointer p_fix = base_type::m_p_root; while (p_fix != 0&& p_fix->m_p_next_sibling != p_parent) p_fix = p_fix->m_p_next_sibling; if (p_fix != 0) p_fix->m_p_next_sibling = p_nd; remove_max_node(); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: clear() { base_type::clear(); m_p_max = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); node_pointer p_nd = it.m_p_nd; remove_node(p_nd); base_type::actual_erase_node(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template<typename Pred> typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) if (base_type::empty()) { PB_DS_ASSERT_VALID((*this)) return 0; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); size_type ersd = 0; while (p_out != 0) { ++ersd; node_pointer p_next = p_out->m_p_next_sibling; base_type::actual_erase_node(p_out); p_out = p_next; } node_pointer p_cur = base_type::m_p_root; m_p_max = base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; make_root_and_link(p_cur); p_cur = p_next; } PB_DS_ASSERT_VALID((*this)) return ersd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: rank_bound() { using namespace std; const size_t* const p_upper = std::upper_bound(g_a_rank_bounds, g_a_rank_bounds + num_distinct_rank_bounds, base_type::m_size); if (p_upper == g_a_rank_bounds + num_distinct_rank_bounds) return max_rank; return (p_upper - g_a_rank_bounds); } c++/8/ext/pb_ds/detail/unordered_iterator/point_iterator.hpp 0000644 00000006766 15146341150 0020106 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file point_iterator.hpp * Contains an iterator class returned by the tables' find and insert * methods. */ /// Find type iterator. class point_iterator_ { public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; /// Default constructor. inline point_iterator_() : m_p_value(0) { } /// Copy constructor. inline point_iterator_(const point_iterator_& other) : m_p_value(other.m_p_value) { } /// Access. pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return (m_p_value); } /// Access. reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return (*m_p_value); } /// Compares content to a different iterator object. bool operator==(const point_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content to a different iterator object. bool operator==(const point_const_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content to a different iterator object. bool operator!=(const point_iterator_& other) const { return m_p_value != other.m_p_value; } /// Compares content (negatively) to a different iterator object. bool operator!=(const point_const_iterator_& other) const { return m_p_value != other.m_p_value; } inline point_iterator_(pointer p_value) : m_p_value(p_value) { } protected: friend class point_const_iterator_; friend class PB_DS_CLASS_C_DEC; protected: pointer m_p_value; }; c++/8/ext/pb_ds/detail/unordered_iterator/iterator.hpp 0000644 00000007325 15146341150 0016665 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file iterator.hpp * Contains an iterator_ class used for ranging over the elements of the * table. */ /// Range-type iterator. class iterator_ : public const_iterator_ { public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; /// Default constructor. inline iterator_() : const_iterator_(0, PB_DS_GEN_POS(), 0) { } /// Conversion to a point-type iterator. inline operator point_iterator_() { return point_iterator_(const_cast<pointer>(const_iterator_::m_p_value)); } /// Conversion to a point-type iterator. inline operator const point_iterator_() const { return point_iterator_(const_cast<pointer>(const_iterator_::m_p_value)); } /// Access. pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_value != 0); return (const_cast<pointer>(base_type::m_p_value)); } /// Access. reference operator*() const { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_value != 0); return (const_cast<reference>(*base_type::m_p_value)); } /// Increments. iterator_& operator++() { base_type::m_p_tbl->inc_it_state(base_type::m_p_value, base_type::m_pos); return *this; } /// Increments. iterator_ operator++(int) { iterator_ ret =* this; base_type::m_p_tbl->inc_it_state(base_type::m_p_value, base_type::m_pos); return ret; } protected: typedef const_iterator_ base_type; /** * Constructor used by the table to initiate the generalized * pointer and position (e.g., this is called from within a find() * of a table. * */ inline iterator_(pointer p_value, PB_DS_GEN_POS pos, PB_DS_CLASS_C_DEC* p_tbl) : const_iterator_(p_value, pos, p_tbl) { } friend class PB_DS_CLASS_C_DEC; }; c++/8/ext/pb_ds/detail/unordered_iterator/point_const_iterator.hpp 0000644 00000007336 15146341150 0021306 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file unordered_iterator/point_const_iterator.hpp * Contains an iterator class returned by the tables' const find and insert * methods. */ class point_iterator_; /// Const point-type iterator. class point_const_iterator_ { public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; inline point_const_iterator_(const_pointer p_value) : m_p_value(p_value) { } /// Default constructor. inline point_const_iterator_() : m_p_value(0) { } /// Copy constructor. inline point_const_iterator_(const point_const_iterator_& other) : m_p_value(other.m_p_value) { } /// Copy constructor. inline point_const_iterator_(const point_iterator_& other) : m_p_value(other.m_p_value) { } /// Access. const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return m_p_value; } /// Access. const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_value != 0); return *m_p_value; } /// Compares content to a different iterator object. bool operator==(const point_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content to a different iterator object. bool operator==(const point_const_iterator_& other) const { return m_p_value == other.m_p_value; } /// Compares content (negatively) to a different iterator object. bool operator!=(const point_iterator_& other) const { return m_p_value != other.m_p_value; } /// Compares content (negatively) to a different iterator object. bool operator!=(const point_const_iterator_& other) const { return m_p_value != other.m_p_value; } protected: const_pointer m_p_value; friend class point_iterator_; friend class PB_DS_CLASS_C_DEC; }; c++/8/ext/pb_ds/detail/unordered_iterator/const_iterator.hpp 0000644 00000006421 15146341150 0020067 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file unordered_iterator/const_iterator.hpp * Contains an iterator class used for const ranging over the elements of the * table. */ /// Const range-type iterator. class const_iterator_ : public point_const_iterator_ { public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef value_type_ value_type; /// Iterator's pointer type. typedef pointer_ pointer; /// Iterator's const pointer type. typedef const_pointer_ const_pointer; /// Iterator's reference type. typedef reference_ reference; /// Iterator's const reference type. typedef const_reference_ const_reference; /// Default constructor. const_iterator_() : m_p_tbl(0) { } /// Increments. const_iterator_& operator++() { m_p_tbl->inc_it_state(base_type::m_p_value, m_pos); return *this; } /// Increments. const_iterator_ operator++(int) { const_iterator_ ret =* this; m_p_tbl->inc_it_state(base_type::m_p_value, m_pos); return ret; } protected: typedef point_const_iterator_ base_type; /** * Constructor used by the table to initiate the generalized * pointer and position (e.g., this is called from within a find() * of a table. * */ const_iterator_(const_pointer_ p_value, PB_DS_GEN_POS pos, const PB_DS_CLASS_C_DEC* p_tbl) : point_const_iterator_(p_value), m_p_tbl(p_tbl), m_pos(pos) { } /** * Pointer to the table object which created the iterator (used for * incrementing its position. * */ const PB_DS_CLASS_C_DEC* m_p_tbl; PB_DS_GEN_POS m_pos; friend class PB_DS_CLASS_C_DEC; }; c++/8/ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp 0000644 00000004562 15146341150 0020433 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/split_join_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC template<typename Pred> void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) make_binomial_heap(); other.make_binomial_heap(); base_type::split(pred, other); base_type::find_max(); other.find_max(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) make_binomial_heap(); other.make_binomial_heap(); base_type::join(other); base_type::find_max(); other.find_max(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } c++/8/ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp 0000644 00000004643 15146341150 0023307 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: rc_binomial_heap() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: rc_binomial_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: rc_binomial_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { make_binomial_heap(); base_type::find_max(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~rc_binomial_heap() { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) base_type::swap(other); m_rc.swap(other.m_rc); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } c++/8/ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp 0000644 00000006722 15146341150 0017347 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/debug_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(false, __file, __line); if (!base_type::empty()) { PB_DS_DEBUG_VERIFY(base_type::m_p_max != 0); base_type::assert_max(__file, __line); } m_rc.assert_valid(__file, __line); if (m_rc.empty()) { base_type::assert_valid(true, __file, __line); PB_DS_DEBUG_VERIFY(next_2_pointer(base_type::m_p_root) == 0); return; } node_const_pointer p_nd = next_2_pointer(base_type::m_p_root); typename rc_t::const_iterator it = m_rc.end(); --it; while (p_nd != 0) { PB_DS_DEBUG_VERIFY(*it == p_nd); node_const_pointer p_next = p_nd->m_p_next_sibling; PB_DS_DEBUG_VERIFY(p_next != 0); PB_DS_DEBUG_VERIFY(p_nd->m_metadata == p_next->m_metadata); PB_DS_DEBUG_VERIFY(p_next->m_p_next_sibling == 0 || p_next->m_metadata < p_next->m_p_next_sibling->m_metadata); --it; p_nd = next_2_pointer(next_after_0_pointer(p_nd)); } PB_DS_DEBUG_VERIFY(it + 1 == m_rc.begin()); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: next_2_pointer(node_const_pointer p_nd) { if (p_nd == 0) return 0; node_pointer p_next = p_nd->m_p_next_sibling; if (p_next == 0) return 0; if (p_nd->m_metadata == p_next->m_metadata) return p_nd; return next_2_pointer(p_next); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_const_pointer PB_DS_CLASS_C_DEC:: next_after_0_pointer(node_const_pointer p_nd) { if (p_nd == 0) return 0; node_pointer p_next = p_nd->m_p_next_sibling; if (p_next == 0) return 0; if (p_nd->m_metadata < p_next->m_metadata) return p_next; return next_after_0_pointer(p_next); } #endif c++/8/ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp 0000644 00000010215 15146341150 0017555 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/insert_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) make_0_exposed(); PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = base_type::get_new_node_for_insert(r_val); p_nd->m_p_l_child = p_nd->m_p_prev_or_parent = 0; p_nd->m_metadata = 0; if (base_type::m_p_max == 0 || Cmp_Fn::operator()(base_type::m_p_max->m_value, r_val)) base_type::m_p_max = p_nd; p_nd->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = p_nd; base_type::m_p_root = p_nd; if (p_nd->m_p_next_sibling != 0&& p_nd->m_p_next_sibling->m_metadata == 0) m_rc.push(p_nd); PB_DS_ASSERT_VALID((*this)) return point_iterator(p_nd); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) make_binomial_heap(); base_type::modify(it, r_new_val); base_type::find_max(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: link_with_next_sibling(node_pointer p_nd) { node_pointer p_next = p_nd->m_p_next_sibling; _GLIBCXX_DEBUG_ASSERT(p_next != 0); _GLIBCXX_DEBUG_ASSERT(p_next->m_p_prev_or_parent == p_nd); if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; if (p_next->m_p_prev_or_parent == 0) base_type::m_p_root = p_next; else p_next->m_p_prev_or_parent->m_p_next_sibling = p_next; if (base_type::m_p_max == p_nd) base_type::m_p_max = p_next; base_type::make_child_of(p_nd, p_next); ++p_next->m_metadata; return p_next; } p_nd->m_p_next_sibling = p_next->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; if (base_type::m_p_max == p_next) base_type::m_p_max = p_nd; base_type::make_child_of(p_next, p_nd); ++p_nd->m_metadata; return p_nd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: make_0_exposed() { if (m_rc.empty()) return; node_pointer p_nd = m_rc.top(); m_rc.pop(); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_next_sibling != 0); _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata); node_pointer p_res = link_with_next_sibling(p_nd); if (p_res->m_p_next_sibling != 0&& p_res->m_metadata == p_res->m_p_next_sibling->m_metadata) m_rc.push(p_res); } c++/8/ext/pb_ds/detail/rc_binomial_heap_/rc.hpp 0000644 00000014171 15146341150 0015147 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/rc.hpp * Contains a redundant (binary counter). */ #ifndef PB_DS_RC_HPP #define PB_DS_RC_HPP namespace __gnu_pbds { namespace detail { /// Redundant binary counter. template<typename _Node, typename _Alloc> class rc { private: typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef _Node node; typedef typename _Alloc::template rebind<node> __rebind_n; typedef typename __rebind_n::other::pointer node_pointer; typedef typename _Alloc::template rebind<node_pointer> __rebind_np; typedef typename __rebind_np::other::pointer entry_pointer; typedef typename __rebind_np::other::const_pointer entry_const_pointer; enum { max_entries = sizeof(size_type) << 3 }; public: typedef node_pointer entry; typedef entry_const_pointer const_iterator; rc(); rc(const rc&); inline void swap(rc&); inline void push(entry); inline node_pointer top() const; inline void pop(); inline bool empty() const; inline size_type size() const; void clear(); const const_iterator begin() const; const const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ void trace() const; #endif private: node_pointer m_a_entries[max_entries]; size_type m_over_top; }; template<typename _Node, typename _Alloc> rc<_Node, _Alloc>:: rc() : m_over_top(0) { PB_DS_ASSERT_VALID((*this)) } template<typename _Node, typename _Alloc> rc<_Node, _Alloc>:: rc(const rc<_Node, _Alloc>& other) : m_over_top(0) { PB_DS_ASSERT_VALID((*this)) } template<typename _Node, typename _Alloc> inline void rc<_Node, _Alloc>:: swap(rc<_Node, _Alloc>& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) const size_type over_top = std::max(m_over_top, other.m_over_top); for (size_type i = 0; i < over_top; ++i) std::swap(m_a_entries[i], other.m_a_entries[i]); std::swap(m_over_top, other.m_over_top); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } template<typename _Node, typename _Alloc> inline void rc<_Node, _Alloc>:: push(entry p_nd) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(m_over_top < max_entries); m_a_entries[m_over_top++] = p_nd; PB_DS_ASSERT_VALID((*this)) } template<typename _Node, typename _Alloc> inline void rc<_Node, _Alloc>:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); --m_over_top; PB_DS_ASSERT_VALID((*this)) } template<typename _Node, typename _Alloc> inline typename rc<_Node, _Alloc>::node_pointer rc<_Node, _Alloc>:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); return *(m_a_entries + m_over_top - 1); } template<typename _Node, typename _Alloc> inline bool rc<_Node, _Alloc>:: empty() const { PB_DS_ASSERT_VALID((*this)) return m_over_top == 0; } template<typename _Node, typename _Alloc> inline typename rc<_Node, _Alloc>::size_type rc<_Node, _Alloc>:: size() const { return m_over_top; } template<typename _Node, typename _Alloc> void rc<_Node, _Alloc>:: clear() { PB_DS_ASSERT_VALID((*this)) m_over_top = 0; PB_DS_ASSERT_VALID((*this)) } template<typename _Node, typename _Alloc> const typename rc<_Node, _Alloc>::const_iterator rc<_Node, _Alloc>:: begin() const { return& m_a_entries[0]; } template<typename _Node, typename _Alloc> const typename rc<_Node, _Alloc>::const_iterator rc<_Node, _Alloc>:: end() const { return& m_a_entries[m_over_top]; } #ifdef _GLIBCXX_DEBUG template<typename _Node, typename _Alloc> void rc<_Node, _Alloc>:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_over_top < max_entries); } #endif #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ template<typename _Node, typename _Alloc> void rc<_Node, _Alloc>:: trace() const { std::cout << "rc" << std::endl; for (size_type i = 0; i < m_over_top; ++i) std::cerr << m_a_entries[i] << std::endl; std::cout << std::endl; } #endif } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp 0000644 00000003560 15146341150 0017354 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/trace_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { base_type::trace(); m_rc.trace(); } #endif // #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ c++/8/ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp 0000644 00000005511 15146341150 0017353 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/erase_fn_imps.hpp * Contains an implementation for rc_binomial_heap_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: pop() { make_binomial_heap(); _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); base_type::pop(); base_type::find_max(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { base_type::clear(); m_rc.clear(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: make_binomial_heap() { node_pointer p_nd = base_type::m_p_root; while (p_nd != 0) { node_pointer p_next = p_nd->m_p_next_sibling; if (p_next == 0) p_nd = p_next; else if (p_nd->m_metadata == p_next->m_metadata) p_nd = link_with_next_sibling(p_nd); else if (p_nd->m_metadata < p_next->m_metadata) p_nd = p_next; #ifdef _GLIBCXX_DEBUG else _GLIBCXX_DEBUG_ASSERT(0); #endif } m_rc.clear(); } PB_DS_CLASS_T_DEC template<typename Pred> typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { make_binomial_heap(); const size_type ersd = base_type::erase_if(pred); base_type::find_max(); PB_DS_ASSERT_VALID((*this)) return ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { make_binomial_heap(); base_type::erase(it); base_type::find_max(); } c++/8/ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp 0000644 00000012267 15146341150 0020161 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rc_binomial_heap_/rc_binomial_heap_.hpp * Contains an implementation for redundant-counter binomial heap. */ #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp> #include <ext/pb_ds/detail/rc_binomial_heap_/rc.hpp> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> #define PB_DS_CLASS_C_DEC \ rc_binomial_heap<Value_Type, Cmp_Fn, _Alloc> #define PB_DS_RC_C_DEC \ rc<typename binomial_heap_base<Value_Type, Cmp_Fn, _Alloc>::node, _Alloc> /** * Redundant-counter binomial heap. * * @ingroup heap-detail */ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> class rc_binomial_heap : public binomial_heap_base<Value_Type, Cmp_Fn, _Alloc> { private: typedef binomial_heap_base<Value_Type, Cmp_Fn, _Alloc> base_type; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; typedef PB_DS_RC_C_DEC rc_t; public: typedef Value_Type value_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::cmp_fn cmp_fn; typedef typename base_type::allocator_type allocator_type; rc_binomial_heap(); rc_binomial_heap(const Cmp_Fn&); rc_binomial_heap(const PB_DS_CLASS_C_DEC&); ~rc_binomial_heap(); void swap(PB_DS_CLASS_C_DEC&); inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline void pop(); void erase(point_iterator); inline void clear(); template<typename Pred> size_type erase_if(Pred); template<typename Pred> void split(Pred, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_RC_BINOMIAL_HEAP_TRACE_ void trace() const; #endif private: inline node_pointer link_with_next_sibling(node_pointer); void make_0_exposed(); void make_binomial_heap(); #ifdef _GLIBCXX_DEBUG static node_const_pointer next_2_pointer(node_const_pointer); static node_const_pointer next_after_0_pointer(node_const_pointer); #endif rc_t m_rc; }; #include <ext/pb_ds/detail/rc_binomial_heap_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/rc_binomial_heap_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/rc_binomial_heap_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/rc_binomial_heap_/trace_fn_imps.hpp> #include <ext/pb_ds/detail/rc_binomial_heap_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/rc_binomial_heap_/split_join_fn_imps.hpp> #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_RC_C_DEC } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp 0000644 00000007276 15146341150 0017465 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/split_join_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (m_size == 0) { other.clear(); return; } if (Cmp_Fn::operator()(r_key, PB_DS_V2F(*begin()))) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(*(end() - 1)))) { return; } if (m_size == 1) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } iterator it = upper_bound(r_key); PB_DS_CLASS_C_DEC new_other(other, other); new_other.copy_from_ordered_range(it, end()); PB_DS_CLASS_C_DEC new_this(*this, *this); new_this.copy_from_ordered_range(begin(), it); // No exceptions from this point. other.update(other.node_begin(), (node_update*)(&other)); update(node_begin(), (node_update*)this); other.value_swap(new_other); value_swap(new_this); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (other.m_size == 0) return; if (m_size == 0) { value_swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } const bool greater = Cmp_Fn::operator()(PB_DS_V2F(*(end() - 1)), PB_DS_V2F(*other.begin())); const bool lesser = Cmp_Fn::operator()(PB_DS_V2F(*(other.end() - 1)), PB_DS_V2F(*begin())); if (!greater && !lesser) __throw_join_error(); PB_DS_CLASS_C_DEC new_this(*this, *this); if (greater) new_this.copy_from_ordered_range(begin(), end(), other.begin(), other.end()); else new_this.copy_from_ordered_range(other.begin(), other.end(), begin(), end()); // No exceptions from this point. value_swap(new_this); other.clear(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } c++/8/ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp 0000644 00000015325 15146341150 0022333 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/constructors_destructor_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::value_allocator PB_DS_CLASS_C_DEC::s_value_alloc; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::metadata_allocator PB_DS_CLASS_C_DEC::s_metadata_alloc; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME() : m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME(const Cmp_Fn& r_cmp_fn) : cmp_fn(r_cmp_fn), m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_nodeu) : cmp_fn(r_cmp_fn), node_update(r_nodeu), m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_OV_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : #ifdef PB_DS_TREE_TRACE trace_base(other), #endif cmp_fn(other), node_update(other), m_a_values(0), m_a_metadata(0), m_end_it(0), m_size(0) { copy_from_ordered_range(other.begin(), other.end()); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template<typename It> inline void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { #ifdef PB_DS_DATA_TRUE_INDICATOR typedef std::map<key_type, mapped_type, Cmp_Fn, typename _Alloc::template rebind<value_type>::other> map_type; #else typedef std::set<key_type, Cmp_Fn, typename _Alloc::template rebind<Key>::other> map_type; #endif map_type m(first_it, last_it); copy_from_ordered_range(m.begin(), m.end()); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_ordered_range(It first_it, It last_it) { const size_type len = std::distance(first_it, last_it); if (len == 0) return; value_vector a_values = s_value_alloc.allocate(len); iterator target_it = a_values; It source_it = first_it; It source_end_it = last_it; cond_dtor<size_type> cd(a_values, target_it, len); while (source_it != source_end_it) { void* __v = const_cast<void*>(static_cast<const void*>(target_it)); new (__v) value_type(*source_it++); ++target_it; } reallocate_metadata((node_update*)this, len); cd.set_no_action(); m_a_values = a_values; m_size = len; m_end_it = m_a_values + m_size; update(PB_DS_node_begin_imp(), (node_update*)this); #ifdef _GLIBCXX_DEBUG for (const_iterator dbg_it = m_a_values; dbg_it != m_end_it; ++dbg_it) debug_base::insert_new(PB_DS_V2F(*dbg_it)); #endif } PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_ordered_range(It first_it, It last_it, It other_first_it, It other_last_it) { clear(); const size_type len = std::distance(first_it, last_it) + std::distance(other_first_it, other_last_it); value_vector a_values = s_value_alloc.allocate(len); iterator target_it = a_values; It source_it = first_it; It source_end_it = last_it; cond_dtor<size_type> cd(a_values, target_it, len); while (source_it != source_end_it) { new (const_cast<void* >(static_cast<const void* >(target_it))) value_type(*source_it++); ++target_it; } source_it = other_first_it; source_end_it = other_last_it; while (source_it != source_end_it) { new (const_cast<void* >(static_cast<const void* >(target_it))) value_type(*source_it++); ++target_it; } reallocate_metadata((node_update* )this, len); cd.set_no_action(); m_a_values = a_values; m_size = len; m_end_it = m_a_values + m_size; update(PB_DS_node_begin_imp(), (node_update* )this); #ifdef _GLIBCXX_DEBUG for (const_iterator dbg_it = m_a_values; dbg_it != m_end_it; ++dbg_it) debug_base::insert_new(PB_DS_V2F(*dbg_it)); #endif } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) value_swap(other); std::swap(static_cast<cmp_fn&>(*this), static_cast<cmp_fn&>(other)); std::swap(static_cast<traits_base&>(*this), static_cast<traits_base&>(other)); PB_DS_ASSERT_VALID(other) PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ONLY(debug_base::swap(other);) std::swap(m_a_values, other.m_a_values); std::swap(m_a_metadata, other.m_a_metadata); std::swap(m_size, other.m_size); std::swap(m_end_it, other.m_end_it); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_OV_TREE_NAME() { PB_DS_ASSERT_VALID((*this)) cond_dtor<size_type> cd(m_a_values, m_end_it, m_size); reallocate_metadata((node_update*)this, 0); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: update(node_iterator, null_node_update_pointer) { } PB_DS_CLASS_T_DEC template<typename Node_Update> void PB_DS_CLASS_C_DEC:: update(node_iterator nd_it, Node_Update* p_update) { node_const_iterator end_it = PB_DS_node_end_imp(); if (nd_it != end_it) { update(nd_it.get_l_child(), p_update); update(nd_it.get_r_child(), p_update); node_update::operator()(nd_it, end_it); } } c++/8/ext/pb_ds/detail/ov_tree_map_/traits.hpp 0000644 00000010722 15146341150 0015074 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/traits.hpp * Contains an implementation class for ov_tree_. */ #ifndef PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP #include <ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp> namespace __gnu_pbds { namespace detail { /// Tree traits. /// @ingroup traits template<typename Key, typename Mapped, class Cmp_Fn, template<typename Node_CItr, class Node_Itr, class Cmp_Fn_, typename _Alloc_> class Node_Update, typename _Alloc> struct tree_traits< Key, Mapped, Cmp_Fn, Node_Update, ov_tree_tag, _Alloc> { private: typedef typename types_traits< Key, Mapped, _Alloc, false>::value_type value_type; public: typedef typename tree_node_metadata_dispatch< Key, Mapped, Cmp_Fn, Node_Update, _Alloc>::type metadata_type; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef ov_tree_node_const_it_< value_type, metadata_type, _Alloc> node_const_iterator; typedef ov_tree_node_it_< value_type, metadata_type, _Alloc> node_iterator; typedef Node_Update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc> node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; /// Specialization. /// @ingroup traits template<typename Key, class Cmp_Fn, template<typename Node_CItr, class Node_Itr, class Cmp_Fn_, typename _Alloc_> class Node_Update, typename _Alloc> struct tree_traits< Key, null_type, Cmp_Fn, Node_Update, ov_tree_tag, _Alloc> { private: typedef typename types_traits< Key, null_type, _Alloc, false>::value_type value_type; public: typedef typename tree_node_metadata_dispatch< Key, null_type, Cmp_Fn, Node_Update, _Alloc>::type metadata_type; /// This is an iterator to an iterator: it iterates over nodes, /// and de-referencing it returns one of the tree's iterators. typedef ov_tree_node_const_it_< value_type, metadata_type, _Alloc> node_const_iterator; typedef node_const_iterator node_iterator; typedef Node_Update< node_const_iterator, node_const_iterator, Cmp_Fn, _Alloc> node_update; typedef __gnu_pbds::null_node_update< node_const_iterator, node_iterator, Cmp_Fn, _Alloc>* null_node_update_pointer; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_OV_TREE_NODE_AND_IT_TRAITS_HPP c++/8/ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp 0000644 00000004044 15146341150 0016234 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/info_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { PB_DS_ASSERT_VALID((*this)) return m_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_value_alloc.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return size() == 0; } c++/8/ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp 0000644 00000006441 15146341150 0017320 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/iterators_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_begin() const { return PB_DS_node_begin_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: node_end() const { return PB_DS_node_end_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_begin() { return PB_DS_node_begin_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: node_end() { return PB_DS_node_end_imp(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_begin_imp() const { return node_const_iterator(const_cast<pointer>(mid_pointer(begin(), end())), const_cast<pointer>(begin()), const_cast<pointer>(end()),(m_a_metadata == 0)? 0 : mid_pointer(m_a_metadata, m_a_metadata + m_size)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_const_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_end_imp() const { return node_const_iterator(end(), end(), end(), (m_a_metadata == 0) ? 0 : m_a_metadata + m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_begin_imp() { return node_iterator(mid_pointer(begin(), end()), begin(), end(), (m_a_metadata == 0) ? 0 : mid_pointer(m_a_metadata, m_a_metadata + m_size)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: PB_DS_node_end_imp() { return node_iterator(end(), end(), end(),(m_a_metadata == 0) ? 0 : m_a_metadata + m_size); } c++/8/ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp 0000644 00000005402 15146341150 0016366 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/debug_fn_imps.hpp * Contains an implementation class for ov_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { if (m_a_values == 0 || m_end_it == 0 || m_size == 0) PB_DS_DEBUG_VERIFY(m_a_values == 0 && m_end_it == 0 && m_size == 0); assert_iterators(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { debug_base::check_size(m_size, __file, __line); size_type iterated_num = 0; const_iterator prev_it = end(); PB_DS_DEBUG_VERIFY(m_end_it == m_a_values + m_size); for (const_iterator it = begin(); it != end(); ++it) { ++iterated_num; debug_base::check_key_exists(PB_DS_V2F(*it), __file, __line); PB_DS_DEBUG_VERIFY(lower_bound(PB_DS_V2F(*it)) == it); const_iterator upper_bound_it = upper_bound(PB_DS_V2F(*it)); --upper_bound_it; PB_DS_DEBUG_VERIFY(upper_bound_it == it); if (prev_it != end()) PB_DS_DEBUG_VERIFY(Cmp_Fn::operator()(PB_DS_V2F(*prev_it), PB_DS_V2F(*it))); prev_it = it; } PB_DS_DEBUG_VERIFY(iterated_num == m_size); } #endif c++/8/ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp 0000644 00000004341 15146341150 0016605 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/insert_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: reallocate_metadata(null_node_update_pointer, size_type) { } PB_DS_CLASS_T_DEC template<typename Node_Update_> void PB_DS_CLASS_C_DEC:: reallocate_metadata(Node_Update_* , size_type new_size) { metadata_pointer a_new_metadata_vec =(new_size == 0) ? 0 : s_metadata_alloc.allocate(new_size); if (m_a_metadata != 0) { for (size_type i = 0; i < m_size; ++i) m_a_metadata[i].~metadata_type(); s_metadata_alloc.deallocate(m_a_metadata, m_size); } std::swap(m_a_metadata, a_new_metadata_vec); } c++/8/ext/pb_ds/detail/ov_tree_map_/node_iterators.hpp 0000644 00000021153 15146341150 0016607 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/node_iterators.hpp * Contains an implementation class for ov_tree_. */ #ifndef PB_DS_OV_TREE_NODE_ITERATORS_HPP #define PB_DS_OV_TREE_NODE_ITERATORS_HPP #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #define PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC \ ov_tree_node_const_it_<Value_Type, Metadata_Type, _Alloc> /// Const node reference. template<typename Value_Type, typename Metadata_Type, typename _Alloc> class ov_tree_node_const_it_ { protected: typedef typename _Alloc::template rebind< Value_Type>::other::pointer pointer; typedef typename _Alloc::template rebind< Value_Type>::other::const_pointer const_pointer; typedef typename _Alloc::template rebind< Metadata_Type>::other::const_pointer const_metadata_pointer; typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC this_type; protected: template<typename Ptr> inline static Ptr mid_pointer(Ptr p_begin, Ptr p_end) { _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); return (p_begin + (p_end - p_begin) / 2); } public: typedef trivial_iterator_tag iterator_category; typedef trivial_iterator_difference_type difference_type; typedef typename _Alloc::template rebind< Value_Type>::other::const_pointer value_type; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::const_pointer reference; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::const_pointer const_reference; typedef Metadata_Type metadata_type; typedef typename _Alloc::template rebind< metadata_type>::other::const_reference metadata_const_reference; public: inline ov_tree_node_const_it_(const_pointer p_nd = 0, const_pointer p_begin_nd = 0, const_pointer p_end_nd = 0, const_metadata_pointer p_metadata = 0) : m_p_value(const_cast<pointer>(p_nd)), m_p_begin_value(const_cast<pointer>(p_begin_nd)), m_p_end_value(const_cast<pointer>(p_end_nd)), m_p_metadata(p_metadata) { } inline const_reference operator*() const { return m_p_value; } inline metadata_const_reference get_metadata() const { enum { has_metadata = !is_same<Metadata_Type, null_type>::value }; PB_DS_STATIC_ASSERT(should_have_metadata, has_metadata); _GLIBCXX_DEBUG_ASSERT(m_p_metadata != 0); return *m_p_metadata; } /// Returns the node iterator associated with the left node. inline this_type get_l_child() const { if (m_p_begin_value == m_p_value) return (this_type(m_p_begin_value, m_p_begin_value, m_p_begin_value)); const_metadata_pointer p_begin_metadata = m_p_metadata - (m_p_value - m_p_begin_value); return (this_type(mid_pointer(m_p_begin_value, m_p_value), m_p_begin_value, m_p_value, mid_pointer(p_begin_metadata, m_p_metadata))); } /// Returns the node iterator associated with the right node. inline this_type get_r_child() const { if (m_p_value == m_p_end_value) return (this_type(m_p_end_value, m_p_end_value, m_p_end_value)); const_metadata_pointer p_end_metadata = m_p_metadata + (m_p_end_value - m_p_value); return (this_type(mid_pointer(m_p_value + 1, m_p_end_value), m_p_value + 1, m_p_end_value,(m_p_metadata == 0) ? 0 : mid_pointer(m_p_metadata + 1, p_end_metadata))); } inline bool operator==(const this_type& other) const { const bool is_end = m_p_begin_value == m_p_end_value; const bool is_other_end = other.m_p_begin_value == other.m_p_end_value; if (is_end) return (is_other_end); if (is_other_end) return (is_end); return m_p_value == other.m_p_value; } inline bool operator!=(const this_type& other) const { return !operator==(other); } public: pointer m_p_value; pointer m_p_begin_value; pointer m_p_end_value; const_metadata_pointer m_p_metadata; }; #define PB_DS_OV_TREE_NODE_ITERATOR_C_DEC \ ov_tree_node_it_<Value_Type, Metadata_Type, _Alloc> /// Node reference. template<typename Value_Type, typename Metadata_Type, typename _Alloc> class ov_tree_node_it_ : public PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC { private: typedef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC this_type; typedef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC base_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::const_metadata_pointer const_metadata_pointer; public: typedef trivial_iterator_tag iterator_category; typedef trivial_iterator_difference_type difference_type; typedef typename _Alloc::template rebind< Value_Type>::other::pointer value_type; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::pointer reference; typedef typename _Alloc::template rebind< typename remove_const< Value_Type>::type>::other::pointer const_reference; inline ov_tree_node_it_(const_pointer p_nd = 0, const_pointer p_begin_nd = 0, const_pointer p_end_nd = 0, const_metadata_pointer p_metadata = 0) : base_type(p_nd, p_begin_nd, p_end_nd, p_metadata) { } /// Access. inline reference operator*() const { return reference(base_type::m_p_value); } /// Returns the node reference associated with the left node. inline ov_tree_node_it_ get_l_child() const { if (base_type::m_p_begin_value == base_type::m_p_value) return (this_type(base_type::m_p_begin_value, base_type::m_p_begin_value, base_type::m_p_begin_value)); const_metadata_pointer p_begin_metadata = base_type::m_p_metadata - (base_type::m_p_value - base_type::m_p_begin_value); return (this_type(base_type::mid_pointer(base_type::m_p_begin_value, base_type::m_p_value), base_type::m_p_begin_value, base_type::m_p_value, base_type::mid_pointer(p_begin_metadata, base_type::m_p_metadata))); } /// Returns the node reference associated with the right node. inline ov_tree_node_it_ get_r_child() const { if (base_type::m_p_value == base_type::m_p_end_value) return this_type(base_type::m_p_end_value, base_type::m_p_end_value, base_type::m_p_end_value); const_metadata_pointer p_end_metadata = base_type::m_p_metadata + (base_type::m_p_end_value - base_type::m_p_value); return (this_type(base_type::mid_pointer(base_type::m_p_value + 1, base_type::m_p_end_value), base_type::m_p_value + 1, base_type::m_p_end_value,(base_type::m_p_metadata == 0)? 0 : base_type::mid_pointer(base_type::m_p_metadata + 1, p_end_metadata))); } }; #undef PB_DS_OV_TREE_NODE_ITERATOR_C_DEC #undef PB_DS_OV_TREE_CONST_NODE_ITERATOR_C_DEC } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/ov_tree_map_/policy_access_fn_imps.hpp 0000644 00000003537 15146341150 0020127 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/policy_access_fn_imps.hpp * Contains an implementation class for ov_tree. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return *this; } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return *this; } c++/8/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp 0000644 00000011565 15146341150 0016406 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/erase_fn_imps.hpp * Contains an implementation class for ov_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_ASSERT_VALID((*this)) if (m_size == 0) { return; } else { reallocate_metadata((node_update* )this, 0); cond_dtor<size_type> cd(m_a_values, m_end_it, m_size); } _GLIBCXX_DEBUG_ONLY(debug_base::clear();) m_a_values = 0; m_size = 0; m_end_it = m_a_values; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template<typename Pred> inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_size); #endif size_type new_size = 0; size_type num_val_ersd = 0; for (iterator source_it = begin(); source_it != m_end_it; ++source_it) if (!pred(*source_it)) ++new_size; else ++num_val_ersd; if (new_size == 0) { clear(); return num_val_ersd; } value_vector a_new_values = s_value_alloc.allocate(new_size); iterator target_it = a_new_values; cond_dtor<size_type> cd(a_new_values, target_it, new_size); _GLIBCXX_DEBUG_ONLY(debug_base::clear()); for (iterator source_it = begin(); source_it != m_end_it; ++source_it) { if (!pred(*source_it)) { new (const_cast<void*>(static_cast<const void*>(target_it))) value_type(*source_it); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(*source_it))); ++target_it; } } reallocate_metadata((node_update*)this, new_size); cd.set_no_action(); { cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size); } m_a_values = a_new_values; m_size = new_size; m_end_it = target_it; update(node_begin(), (node_update*)this); PB_DS_ASSERT_VALID((*this)) return num_val_ersd; } PB_DS_CLASS_T_DEC template<typename It> It PB_DS_CLASS_C_DEC:: erase_imp(It it) { PB_DS_ASSERT_VALID((*this)) if (it == end()) return end(); PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(*it)) #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_size); #endif _GLIBCXX_DEBUG_ASSERT(m_size > 0); value_vector a_values = s_value_alloc.allocate(m_size - 1); iterator source_it = begin(); iterator source_end_it = end(); iterator target_it = a_values; iterator ret_it = end(); cond_dtor<size_type> cd(a_values, target_it, m_size - 1); _GLIBCXX_DEBUG_ONLY(size_type cnt = 0;) while (source_it != source_end_it) { if (source_it != it) { _GLIBCXX_DEBUG_ONLY(++cnt;) _GLIBCXX_DEBUG_ASSERT(cnt != m_size); new (const_cast<void*>(static_cast<const void*>(target_it))) value_type(*source_it); ++target_it; } else ret_it = target_it; ++source_it; } _GLIBCXX_DEBUG_ASSERT(m_size > 0); reallocate_metadata((node_update*)this, m_size - 1); cd.set_no_action(); _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(*it));) { cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size); } m_a_values = a_values; --m_size; m_end_it = m_a_values + m_size; update(node_begin(), (node_update*)this); PB_DS_ASSERT_VALID((*this)) return It(ret_it); } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { point_iterator it = find(r_key); if (it == end()) return false; erase(it); return true; } c++/8/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp 0000644 00000036006 15146341150 0016230 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file ov_tree_map_/ov_tree_map_.hpp * Contains an implementation class for ov_tree. */ #include <map> #include <set> #include <ext/pb_ds/exception.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/detail/eq_fn/eq_by_less.hpp> #include <ext/pb_ds/detail/types_traits.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/tree_trace_base.hpp> #ifdef _GLIBCXX_DEBUG #include <ext/pb_ds/detail/debug_map_base.hpp> #endif #include <utility> #include <functional> #include <algorithm> #include <vector> #include <assert.h> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_OV_TREE_NAME ov_tree_map #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_node_const_iterator_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_OV_TREE_NAME ov_tree_set #define PB_DS_CONST_NODE_ITERATOR_NAME ov_tree_node_const_iterator_set #endif #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Mapped, typename Cmp_Fn, \ typename Node_And_It_Traits, typename _Alloc> #define PB_DS_CLASS_C_DEC \ PB_DS_OV_TREE_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, _Alloc> #define PB_DS_OV_TREE_TRAITS_BASE \ types_traits<Key, Mapped, _Alloc, false> #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base<Key, eq_by_less<Key, Cmp_Fn>, \ typename _Alloc::template rebind<Key>::other::const_reference> #endif #ifdef PB_DS_TREE_TRACE #define PB_DS_TREE_TRACE_BASE_C_DEC \ tree_trace_base<typename Node_And_It_Traits::node_const_iterator, \ typename Node_And_It_Traits::node_iterator, \ Cmp_Fn, false, _Alloc> #endif #ifndef PB_DS_CHECK_KEY_EXISTS # error Missing definition #endif /** * @brief Ordered-vector tree associative-container. * @ingroup branch-detail */ template<typename Key, typename Mapped, typename Cmp_Fn, typename Node_And_It_Traits, typename _Alloc> class PB_DS_OV_TREE_NAME : #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif #ifdef PB_DS_TREE_TRACE public PB_DS_TREE_TRACE_BASE_C_DEC, #endif public Cmp_Fn, public Node_And_It_Traits::node_update, public PB_DS_OV_TREE_TRAITS_BASE { private: typedef PB_DS_OV_TREE_TRAITS_BASE traits_base; typedef Node_And_It_Traits traits_type; typedef typename remove_const<typename traits_base::value_type>::type non_const_value_type; typedef typename _Alloc::template rebind<non_const_value_type>::other value_allocator; typedef typename value_allocator::pointer value_vector; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif #ifdef PB_DS_TREE_TRACE typedef PB_DS_TREE_TRACE_BASE_C_DEC trace_base; #endif typedef typename traits_base::pointer mapped_pointer_; typedef typename traits_base::const_pointer mapped_const_pointer_; typedef typename traits_type::metadata_type metadata_type; typedef typename _Alloc::template rebind<metadata_type>::other metadata_allocator; typedef typename metadata_allocator::pointer metadata_pointer; typedef typename metadata_allocator::const_reference metadata_const_reference; typedef typename metadata_allocator::reference metadata_reference; typedef typename traits_type::null_node_update_pointer null_node_update_pointer; public: typedef ov_tree_tag container_category; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Cmp_Fn cmp_fn; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; typedef const_pointer point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef pointer point_iterator; #else typedef point_const_iterator point_iterator; #endif typedef point_iterator iterator; typedef point_const_iterator const_iterator; /// Conditional destructor. template<typename Size_Type> class cond_dtor { public: cond_dtor(value_vector a_vec, iterator& r_last_it, Size_Type total_size) : m_a_vec(a_vec), m_r_last_it(r_last_it), m_max_size(total_size), m_no_action(false) { } ~cond_dtor() { if (m_no_action) return; iterator it = m_a_vec; while (it != m_r_last_it) { it->~value_type(); ++it; } if (m_max_size > 0) value_allocator().deallocate(m_a_vec, m_max_size); } inline void set_no_action() { m_no_action = true; } protected: value_vector m_a_vec; iterator& m_r_last_it; const Size_Type m_max_size; bool m_no_action; }; typedef typename traits_type::node_update node_update; typedef typename traits_type::node_iterator node_iterator; typedef typename traits_type::node_const_iterator node_const_iterator; PB_DS_OV_TREE_NAME(); PB_DS_OV_TREE_NAME(const Cmp_Fn&); PB_DS_OV_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_OV_TREE_NAME(const PB_DS_CLASS_C_DEC&); ~PB_DS_OV_TREE_NAME(); void swap(PB_DS_CLASS_C_DEC&); template<typename It> void copy_from_range(It, It); inline size_type max_size() const; inline bool empty() const; inline size_type size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR PB_DS_ASSERT_VALID((*this)) point_iterator it = lower_bound(r_key); if (it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) { PB_DS_CHECK_KEY_EXISTS(r_key) PB_DS_ASSERT_VALID((*this)) return it->second; } return insert_new_val(it, std::make_pair(r_key, mapped_type()))->second; #else insert(r_key); return traits_base::s_null_type; #endif } inline std::pair<point_iterator, bool> insert(const_reference r_value) { PB_DS_ASSERT_VALID((*this)) key_const_reference r_key = PB_DS_V2F(r_value); point_iterator it = lower_bound(r_key); if (it != end()&& !Cmp_Fn::operator()(r_key, PB_DS_V2F(*it))) { PB_DS_ASSERT_VALID((*this)) PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(it, false); } return std::make_pair(insert_new_val(it, r_value), true); } inline point_iterator lower_bound(key_const_reference r_key) { pointer it = m_a_values; pointer e_it = m_a_values + m_size; while (it != e_it) { pointer mid_it = it + ((e_it - it) >> 1); if (cmp_fn::operator()(PB_DS_V2F(*mid_it), r_key)) it = ++mid_it; else e_it = mid_it; } return it; } inline point_const_iterator lower_bound(key_const_reference r_key) const { return const_cast<PB_DS_CLASS_C_DEC& >(*this).lower_bound(r_key); } inline point_iterator upper_bound(key_const_reference r_key) { iterator pot_it = lower_bound(r_key); if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) { PB_DS_CHECK_KEY_EXISTS(r_key) return ++pot_it; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return pot_it; } inline point_const_iterator upper_bound(key_const_reference r_key) const { return const_cast<PB_DS_CLASS_C_DEC&>(*this).upper_bound(r_key); } inline point_iterator find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) iterator pot_it = lower_bound(r_key); if (pot_it != end() && !Cmp_Fn::operator()(r_key, PB_DS_V2F(*pot_it))) { PB_DS_CHECK_KEY_EXISTS(r_key) return pot_it; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return end(); } inline point_const_iterator find(key_const_reference r_key) const { return (const_cast<PB_DS_CLASS_C_DEC&>(*this).find(r_key)); } bool erase(key_const_reference); template<typename Pred> inline size_type erase_if(Pred); inline iterator erase(iterator it) { return erase_imp<iterator>(it); } void clear(); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); inline iterator begin() { return m_a_values; } inline const_iterator begin() const { return m_a_values; } inline iterator end() { return m_end_it; } inline const_iterator end() const { return m_end_it; } /// Returns a const node_iterator corresponding to the node at the /// root of the tree. inline node_const_iterator node_begin() const; /// Returns a node_iterator corresponding to the node at the /// root of the tree. inline node_iterator node_begin(); /// Returns a const node_iterator corresponding to a node just /// after a leaf of the tree. inline node_const_iterator node_end() const; /// Returns a node_iterator corresponding to a node just /// after a leaf of the tree. inline node_iterator node_end(); private: inline void update(node_iterator, null_node_update_pointer); template<typename Node_Update> void update(node_iterator, Node_Update*); void reallocate_metadata(null_node_update_pointer, size_type); template<typename Node_Update_> void reallocate_metadata(Node_Update_*, size_type); template<typename It> void copy_from_ordered_range(It, It); void value_swap(PB_DS_CLASS_C_DEC&); template<typename It> void copy_from_ordered_range(It, It, It, It); template<typename Ptr> inline static Ptr mid_pointer(Ptr p_begin, Ptr p_end) { _GLIBCXX_DEBUG_ASSERT(p_end >= p_begin); return (p_begin + (p_end - p_begin) / 2); } inline iterator insert_new_val(iterator it, const_reference r_value) { #ifdef PB_DS_REGRESSION typename _Alloc::group_adjustor adjust(m_size); #endif PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_value)) value_vector a_values = s_value_alloc.allocate(m_size + 1); iterator source_it = begin(); iterator source_end_it = end(); iterator target_it = a_values; iterator ret_it; cond_dtor<size_type> cd(a_values, target_it, m_size + 1); while (source_it != it) { new (const_cast<void*>(static_cast<const void*>(target_it))) value_type(*source_it++); ++target_it; } new (const_cast<void*>(static_cast<const void*>(ret_it = target_it))) value_type(r_value); ++target_it; while (source_it != source_end_it) { new (const_cast<void*>(static_cast<const void*>(target_it))) value_type(*source_it++); ++target_it; } reallocate_metadata((node_update*)this, m_size + 1); cd.set_no_action(); if (m_size != 0) { cond_dtor<size_type> cd1(m_a_values, m_end_it, m_size); } ++m_size; m_a_values = a_values; m_end_it = m_a_values + m_size; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_value))); update(node_begin(), (node_update* )this); PB_DS_ASSERT_VALID((*this)) return ret_it; } #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_iterators(const char*, int) const; #endif template<typename It> It erase_imp(It); inline node_const_iterator PB_DS_node_begin_imp() const; inline node_const_iterator PB_DS_node_end_imp() const; inline node_iterator PB_DS_node_begin_imp(); inline node_iterator PB_DS_node_end_imp(); private: static value_allocator s_value_alloc; static metadata_allocator s_metadata_alloc; value_vector m_a_values; metadata_pointer m_a_metadata; iterator m_end_it; size_type m_size; }; #include <ext/pb_ds/detail/ov_tree_map_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/ov_tree_map_/iterators_fn_imps.hpp> #include <ext/pb_ds/detail/ov_tree_map_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/ov_tree_map_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/ov_tree_map_/info_fn_imps.hpp> #include <ext/pb_ds/detail/ov_tree_map_/split_join_fn_imps.hpp> #include <ext/pb_ds/detail/bin_search_tree_/policy_access_fn_imps.hpp> #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_OV_TREE_NAME #undef PB_DS_OV_TREE_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #ifdef PB_DS_TREE_TRACE #undef PB_DS_TREE_TRACE_BASE_C_DEC #endif #undef PB_DS_CONST_NODE_ITERATOR_NAME } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/priority_queue_base_dispatch.hpp 0000644 00000010054 15146341150 0017063 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/priority_queue_base_dispatch.hpp * Contains an pqiative container dispatching base. */ #ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP #define PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) #include <ext/pb_ds/detail/pairing_heap_/pairing_heap_.hpp> #include <ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp> #include <ext/pb_ds/detail/rc_binomial_heap_/rc_binomial_heap_.hpp> #include <ext/pb_ds/detail/binary_heap_/binary_heap_.hpp> #include <ext/pb_ds/detail/thin_heap_/thin_heap_.hpp> #undef PB_DS_DEBUG_VERIFY #undef PB_DS_ASSERT_VALID namespace __gnu_pbds { namespace detail { /// Specialization for pairing_heap. template<typename _VTp, typename Cmp_Fn, typename _Alloc> struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, pairing_heap_tag, null_type> { /// Dispatched type. typedef pairing_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for binomial_heap. template<typename _VTp, typename Cmp_Fn, typename _Alloc> struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, binomial_heap_tag, null_type> { /// Dispatched type. typedef binomial_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for rc_binary_heap. template<typename _VTp, typename Cmp_Fn, typename _Alloc> struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, rc_binomial_heap_tag, null_type> { /// Dispatched type. typedef rc_binomial_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for binary_heap. template<typename _VTp, typename Cmp_Fn, typename _Alloc> struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, binary_heap_tag, null_type> { /// Dispatched type. typedef binary_heap<_VTp, Cmp_Fn, _Alloc> type; }; /// Specialization for thin_heap. template<typename _VTp, typename Cmp_Fn, typename _Alloc> struct container_base_dispatch<_VTp, Cmp_Fn, _Alloc, thin_heap_tag, null_type> { /// Dispatched type. typedef thin_heap<_VTp, Cmp_Fn, _Alloc> type; }; //@} group pbds } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_PRIORITY_QUEUE_BASE_DS_DISPATCHER_HPP c++/8/ext/pb_ds/detail/types_traits.hpp 0000644 00000023416 15146341150 0013665 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/types_traits.hpp * Contains a traits class of types used by containers. */ #ifndef PB_DS_TYPES_TRAITS_HPP #define PB_DS_TYPES_TRAITS_HPP #include <algorithm> #include <utility> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <utility> namespace __gnu_pbds { namespace detail { /** * @addtogroup traits Traits * @{ */ /// Primary template. template<typename Key, typename Mapped> struct no_throw_copies { static const bool __simple = is_simple<Key>::value && is_simple<Mapped>::value; typedef integral_constant<int, __simple> indicator; }; /// Specialization. template<typename Key> struct no_throw_copies<Key, null_type> { typedef integral_constant<int, is_simple<Key>::value> indicator; }; /// Stored value. template<typename _Tv> struct stored_value { typedef _Tv value_type; value_type m_value; }; /// Stored hash. template<typename _Th> struct stored_hash { typedef _Th hash_type; hash_type m_hash; }; /// Primary template for representation of stored data. /// Two types of data can be stored: value and hash. template<typename _Tv, typename _Th> struct stored_data : public stored_value<_Tv>, public stored_hash<_Th> { }; /// Specialization for representation of stored data of just value type. template<typename _Tv> struct stored_data<_Tv, null_type> : public stored_value<_Tv> { }; /// Primary template. template<typename Key, typename Mapped, typename _Alloc, bool Store_Hash> struct type_base; /** * Specialization of type_base for the case where the hash value * is not stored alongside each value. */ template<typename Key, typename Mapped, typename _Alloc> struct type_base<Key, Mapped, _Alloc, false> { public: typedef typename _Alloc::size_type size_type; private: typedef typename _Alloc::template rebind<Mapped> __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef std::pair<const Key, Mapped> __value_type; typedef typename _Alloc::template rebind<__value_type> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::value_type value_type; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data<value_type, null_type> stored_data_type; }; /** * Specialization of type_base for the case where the hash value * is stored alongside each value. */ template<typename Key, typename Mapped, typename _Alloc> struct type_base<Key, Mapped, _Alloc, true> { public: typedef typename _Alloc::size_type size_type; private: typedef typename _Alloc::template rebind<Mapped> __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef std::pair<const Key, Mapped> __value_type; typedef typename _Alloc::template rebind<__value_type> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::value_type value_type; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data<value_type, size_type> stored_data_type; }; /** * Specialization of type_base for the case where the hash value * is not stored alongside each value. */ template<typename Key, typename _Alloc> struct type_base<Key, null_type, _Alloc, false> { public: typedef typename _Alloc::size_type size_type; typedef Key value_type; private: typedef typename _Alloc::template rebind<null_type> __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename _Alloc::template rebind<value_type> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data<value_type, null_type> stored_data_type; static null_type s_null_type; }; template<typename Key, typename _Alloc> null_type type_base<Key, null_type, _Alloc, false>::s_null_type; /** * Specialization of type_base for the case where the hash value * is stored alongside each value. */ template<typename Key, typename _Alloc> struct type_base<Key, null_type, _Alloc, true> { public: typedef typename _Alloc::size_type size_type; typedef Key value_type; private: typedef typename _Alloc::template rebind<null_type> __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename _Alloc::template rebind<value_type> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_ma::value_type mapped_type; typedef typename __rebind_ma::pointer mapped_pointer; typedef typename __rebind_ma::const_pointer mapped_const_pointer; typedef typename __rebind_ma::reference mapped_reference; typedef typename __rebind_ma::const_reference mapped_const_reference; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef stored_data<value_type, size_type> stored_data_type; static null_type s_null_type; }; template<typename Key, typename _Alloc> null_type type_base<Key, null_type, _Alloc, true>::s_null_type; /// Type base dispatch. template<typename Key, typename Mapped, typename _Alloc, bool Store_Hash> struct type_dispatch { typedef type_base<Key, Mapped, _Alloc, Store_Hash> type; }; /// Traits for abstract types. template<typename Key, typename Mapped, typename _Alloc, bool Store_Hash> struct types_traits : public type_dispatch<Key, Mapped, _Alloc, Store_Hash>::type { private: typedef no_throw_copies<Key, Mapped> __nothrowcopy; typedef typename _Alloc::template rebind<Key>::other __rebind_a; public: typedef typename _Alloc::size_type size_type; typedef typename __rebind_a::value_type key_type; typedef typename __rebind_a::pointer key_pointer; typedef typename __rebind_a::const_pointer key_const_pointer; typedef typename __rebind_a::reference key_reference; typedef typename __rebind_a::const_reference key_const_reference; typedef std::pair<size_type, size_type> comp_hash; typedef integral_constant<int, Store_Hash> store_extra; typedef typename __nothrowcopy::indicator no_throw_indicator; store_extra m_store_extra_indicator; no_throw_indicator m_no_throw_copies_indicator; }; //@} } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/container_base_dispatch.hpp 0000644 00000031500 15146341150 0015757 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file container_base_dispatch.hpp * Contains associative container dispatching. */ #ifndef PB_DS_ASSOC_CNTNR_BASE_DS_DISPATCHER_HPP #define PB_DS_ASSOC_CNTNR_BASE_DS_DISPATCHER_HPP #include <ext/typelist.h> #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) #define PB_DS_CHECK_KEY_EXISTS(_Key) \ _GLIBCXX_DEBUG_ONLY(debug_base::check_key_exists(_Key, __FILE__, __LINE__);) #define PB_DS_CHECK_KEY_DOES_NOT_EXIST(_Key) \ _GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(_Key, \ __FILE__, __LINE__);) #define PB_DS_DATA_TRUE_INDICATOR #define PB_DS_V2F(X) (X).first #define PB_DS_V2S(X) (X).second #define PB_DS_EP2VP(X)& ((X)->m_value) #include <ext/pb_ds/detail/list_update_map_/lu_map_.hpp> #include <ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp> #include <ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp> #include <ext/pb_ds/detail/splay_tree_/splay_tree_.hpp> #include <ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp> #include <ext/pb_ds/detail/pat_trie_/pat_trie_.hpp> #undef PB_DS_DATA_TRUE_INDICATOR #undef PB_DS_V2F #undef PB_DS_V2S #undef PB_DS_EP2VP #define PB_DS_DATA_FALSE_INDICATOR #define PB_DS_V2F(X) (X) #define PB_DS_V2S(X) Mapped_Data() #define PB_DS_EP2VP(X)& ((X)->m_value.first) #include <ext/pb_ds/detail/list_update_map_/lu_map_.hpp> #include <ext/pb_ds/detail/bin_search_tree_/bin_search_tree_.hpp> #include <ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp> #include <ext/pb_ds/detail/splay_tree_/splay_tree_.hpp> #include <ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp> #include <ext/pb_ds/detail/gp_hash_table_map_/gp_ht_map_.hpp> #include <ext/pb_ds/detail/pat_trie_/pat_trie_.hpp> #undef PB_DS_DATA_FALSE_INDICATOR #undef PB_DS_V2F #undef PB_DS_V2S #undef PB_DS_EP2VP #undef PB_DS_CHECK_KEY_DOES_NOT_EXIST #undef PB_DS_CHECK_KEY_EXISTS #undef PB_DS_DEBUG_VERIFY #undef PB_DS_ASSERT_VALID namespace __gnu_pbds { namespace detail { /// Specialization for list-update map. template<typename Key, typename Mapped, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, Mapped, _Alloc, list_update_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef lu_map<Key, Mapped, at0t, _Alloc, at1t> type; }; /// Specialization for list-update set. template<typename Key, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, null_type, _Alloc, list_update_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef lu_set<Key, null_type, at0t, _Alloc, at1t> type; }; /// Specialization for PATRICIA trie map. template<typename Key, typename Mapped, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, Mapped, _Alloc, pat_trie_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; public: typedef pat_trie_map<Key, Mapped, at1t, _Alloc> type; }; /// Specialization for PATRICIA trie set. template<typename Key, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, null_type, _Alloc, pat_trie_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef pat_trie_set<Key, null_type, at1t, _Alloc> type; }; /// Specialization for R-B tree map. template<typename Key, typename Mapped, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, Mapped, _Alloc, rb_tree_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef rb_tree_map<Key, Mapped, at0t, at1t, _Alloc> type; }; /// Specialization for R-B tree set. template<typename Key, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, null_type, _Alloc, rb_tree_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; public: typedef rb_tree_set<Key, null_type, at0t, at1t, _Alloc> type; }; /// Specialization splay tree map. template<typename Key, typename Mapped, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, Mapped, _Alloc, splay_tree_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef splay_tree_map<Key, Mapped, at0t, at1t, _Alloc> type; }; /// Specialization splay tree set. template<typename Key, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, null_type, _Alloc, splay_tree_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef splay_tree_set<Key, null_type, at0t, at1t, _Alloc> type; }; /// Specialization ordered-vector tree map. template<typename Key, typename Mapped, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, Mapped, _Alloc, ov_tree_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef ov_tree_map<Key, Mapped, at0t, at1t, _Alloc> type; }; /// Specialization ordered-vector tree set. template<typename Key, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, null_type, _Alloc, ov_tree_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; public: /// Dispatched type. typedef ov_tree_set<Key, null_type, at0t, at1t, _Alloc> type; }; /// Specialization colision-chaining hash map. template<typename Key, typename Mapped, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, Mapped, _Alloc, cc_hash_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; typedef typename at4::type at4t; public: /// Dispatched type. typedef cc_ht_map<Key, Mapped, at0t, at1t, _Alloc, at3t::value, at4t, at2t> type; }; /// Specialization colision-chaining hash set. template<typename Key, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, null_type, _Alloc, cc_hash_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; typedef typename at4::type at4t; public: /// Dispatched type. typedef cc_ht_set<Key, null_type, at0t, at1t, _Alloc, at3t::value, at4t, at2t> type; }; /// Specialization general-probe hash map. template<typename Key, typename Mapped, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, Mapped, _Alloc, gp_hash_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; typedef typename at4::type at4t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 5> at5; typedef typename at5::type at5t; public: /// Dispatched type. typedef gp_ht_map<Key, Mapped, at0t, at1t, _Alloc, at3t::value, at4t, at5t, at2t> type; }; /// Specialization general-probe hash set. template<typename Key, typename _Alloc, typename Policy_Tl> struct container_base_dispatch<Key, null_type, _Alloc, gp_hash_tag, Policy_Tl> { private: typedef __gnu_cxx::typelist::at_index<Policy_Tl, 0> at0; typedef typename at0::type at0t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 1> at1; typedef typename at1::type at1t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 2> at2; typedef typename at2::type at2t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 3> at3; typedef typename at3::type at3t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 4> at4; typedef typename at4::type at4t; typedef __gnu_cxx::typelist::at_index<Policy_Tl, 5> at5; typedef typename at5::type at5t; public: /// Dispatched type. typedef gp_ht_set<Key, null_type, at0t, at1t, _Alloc, at3t::value, at4t, at5t, at2t> type; }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp 0000644 00000021462 15146341150 0016172 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/binary_heap_.hpp * Contains an implementation class for a binary heap. */ #ifndef PB_DS_BINARY_HEAP_HPP #define PB_DS_BINARY_HEAP_HPP #include <queue> #include <algorithm> #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/binary_heap_/entry_cmp.hpp> #include <ext/pb_ds/detail/binary_heap_/entry_pred.hpp> #include <ext/pb_ds/detail/binary_heap_/resize_policy.hpp> #include <ext/pb_ds/detail/binary_heap_/point_const_iterator.hpp> #include <ext/pb_ds/detail/binary_heap_/const_iterator.hpp> #ifdef PB_DS_BINARY_HEAP_TRACE_ #include <iostream> #endif #include <ext/pb_ds/detail/type_utils.hpp> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> #define PB_DS_CLASS_C_DEC \ binary_heap<Value_Type, Cmp_Fn, _Alloc> #define PB_DS_ENTRY_CMP_DEC \ entry_cmp<Value_Type, Cmp_Fn, _Alloc, is_simple<Value_Type>::value>::type #define PB_DS_RESIZE_POLICY_DEC \ __gnu_pbds::detail::resize_policy<typename _Alloc::size_type> /** * Binary heaps composed of resize and compare policies. * * @ingroup heap-detail * * Based on CLRS. */ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> class binary_heap : public PB_DS_ENTRY_CMP_DEC, public PB_DS_RESIZE_POLICY_DEC { public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename PB_DS_ENTRY_CMP_DEC entry_cmp; typedef PB_DS_RESIZE_POLICY_DEC resize_policy; typedef cond_dealtor<value_type, _Alloc> cond_dealtor_t; private: enum { simple_value = is_simple<value_type>::value }; typedef integral_constant<int, simple_value> no_throw_copies_t; typedef typename _Alloc::template rebind<value_type> __rebind_v; typedef typename __rebind_v::other value_allocator; public: typedef typename value_allocator::pointer pointer; typedef typename value_allocator::const_pointer const_pointer; typedef typename value_allocator::reference reference; typedef typename value_allocator::const_reference const_reference; typedef typename __conditional_type<simple_value, value_type, pointer>::__type entry; typedef typename _Alloc::template rebind<entry>::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef binary_heap_point_const_iterator_<value_type, entry, simple_value, _Alloc> point_const_iterator; typedef point_const_iterator point_iterator; typedef binary_heap_const_iterator_<value_type, entry, simple_value, _Alloc> const_iterator; typedef const_iterator iterator; binary_heap(); binary_heap(const cmp_fn&); binary_heap(const binary_heap&); void swap(binary_heap&); ~binary_heap(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; inline void pop(); inline void erase(point_iterator); template<typename Pred> size_type erase_if(Pred); inline void erase_at(entry_pointer, size_type, false_type); inline void erase_at(entry_pointer, size_type, true_type); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; void clear(); template<typename Pred> void split(Pred, binary_heap&); void join(binary_heap&); #ifdef PB_DS_BINARY_HEAP_TRACE_ void trace() const; #endif protected: template<typename It> void copy_from_range(It, It); private: void value_swap(binary_heap&); inline void insert_value(const_reference, false_type); inline void insert_value(value_type, true_type); inline void resize_for_insert_if_needed(); inline void swap_value_imp(entry_pointer, value_type, true_type); inline void swap_value_imp(entry_pointer, const_reference, false_type); void fix(entry_pointer); inline const_reference top_imp(true_type) const; inline const_reference top_imp(false_type) const; inline static size_type left_child(size_type); inline static size_type right_child(size_type); inline static size_type parent(size_type); inline void resize_for_erase_if_needed(); template<typename Pred> size_type partition(Pred); void make_heap() { const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this); entry_pointer end = m_a_entries + m_size; std::make_heap(m_a_entries, end, m_cmp); } void push_heap() { const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this); entry_pointer end = m_a_entries + m_size; std::push_heap(m_a_entries, end, m_cmp); } void pop_heap() { const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this); entry_pointer end = m_a_entries + m_size; std::pop_heap(m_a_entries, end, m_cmp); } #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_BINARY_HEAP_TRACE_ void trace_entry(const entry&, false_type) const; void trace_entry(const entry&, true_type) const; #endif static entry_allocator s_entry_allocator; static value_allocator s_value_allocator; static no_throw_copies_t s_no_throw_copies_ind; size_type m_size; size_type m_actual_size; entry_pointer m_a_entries; }; #define PB_DS_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(__FILE__, __LINE__);) #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) #include <ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp> #include <ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp> #include <ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp> #include <ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp> #include <ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp> #include <ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp> #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_ENTRY_CMP_DEC #undef PB_DS_RESIZE_POLICY_DEC } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/binary_heap_/split_join_fn_imps.hpp 0000644 00000011473 15146341150 0017440 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/split_join_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC template<typename Pred> void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) typedef typename entry_pred<value_type, Pred, _Alloc, simple_value>::type pred_t; const size_type left = partition(pred_t(pred)); _GLIBCXX_DEBUG_ASSERT(m_size >= left); const size_type ersd = m_size - left; _GLIBCXX_DEBUG_ASSERT(m_size >= ersd); const size_type new_size = resize_policy::get_new_size_for_arbitrary(left); const size_type other_actual_size = other.get_new_size_for_arbitrary(ersd); entry_pointer a_entries = 0; entry_pointer a_other_entries = 0; __try { a_entries = s_entry_allocator.allocate(new_size); a_other_entries = s_entry_allocator.allocate(other_actual_size); } __catch(...) { if (a_entries != 0) s_entry_allocator.deallocate(a_entries, new_size); if (a_other_entries != 0) s_entry_allocator.deallocate(a_other_entries, other_actual_size); __throw_exception_again; }; for (size_type i = 0; i < other.m_size; ++i) erase_at(other.m_a_entries, i, s_no_throw_copies_ind); _GLIBCXX_DEBUG_ASSERT(new_size >= left); std::copy(m_a_entries, m_a_entries + left, a_entries); std::copy(m_a_entries + left, m_a_entries + m_size, a_other_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); s_entry_allocator.deallocate(other.m_a_entries, other.m_actual_size); m_actual_size = new_size; other.m_actual_size = other_actual_size; m_size = left; other.m_size = ersd; m_a_entries = a_entries; other.m_a_entries = a_other_entries; make_heap(); other.make_heap(); resize_policy::notify_arbitrary(m_actual_size); other.notify_arbitrary(other.m_actual_size); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) const size_type len = m_size + other.m_size; const size_type new_size = resize_policy::get_new_size_for_arbitrary(len); entry_pointer a_entries = 0; entry_pointer a_other_entries = 0; __try { a_entries = s_entry_allocator.allocate(new_size); a_other_entries = s_entry_allocator.allocate(resize_policy::min_size); } __catch(...) { if (a_entries != 0) s_entry_allocator.deallocate(a_entries, new_size); if (a_other_entries != 0) s_entry_allocator.deallocate(a_other_entries, resize_policy::min_size); __throw_exception_again; } std::copy(m_a_entries, m_a_entries + m_size, a_entries); std::copy(other.m_a_entries, other.m_a_entries + other.m_size, a_entries + m_size); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_a_entries = a_entries; m_size = len; m_actual_size = new_size; resize_policy::notify_arbitrary(new_size); make_heap(); s_entry_allocator.deallocate(other.m_a_entries, other.m_actual_size); other.m_a_entries = a_other_entries; other.m_size = 0; other.m_actual_size = resize_policy::min_size; other.notify_arbitrary(resize_policy::min_size); other.make_heap(); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } c++/8/ext/pb_ds/detail/binary_heap_/entry_cmp.hpp 0000644 00000005404 15146341150 0015550 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/entry_cmp.hpp * Contains an implementation class for a binary_heap. */ #ifndef PB_DS_BINARY_HEAP_ENTRY_CMP_HPP #define PB_DS_BINARY_HEAP_ENTRY_CMP_HPP namespace __gnu_pbds { namespace detail { /// Entry compare, primary template. template<typename _VTp, typename Cmp_Fn, typename _Alloc, bool No_Throw> struct entry_cmp; /// Specialization, true. template<typename _VTp, typename Cmp_Fn, typename _Alloc> struct entry_cmp<_VTp, Cmp_Fn, _Alloc, true> { /// Compare. typedef Cmp_Fn type; }; /// Specialization, false. template<typename _VTp, typename Cmp_Fn, typename _Alloc> struct entry_cmp<_VTp, Cmp_Fn, _Alloc, false> { private: typedef typename _Alloc::template rebind<_VTp> __rebind_v; public: typedef typename __rebind_v::other::const_pointer entry; /// Compare plus entry. struct type : public Cmp_Fn { type() { } type(const Cmp_Fn& other) : Cmp_Fn(other) { } bool operator()(entry lhs, entry rhs) const { return Cmp_Fn::operator()(*lhs, *rhs); } }; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BINARY_HEAP_ENTRY_CMP_HPP c++/8/ext/pb_ds/detail/binary_heap_/constructors_destructor_fn_imps.hpp 0000644 00000010135 15146341150 0022306 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation class for binary_heap_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::value_allocator PB_DS_CLASS_C_DEC::s_value_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::no_throw_copies_t PB_DS_CLASS_C_DEC::s_no_throw_copies_ind; PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) { insert_value(*first_it, s_no_throw_copies_ind); ++first_it; } make_heap(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binary_heap() : m_size(0), m_actual_size(resize_policy::min_size), m_a_entries(s_entry_allocator.allocate(m_actual_size)) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binary_heap(const Cmp_Fn& r_cmp_fn) : entry_cmp(r_cmp_fn), m_size(0), m_actual_size(resize_policy::min_size), m_a_entries(s_entry_allocator.allocate(m_actual_size)) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binary_heap(const PB_DS_CLASS_C_DEC& other) : entry_cmp(other), resize_policy(other), m_size(0), m_actual_size(other.m_actual_size), m_a_entries(s_entry_allocator.allocate(m_actual_size)) { PB_DS_ASSERT_VALID(other) _GLIBCXX_DEBUG_ASSERT(m_a_entries != other.m_a_entries); __try { copy_from_range(other.begin(), other.end()); } __catch(...) { for (size_type i = 0; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); s_entry_allocator.deallocate(m_a_entries, m_actual_size); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) _GLIBCXX_DEBUG_ASSERT(m_a_entries != other.m_a_entries); value_swap(other); std::swap((entry_cmp&)(*this), (entry_cmp&)other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_a_entries, other.m_a_entries); std::swap(m_size, other.m_size); std::swap(m_actual_size, other.m_actual_size); static_cast<resize_policy*>(this)->swap(other); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~binary_heap() { for (size_type i = 0; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); s_entry_allocator.deallocate(m_a_entries, m_actual_size); } c++/8/ext/pb_ds/detail/binary_heap_/info_fn_imps.hpp 0000644 00000004016 15146341150 0016214 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/info_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return m_size == 0; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_size; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } c++/8/ext/pb_ds/detail/binary_heap_/iterators_fn_imps.hpp 0000644 00000004336 15146341150 0017302 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/iterators_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { return iterator(m_a_entries); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { return const_iterator(m_a_entries); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return iterator(m_a_entries + m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return const_iterator(m_a_entries + m_size); } c++/8/ext/pb_ds/detail/binary_heap_/debug_fn_imps.hpp 0000644 00000004755 15146341150 0016361 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/debug_fn_imps.hpp * Contains an implementation class for a binary_heap. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { #ifdef PB_DS_REGRESSION s_entry_allocator.check_allocated(m_a_entries, m_actual_size); #endif resize_policy::assert_valid(__file, __line); PB_DS_DEBUG_VERIFY(m_size <= m_actual_size); for (size_type i = 0; i < m_size; ++i) { #ifdef PB_DS_REGRESSION s_value_allocator.check_allocated(m_a_entries[i], 1); #endif if (left_child(i) < m_size) PB_DS_DEBUG_VERIFY(!entry_cmp::operator()(m_a_entries[i], m_a_entries[left_child(i)])); PB_DS_DEBUG_VERIFY(parent(left_child(i)) == i); if (right_child(i) < m_size) PB_DS_DEBUG_VERIFY(!entry_cmp::operator()(m_a_entries[i], m_a_entries[right_child(i)])); PB_DS_DEBUG_VERIFY(parent(right_child(i)) == i); } } #endif c++/8/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp 0000644 00000011562 15146341150 0016571 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/insert_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID((*this)) insert_value(r_val, s_no_throw_copies_ind); push_heap(); PB_DS_ASSERT_VALID((*this)) return point_iterator(m_a_entries); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_value(value_type val, true_type) { resize_for_insert_if_needed(); m_a_entries[m_size++] = val; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_value(const_reference r_val, false_type) { resize_for_insert_if_needed(); pointer p_new = s_value_allocator.allocate(1); cond_dealtor_t cond(p_new); new (p_new) value_type(r_val); cond.set_no_action(); m_a_entries[m_size++] = p_new; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_for_insert_if_needed() { if (!resize_policy::resize_needed_for_grow(m_size)) { _GLIBCXX_DEBUG_ASSERT(m_size < m_actual_size); return; } const size_type new_size = resize_policy::get_new_size_for_grow(); entry_pointer new_entries = s_entry_allocator.allocate(new_size); resize_policy::notify_grow_resize(); std::copy(m_a_entries, m_a_entries + m_size, new_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; m_a_entries = new_entries; make_heap(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID((*this)) swap_value_imp(it.m_p_e, r_new_val, s_no_throw_copies_ind); fix(it.m_p_e); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: fix(entry_pointer p_e) { size_type i = p_e - m_a_entries; if (i > 0 && entry_cmp::operator()(m_a_entries[parent(i)], m_a_entries[i])) { size_type parent_i = parent(i); while (i > 0 && entry_cmp::operator()(m_a_entries[parent_i], m_a_entries[i])) { std::swap(m_a_entries[i], m_a_entries[parent_i]); i = parent_i; parent_i = parent(i); } PB_DS_ASSERT_VALID((*this)) return; } while (i < m_size) { const size_type lchild_i = left_child(i); const size_type rchild_i = right_child(i); _GLIBCXX_DEBUG_ASSERT(rchild_i > lchild_i); const bool smaller_than_lchild = lchild_i < m_size && entry_cmp::operator()(m_a_entries[i], m_a_entries[lchild_i]); const bool smaller_than_rchild = rchild_i < m_size && entry_cmp::operator()(m_a_entries[i], m_a_entries[rchild_i]); const bool swap_with_rchild = smaller_than_rchild && (!smaller_than_lchild || entry_cmp::operator()(m_a_entries[lchild_i], m_a_entries[rchild_i])); const bool swap_with_lchild = !swap_with_rchild && smaller_than_lchild; if (swap_with_lchild) { std::swap(m_a_entries[i], m_a_entries[lchild_i]); i = lchild_i; } else if (swap_with_rchild) { std::swap(m_a_entries[i], m_a_entries[rchild_i]); i = rchild_i; } else i = m_size; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap_value_imp(entry_pointer p_e, value_type new_val, true_type) { *p_e = new_val; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap_value_imp(entry_pointer p_e, const_reference r_new_val, false_type) { value_type tmp(r_new_val); (*p_e)->swap(tmp); } c++/8/ext/pb_ds/detail/binary_heap_/trace_fn_imps.hpp 0000644 00000004617 15146341150 0016366 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/trace_fn_imps.hpp * Contains an implementation class for a binary_heap. */ #ifdef PB_DS_BINARY_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << this << std::endl; std::cerr << m_a_entries << std::endl; for (size_type i = 0; i < m_size; ++i) trace_entry(m_a_entries[i], s_no_throw_copies_ind); std::cerr << std::endl; std::cerr << "size = " << m_size << " " << "actual_size = " << m_actual_size << std::endl; resize_policy::trace(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_entry(const entry& r_e, false_type) const { std::cout << r_e << " " <<* r_e << std::endl; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_entry(const entry& r_e, true_type) const { std::cout << r_e << std::endl; } #endif // #ifdef PB_DS_BINARY_HEAP_TRACE_ c++/8/ext/pb_ds/detail/binary_heap_/resize_policy.hpp 0000644 00000013765 15146341150 0016441 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/resize_policy.hpp * Contains an implementation class for a binary_heap. */ #ifndef PB_DS_BINARY_HEAP_RESIZE_POLICY_HPP #define PB_DS_BINARY_HEAP_RESIZE_POLICY_HPP #include <debug/debug.h> namespace __gnu_pbds { namespace detail { /// Resize policy for binary heap. template<typename _Tp> class resize_policy { private: enum { ratio = 8, factor = 2 }; /// Next shrink size. _Tp m_shrink_size; /// Next grow size. _Tp m_grow_size; public: typedef _Tp size_type; static const _Tp min_size = 16; resize_policy() : m_shrink_size(0), m_grow_size(min_size) { PB_DS_ASSERT_VALID((*this)) } resize_policy(const resize_policy& other) : m_shrink_size(other.m_shrink_size), m_grow_size(other.m_grow_size) { PB_DS_ASSERT_VALID((*this)) } inline void swap(resize_policy<_Tp>&); inline bool resize_needed_for_grow(size_type) const; inline bool resize_needed_for_shrink(size_type) const; inline bool grow_needed(size_type) const; inline bool shrink_needed(size_type) const; inline size_type get_new_size_for_grow() const; inline size_type get_new_size_for_shrink() const; inline size_type get_new_size_for_arbitrary(size_type) const; inline void notify_grow_resize(); inline void notify_shrink_resize(); void notify_arbitrary(size_type); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_BINARY_HEAP_TRACE_ void trace() const; #endif }; template<typename _Tp> const _Tp resize_policy<_Tp>::min_size; template<typename _Tp> inline void resize_policy<_Tp>:: swap(resize_policy<_Tp>& other) { std::swap(m_shrink_size, other.m_shrink_size); std::swap(m_grow_size, other.m_grow_size); } template<typename _Tp> inline bool resize_policy<_Tp>:: resize_needed_for_grow(size_type size) const { _GLIBCXX_DEBUG_ASSERT(size <= m_grow_size); return size == m_grow_size; } template<typename _Tp> inline bool resize_policy<_Tp>:: resize_needed_for_shrink(size_type size) const { _GLIBCXX_DEBUG_ASSERT(size <= m_grow_size); return size == m_shrink_size; } template<typename _Tp> inline typename resize_policy<_Tp>::size_type resize_policy<_Tp>:: get_new_size_for_grow() const { return m_grow_size * factor; } template<typename _Tp> inline typename resize_policy<_Tp>::size_type resize_policy<_Tp>:: get_new_size_for_shrink() const { const size_type half_size = m_grow_size / factor; return std::max(min_size, half_size); } template<typename _Tp> inline typename resize_policy<_Tp>::size_type resize_policy<_Tp>:: get_new_size_for_arbitrary(size_type size) const { size_type ret = min_size; while (ret < size) ret *= factor; return ret; } template<typename _Tp> inline void resize_policy<_Tp>:: notify_grow_resize() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(m_grow_size >= min_size); m_grow_size *= factor; m_shrink_size = m_grow_size / ratio; PB_DS_ASSERT_VALID((*this)) } template<typename _Tp> inline void resize_policy<_Tp>:: notify_shrink_resize() { PB_DS_ASSERT_VALID((*this)) m_shrink_size /= factor; if (m_shrink_size == 1) m_shrink_size = 0; m_grow_size = std::max(m_grow_size / factor, min_size); PB_DS_ASSERT_VALID((*this)) } template<typename _Tp> inline void resize_policy<_Tp>:: notify_arbitrary(size_type actual_size) { m_grow_size = actual_size; m_shrink_size = m_grow_size / ratio; PB_DS_ASSERT_VALID((*this)) } #ifdef _GLIBCXX_DEBUG template<typename _Tp> void resize_policy<_Tp>:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_shrink_size == 0 || m_shrink_size * ratio == m_grow_size); PB_DS_DEBUG_VERIFY(m_grow_size >= min_size); } #endif #ifdef PB_DS_BINARY_HEAP_TRACE_ template<typename _Tp> void resize_policy<_Tp>:: trace() const { std::cerr << "shrink = " << m_shrink_size << " grow = " << m_grow_size << std::endl; } #endif } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/binary_heap_/policy_access_fn_imps.hpp 0000644 00000003556 15146341150 0020111 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/policy_access_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return (*this); } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return (*this); } c++/8/ext/pb_ds/detail/binary_heap_/find_fn_imps.hpp 0000644 00000005045 15146341150 0016204 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/find_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); return top_imp(s_no_throw_copies_ind); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top_imp(true_type) const { return *m_a_entries; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top_imp(false_type) const { return **m_a_entries; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: left_child(size_type i) { return i * 2 + 1; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: right_child(size_type i) { return i * 2 + 2; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: parent(size_type i) { return (i - 1) / 2; } c++/8/ext/pb_ds/detail/binary_heap_/entry_pred.hpp 0000644 00000005341 15146341150 0015723 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/entry_pred.hpp * Contains an implementation class for a binary_heap. */ #ifndef PB_DS_BINARY_HEAP_ENTRY_PRED_HPP #define PB_DS_BINARY_HEAP_ENTRY_PRED_HPP namespace __gnu_pbds { namespace detail { /// Entry predicate primary class template. template<typename _VTp, typename Pred, typename _Alloc, bool No_Throw> struct entry_pred; /// Specialization, true. template<typename _VTp, typename Pred, typename _Alloc> struct entry_pred<_VTp, Pred, _Alloc, true> { typedef Pred type; }; /// Specialization, false. template<typename _VTp, typename Pred, typename _Alloc> struct entry_pred<_VTp, Pred, _Alloc, false> { private: typedef typename _Alloc::template rebind<_VTp> __rebind_v; public: typedef typename __rebind_v::other::const_pointer entry; struct type : public Pred { inline type() { } inline type(const Pred& other) : Pred(other) { } inline bool operator()(entry p_v) const { return Pred::operator()(*p_v); } }; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BINARY_HEAP_ENTRY_PRED_HPP c++/8/ext/pb_ds/detail/binary_heap_/point_const_iterator.hpp 0000644 00000010537 15146341150 0020023 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/point_const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_BINARY_HEAP_CONST_FIND_ITERATOR_HPP #define PB_DS_BINARY_HEAP_CONST_FIND_ITERATOR_HPP #include <ext/pb_ds/tag_and_trait.hpp> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { /// Const point-type iterator. template<typename Value_Type, typename Entry, bool Simple, typename _Alloc> class binary_heap_point_const_iterator_ { protected: typedef typename _Alloc::template rebind<Entry>::other::pointer entry_pointer; public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef Value_Type value_type; /// Iterator's pointer type. typedef typename _Alloc::template rebind<value_type>::other::pointer pointer; /// Iterator's const pointer type. typedef typename _Alloc::template rebind<value_type>::other::const_pointer const_pointer; /// Iterator's reference type. typedef typename _Alloc::template rebind<value_type>::other::reference reference; /// Iterator's const reference type. typedef typename _Alloc::template rebind<value_type>::other::const_reference const_reference; inline binary_heap_point_const_iterator_(entry_pointer p_e) : m_p_e(p_e) { } /// Default constructor. inline binary_heap_point_const_iterator_() : m_p_e(0) { } /// Copy constructor. inline binary_heap_point_const_iterator_(const binary_heap_point_const_iterator_& other) : m_p_e(other.m_p_e) { } /// Access. inline const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_e != 0); return to_ptr(integral_constant<int, Simple>()); } /// Access. inline const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_e != 0); return *to_ptr(integral_constant<int, Simple>()); } /// Compares content to a different iterator object. inline bool operator==(const binary_heap_point_const_iterator_& other) const { return m_p_e == other.m_p_e; } /// Compares content (negatively) to a different iterator object. inline bool operator!=(const binary_heap_point_const_iterator_& other) const { return m_p_e != other.m_p_e; } private: inline const_pointer to_ptr(true_type) const { return m_p_e; } inline const_pointer to_ptr(false_type) const { return *m_p_e; } public: entry_pointer m_p_e; }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/binary_heap_/erase_fn_imps.hpp 0000644 00000012600 15146341150 0016356 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/erase_fn_imps.hpp * Contains an implementation class for a binary_heap. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { for (size_type i = 0; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); __try { const size_type new_size = resize_policy::get_new_size_for_arbitrary(0); entry_pointer new_entries = s_entry_allocator.allocate(new_size); resize_policy::notify_arbitrary(new_size); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; m_a_entries = new_entries; } __catch(...) { } m_size = 0; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_at(entry_pointer a_entries, size_type i, false_type) { a_entries[i]->~value_type(); s_value_allocator.deallocate(a_entries[i], 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_at(entry_pointer, size_type, true_type) { } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); pop_heap(); erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind); resize_for_erase_if_needed(); _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC template<typename Pred> typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) typedef typename entry_pred<value_type, Pred, _Alloc, simple_value>::type pred_t; const size_type left = partition(pred_t(pred)); _GLIBCXX_DEBUG_ASSERT(m_size >= left); const size_type ersd = m_size - left; for (size_type i = left; i < m_size; ++i) erase_at(m_a_entries, i, s_no_throw_copies_ind); __try { const size_type new_size = resize_policy::get_new_size_for_arbitrary(left); entry_pointer new_entries = s_entry_allocator.allocate(new_size); std::copy(m_a_entries, m_a_entries + left, new_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; resize_policy::notify_arbitrary(m_actual_size); } __catch(...) { }; m_size = left; make_heap(); PB_DS_ASSERT_VALID((*this)) return ersd; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(!empty()); const size_type fix_pos = it.m_p_e - m_a_entries; std::swap(*it.m_p_e, m_a_entries[m_size - 1]); erase_at(m_a_entries, m_size - 1, s_no_throw_copies_ind); resize_for_erase_if_needed(); _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; _GLIBCXX_DEBUG_ASSERT(fix_pos <= m_size); if (fix_pos != m_size) fix(m_a_entries + fix_pos); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: resize_for_erase_if_needed() { if (!resize_policy::resize_needed_for_shrink(m_size)) return; __try { const size_type new_size = resize_policy::get_new_size_for_shrink(); entry_pointer new_entries = s_entry_allocator.allocate(new_size); resize_policy::notify_shrink_resize(); _GLIBCXX_DEBUG_ASSERT(m_size > 0); std::copy(m_a_entries, m_a_entries + m_size - 1, new_entries); s_entry_allocator.deallocate(m_a_entries, m_actual_size); m_actual_size = new_size; m_a_entries = new_entries; } __catch(...) { } } PB_DS_CLASS_T_DEC template<typename Pred> typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: partition(Pred pred) { size_type left = 0; size_type right = m_size - 1; while (right + 1 != left) { _GLIBCXX_DEBUG_ASSERT(left <= m_size); if (!pred(m_a_entries[left])) ++left; else if (pred(m_a_entries[right])) --right; else { _GLIBCXX_DEBUG_ASSERT(left < right); std::swap(m_a_entries[left], m_a_entries[right]); ++left; --right; } } return left; } c++/8/ext/pb_ds/detail/binary_heap_/const_iterator.hpp 0000644 00000010362 15146341150 0016606 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binary_heap_/const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_BINARY_HEAP_CONST_ITERATOR_HPP #define PB_DS_BINARY_HEAP_CONST_ITERATOR_HPP #include <ext/pb_ds/detail/binary_heap_/point_const_iterator.hpp> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #define PB_DS_BIN_HEAP_CIT_BASE \ binary_heap_point_const_iterator_<Value_Type, Entry, Simple, _Alloc> /// Const point-type iterator. template<typename Value_Type, typename Entry, bool Simple, typename _Alloc> class binary_heap_const_iterator_ : public PB_DS_BIN_HEAP_CIT_BASE { private: typedef PB_DS_BIN_HEAP_CIT_BASE base_type; typedef typename base_type::entry_pointer entry_pointer; public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef typename base_type::value_type value_type; /// Iterator's pointer type. typedef typename base_type::pointer pointer; /// Iterator's const pointer type. typedef typename base_type::const_pointer const_pointer; /// Iterator's reference type. typedef typename base_type::reference reference; /// Iterator's const reference type. typedef typename base_type::const_reference const_reference; inline binary_heap_const_iterator_(entry_pointer p_e) : base_type(p_e) { } /// Default constructor. inline binary_heap_const_iterator_() { } /// Copy constructor. inline binary_heap_const_iterator_(const binary_heap_const_iterator_& other) : base_type(other) { } /// Compares content to a different iterator object. inline bool operator==(const binary_heap_const_iterator_& other) const { return base_type::m_p_e == other.m_p_e; } /// Compares content (negatively) to a different iterator object. inline bool operator!=(const binary_heap_const_iterator_& other) const { return base_type::m_p_e != other.m_p_e; } inline binary_heap_const_iterator_& operator++() { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_e != 0); inc(); return *this; } inline binary_heap_const_iterator_ operator++(int) { binary_heap_const_iterator_ ret_it(base_type::m_p_e); operator++(); return ret_it; } private: void inc() { ++base_type::m_p_e; } }; #undef PB_DS_BIN_HEAP_CIT_BASE } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp 0000644 00000004144 15146341150 0021703 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/debug_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_pointer_valid(const entry_pointer p_e, true_type, const char* __file, int __line) const { debug_base::check_key_exists(PB_DS_V2F(p_e->m_value), __file, __line); comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value)); PB_DS_DEBUG_VERIFY(p_e->m_hash == pos_hash_pair.second); } #endif c++/8/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp 0000644 00000013237 15146341150 0023244 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/constructor_destructor_fn_imps.hpp * Contains implementations of cc_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_allocator PB_DS_CLASS_C_DEC::s_entry_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::entry_pointer_allocator PB_DS_CLASS_C_DEC::s_entry_pointer_allocator; PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME() : ranged_hash_fn_base(resize_base::get_nearest_larger_size(1)), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn) : ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn) : PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { std::fill(m_entries, m_entries + m_num_e, (entry_pointer)0); Resize_Policy::notify_cleared(); ranged_hash_fn_base::notify_resized(m_num_e); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Hash_Fn& r_comb_hash_fn) : PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, r_comb_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const Hash_Fn& r_hash_fn, const Eq_Fn& r_eq_fn, const Comb_Hash_Fn& r_comb_hash_fn, const Resize_Policy& r_resize_policy) : PB_DS_HASH_EQ_FN_C_DEC(r_eq_fn), Resize_Policy(r_resize_policy), ranged_hash_fn_base(resize_base::get_nearest_larger_size(1), r_hash_fn, r_comb_hash_fn), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_CC_HASH_NAME(const PB_DS_CLASS_C_DEC& other) : PB_DS_HASH_EQ_FN_C_DEC(other), resize_base(other), ranged_hash_fn_base(other), m_num_e(resize_base::get_nearest_larger_size(1)), m_num_used_e(0), m_entries(s_entry_pointer_allocator.allocate(m_num_e)) { initialize(); PB_DS_ASSERT_VALID((*this)) __try { copy_from_range(other.begin(), other.end()); } __catch(...) { deallocate_all(); __throw_exception_again; } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~PB_DS_CC_HASH_NAME() { deallocate_all(); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) std::swap(m_entries, other.m_entries); std::swap(m_num_e, other.m_num_e); std::swap(m_num_used_e, other.m_num_used_e); ranged_hash_fn_base::swap(other); hash_eq_fn_base::swap(other); resize_base::swap(other); _GLIBCXX_DEBUG_ONLY(debug_base::swap(other)); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_all() { clear(); s_entry_pointer_allocator.deallocate(m_entries, m_num_e); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { std::fill(m_entries, m_entries + m_num_e, entry_pointer(0)); Resize_Policy::notify_resized(m_num_e); Resize_Policy::notify_cleared(); ranged_hash_fn_base::notify_resized(m_num_e); } c++/8/ext/pb_ds/detail/cc_hash_table_map_/info_fn_imps.hpp 0000644 00000006047 15146341150 0017335 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/info_fn_imps.hpp * Contains implementations of cc_ht_map_'s entire container info related * functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_num_used_e; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return m_entry_allocator.max_size(); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (size() == 0); } PB_DS_CLASS_T_DEC template<typename Other_HT_Map_Type> bool PB_DS_CLASS_C_DEC:: operator==(const Other_HT_Map_Type& other) const { return cmp_with_other(other); } PB_DS_CLASS_T_DEC template<typename Other_Map_Type> bool PB_DS_CLASS_C_DEC:: cmp_with_other(const Other_Map_Type& other) const { if (size() != other.size()) return false; for (typename Other_Map_Type::const_iterator it = other.begin(); it != other.end(); ++it) { key_const_reference r_key =(key_const_reference)PB_DS_V2F(*it); mapped_const_pointer p_mapped_value = const_cast<PB_DS_CLASS_C_DEC& >(*this). find_key_pointer(r_key, traits_base::m_store_extra_indicator); if (p_mapped_value == 0) return false; #ifdef PB_DS_DATA_TRUE_INDICATOR if (p_mapped_value->second != it->second) return false; #endif } return true; } PB_DS_CLASS_T_DEC template<typename Other_HT_Map_Type> bool PB_DS_CLASS_C_DEC:: operator!=(const Other_HT_Map_Type& other) const { return !operator==(other); } c++/8/ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp 0000644 00000005150 15146341150 0020410 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/iterators_fn_imps.hpp * Contains implementations of cc_ht_map_'s iterators related functions, e.g., * begin(). */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC::s_end_it; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC::s_const_end_it; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { pointer p_value; std::pair<entry_pointer, size_type> pos; get_start_it_state(p_value, pos); return iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return s_end_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { pointer p_value; std::pair<entry_pointer, size_type> pos; get_start_it_state(p_value, pos); return const_iterator(p_value, pos, this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return s_const_end_it; } c++/8/ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp 0000644 00000006231 15146341150 0021713 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/erase_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s erase related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_in_pos_imp(key_const_reference r_key, const comp_hash& r_pos_hash_pair) { PB_DS_ASSERT_VALID((*this)) entry_pointer p_e = m_entries[r_pos_hash_pair.first]; resize_base::notify_erase_search_start(); if (p_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, r_pos_hash_pair.second)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(m_entries[r_pos_hash_pair.first]); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } while (true) { entry_pointer p_next_e = p_e->m_p_next; if (p_next_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_next_e->m_value), p_next_e->m_hash, r_key, r_pos_hash_pair.second)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(p_e->m_p_next); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } resize_base::notify_erase_search_collision(); p_e = p_next_e; } } c++/8/ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp 0000644 00000005205 15146341150 0017463 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/debug_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { debug_base::check_size(m_num_used_e, __file, __line); assert_entry_pointer_array_valid(m_entries, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_pointer_array_valid(const entry_pointer_array a_p_entries, const char* __file, int __line) const { size_type iterated_num_used_e = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { entry_pointer p_e = a_p_entries[pos]; while (p_e != 0) { ++iterated_num_used_e; assert_entry_pointer_valid(p_e, traits_base::m_store_extra_indicator, __file, __line); p_e = p_e->m_p_next; } } PB_DS_DEBUG_VERIFY(iterated_num_used_e == m_num_used_e); } #include <ext/pb_ds/detail/cc_hash_table_map_/debug_store_hash_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp> #endif c++/8/ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp 0000644 00000007736 15146341150 0017711 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/resize_fn_imps.hpp * Contains implementations of cc_ht_map_'s resize related functions. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: do_resize_if_needed() { if (!resize_base::is_resize_needed()) return false; resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); return true; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: do_resize(size_type len) { resize_imp(resize_base::get_nearest_larger_size(len)); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: do_resize_if_needed_no_throw() { if (!resize_base::is_resize_needed()) return; __try { resize_imp(resize_base::get_new_size(m_num_e, m_num_used_e)); } __catch(...) { } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp(size_type new_size) { PB_DS_ASSERT_VALID((*this)) if (new_size == m_num_e) return; const size_type old_size = m_num_e; entry_pointer_array a_p_entries_resized; // Following line might throw an exception. ranged_hash_fn_base::notify_resized(new_size); __try { // Following line might throw an exception. a_p_entries_resized = s_entry_pointer_allocator.allocate(new_size); m_num_e = new_size; } __catch(...) { ranged_hash_fn_base::notify_resized(old_size); __throw_exception_again; } // At this point no exceptions can be thrown. resize_imp_no_exceptions(new_size, a_p_entries_resized, old_size); Resize_Policy::notify_resized(new_size); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: resize_imp_no_exceptions(size_type new_size, entry_pointer_array a_p_entries_resized, size_type old_size) { std::fill(a_p_entries_resized, a_p_entries_resized + m_num_e, entry_pointer(0)); for (size_type pos = 0; pos < old_size; ++pos) { entry_pointer p_e = m_entries[pos]; while (p_e != 0) p_e = resize_imp_no_exceptions_reassign_pointer(p_e, a_p_entries_resized, traits_base::m_store_extra_indicator); } m_num_e = new_size; _GLIBCXX_DEBUG_ONLY(assert_entry_pointer_array_valid(a_p_entries_resized, __FILE__, __LINE__);) s_entry_pointer_allocator.deallocate(m_entries, old_size); m_entries = a_p_entries_resized; PB_DS_ASSERT_VALID((*this)) } #include <ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp> c++/8/ext/pb_ds/detail/cc_hash_table_map_/find_store_hash_fn_imps.hpp 0000644 00000003363 15146341150 0021537 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/find_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s find related functions, * when the hash value is stored. */ c++/8/ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp 0000644 00000003550 15146341150 0017702 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/insert_fn_imps.hpp * Contains implementations of cc_ht_map_'s insert related functions. */ #include <ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp> c++/8/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp 0000644 00000004402 15146341150 0025455 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/constructor_destructor_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(const_reference r_val, size_type pos, true_type) { // Following lines might throw an exception. entry_pointer p = get_entry(r_val, traits_base::s_no_throw_copies_indicator); // At this point no exceptions can be thrown. p->m_p_next = m_entries[pos]; p->m_hash = ranged_hash_fn_base::operator()((key_const_reference)(PB_DS_V2F(p->m_value))).second; m_entries[pos] = p; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(r_key);) } c++/8/ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp 0000644 00000005612 15146341150 0020573 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/entry_list_fn_imps.hpp * Contains implementations of cc_ht_map_'s entry-list related functions. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: deallocate_links_in_list(entry_pointer p_e) { while (p_e != 0) { entry_pointer p_dealloc_e = p_e; p_e = p_e->m_p_next; s_entry_allocator.deallocate(p_dealloc_e, 1); } } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: get_entry(const_reference r_val, true_type) { // Following line might throw an exception. entry_pointer p_e = s_entry_allocator.allocate(1); // Following lines* cannot* throw an exception. new (&p_e->m_value) value_type(r_val); return p_e; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: get_entry(const_reference r_val, false_type) { // Following line might throw an exception. entry_pointer p_e = s_entry_allocator.allocate(1); cond_dealtor_t cond(p_e); // Following lines might throw an exception. new (&p_e->m_value) value_type(r_val); cond.set_no_action(); return p_e; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: rels_entry(entry_pointer p_e) { // The following lines cannot throw exceptions (unless if key-data dtors do). p_e->m_value.~value_type(); s_entry_allocator.deallocate(p_e, 1); } c++/8/ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp 0000644 00000006300 15146341150 0022404 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s erase related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) return erase_in_pos_imp(r_key, ranged_hash_fn_base::operator()(r_key)); } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase_in_pos_imp(key_const_reference r_key, size_type pos) { PB_DS_ASSERT_VALID((*this)) entry_pointer p_e = m_entries[pos]; resize_base::notify_erase_search_start(); if (p_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(m_entries[pos]); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } while (true) { entry_pointer p_next_e = p_e->m_p_next; if (p_next_e == 0) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) PB_DS_ASSERT_VALID((*this)) return false; } if (hash_eq_fn_base::operator()(PB_DS_V2F(p_next_e->m_value), r_key)) { resize_base::notify_erase_search_end(); PB_DS_CHECK_KEY_EXISTS(r_key) erase_entry_pointer(p_e->m_p_next); do_resize_if_needed_no_throw(); PB_DS_ASSERT_VALID((*this)) return true; } resize_base::notify_erase_search_collision(); p_e = p_next_e; } } c++/8/ext/pb_ds/detail/cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp 0000644 00000005472 15146341150 0022446 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/cond_key_dtor_entry_dealtor.hpp * Contains a conditional key destructor, used for exception handling. */ namespace __gnu_pbds { namespace detail { /// Conditional dey destructor, cc_hash. template<typename HT_Map> class cond_dealtor { public: typedef typename HT_Map::entry entry; typedef typename HT_Map::entry_allocator entry_allocator; typedef typename HT_Map::key_type key_type; cond_dealtor(entry_allocator* p_a, entry* p_e) : m_p_a(p_a), m_p_e(p_e), m_key_destruct(false), m_no_action_destructor(false) { } inline ~cond_dealtor(); void set_key_destruct() { m_key_destruct = true; } void set_no_action_destructor() { m_no_action_destructor = true; } protected: entry_allocator* const m_p_a; entry* const m_p_e; bool m_key_destruct; bool m_no_action_destructor; }; template<typename HT_Map> inline cond_dealtor<HT_Map>:: ~cond_dealtor() { if (m_no_action_destructor) return; if (m_key_destruct) m_p_e->m_value.first.~key_type(); m_p_a->deallocate(m_p_e, 1); } } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/cc_hash_table_map_/insert_store_hash_fn_imps.hpp 0000644 00000005162 15146341150 0022122 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/insert_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s insert related functions, * when the hash value is stored. */ PB_DS_CLASS_T_DEC inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, true_type) { PB_DS_ASSERT_VALID((*this)) key_const_reference key = PB_DS_V2F(r_val); comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(key); entry_pointer p_e = m_entries[pos_hash_pair.first]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, key, pos_hash_pair.second)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(key) return std::make_pair(&p_e->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(key) return std::make_pair(insert_new_imp(r_val, pos_hash_pair), true); } c++/8/ext/pb_ds/detail/cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp 0000644 00000005072 15146341150 0022616 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/insert_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s insert related functions, * when the hash value is not stored. */ PB_DS_CLASS_T_DEC inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert_imp(const_reference r_val, false_type) { PB_DS_ASSERT_VALID((*this)) key_const_reference r_key = PB_DS_V2F(r_val); const size_type pos = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(r_key) return std::make_pair(&p_e->m_value, false); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return std::make_pair(insert_new_imp(r_val, pos), true); } c++/8/ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp 0000644 00000004473 15146341150 0017501 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/trace_fn_imps.hpp * Contains implementations of cc_ht_map_'s trace-mode functions. */ #ifdef PB_DS_HT_MAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << static_cast<unsigned long>(m_num_e) << " " << static_cast<unsigned long>(m_num_used_e) << std::endl; for (size_type i = 0; i < m_num_e; ++i) { std::cerr << static_cast<unsigned long>(i) << " "; trace_list(m_entries[i]); std::cerr << std::endl; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_list(const_entry_pointer p_l) const { size_type iterated_num_used_e = 0; while (p_l != 0) { std::cerr << PB_DS_V2F(p_l->m_value) << " "; p_l = p_l->m_p_next; } } #endif c++/8/ext/pb_ds/detail/cc_hash_table_map_/cmp_fn_imps.hpp 0000644 00000005315 15146341150 0017156 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/cmp_fn_imps.hpp * Contains implementations of cc_ht_map_'s entire container comparison related * functions. */ PB_DS_CLASS_T_DEC template<typename Other_HT_Map_Type> bool PB_DS_CLASS_C_DEC:: operator==(const Other_HT_Map_Type& other) const { return cmp_with_other(other); } PB_DS_CLASS_T_DEC template<typename Other_Map_Type> bool PB_DS_CLASS_C_DEC:: cmp_with_other(const Other_Map_Type& other) const { if (size() != other.size()) return false; for (typename Other_Map_Type::const_iterator it = other.begin(); it != other.end(); ++it) { key_const_reference r_key = key_const_reference(PB_DS_V2F(*it)); mapped_const_pointer p_mapped_value = const_cast<PB_DS_CLASS_C_DEC& >(*this). find_key_pointer(r_key, traits_base::m_store_extra_indicator); if (p_mapped_value == 0) return false; #ifdef PB_DS_DATA_TRUE_INDICATOR if (p_mapped_value->second != it->second) return false; #endif } return true; } PB_DS_CLASS_T_DEC template<typename Other_HT_Map_Type> bool PB_DS_CLASS_C_DEC:: operator!=(const Other_HT_Map_Type& other) const { return !operator==(other); } c++/8/ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp 0000644 00000004661 15146341150 0021222 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/policy_access_fn_imps.hpp * Contains implementations of cc_ht_map_'s policy access * functions. */ PB_DS_CLASS_T_DEC Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() { return *this; } PB_DS_CLASS_T_DEC const Hash_Fn& PB_DS_CLASS_C_DEC:: get_hash_fn() const { return *this; } PB_DS_CLASS_T_DEC Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() { return *this; } PB_DS_CLASS_T_DEC const Eq_Fn& PB_DS_CLASS_C_DEC:: get_eq_fn() const { return *this; } PB_DS_CLASS_T_DEC Comb_Hash_Fn& PB_DS_CLASS_C_DEC:: get_comb_hash_fn() { return *this; } PB_DS_CLASS_T_DEC const Comb_Hash_Fn& PB_DS_CLASS_C_DEC:: get_comb_hash_fn() const { return *this; } PB_DS_CLASS_T_DEC Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() { return *this; } PB_DS_CLASS_T_DEC const Resize_Policy& PB_DS_CLASS_C_DEC:: get_resize_policy() const { return *this; } c++/8/ext/pb_ds/detail/cc_hash_table_map_/resize_store_hash_fn_imps.hpp 0000644 00000004342 15146341150 0022116 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/resize_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s resize related functions, when the * hash value is stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: resize_imp_no_exceptions_reassign_pointer(entry_pointer p_e, entry_pointer_array a_p_entries_resized, true_type) { const comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash); entry_pointer const p_next_e = p_e->m_p_next; p_e->m_p_next = a_p_entries_resized[pos_hash_pair.first]; a_p_entries_resized[pos_hash_pair.first] = p_e; return p_next_e; } c++/8/ext/pb_ds/detail/cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp 0000644 00000003720 15146341150 0022376 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/debug_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s debug-mode functions. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_entry_pointer_valid(const entry_pointer p, false_type, const char* __file, int __line) const { debug_base::check_key_exists(PB_DS_V2F(p->m_value), __file, __line); } #endif c++/8/ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp 0000644 00000004262 15146341150 0026155 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/constructor_destructor_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s constructors, destructor, * and related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: constructor_insert_new_imp(mapped_const_reference r_val, size_type pos, false_type) { // Following lines might throw an exception. entry_pointer p = get_entry(r_val, traits_base::s_no_throw_copies_indicator); // At this point no exceptions can be thrown. p->m_p_next = m_entries[pos]; m_entries[pos] = p; _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(r_key);) } c++/8/ext/pb_ds/detail/cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp 0000644 00000004302 15146341150 0022606 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/resize_no_store_hash_fn_imps.hpp * Contains implementations of cc_ht_map_'s resize related functions, when the * hash value is not stored. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::entry_pointer PB_DS_CLASS_C_DEC:: resize_imp_no_exceptions_reassign_pointer(entry_pointer p_e, entry_pointer_array a_p_entries_resized, false_type) { const size_type hash_pos = ranged_hash_fn_base::operator()(PB_DS_V2F(p_e->m_value)); entry_pointer const p_next_e = p_e->m_p_next; p_e->m_p_next = a_p_entries_resized[hash_pos]; a_p_entries_resized[hash_pos] = p_e; return p_next_e; } c++/8/ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp 0000644 00000004665 15146341150 0017326 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/find_fn_imps.hpp * Contains implementations of cc_ht_map_'s find related functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) return find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) return const_cast<PB_DS_CLASS_C_DEC& >(*this).find_key_pointer(r_key, traits_base::m_store_extra_indicator); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find_end() { return 0; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find_end() const { return 0; } c++/8/ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp 0000644 00000004075 15146341150 0017353 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/size_fn_imps.hpp * Contains implementations of cc_ht_map_'s entire container size related * functions. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return m_num_used_e; } PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (size() == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return s_entry_allocator.max_size(); } c++/8/ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp 0000644 00000006255 15146341150 0017502 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/erase_fn_imps.hpp * Contains implementations of cc_ht_map_'s erase related functions. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase_entry_pointer(entry_pointer& r_p_e) { _GLIBCXX_DEBUG_ONLY(debug_base::erase_existing(PB_DS_V2F(r_p_e->m_value))); entry_pointer p_e = r_p_e; r_p_e = r_p_e->m_p_next; rels_entry(p_e); _GLIBCXX_DEBUG_ASSERT(m_num_used_e > 0); resize_base::notify_erased(--m_num_used_e); } PB_DS_CLASS_T_DEC template<typename Pred> inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { size_type num_ersd = 0; for (size_type pos = 0; pos < m_num_e; ++pos) { while (m_entries[pos] != 0 && pred(m_entries[pos]->m_value)) { ++num_ersd; entry_pointer p_next_e = m_entries[pos]->m_p_next; erase_entry_pointer(m_entries[pos]); m_entries[pos] = p_next_e; } entry_pointer p_e = m_entries[pos]; while (p_e != 0 && p_e->m_p_next != 0) { if (pred(p_e->m_p_next->m_value)) { ++num_ersd; erase_entry_pointer(p_e->m_p_next); } else p_e = p_e->m_p_next; } } do_resize_if_needed_no_throw(); return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { for (size_type pos = 0; pos < m_num_e; ++pos) while (m_entries[pos] != 0) erase_entry_pointer(m_entries[pos]); do_resize_if_needed_no_throw(); resize_base::notify_cleared(); } #include <ext/pb_ds/detail/cc_hash_table_map_/erase_no_store_hash_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/erase_store_hash_fn_imps.hpp> c++/8/ext/pb_ds/detail/cc_hash_table_map_/cc_ht_map_.hpp 0000644 00000046761 15146341150 0016752 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file cc_hash_table_map_/cc_ht_map_.hpp * Contains an implementation class for cc_ht_map_. */ #include <utility> #include <iterator> #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/detail/hash_fn/ranged_hash_fn.hpp> #include <ext/pb_ds/detail/types_traits.hpp> #include <ext/pb_ds/exception.hpp> #include <ext/pb_ds/detail/eq_fn/hash_eq_fn.hpp> #ifdef _GLIBCXX_DEBUG #include <ext/pb_ds/detail/debug_map_base.hpp> #endif #ifdef PB_DS_HT_MAP_TRACE_ #include <iostream> #endif #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR #define PB_DS_CC_HASH_NAME cc_ht_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR #define PB_DS_CC_HASH_NAME cc_ht_set #endif #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Mapped, typename Hash_Fn, \ typename Eq_Fn, typename _Alloc, bool Store_Hash, \ typename Comb_Hash_Fn, typename Resize_Policy> #define PB_DS_CLASS_C_DEC \ PB_DS_CC_HASH_NAME<Key, Mapped, Hash_Fn, Eq_Fn, _Alloc, \ Store_Hash, Comb_Hash_Fn, Resize_Policy> #define PB_DS_HASH_EQ_FN_C_DEC \ hash_eq_fn<Key, Eq_Fn, _Alloc, Store_Hash> #define PB_DS_RANGED_HASH_FN_C_DEC \ ranged_hash_fn<Key, Hash_Fn, _Alloc, Comb_Hash_Fn, Store_Hash> #define PB_DS_CC_HASH_TRAITS_BASE \ types_traits<Key, Mapped, _Alloc, Store_Hash> #ifdef _GLIBCXX_DEBUG #define PB_DS_DEBUG_MAP_BASE_C_DEC \ debug_map_base<Key, Eq_Fn, \ typename _Alloc::template rebind<Key>::other::const_reference> #endif /** * A collision-chaining hash-based container. * * * @ingroup hash-detail * * @tparam Key Key type. * * @tparam Mapped Map type. * * @tparam Hash_Fn Hashing functor. * Default is __gnu_cxx::hash. * * @tparam Eq_Fn Equal functor. * Default std::equal_to<Key> * * @tparam _Alloc Allocator type. * * @tparam Store_Hash If key type stores extra metadata. * Defaults to false. * * @tparam Comb_Hash_Fn Combining hash functor. * If Hash_Fn is not null_type, then this * is the ranged-hash functor; otherwise, * this is the range-hashing functor. * XXX(See Design::Hash-Based Containers::Hash Policies.) * Default direct_mask_range_hashing. * * @tparam Resize_Policy Resizes hash. * Defaults to hash_standard_resize_policy, * using hash_exponential_size_policy and * hash_load_check_resize_trigger. * * * Bases are: detail::hash_eq_fn, Resize_Policy, detail::ranged_hash_fn, * detail::types_traits. (Optional: detail::debug_map_base.) */ template<typename Key, typename Mapped, typename Hash_Fn, typename Eq_Fn, typename _Alloc, bool Store_Hash, typename Comb_Hash_Fn, typename Resize_Policy > class PB_DS_CC_HASH_NAME: #ifdef _GLIBCXX_DEBUG protected PB_DS_DEBUG_MAP_BASE_C_DEC, #endif public PB_DS_HASH_EQ_FN_C_DEC, public Resize_Policy, public PB_DS_RANGED_HASH_FN_C_DEC, public PB_DS_CC_HASH_TRAITS_BASE { private: typedef PB_DS_CC_HASH_TRAITS_BASE traits_base; typedef typename traits_base::comp_hash comp_hash; typedef typename traits_base::value_type value_type_; typedef typename traits_base::pointer pointer_; typedef typename traits_base::const_pointer const_pointer_; typedef typename traits_base::reference reference_; typedef typename traits_base::const_reference const_reference_; struct entry : public traits_base::stored_data_type { typename _Alloc::template rebind<entry>::other::pointer m_p_next; }; typedef cond_dealtor<entry, _Alloc> cond_dealtor_t; typedef typename _Alloc::template rebind<entry>::other entry_allocator; typedef typename entry_allocator::pointer entry_pointer; typedef typename entry_allocator::const_pointer const_entry_pointer; typedef typename entry_allocator::reference entry_reference; typedef typename entry_allocator::const_reference const_entry_reference; typedef typename _Alloc::template rebind<entry_pointer>::other entry_pointer_allocator; typedef typename entry_pointer_allocator::pointer entry_pointer_array; typedef PB_DS_RANGED_HASH_FN_C_DEC ranged_hash_fn_base; typedef PB_DS_HASH_EQ_FN_C_DEC hash_eq_fn_base; typedef Resize_Policy resize_base; #ifdef _GLIBCXX_DEBUG typedef PB_DS_DEBUG_MAP_BASE_C_DEC debug_base; #endif #define PB_DS_GEN_POS std::pair<entry_pointer, typename _Alloc::size_type> #include <ext/pb_ds/detail/unordered_iterator/point_const_iterator.hpp> #include <ext/pb_ds/detail/unordered_iterator/point_iterator.hpp> #include <ext/pb_ds/detail/unordered_iterator/const_iterator.hpp> #include <ext/pb_ds/detail/unordered_iterator/iterator.hpp> #undef PB_DS_GEN_POS public: typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Comb_Hash_Fn comb_hash_fn; typedef Resize_Policy resize_policy; /// Value stores hash, true or false. enum { store_hash = Store_Hash }; typedef typename traits_base::key_type key_type; typedef typename traits_base::key_pointer key_pointer; typedef typename traits_base::key_const_pointer key_const_pointer; typedef typename traits_base::key_reference key_reference; typedef typename traits_base::key_const_reference key_const_reference; typedef typename traits_base::mapped_type mapped_type; typedef typename traits_base::mapped_pointer mapped_pointer; typedef typename traits_base::mapped_const_pointer mapped_const_pointer; typedef typename traits_base::mapped_reference mapped_reference; typedef typename traits_base::mapped_const_reference mapped_const_reference; typedef typename traits_base::value_type value_type; typedef typename traits_base::pointer pointer; typedef typename traits_base::const_pointer const_pointer; typedef typename traits_base::reference reference; typedef typename traits_base::const_reference const_reference; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef point_iterator_ point_iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef point_const_iterator_ point_iterator; #endif typedef point_const_iterator_ point_const_iterator; #ifdef PB_DS_DATA_TRUE_INDICATOR typedef iterator_ iterator; #endif #ifdef PB_DS_DATA_FALSE_INDICATOR typedef const_iterator_ iterator; #endif typedef const_iterator_ const_iterator; PB_DS_CC_HASH_NAME(); PB_DS_CC_HASH_NAME(const Hash_Fn&); PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&); PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&); PB_DS_CC_HASH_NAME(const Hash_Fn&, const Eq_Fn&, const Comb_Hash_Fn&, const Resize_Policy&); PB_DS_CC_HASH_NAME(const PB_DS_CLASS_C_DEC&); virtual ~PB_DS_CC_HASH_NAME(); void swap(PB_DS_CLASS_C_DEC&); template<typename It> void copy_from_range(It, It); void initialize(); inline size_type size() const; inline size_type max_size() const; /// True if size() == 0. inline bool empty() const; /// Return current hash_fn. Hash_Fn& get_hash_fn(); /// Return current const hash_fn. const Hash_Fn& get_hash_fn() const; /// Return current eq_fn. Eq_Fn& get_eq_fn(); /// Return current const eq_fn. const Eq_Fn& get_eq_fn() const; /// Return current comb_hash_fn. Comb_Hash_Fn& get_comb_hash_fn(); /// Return current const comb_hash_fn. const Comb_Hash_Fn& get_comb_hash_fn() const; /// Return current resize_policy. Resize_Policy& get_resize_policy(); /// Return current const resize_policy. const Resize_Policy& get_resize_policy() const; inline std::pair<point_iterator, bool> insert(const_reference r_val) { return insert_imp(r_val, traits_base::m_store_extra_indicator); } inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR return (subscript_imp(r_key, traits_base::m_store_extra_indicator)); #else insert(r_key); return traits_base::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline point_iterator find_end(); inline point_const_iterator find_end() const; inline bool erase(key_const_reference); template<typename Pred> inline size_type erase_if(Pred); void clear(); inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif #ifdef PB_DS_HT_MAP_TRACE_ void trace() const; #endif private: void deallocate_all(); inline bool do_resize_if_needed(); inline void do_resize_if_needed_no_throw(); void resize_imp(size_type); void do_resize(size_type); void resize_imp_no_exceptions(size_type, entry_pointer_array, size_type); inline entry_pointer resize_imp_no_exceptions_reassign_pointer(entry_pointer, entry_pointer_array, false_type); inline entry_pointer resize_imp_no_exceptions_reassign_pointer(entry_pointer, entry_pointer_array, true_type); void deallocate_links_in_list(entry_pointer); inline entry_pointer get_entry(const_reference, false_type); inline entry_pointer get_entry(const_reference, true_type); inline void rels_entry(entry_pointer); #ifdef PB_DS_DATA_TRUE_INDICATOR inline mapped_reference subscript_imp(key_const_reference r_key, false_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) const size_type pos = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(p_e->m_value.first, r_key)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(r_key) return (p_e->m_value.second); } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return insert_new_imp(value_type(r_key, mapped_type()), pos)->second; } inline mapped_reference subscript_imp(key_const_reference r_key, true_type) { _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos_hash_pair.first]; resize_base::notify_insert_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(p_e->m_value.first, p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_insert_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_insert_search_end(); if (p_e != 0) { PB_DS_CHECK_KEY_EXISTS(r_key) return p_e->m_value.second; } PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) return insert_new_imp(value_type(r_key, mapped_type()), pos_hash_pair)->second; } #endif inline std::pair<point_iterator, bool> insert_imp(const_reference, false_type); inline std::pair<point_iterator, bool> insert_imp(const_reference, true_type); inline pointer insert_new_imp(const_reference r_val, size_type pos) { if (do_resize_if_needed()) pos = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); // Following lines might throw an exception. entry_pointer p_e = get_entry(r_val, traits_base::m_no_throw_copies_indicator); // At this point no exceptions can be thrown. p_e->m_p_next = m_entries[pos]; m_entries[pos] = p_e; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } inline pointer insert_new_imp(const_reference r_val, comp_hash& r_pos_hash_pair) { // Following lines might throw an exception. if (do_resize_if_needed()) r_pos_hash_pair = ranged_hash_fn_base::operator()(PB_DS_V2F(r_val)); entry_pointer p_e = get_entry(r_val, traits_base::m_no_throw_copies_indicator); // At this point no exceptions can be thrown. p_e->m_hash = r_pos_hash_pair.second; p_e->m_p_next = m_entries[r_pos_hash_pair.first]; m_entries[r_pos_hash_pair.first] = p_e; resize_base::notify_inserted(++m_num_used_e); _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));) _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return &p_e->m_value; } inline pointer find_key_pointer(key_const_reference r_key, false_type) { entry_pointer p_e = m_entries[ranged_hash_fn_base::operator()(r_key)]; resize_base::notify_find_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), r_key)) { resize_base::notify_find_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_find_search_end(); #ifdef _GLIBCXX_DEBUG if (p_e == 0) PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) else PB_DS_CHECK_KEY_EXISTS(r_key) #endif return &p_e->m_value; } inline pointer find_key_pointer(key_const_reference r_key, true_type) { comp_hash pos_hash_pair = ranged_hash_fn_base::operator()(r_key); entry_pointer p_e = m_entries[pos_hash_pair.first]; resize_base::notify_find_search_start(); while (p_e != 0 && !hash_eq_fn_base::operator()(PB_DS_V2F(p_e->m_value), p_e->m_hash, r_key, pos_hash_pair.second)) { resize_base::notify_find_search_collision(); p_e = p_e->m_p_next; } resize_base::notify_find_search_end(); #ifdef _GLIBCXX_DEBUG if (p_e == 0) PB_DS_CHECK_KEY_DOES_NOT_EXIST(r_key) else PB_DS_CHECK_KEY_EXISTS(r_key) #endif return &p_e->m_value; } inline bool erase_in_pos_imp(key_const_reference, size_type); inline bool erase_in_pos_imp(key_const_reference, const comp_hash&); inline void erase_entry_pointer(entry_pointer&); #ifdef PB_DS_DATA_TRUE_INDICATOR void inc_it_state(pointer& r_p_value, std::pair<entry_pointer, size_type>& r_pos) const { inc_it_state((mapped_const_pointer& )r_p_value, r_pos); } #endif void inc_it_state(const_pointer& r_p_value, std::pair<entry_pointer, size_type>& r_pos) const { _GLIBCXX_DEBUG_ASSERT(r_p_value != 0); r_pos.first = r_pos.first->m_p_next; if (r_pos.first != 0) { r_p_value = &r_pos.first->m_value; return; } for (++r_pos.second; r_pos.second < m_num_e; ++r_pos.second) if (m_entries[r_pos.second] != 0) { r_pos.first = m_entries[r_pos.second]; r_p_value = &r_pos.first->m_value; return; } r_p_value = 0; } void get_start_it_state(pointer& r_p_value, std::pair<entry_pointer, size_type>& r_pos) const { for (r_pos.second = 0; r_pos.second < m_num_e; ++r_pos.second) if (m_entries[r_pos.second] != 0) { r_pos.first = m_entries[r_pos.second]; r_p_value = &r_pos.first->m_value; return; } r_p_value = 0; } #ifdef _GLIBCXX_DEBUG void assert_entry_pointer_array_valid(const entry_pointer_array, const char*, int) const; void assert_entry_pointer_valid(const entry_pointer, true_type, const char*, int) const; void assert_entry_pointer_valid(const entry_pointer, false_type, const char*, int) const; #endif #ifdef PB_DS_HT_MAP_TRACE_ void trace_list(const_entry_pointer) const; #endif private: #ifdef PB_DS_DATA_TRUE_INDICATOR friend class iterator_; #endif friend class const_iterator_; static entry_allocator s_entry_allocator; static entry_pointer_allocator s_entry_pointer_allocator; static iterator s_end_it; static const_iterator s_const_end_it; static point_iterator s_find_end_it; static point_const_iterator s_const_find_end_it; size_type m_num_e; size_type m_num_used_e; entry_pointer_array m_entries; enum { store_hash_ok = !Store_Hash || !is_same<Hash_Fn, __gnu_pbds::null_type>::value }; PB_DS_STATIC_ASSERT(sth, store_hash_ok); }; #include <ext/pb_ds/detail/cc_hash_table_map_/constructor_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/entry_list_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/find_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/resize_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/size_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/policy_access_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/iterators_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/cc_hash_table_map_/trace_fn_imps.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_HASH_EQ_FN_C_DEC #undef PB_DS_RANGED_HASH_FN_C_DEC #undef PB_DS_CC_HASH_TRAITS_BASE #undef PB_DS_DEBUG_MAP_BASE_C_DEC #undef PB_DS_CC_HASH_NAME } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/trie_policy/trie_policy_base.hpp 0000644 00000013327 15146341150 0016771 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/trie_policy_base.hpp * Contains an implementation of trie_policy_base. */ #ifndef PB_DS_TRIE_POLICY_BASE_HPP #define PB_DS_TRIE_POLICY_BASE_HPP #include <ext/pb_ds/detail/branch_policy/branch_policy.hpp> namespace __gnu_pbds { namespace detail { /// Base class for trie policies. template<typename Node_CItr, typename Node_Itr, typename _ATraits, typename _Alloc> class trie_policy_base : public branch_policy<Node_CItr, Node_Itr, _Alloc> { typedef branch_policy<Node_CItr, Node_Itr, _Alloc> base_type; public: typedef _ATraits access_traits; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef null_type metadata_type; typedef Node_CItr node_const_iterator; typedef Node_Itr node_iterator; typedef typename node_const_iterator::value_type const_iterator; typedef typename node_iterator::value_type iterator; typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; protected: virtual const_iterator end() const = 0; virtual iterator end() = 0; virtual node_const_iterator node_begin() const = 0; virtual node_iterator node_begin() = 0; virtual node_const_iterator node_end() const = 0; virtual node_iterator node_end() = 0; virtual const access_traits& get_access_traits() const = 0; private: typedef typename access_traits::const_iterator e_const_iterator; typedef std::pair<e_const_iterator, e_const_iterator> prefix_range_t; protected: static size_type common_prefix_len(node_iterator, e_const_iterator, e_const_iterator, const access_traits&); static iterator leftmost_it(node_iterator); static iterator rightmost_it(node_iterator); static bool less(e_const_iterator, e_const_iterator, e_const_iterator, e_const_iterator, const access_traits&); }; #define PB_DS_CLASS_T_DEC \ template<typename Node_CItr, typename Node_Itr, \ typename _ATraits, typename _Alloc> #define PB_DS_CLASS_C_DEC \ trie_policy_base<Node_CItr, Node_Itr, _ATraits, _Alloc> PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: common_prefix_len(node_iterator nd_it, e_const_iterator b_r, e_const_iterator e_r, const access_traits& r_traits) { prefix_range_t pref_range = nd_it.valid_prefix(); e_const_iterator b_l = pref_range.first; e_const_iterator e_l = pref_range.second; const size_type range_length_l = std::distance(b_l, e_l); const size_type range_length_r = std::distance(b_r, e_r); if (range_length_r < range_length_l) { std::swap(b_l, b_r); std::swap(e_l, e_r); } size_type ret = 0; while (b_l != e_l) { if (r_traits.e_pos(*b_l) != r_traits.e_pos(*b_r)) return ret; ++ret; ++b_l; ++b_r; } return ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: leftmost_it(node_iterator nd_it) { if (nd_it.num_children() == 0) return *nd_it; return leftmost_it(nd_it.get_child(0)); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: rightmost_it(node_iterator nd_it) { const size_type num_children = nd_it.num_children(); if (num_children == 0) return *nd_it; return rightmost_it(nd_it.get_child(num_children - 1)); } PB_DS_CLASS_T_DEC bool PB_DS_CLASS_C_DEC:: less(e_const_iterator b_l, e_const_iterator e_l, e_const_iterator b_r, e_const_iterator e_r, const access_traits& r_traits) { while (b_l != e_l) { if (b_r == e_r) return false; size_type l_pos = r_traits.e_pos(*b_l); size_type r_pos = r_traits.e_pos(*b_r); if (l_pos != r_pos) return (l_pos < r_pos); ++b_l; ++b_r; } return b_r != e_r; } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_TRIE_POLICY_BASE_HPP c++/8/ext/pb_ds/detail/trie_policy/trie_string_access_traits_imp.hpp 0000644 00000005753 15146341150 0021566 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/trie_string_access_traits_imp.hpp * Contains a policy for extracting character positions from * a string for a vector-based PATRICIA tree */ PB_DS_CLASS_T_DEC detail::integral_constant<int, Reverse> PB_DS_CLASS_C_DEC::s_rev_ind; PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: e_pos(e_type e) { return (static_cast<size_type>(e - min_e_val)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin(key_const_reference r_key) { return (begin_imp(r_key, s_rev_ind)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end(key_const_reference r_key) { return (end_imp(r_key, s_rev_ind)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin_imp(key_const_reference r_key, detail::false_type) { return (r_key.begin()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin_imp(key_const_reference r_key, detail::true_type) { return (r_key.rbegin()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end_imp(key_const_reference r_key, detail::false_type) { return (r_key.end()); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end_imp(key_const_reference r_key, detail::true_type) { return (r_key.rend()); } c++/8/ext/pb_ds/detail/trie_policy/sample_trie_access_traits.hpp 0000644 00000005231 15146341150 0020663 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/sample_trie_access_traits.hpp * Contains a sample probe policy. */ #ifndef PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP #define PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP namespace __gnu_pbds { /// A sample trie element access traits. struct sample_trie_access_traits { typedef std::size_t size_type; typedef std::string key_type; typedef typename _Alloc::template rebind<key_type> __rebind_k; typedef typename __rebind_k::other::const_reference key_const_reference; typedef std::string::const_iterator const_iterator; /// Element type. typedef char e_type; enum { max_size = 4 }; /// Returns a const_iterator to the first element of r_key. inline static const_iterator begin(key_const_reference); /// Returns a const_iterator to the after-last element of r_key. inline static const_iterator end(key_const_reference); /// Maps an element to a position. inline static size_type e_pos(e_type); }; } #endif // #ifndef PB_DS_SAMPLE_TRIE_E_ACCESS_TRAITS_HPP c++/8/ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp 0000644 00000006412 15146341150 0020137 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/node_metadata_selector.hpp * Contains an implementation class for tries. */ #ifndef PB_DS_TRIE_NODE_METADATA_DISPATCH_HPP #define PB_DS_TRIE_NODE_METADATA_DISPATCH_HPP #include <ext/pb_ds/detail/branch_policy/null_node_metadata.hpp> #include <ext/pb_ds/detail/types_traits.hpp> namespace __gnu_pbds { namespace detail { /** * @addtogroup traits Traits * @{ */ /// Trie metadata helper. template<typename Node_Update, bool _BTp> struct trie_metadata_helper; /// Specialization, false. template<typename Node_Update> struct trie_metadata_helper<Node_Update, false> { typedef typename Node_Update::metadata_type type; }; /// Specialization, true. template<typename Node_Update> struct trie_metadata_helper<Node_Update, true> { typedef null_type type; }; /// Trie node metadata dispatch. template<typename Key, typename Data, typename Cmp_Fn, template<typename Node_CItr, typename Const_Iterator, typename Cmp_Fn_, typename _Alloc_> class Node_Update, typename _Alloc> struct trie_node_metadata_dispatch { private: typedef dumnode_const_iterator<Key, Data, _Alloc> __it_type; typedef Node_Update<__it_type, __it_type, Cmp_Fn, _Alloc> __node_u; typedef null_node_update<__it_type, __it_type, Cmp_Fn, _Alloc> __nnode_u; enum { null_update = is_same<__node_u, __nnode_u>::value }; public: typedef typename trie_metadata_helper<__node_u, null_update>::type type; }; //@} } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_TRIE_NODE_METADATA_DISPATCH_HPP c++/8/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp 0000644 00000010637 15146341150 0021514 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/prefix_search_node_update_imp.hpp * Contains an implementation of prefix_search_node_update. */ PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::const_iterator, typename PB_DS_CLASS_C_DEC::const_iterator> PB_DS_CLASS_C_DEC:: prefix_range(key_const_reference r_key) const { const access_traits& r_traits = get_access_traits(); return (prefix_range(r_traits.begin(r_key), r_traits.end(r_key))); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::iterator, typename PB_DS_CLASS_C_DEC::iterator> PB_DS_CLASS_C_DEC:: prefix_range(key_const_reference r_key) { return (prefix_range(get_access_traits().begin(r_key), get_access_traits().end(r_key))); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::const_iterator, typename PB_DS_CLASS_C_DEC::const_iterator> PB_DS_CLASS_C_DEC:: prefix_range(typename access_traits::const_iterator b, typename access_traits::const_iterator e) const { const std::pair<iterator, iterator> non_const_ret = const_cast<PB_DS_CLASS_C_DEC* >(this)->prefix_range(b, e); return (std::make_pair(const_iterator(non_const_ret.first), const_iterator(non_const_ret.second))); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::iterator, typename PB_DS_CLASS_C_DEC::iterator> PB_DS_CLASS_C_DEC:: prefix_range(typename access_traits::const_iterator b, typename access_traits::const_iterator e) { Node_Itr nd_it = node_begin(); Node_Itr end_nd_it = node_end(); const access_traits& r_traits = get_access_traits(); const size_type given_range_length = std::distance(b, e); while (true) { if (nd_it == end_nd_it) return (std::make_pair(end(), end())); const size_type common_range_length = base_type::common_prefix_len(nd_it, b, e, r_traits); if (common_range_length >= given_range_length) { iterator ret_b = this->leftmost_it(nd_it); iterator ret_e = this->rightmost_it(nd_it); return (std::make_pair(ret_b, ++ret_e)); } nd_it = next_child(nd_it, b, e, end_nd_it, r_traits); } } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_iterator PB_DS_CLASS_C_DEC:: next_child(node_iterator nd_it, typename access_traits::const_iterator b, typename access_traits::const_iterator e, node_iterator end_nd_it, const access_traits& r_traits) { const size_type num_children = nd_it.num_children(); node_iterator ret = end_nd_it; size_type max_length = 0; for (size_type i = 0; i < num_children; ++i) { node_iterator pot = nd_it.get_child(i); const size_type common_range_length = base_type::common_prefix_len(pot, b, e, r_traits); if (common_range_length > max_length) { ret = pot; max_length = common_range_length; } } return (ret); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: operator()(node_iterator /*nd_it*/, node_const_iterator /*end_nd_it*/) const { } c++/8/ext/pb_ds/detail/trie_policy/sample_trie_node_update.hpp 0000644 00000004454 15146341150 0020331 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/sample_trie_node_update.hpp * Contains a samle node update functor. */ #ifndef PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP #define PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP namespace __gnu_pbds { /// A sample node updator. template<typename Node_CItr, typename Node_Itr, typename _ATraits, typename _Alloc> class sample_trie_node_update { public: typedef std::size_t metadata_type; protected: /// Default constructor. sample_trie_node_update(); /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator, node_const_iterator) const; }; } #endif // #ifndef PB_DS_SAMPLE_TRIE_NODE_UPDATOR_HPP c++/8/ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp 0000644 00000011135 15146341150 0017702 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy/order_statistics_imp.hpp * Contains forward declarations for order_statistics_key */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) { if (empty()) return end(); ++order; node_iterator nd_it = node_begin(); while (true) { if (order > nd_it.get_metadata()) return ++base_type::rightmost_it(nd_it); const size_type num_children = nd_it.num_children(); if (num_children == 0) return *nd_it; for (size_type i = 0; i < num_children; ++i) { node_iterator child_nd_it = nd_it.get_child(i); if (order <= child_nd_it.get_metadata()) { i = num_children; nd_it = child_nd_it; } else order -= child_nd_it.get_metadata(); } } } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) const { return const_cast<PB_DS_CLASS_C_DEC*>(this)->find_by_order(order); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: order_of_key(key_const_reference r_key) const { const _ATraits& r_traits = const_cast<PB_DS_CLASS_C_DEC* >(this)->get_access_traits(); return order_of_prefix(r_traits.begin(r_key), r_traits.end(r_key)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: order_of_prefix(typename access_traits::const_iterator b, typename access_traits::const_iterator e) const { if (empty()) return 0; const _ATraits& r_traits = const_cast<PB_DS_CLASS_C_DEC*>(this)->get_access_traits(); node_const_iterator nd_it = node_begin(); node_const_iterator end_nd_it = node_end(); size_type ord = 0; while (true) { const size_type num_children = nd_it.num_children(); if (num_children == 0) { key_const_reference r_key = base_type::extract_key(*(*nd_it)); typename access_traits::const_iterator key_b = r_traits.begin(r_key); typename access_traits::const_iterator key_e = r_traits.end(r_key); return (base_type::less(key_b, key_e, b, e, r_traits)) ? ord + 1 : ord; } node_const_iterator next_nd_it = end_nd_it; size_type i = num_children - 1; do { node_const_iterator child_nd_it = nd_it.get_child(i); if (next_nd_it != end_nd_it) ord += child_nd_it.get_metadata(); else if (!base_type::less(b, e, child_nd_it.valid_prefix().first, child_nd_it.valid_prefix().second, r_traits)) next_nd_it = child_nd_it; } while (i-- > 0); if (next_nd_it == end_nd_it) return ord; nd_it = next_nd_it; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: operator()(node_iterator nd_it, node_const_iterator /*end_nd_it*/) const { const size_type num_children = nd_it.num_children(); size_type children_rank = 0; for (size_type i = 0; i < num_children; ++i) children_rank += nd_it.get_child(i).get_metadata(); const size_type res = (num_children == 0) ? 1 : children_rank; const_cast<size_type&>(nd_it.get_metadata()) = res; } c++/8/ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp 0000644 00000004147 15146341150 0022622 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/binomial_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation for binomial_heap_. */ PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap(const PB_DS_CLASS_C_DEC& other) : base_type(other) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~binomial_heap() { } c++/8/ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp 0000644 00000003551 15146341150 0016660 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/binomial_heap_/debug_fn_imps.hpp * Contains an implementation for binomial_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(true, __file, __line); } #endif c++/8/ext/pb_ds/detail/binomial_heap_/binomial_heap_.hpp 0000644 00000007522 15146341150 0017007 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_.hpp * Contains an implementation class for a binomial heap. */ /* * Binomial heap. * Vuillemin J is the mastah. * Modified from CLRS. */ #include <debug/debug.h> #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp> namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> #define PB_DS_CLASS_C_DEC \ binomial_heap<Value_Type, Cmp_Fn, _Alloc> /** * Binomial heap. * * @ingroup heap-detail */ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> class binomial_heap : public binomial_heap_base<Value_Type, Cmp_Fn, _Alloc> { private: typedef binomial_heap_base<Value_Type, Cmp_Fn, _Alloc> base_type; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; public: typedef Value_Type value_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::cmp_fn cmp_fn; typedef typename base_type::allocator_type allocator_type; binomial_heap(); binomial_heap(const Cmp_Fn&); binomial_heap(const binomial_heap&); ~binomial_heap(); protected: #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; #endif }; #include <ext/pb_ds/detail/binomial_heap_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/binomial_heap_/debug_fn_imps.hpp> #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp 0000644 00000006412 15146341150 0020133 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy/node_metadata_selector.hpp * Contains an implementation class for trees. */ #ifndef PB_DS_TREE_NODE_METADATA_DISPATCH_HPP #define PB_DS_TREE_NODE_METADATA_DISPATCH_HPP #include <ext/pb_ds/detail/branch_policy/null_node_metadata.hpp> #include <ext/pb_ds/detail/types_traits.hpp> namespace __gnu_pbds { namespace detail { /** * @addtogroup traits Traits * @{ */ /// Tree metadata helper. template<typename Node_Update, bool _BTp> struct tree_metadata_helper; /// Specialization, false. template<typename Node_Update> struct tree_metadata_helper<Node_Update, false> { typedef typename Node_Update::metadata_type type; }; /// Specialization, true. template<typename Node_Update> struct tree_metadata_helper<Node_Update, true> { typedef null_type type; }; /// Tree node metadata dispatch. template<typename Key, typename Data, typename Cmp_Fn, template<typename Node_CItr, typename Const_Iterator, typename Cmp_Fn_, typename _Alloc_> class Node_Update, typename _Alloc> struct tree_node_metadata_dispatch { private: typedef dumnode_const_iterator<Key, Data, _Alloc> __it_type; typedef Node_Update<__it_type, __it_type, Cmp_Fn, _Alloc> __node_u; typedef null_node_update<__it_type, __it_type, Cmp_Fn, _Alloc> __nnode_u; enum { null_update = is_same<__node_u, __nnode_u>::value }; public: typedef typename tree_metadata_helper<__node_u, null_update>::type type; }; //@} } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_TREE_NODE_METADATA_DISPATCH_HPP c++/8/ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp 0000644 00000007213 15146341150 0017700 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy/order_statistics_imp.hpp * Contains forward declarations for order_statistics_key */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) { node_iterator it = node_begin(); node_iterator end_it = node_end(); while (it != end_it) { node_iterator l_it = it.get_l_child(); const size_type o = (l_it == end_it)? 0 : l_it.get_metadata(); if (order == o) return *it; else if (order < o) it = l_it; else { order -= o + 1; it = it.get_r_child(); } } return base_type::end_iterator(); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: find_by_order(size_type order) const { return const_cast<PB_DS_CLASS_C_DEC*>(this)->find_by_order(order); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: order_of_key(key_const_reference r_key) const { node_const_iterator it = node_begin(); node_const_iterator end_it = node_end(); const cmp_fn& r_cmp_fn = const_cast<PB_DS_CLASS_C_DEC*>(this)->get_cmp_fn(); size_type ord = 0; while (it != end_it) { node_const_iterator l_it = it.get_l_child(); if (r_cmp_fn(r_key, this->extract_key(*(*it)))) it = l_it; else if (r_cmp_fn(this->extract_key(*(*it)), r_key)) { ord += (l_it == end_it)? 1 : 1 + l_it.get_metadata(); it = it.get_r_child(); } else { ord += (l_it == end_it)? 0 : l_it.get_metadata(); it = end_it; } } return ord; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: operator()(node_iterator node_it, node_const_iterator end_nd_it) const { node_iterator l_it = node_it.get_l_child(); const size_type l_rank = (l_it == end_nd_it) ? 0 : l_it.get_metadata(); node_iterator r_it = node_it.get_r_child(); const size_type r_rank = (r_it == end_nd_it) ? 0 : r_it.get_metadata(); const_cast<metadata_reference>(node_it.get_metadata())= 1 + l_rank + r_rank; } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~tree_order_statistics_node_update() { } c++/8/ext/pb_ds/detail/tree_policy/sample_tree_node_update.hpp 0000644 00000004452 15146341150 0020317 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy/sample_tree_node_update.hpp * Contains a samle node update functor. */ #ifndef PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP #define PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP namespace __gnu_pbds { /// A sample node updator. template<typename Const_Node_Iter, typename Node_Iter, typename Cmp_Fn, typename _Alloc> class sample_tree_node_update { typedef std::size_t metadata_type; /// Default constructor. sample_tree_node_update(); /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator node_it, node_const_iterator end_nd_it) const; }; } #endif // #ifndef PB_DS_SAMPLE_TREE_NODE_UPDATOR_HPP c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp 0000644 00000017757 15146341150 0025142 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp * Contains an implementation class for a basic heap. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_HPP /* * Based on CLRS. */ #include <iterator> #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/point_const_iterator.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp> #ifdef PB_DS_LC_NS_HEAP_TRACE_ #include <iostream> #endif #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #ifdef _GLIBCXX_DEBUG #define PB_DS_CLASS_T_DEC \ template<typename Value_Type, typename Cmp_Fn, typename Node_Metadata, \ typename _Alloc, bool Single_Link_Roots> #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap<Value_Type, Cmp_Fn, Node_Metadata, \ _Alloc, Single_Link_Roots> #else #define PB_DS_CLASS_T_DEC \ template<typename Value_Type, typename Cmp_Fn, typename Node_Metadata, \ typename _Alloc> #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap<Value_Type, Cmp_Fn, Node_Metadata, _Alloc> #endif /// Base class for a basic heap. template<typename Value_Type, typename Cmp_Fn, typename Node_Metadata, typename _Alloc #ifdef _GLIBCXX_DEBUG ,bool Single_Link_Roots> #else > #endif class left_child_next_sibling_heap : public Cmp_Fn { protected: typedef typename _Alloc::template rebind< left_child_next_sibling_heap_node_<Value_Type, Node_Metadata, _Alloc> >::other node_allocator; typedef typename node_allocator::value_type node; typedef typename node_allocator::pointer node_pointer; typedef typename node_allocator::const_pointer node_const_pointer; typedef Node_Metadata node_metadata; typedef std::pair< node_pointer, node_pointer> node_pointer_pair; private: typedef cond_dealtor< node, _Alloc> cond_dealtor_t; enum { simple_value = is_simple<Value_Type>::value }; typedef integral_constant<int, simple_value> no_throw_copies_t; typedef typename _Alloc::template rebind<Value_Type> __rebind_v; public: typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Value_Type value_type; typedef typename __rebind_v::other::pointer pointer; typedef typename __rebind_v::other::const_pointer const_pointer; typedef typename __rebind_v::other::reference reference; typedef typename __rebind_v::other::const_reference const_reference; typedef left_child_next_sibling_heap_node_point_const_iterator_<node, _Alloc> point_const_iterator; typedef point_const_iterator point_iterator; typedef left_child_next_sibling_heap_const_iterator_<node, _Alloc> const_iterator; typedef const_iterator iterator; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; left_child_next_sibling_heap(); left_child_next_sibling_heap(const Cmp_Fn&); left_child_next_sibling_heap(const left_child_next_sibling_heap&); void swap(PB_DS_CLASS_C_DEC&); ~left_child_next_sibling_heap(); inline bool empty() const; inline size_type size() const; inline size_type max_size() const; Cmp_Fn& get_cmp_fn(); const Cmp_Fn& get_cmp_fn() const; inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; void clear(); #ifdef PB_DS_LC_NS_HEAP_TRACE_ void trace() const; #endif protected: inline node_pointer get_new_node_for_insert(const_reference); inline static void make_child_of(node_pointer, node_pointer); void value_swap(left_child_next_sibling_heap&); inline static node_pointer parent(node_pointer); inline void swap_with_parent(node_pointer, node_pointer); void bubble_to_top(node_pointer); inline void actual_erase_node(node_pointer); void clear_imp(node_pointer); void to_linked_list(); template<typename Pred> node_pointer prune(Pred); #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; void assert_node_consistent(node_const_pointer, bool, const char*, int) const; static size_type size_under_node(node_const_pointer); static size_type degree(node_const_pointer); #endif #ifdef PB_DS_LC_NS_HEAP_TRACE_ static void trace_node(node_const_pointer, size_type); #endif private: #ifdef _GLIBCXX_DEBUG void assert_iterators(const char*, int) const; void assert_size(const char*, int) const; static size_type size_from_node(node_const_pointer); #endif node_pointer recursive_copy_node(node_const_pointer); inline node_pointer get_new_node_for_insert(const_reference, false_type); inline node_pointer get_new_node_for_insert(const_reference, true_type); #ifdef PB_DS_LC_NS_HEAP_TRACE_ template<typename Metadata_> static void trace_node_metadata(node_const_pointer, type_to_type<Metadata_>); static void trace_node_metadata(node_const_pointer, type_to_type<null_type>); #endif static node_allocator s_node_allocator; static no_throw_copies_t s_no_throw_copies_ind; protected: node_pointer m_p_root; size_type m_size; }; #include <ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp> #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp 0000644 00000007727 15146341150 0025701 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/constructors_destructor_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_allocator PB_DS_CLASS_C_DEC::s_node_allocator; PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::no_throw_copies_t PB_DS_CLASS_C_DEC::s_no_throw_copies_ind; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: left_child_next_sibling_heap() : m_p_root(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: left_child_next_sibling_heap(const Cmp_Fn& r_cmp_fn) : Cmp_Fn(r_cmp_fn), m_p_root(0), m_size(0) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: left_child_next_sibling_heap(const PB_DS_CLASS_C_DEC& other) : Cmp_Fn(other), m_p_root(0), m_size(0) { m_size = other.m_size; PB_DS_ASSERT_VALID(other) m_p_root = recursive_copy_node(other.m_p_root); m_size = other.m_size; PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) value_swap(other); std::swap((Cmp_Fn& )(*this), (Cmp_Fn& )other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: value_swap(PB_DS_CLASS_C_DEC& other) { std::swap(m_p_root, other.m_p_root); std::swap(m_size, other.m_size); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~left_child_next_sibling_heap() { clear(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: recursive_copy_node(node_const_pointer p_nd) { if (p_nd == 0) return (0); node_pointer p_ret = s_node_allocator.allocate(1); __try { new (p_ret) node(*p_nd); } __catch(...) { s_node_allocator.deallocate(p_ret, 1); __throw_exception_again; } p_ret->m_p_l_child = p_ret->m_p_next_sibling = p_ret->m_p_prev_or_parent = 0; __try { p_ret->m_p_l_child = recursive_copy_node(p_nd->m_p_l_child); p_ret->m_p_next_sibling = recursive_copy_node(p_nd->m_p_next_sibling); } __catch(...) { clear_imp(p_ret); __throw_exception_again; } if (p_ret->m_p_l_child != 0) p_ret->m_p_l_child->m_p_prev_or_parent = p_ret; if (p_ret->m_p_next_sibling != 0) p_ret->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_next_sibling->m_p_prev_or_parent == p_nd ? p_ret : 0; return p_ret; } c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/info_fn_imps.hpp 0000644 00000004072 15146341150 0021574 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/info_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: empty() const { return (m_size == 0); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size() const { return (m_size); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: max_size() const { return (s_node_allocator.max_size()); } c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/iterators_fn_imps.hpp 0000644 00000004773 15146341150 0022665 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/iterators_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: begin() { node_pointer p_nd = m_p_root; if (p_nd == 0) return (iterator(0)); while (p_nd->m_p_l_child != 0) p_nd = p_nd->m_p_l_child; return (iterator(p_nd)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: begin() const { node_pointer p_nd = m_p_root; if (p_nd == 0) return (const_iterator(0)); while (p_nd->m_p_l_child != 0) p_nd = p_nd->m_p_l_child; return (const_iterator(p_nd)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: end() { return (iterator(0)); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: end() const { return (const_iterator(0)); } c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/debug_fn_imps.hpp 0000644 00000007753 15146341150 0021740 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/debug_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(m_p_root == 0 || m_p_root->m_p_prev_or_parent == 0); if (m_p_root != 0) assert_node_consistent(m_p_root, Single_Link_Roots, __file, __line); assert_size(__file, __line); assert_iterators(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(node_const_pointer p_nd, bool single_link, const char* __file, int __line) const { if (p_nd == 0) return; assert_node_consistent(p_nd->m_p_l_child, false, __file, __line); assert_node_consistent(p_nd->m_p_next_sibling, single_link, __file, __line); if (single_link) PB_DS_DEBUG_VERIFY(p_nd->m_p_prev_or_parent == 0); else if (p_nd->m_p_next_sibling != 0) PB_DS_DEBUG_VERIFY(p_nd->m_p_next_sibling->m_p_prev_or_parent == p_nd); if (p_nd->m_p_l_child == 0) return; node_const_pointer p_child = p_nd->m_p_l_child; while (p_child != 0) { node_const_pointer p_next_child = p_child->m_p_next_sibling; PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(p_nd->m_value, p_child->m_value)); p_child = p_next_child; } PB_DS_DEBUG_VERIFY(p_nd->m_p_l_child->m_p_prev_or_parent == p_nd); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_iterators(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(std::distance(begin(), end()) == size()); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_size(const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(size_from_node(m_p_root) == m_size); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size_under_node(node_const_pointer p_nd) { return 1 + size_from_node(p_nd->m_p_l_child); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: size_from_node(node_const_pointer p_nd) { size_type ret = 0; while (p_nd != 0) { ret += 1 + size_from_node(p_nd->m_p_l_child); p_nd = p_nd->m_p_next_sibling; } return ret; } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: degree(node_const_pointer p_nd) { size_type ret = 0; node_const_pointer p_child = p_nd->m_p_l_child; while (p_child != 0) { ++ret; p_child = p_child->m_p_next_sibling; } return ret; } #endif c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/insert_fn_imps.hpp 0000644 00000012121 15146341150 0022137 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/insert_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_insert(const_reference r_val) { return get_new_node_for_insert(r_val, s_no_throw_copies_ind); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_insert(const_reference r_val, false_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); cond_dealtor_t cond(p_new_nd); new (const_cast<void* >( static_cast<const void* >(&p_new_nd->m_value))) typename node::value_type(r_val); cond.set_no_action(); ++m_size; return (p_new_nd); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: get_new_node_for_insert(const_reference r_val, true_type) { node_pointer p_new_nd = s_node_allocator.allocate(1); new (const_cast<void* >( static_cast<const void* >(&p_new_nd->m_value))) typename node::value_type(r_val); ++m_size; return (p_new_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: make_child_of(node_pointer p_nd, node_pointer p_new_parent) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_new_parent != 0); p_nd->m_p_next_sibling = p_new_parent->m_p_l_child; if (p_new_parent->m_p_l_child != 0) p_new_parent->m_p_l_child->m_p_prev_or_parent = p_nd; p_nd->m_p_prev_or_parent = p_new_parent; p_new_parent->m_p_l_child = p_nd; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: parent(node_pointer p_nd) { while (true) { node_pointer p_pot = p_nd->m_p_prev_or_parent; if (p_pot == 0 || p_pot->m_p_l_child == p_nd) return p_pot; p_nd = p_pot; } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: swap_with_parent(node_pointer p_nd, node_pointer p_parent) { if (p_parent == m_p_root) m_p_root = p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_parent != 0); _GLIBCXX_DEBUG_ASSERT(parent(p_nd) == p_parent); const bool nd_direct_child = p_parent->m_p_l_child == p_nd; const bool parent_root = p_parent->m_p_prev_or_parent == 0; const bool parent_direct_child = !parent_root&& p_parent->m_p_prev_or_parent->m_p_l_child == p_parent; std::swap(p_parent->m_p_prev_or_parent, p_nd->m_p_prev_or_parent); std::swap(p_parent->m_p_next_sibling, p_nd->m_p_next_sibling); std::swap(p_parent->m_p_l_child, p_nd->m_p_l_child); std::swap(p_parent->m_metadata, p_nd->m_metadata); _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child != 0); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_prev_or_parent != 0); if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; if (p_parent->m_p_next_sibling != 0) p_parent->m_p_next_sibling->m_p_prev_or_parent = p_parent; if (p_parent->m_p_l_child != 0) p_parent->m_p_l_child->m_p_prev_or_parent = p_parent; if (parent_direct_child) p_nd->m_p_prev_or_parent->m_p_l_child = p_nd; else if (!parent_root) p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd; if (!nd_direct_child) { p_nd->m_p_l_child->m_p_prev_or_parent = p_nd; p_parent->m_p_prev_or_parent->m_p_next_sibling = p_parent; } else { _GLIBCXX_DEBUG_ASSERT(p_nd->m_p_l_child == p_nd); _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_prev_or_parent == p_parent); p_nd->m_p_l_child = p_parent; p_parent->m_p_prev_or_parent = p_nd; } _GLIBCXX_DEBUG_ASSERT(parent(p_parent) == p_nd); } c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/node.hpp 0000644 00000006214 15146341150 0020053 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/node.hpp * Contains an implementation struct for this type of heap's node. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP namespace __gnu_pbds { namespace detail { /// Node. template<typename _Value, typename _Metadata, typename _Alloc> struct left_child_next_sibling_heap_node_ { private: typedef left_child_next_sibling_heap_node_<_Value, _Metadata, _Alloc> this_type; public: typedef _Value value_type; typedef typename _Alloc::size_type size_type; typedef _Metadata metadata_type; typedef typename _Alloc::template rebind<this_type>::other::pointer node_pointer; value_type m_value; metadata_type m_metadata; node_pointer m_p_l_child; node_pointer m_p_next_sibling; node_pointer m_p_prev_or_parent; }; template<typename _Value, typename _Alloc> struct left_child_next_sibling_heap_node_<_Value, null_type, _Alloc> { private: typedef left_child_next_sibling_heap_node_<_Value, null_type, _Alloc> this_type; public: typedef _Value value_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::template rebind<this_type>::other::pointer node_pointer; value_type m_value; node_pointer m_p_l_child; node_pointer m_p_next_sibling; node_pointer m_p_prev_or_parent; }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NODE_HPP c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/trace_fn_imps.hpp 0000644 00000005377 15146341150 0021750 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/trace_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ #ifdef PB_DS_LC_NS_HEAP_TRACE_ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { std::cerr << std::endl; trace_node(m_p_root, 0); std::cerr << std::endl; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node(node_const_pointer p_nd, size_type level) { while (p_nd != 0) { for (size_type i = 0; i < level; ++i) std::cerr << ' '; std::cerr << p_nd << " prev = " << p_nd->m_p_prev_or_parent << " next " << p_nd->m_p_next_sibling << " left = " << p_nd->m_p_l_child << " "; trace_node_metadata(p_nd, type_to_type<node_metadata>()); std::cerr << p_nd->m_value << std::endl; trace_node(p_nd->m_p_l_child, level + 1); p_nd = p_nd->m_p_next_sibling; } } PB_DS_CLASS_T_DEC template<typename Metadata_> void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer p_nd, type_to_type<Metadata_>) { std::cerr << "(" << p_nd->m_metadata << ") "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node_metadata(node_const_pointer, type_to_type<null_type>) { } #endif // #ifdef PB_DS_LC_NS_HEAP_TRACE_ c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/policy_access_fn_imps.hpp 0000644 00000003607 15146341150 0023464 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/policy_access_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() { return *this; } PB_DS_CLASS_T_DEC const Cmp_Fn& PB_DS_CLASS_C_DEC:: get_cmp_fn() const { return *this; } c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/point_const_iterator.hpp 0000644 00000010620 15146341150 0023372 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/point_const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_FIND_ITERATOR_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_FIND_ITERATOR_HPP #include <ext/pb_ds/tag_and_trait.hpp> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template<typename Node, typename _Alloc> #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap_node_point_const_iterator_<Node, _Alloc> /// Const point-type iterator. template<typename Node, typename _Alloc> class left_child_next_sibling_heap_node_point_const_iterator_ { protected: typedef typename _Alloc::template rebind<Node>::other::pointer node_pointer; public: /// Category. typedef trivial_iterator_tag iterator_category; /// Difference type. typedef trivial_iterator_difference_type difference_type; /// Iterator's value type. typedef typename Node::value_type value_type; /// Iterator's pointer type. typedef typename _Alloc::template rebind< value_type>::other::pointer pointer; /// Iterator's const pointer type. typedef typename _Alloc::template rebind< value_type>::other::const_pointer const_pointer; /// Iterator's reference type. typedef typename _Alloc::template rebind< value_type>::other::reference reference; /// Iterator's const reference type. typedef typename _Alloc::template rebind< value_type>::other::const_reference const_reference; inline left_child_next_sibling_heap_node_point_const_iterator_(node_pointer p_nd) : m_p_nd(p_nd) { } /// Default constructor. inline left_child_next_sibling_heap_node_point_const_iterator_() : m_p_nd(0) { } /// Copy constructor. inline left_child_next_sibling_heap_node_point_const_iterator_(const PB_DS_CLASS_C_DEC& other) : m_p_nd(other.m_p_nd) { } /// Access. const_pointer operator->() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return &m_p_nd->m_value; } /// Access. const_reference operator*() const { _GLIBCXX_DEBUG_ASSERT(m_p_nd != 0); return m_p_nd->m_value; } /// Compares content to a different iterator object. bool operator==(const PB_DS_CLASS_C_DEC& other) const { return m_p_nd == other.m_p_nd; } /// Compares content (negatively) to a different iterator object. bool operator!=(const PB_DS_CLASS_C_DEC& other) const { return m_p_nd != other.m_p_nd; } node_pointer m_p_nd; }; #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/erase_fn_imps.hpp 0000644 00000007567 15146341150 0021754 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/erase_fn_imps.hpp * Contains an implementation class for left_child_next_sibling_heap_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { clear_imp(m_p_root); _GLIBCXX_DEBUG_ASSERT(m_size == 0); m_p_root = 0; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: actual_erase_node(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(m_size > 0); --m_size; p_nd->~node(); s_node_allocator.deallocate(p_nd, 1); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear_imp(node_pointer p_nd) { while (p_nd != 0) { clear_imp(p_nd->m_p_l_child); node_pointer p_next = p_nd->m_p_next_sibling; actual_erase_node(p_nd); p_nd = p_next; } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: to_linked_list() { PB_DS_ASSERT_VALID((*this)) node_pointer p_cur = m_p_root; while (p_cur != 0) if (p_cur->m_p_l_child != 0) { node_pointer p_child_next = p_cur->m_p_l_child->m_p_next_sibling; p_cur->m_p_l_child->m_p_next_sibling = p_cur->m_p_next_sibling; p_cur->m_p_next_sibling = p_cur->m_p_l_child; p_cur->m_p_l_child = p_child_next; } else p_cur = p_cur->m_p_next_sibling; #ifdef _GLIBCXX_DEBUG node_const_pointer p_counter = m_p_root; size_type count = 0; while (p_counter != 0) { ++count; _GLIBCXX_DEBUG_ASSERT(p_counter->m_p_l_child == 0); p_counter = p_counter->m_p_next_sibling; } _GLIBCXX_DEBUG_ASSERT(count == m_size); #endif } PB_DS_CLASS_T_DEC template<typename Pred> typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: prune(Pred pred) { node_pointer p_cur = m_p_root; m_p_root = 0; node_pointer p_out = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; if (pred(p_cur->m_value)) { p_cur->m_p_next_sibling = p_out; if (p_out != 0) p_out->m_p_prev_or_parent = p_cur; p_out = p_cur; } else { p_cur->m_p_next_sibling = m_p_root; if (m_p_root != 0) m_p_root->m_p_prev_or_parent = p_cur; m_p_root = p_cur; } p_cur = p_next; } return p_out; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: bubble_to_top(node_pointer p_nd) { node_pointer p_parent = parent(p_nd); while (p_parent != 0) { swap_with_parent(p_nd, p_parent); p_parent = parent(p_nd); } } c++/8/ext/pb_ds/detail/left_child_next_sibling_heap_/const_iterator.hpp 0000644 00000011474 15146341150 0022171 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file left_child_next_sibling_heap_/const_iterator.hpp * Contains an iterator class returned by the table's const find and insert * methods. */ #ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_ITERATOR_HPP #define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_CONST_ITERATOR_HPP #include <ext/pb_ds/detail/left_child_next_sibling_heap_/point_const_iterator.hpp> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_C_DEC \ left_child_next_sibling_heap_const_iterator_<Node, _Alloc> #define PB_DS_BASIC_HEAP_CIT_BASE \ left_child_next_sibling_heap_node_point_const_iterator_<Node, _Alloc> /// Const point-type iterator. template<typename Node, typename _Alloc> class left_child_next_sibling_heap_const_iterator_ : public PB_DS_BASIC_HEAP_CIT_BASE { private: typedef PB_DS_BASIC_HEAP_CIT_BASE base_type; typedef typename base_type::node_pointer node_pointer; public: /// Category. typedef std::forward_iterator_tag iterator_category; /// Difference type. typedef typename _Alloc::difference_type difference_type; /// Iterator's value type. typedef typename base_type::value_type value_type; /// Iterator's pointer type. typedef typename base_type::pointer pointer; /// Iterator's const pointer type. typedef typename base_type::const_pointer const_pointer; /// Iterator's reference type. typedef typename base_type::reference reference; /// Iterator's const reference type. typedef typename base_type::const_reference const_reference; inline left_child_next_sibling_heap_const_iterator_(node_pointer p_nd) : base_type(p_nd) { } /// Default constructor. inline left_child_next_sibling_heap_const_iterator_() { } /// Copy constructor. inline left_child_next_sibling_heap_const_iterator_(const PB_DS_CLASS_C_DEC& other) : base_type(other) { } /// Compares content to a different iterator object. bool operator==(const PB_DS_CLASS_C_DEC& other) const { return (base_type::m_p_nd == other.m_p_nd); } /// Compares content (negatively) to a different iterator object. bool operator!=(const PB_DS_CLASS_C_DEC& other) const { return (base_type::m_p_nd != other.m_p_nd); } PB_DS_CLASS_C_DEC& operator++() { _GLIBCXX_DEBUG_ASSERT(base_type::m_p_nd != 0); inc(); return (*this); } PB_DS_CLASS_C_DEC operator++(int) { PB_DS_CLASS_C_DEC ret_it(base_type::m_p_nd); operator++(); return (ret_it); } private: void inc() { if (base_type::m_p_nd->m_p_next_sibling != 0) { base_type::m_p_nd = base_type::m_p_nd->m_p_next_sibling; while (base_type::m_p_nd->m_p_l_child != 0) base_type::m_p_nd = base_type::m_p_nd->m_p_l_child; return; } while (true) { node_pointer p_next = base_type::m_p_nd; base_type::m_p_nd = base_type::m_p_nd->m_p_prev_or_parent; if (base_type::m_p_nd == 0 || base_type::m_p_nd->m_p_l_child == p_next) return; } } }; #undef PB_DS_CLASS_C_DEC #undef PB_DS_BASIC_HEAP_CIT_BASE } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp 0000644 00000007062 15146341150 0017325 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/split_join_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::join_prep(other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } node_pointer p_target_r = other.leftmost(other.m_p_head); _GLIBCXX_DEBUG_ASSERT(p_target_r != 0); other.splay(p_target_r); _GLIBCXX_DEBUG_ASSERT(p_target_r == other.m_p_head->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_left == 0); p_target_r->m_p_left = base_type::m_p_head->m_p_parent; _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_left != 0); p_target_r->m_p_left->m_p_parent = p_target_r; base_type::m_p_head->m_p_parent = p_target_r; p_target_r->m_p_parent = base_type::m_p_head; this->apply_update(p_target_r, (node_update*)this); base_type::join_finish(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::split_prep(r_key, other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } node_pointer p_upper_bound = this->upper_bound(r_key).m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_upper_bound != 0); splay(p_upper_bound); _GLIBCXX_DEBUG_ASSERT(p_upper_bound->m_p_parent == this->m_p_head); node_pointer p_new_root = p_upper_bound->m_p_left; _GLIBCXX_DEBUG_ASSERT(p_new_root != 0); base_type::m_p_head->m_p_parent = p_new_root; p_new_root->m_p_parent = base_type::m_p_head; other.m_p_head->m_p_parent = p_upper_bound; p_upper_bound->m_p_parent = other.m_p_head; p_upper_bound->m_p_left = 0; this->apply_update(p_upper_bound, (node_update*)this); base_type::split_finish(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } c++/8/ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp 0000644 00000005437 15146341150 0022205 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/constructors_destructor_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME() { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : base_type(r_cmp_fn, r_node_update) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_S_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : base_type(other) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) base_type::swap(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { base_type::m_p_head->m_special = true; } c++/8/ext/pb_ds/detail/splay_tree_/traits.hpp 0000644 00000006427 15146341150 0014752 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/traits.hpp * Contains an implementation for splay_tree_. */ #ifndef PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP #include <ext/pb_ds/detail/splay_tree_/node.hpp> namespace __gnu_pbds { namespace detail { /// Specialization. /// @ingroup traits template<typename Key, typename Mapped, typename Cmp_Fn, template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn_, typename _Alloc_> class Node_Update, typename _Alloc> struct tree_traits<Key, Mapped, Cmp_Fn, Node_Update, splay_tree_tag, _Alloc> : public bin_search_tree_traits<Key, Mapped, Cmp_Fn, Node_Update, splay_tree_node_< typename types_traits<Key, Mapped, _Alloc, false>::value_type, typename tree_node_metadata_dispatch<Key, Mapped, Cmp_Fn, Node_Update, _Alloc>::type, _Alloc>, _Alloc> { }; /// Specialization. /// @ingroup traits template<typename Key, class Cmp_Fn, template<typename Node_CItr, class Node_Itr, class Cmp_Fn_, typename _Alloc_> class Node_Update, typename _Alloc> struct tree_traits<Key, null_type, Cmp_Fn, Node_Update, splay_tree_tag, _Alloc> : public bin_search_tree_traits<Key, null_type, Cmp_Fn, Node_Update, splay_tree_node_< typename types_traits<Key, null_type, _Alloc, false>::value_type, typename tree_node_metadata_dispatch<Key, null_type, Cmp_Fn, Node_Update, _Alloc>::type, _Alloc>, _Alloc> { }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_SPLAY_TREE_NODE_AND_IT_TRAITS_HPP c++/8/ext/pb_ds/detail/splay_tree_/info_fn_imps.hpp 0000644 00000003231 15146341150 0016100 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/info_fn_imps.hpp * Contains an implementation. */ c++/8/ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp 0000644 00000004637 15146341150 0016246 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/debug_fn_imps.hpp * Contains an implementation class for splay_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(__file, __line); const node_pointer p_head = base_type::m_p_head; assert_special_imp(p_head, __file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_special_imp(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return; if (p_nd == base_type::m_p_head) { PB_DS_DEBUG_VERIFY(p_nd->m_special); assert_special_imp(p_nd->m_p_parent, __file, __line); return; } PB_DS_DEBUG_VERIFY(!p_nd->m_special); assert_special_imp(p_nd->m_p_left, __file, __line); assert_special_imp(p_nd->m_p_right, __file, __line); } #endif c++/8/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp 0000644 00000006431 15146341150 0016456 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/insert_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert(const_reference r_value) { PB_DS_ASSERT_VALID((*this)) std::pair<point_iterator, bool> ins_pair = insert_leaf_imp(r_value); ins_pair.first.m_p_nd->m_special = false; PB_DS_ASSERT_VALID((*this)) splay(ins_pair.first.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ins_pair; } PB_DS_CLASS_T_DEC inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert_leaf_imp(const_reference r_value) { _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid(__FILE__, __LINE__);) if (base_type::m_size == 0) return std::make_pair(base_type::insert_imp_empty(r_value), true); node_pointer p_nd = base_type::m_p_head->m_p_parent; node_pointer p_pot = base_type::m_p_head; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), PB_DS_V2F(r_value))) { if (!Cmp_Fn::operator()(PB_DS_V2F(r_value), PB_DS_V2F(p_nd->m_value))) { return std::make_pair(point_iterator(p_nd), false); } p_pot = p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; if (p_pot == base_type::m_p_head) return std::make_pair(base_type::insert_leaf_new(r_value, base_type::m_p_head->m_p_right, false), true); PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_value)) p_nd = p_pot->m_p_left; if (p_nd == 0) return (std::make_pair(base_type::insert_leaf_new(r_value, p_pot, true), true)); while (p_nd->m_p_right != 0) p_nd = p_nd->m_p_right; return std::make_pair(this->insert_leaf_new(r_value, p_nd, false), true); } c++/8/ext/pb_ds/detail/splay_tree_/node.hpp 0000644 00000007240 15146341150 0014363 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/node.hpp * Contains an implementation struct for splay_tree_'s node. */ #ifndef PB_DS_SPLAY_TREE_NODE_HPP #define PB_DS_SPLAY_TREE_NODE_HPP namespace __gnu_pbds { namespace detail { /// Node for splay tree. template<typename Value_Type, class Metadata, typename _Alloc> struct splay_tree_node_ { public: typedef Value_Type value_type; typedef Metadata metadata_type; typedef typename _Alloc::template rebind< splay_tree_node_<Value_Type, Metadata, _Alloc> >::other::pointer node_pointer; typedef typename _Alloc::template rebind<metadata_type>::other::reference metadata_reference; typedef typename _Alloc::template rebind<metadata_type>::other::const_reference metadata_const_reference; #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value) << "(" << m_metadata << ")"; } #endif inline bool special() const { return m_special; } inline metadata_const_reference get_metadata() const { return m_metadata; } inline metadata_reference get_metadata() { return m_metadata; } value_type m_value; bool m_special; node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; metadata_type m_metadata; }; template<typename Value_Type, typename _Alloc> struct splay_tree_node_<Value_Type, null_type, _Alloc> { public: typedef Value_Type value_type; typedef null_type metadata_type; typedef typename _Alloc::template rebind< splay_tree_node_<Value_Type, null_type, _Alloc> >::other::pointer node_pointer; inline bool special() const { return m_special; } #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value); } #endif node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; value_type m_value; bool m_special; }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp 0000644 00000017561 15146341150 0016310 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/splay_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: splay(node_pointer p_nd) { while (p_nd->m_p_parent != base_type::m_p_head) { #ifdef _GLIBCXX_DEBUG { node_pointer p_head = base_type::m_p_head; assert_special_imp(p_head, __FILE__, __LINE__); } #endif PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd) if (p_nd->m_p_parent->m_p_parent == base_type::m_p_head) { base_type::rotate_parent(p_nd); _GLIBCXX_DEBUG_ASSERT(p_nd == this->m_p_head->m_p_parent); } else { const node_pointer p_parent = p_nd->m_p_parent; const node_pointer p_grandparent = p_parent->m_p_parent; #ifdef _GLIBCXX_DEBUG const size_type total = base_type::recursive_count(p_grandparent); _GLIBCXX_DEBUG_ASSERT(total >= 3); #endif if (p_parent->m_p_left == p_nd && p_grandparent->m_p_right == p_parent) splay_zig_zag_left(p_nd, p_parent, p_grandparent); else if (p_parent->m_p_right == p_nd && p_grandparent->m_p_left == p_parent) splay_zig_zag_right(p_nd, p_parent, p_grandparent); else if (p_parent->m_p_left == p_nd && p_grandparent->m_p_left == p_parent) splay_zig_zig_left(p_nd, p_parent, p_grandparent); else splay_zig_zig_right(p_nd, p_parent, p_grandparent); _GLIBCXX_DEBUG_ASSERT(total ==this->recursive_count(p_nd)); } PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd) } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zag_left(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_left == p_nd && p_grandparent->m_p_right == p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_right; node_pointer p_c = p_nd->m_p_left; p_nd->m_p_right = p_parent; p_parent->m_p_parent = p_nd; p_nd->m_p_left = p_grandparent; p_grandparent->m_p_parent = p_nd; p_parent->m_p_left = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_right = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zag_right(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_right == p_nd && p_grandparent->m_p_left == p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_left; node_pointer p_c = p_nd->m_p_right; p_nd->m_p_left = p_parent; p_parent->m_p_parent = p_nd; p_nd->m_p_right = p_grandparent; p_grandparent->m_p_parent = p_nd; p_parent->m_p_right = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_left = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zig_left(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_left == p_nd && p_nd->m_p_parent->m_p_parent->m_p_left == p_nd->m_p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_right; node_pointer p_c = p_parent->m_p_right; p_nd->m_p_right = p_parent; p_parent->m_p_parent = p_nd; p_parent->m_p_right = p_grandparent; p_grandparent->m_p_parent = p_parent; p_parent->m_p_left = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_left = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zig_zig_right(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_parent == p_nd->m_p_parent); _GLIBCXX_DEBUG_ASSERT(p_grandparent == p_parent->m_p_parent); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_grandparent) _GLIBCXX_DEBUG_ASSERT(p_parent->m_p_right == p_nd && p_nd->m_p_parent->m_p_parent->m_p_right == p_nd->m_p_parent); splay_zz_start(p_nd, p_parent, p_grandparent); node_pointer p_b = p_nd->m_p_left; node_pointer p_c = p_parent->m_p_left; p_nd->m_p_left = p_parent; p_parent->m_p_parent = p_nd; p_parent->m_p_left = p_grandparent; p_grandparent->m_p_parent = p_parent; p_parent->m_p_right = p_b; if (p_b != 0) p_b->m_p_parent = p_parent; p_grandparent->m_p_right = p_c; if (p_c != 0) p_c->m_p_parent = p_grandparent; base_type::update_to_top(p_grandparent, (node_update*)this); splay_zz_end(p_nd, p_parent, p_grandparent); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zz_start(node_pointer p_nd, #ifdef _GLIBCXX_DEBUG node_pointer p_parent, #else node_pointer /*p_parent*/, #endif node_pointer p_grandparent) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(p_parent != 0); _GLIBCXX_DEBUG_ASSERT(p_grandparent != 0); const bool grandparent_head = p_grandparent->m_p_parent == base_type::m_p_head; if (grandparent_head) { base_type::m_p_head->m_p_parent = base_type::m_p_head->m_p_parent; p_nd->m_p_parent = base_type::m_p_head; return; } node_pointer p_greatgrandparent = p_grandparent->m_p_parent; p_nd->m_p_parent = p_greatgrandparent; if (p_grandparent == p_greatgrandparent->m_p_left) p_greatgrandparent->m_p_left = p_nd; else p_greatgrandparent->m_p_right = p_nd; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: splay_zz_end(node_pointer p_nd, node_pointer p_parent, node_pointer p_grandparent) { if (p_nd->m_p_parent == base_type::m_p_head) base_type::m_p_head->m_p_parent = p_nd; this->apply_update(p_grandparent, (node_update*)this); this->apply_update(p_parent, (node_update*)this); this->apply_update(p_nd, (node_update*)this); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd) } c++/8/ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp 0000644 00000006367 15146341150 0016102 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/find_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { node_pointer p_found = find_imp(r_key); if (p_found != base_type::m_p_head) splay(p_found); return point_iterator(p_found); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { const node_pointer p_found = find_imp(r_key); if (p_found != base_type::m_p_head) const_cast<PB_DS_CLASS_C_DEC* >(this)->splay(p_found); return point_iterator(p_found); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) { _GLIBCXX_DEBUG_ONLY(base_type::structure_only_assert_valid(__FILE__, __LINE__);) node_pointer p_nd = base_type::m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) return p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return base_type::m_p_head; } PB_DS_CLASS_T_DEC inline const typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: find_imp(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) node_pointer p_nd = base_type::m_p_head->m_p_parent; while (p_nd != 0) if (!Cmp_Fn::operator()(PB_DS_V2F(p_nd->m_value), r_key)) { if (!Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) return p_nd; p_nd = p_nd->m_p_left; } else p_nd = p_nd->m_p_right; return base_type::m_p_head; } c++/8/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp 0000644 00000010255 15146341150 0016250 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/erase_fn_imps.hpp * Contains an implementation class for splay_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { point_iterator it = find(r_key); if (it == base_type::end()) return false; erase(it); return true; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: erase(iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == base_type::end()) return it; iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: erase(reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == base_type::m_p_head) return (it); reverse_iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC template<typename Pred> inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; iterator it = base_type::begin(); while (it != base_type::end()) { if (pred(*it)) { ++num_ersd; it = erase(it); } else ++it; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_node(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); splay(p_nd); PB_DS_ASSERT_VALID((*this)) _GLIBCXX_DEBUG_ASSERT(p_nd == this->m_p_head->m_p_parent); node_pointer p_l = p_nd->m_p_left; node_pointer p_r = p_nd->m_p_right; base_type::update_min_max_for_erased_node(p_nd); base_type::actual_erase_node(p_nd); if (p_r == 0) { base_type::m_p_head->m_p_parent = p_l; if (p_l != 0) p_l->m_p_parent = base_type::m_p_head; PB_DS_ASSERT_VALID((*this)) return; } node_pointer p_target_r = leftmost(p_r); _GLIBCXX_DEBUG_ASSERT(p_target_r != 0); p_r->m_p_parent = base_type::m_p_head; base_type::m_p_head->m_p_parent = p_r; splay(p_target_r); _GLIBCXX_DEBUG_ONLY(p_target_r->m_p_left = 0); _GLIBCXX_DEBUG_ASSERT(p_target_r->m_p_parent == this->m_p_head); _GLIBCXX_DEBUG_ASSERT(this->m_p_head->m_p_parent == p_target_r); p_target_r->m_p_left = p_l; if (p_l != 0) p_l->m_p_parent = p_target_r; PB_DS_ASSERT_VALID((*this)) this->apply_update(p_target_r, (node_update*)this); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: leftmost(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); while (p_nd->m_p_left != 0) p_nd = p_nd->m_p_left; return p_nd; } c++/8/ext/pb_ds/detail/splay_tree_/splay_tree_.hpp 0000644 00000022133 15146341150 0015742 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file splay_tree_/splay_tree_.hpp * Contains an implementation class for splay trees. */ /* * This implementation uses an idea from the SGI STL (using a @a header node * which is needed for efficient iteration). Following is the SGI STL * copyright. * * 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. * * * 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. * * */ #include <utility> #include <vector> #include <assert.h> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #ifdef PB_DS_DATA_TRUE_INDICATOR # define PB_DS_S_TREE_NAME splay_tree_map # define PB_DS_S_TREE_BASE_NAME bin_search_tree_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR # define PB_DS_S_TREE_NAME splay_tree_set # define PB_DS_S_TREE_BASE_NAME bin_search_tree_set #endif #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Mapped, typename Cmp_Fn, \ typename Node_And_It_Traits, typename _Alloc> #define PB_DS_CLASS_C_DEC \ PB_DS_S_TREE_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, _Alloc> #define PB_DS_S_TREE_BASE \ PB_DS_S_TREE_BASE_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, _Alloc> /** * @brief Splay tree. * @ingroup branch-detail */ template<typename Key, typename Mapped, typename Cmp_Fn, typename Node_And_It_Traits, typename _Alloc> class PB_DS_S_TREE_NAME : public PB_DS_S_TREE_BASE { private: typedef PB_DS_S_TREE_BASE base_type; #ifdef _GLIBCXX_DEBUG typedef base_type debug_base; #endif typedef typename base_type::node_pointer node_pointer; public: typedef splay_tree_tag container_category; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef Cmp_Fn cmp_fn; typedef typename base_type::key_type key_type; typedef typename base_type::key_pointer key_pointer; typedef typename base_type::key_const_pointer key_const_pointer; typedef typename base_type::key_reference key_reference; typedef typename base_type::key_const_reference key_const_reference; typedef typename base_type::mapped_type mapped_type; typedef typename base_type::mapped_pointer mapped_pointer; typedef typename base_type::mapped_const_pointer mapped_const_pointer; typedef typename base_type::mapped_reference mapped_reference; typedef typename base_type::mapped_const_reference mapped_const_reference; typedef typename base_type::value_type value_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::reverse_iterator reverse_iterator; typedef typename base_type::const_reverse_iterator const_reverse_iterator; typedef typename base_type::node_update node_update; PB_DS_S_TREE_NAME(); PB_DS_S_TREE_NAME(const Cmp_Fn&); PB_DS_S_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_S_TREE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); template<typename It> void copy_from_range(It, It); void initialize(); inline std::pair<point_iterator, bool> insert(const_reference r_value); inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) std::pair<point_iterator, bool> ins_pair = insert_leaf_imp(value_type(r_key, mapped_type())); ins_pair.first.m_p_nd->m_special = false; _GLIBCXX_DEBUG_ONLY(base_type::assert_valid(__FILE__, __LINE__)); splay(ins_pair.first.m_p_nd); _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return ins_pair.first.m_p_nd->m_value.second; #else insert(r_key); return base_type::s_null_type; #endif } inline point_iterator find(key_const_reference); inline point_const_iterator find(key_const_reference) const; inline bool erase(key_const_reference); inline iterator erase(iterator it); inline reverse_iterator erase(reverse_iterator); template<typename Pred> inline size_type erase_if(Pred); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); private: inline std::pair<point_iterator, bool> insert_leaf_imp(const_reference); inline node_pointer find_imp(key_const_reference); inline const node_pointer find_imp(key_const_reference) const; #ifdef _GLIBCXX_DEBUG void assert_valid(const char* file, int line) const; void assert_special_imp(const node_pointer, const char* file, int line) const; #endif void splay(node_pointer); inline void splay_zig_zag_left(node_pointer, node_pointer, node_pointer); inline void splay_zig_zag_right(node_pointer, node_pointer, node_pointer); inline void splay_zig_zig_left(node_pointer, node_pointer, node_pointer); inline void splay_zig_zig_right(node_pointer, node_pointer, node_pointer); inline void splay_zz_start(node_pointer, node_pointer, node_pointer); inline void splay_zz_end(node_pointer, node_pointer, node_pointer); inline node_pointer leftmost(node_pointer); void erase_node(node_pointer); }; #define PB_DS_ASSERT_BASE_NODE_CONSISTENT(_Node) \ _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(_Node, \ __FILE__, __LINE__);) #include <ext/pb_ds/detail/splay_tree_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp> #include <ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/splay_tree_/find_fn_imps.hpp> #include <ext/pb_ds/detail/splay_tree_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp> #undef PB_DS_ASSERT_BASE_NODE_CONSISTENT #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_S_TREE_NAME #undef PB_DS_S_TREE_BASE_NAME #undef PB_DS_S_TREE_BASE } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/tree_trace_base.hpp 0000644 00000012016 15146341150 0014234 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/tree_trace_base.hpp * Contains tree-related policies. */ #ifndef PB_DS_TREE_TRACE_BASE_HPP #define PB_DS_TREE_TRACE_BASE_HPP #ifdef PB_DS_TREE_TRACE #include <ext/pb_ds/detail/branch_policy/branch_policy.hpp> #include <ext/pb_ds/detail/branch_policy/null_node_metadata.hpp> namespace __gnu_pbds { namespace detail { #ifdef PB_DS_TREE_TRACE #define PB_DS_CLASS_T_DEC \ template<typename Node_CItr, typename Node_Itr, \ typename Cmp_Fn, bool Node_Based, typename _Alloc> #define PB_DS_CLASS_C_DEC \ tree_trace_base<Node_CItr, Node_Itr, Cmp_Fn, \ Node_Based, _Alloc> #define PB_DS_TRACE_BASE \ branch_policy<Node_CItr, Node_Itr, _Alloc> /// Tracing base class. template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn, bool Node_Based, typename _Alloc> class tree_trace_base : private PB_DS_TRACE_BASE { public: void trace() const; private: typedef PB_DS_TRACE_BASE base_type; typedef Node_CItr node_const_iterator; typedef typename _Alloc::size_type size_type; void trace_node(node_const_iterator, size_type) const; virtual bool empty() const = 0; virtual node_const_iterator node_begin() const = 0; virtual node_const_iterator node_end() const = 0; static void print_node_pointer(Node_CItr, integral_constant<int,true>); static void print_node_pointer(Node_CItr, integral_constant<int,false>); template<typename Metadata_> static void trace_it_metadata(Node_CItr, type_to_type<Metadata_>); static void trace_it_metadata(Node_CItr, type_to_type<null_type>); }; PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace() const { if (empty()) return; trace_node(node_begin(), 0); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_node(node_const_iterator nd_it, size_type level) const { if (nd_it.get_r_child() != node_end()) trace_node(nd_it.get_r_child(), level + 1); for (size_type i = 0; i < level; ++i) std::cerr << ' '; print_node_pointer(nd_it, integral_constant<int,Node_Based>()); std::cerr << base_type::extract_key(*(*nd_it)); typedef type_to_type<typename node_const_iterator::metadata_type> m_type_ind_t; trace_it_metadata(nd_it, m_type_ind_t()); std::cerr << std::endl; if (nd_it.get_l_child() != node_end()) trace_node(nd_it.get_l_child(), level + 1); } PB_DS_CLASS_T_DEC template<typename Metadata_> void PB_DS_CLASS_C_DEC:: trace_it_metadata(Node_CItr nd_it, type_to_type<Metadata_>) { const unsigned long ul = static_cast<unsigned long>(nd_it.get_metadata()); std::cerr << " (" << ul << ") "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: trace_it_metadata(Node_CItr, type_to_type<null_type>) { } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: print_node_pointer(Node_CItr nd_it, integral_constant<int,true>) { std::cerr << nd_it.m_p_nd << " "; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: print_node_pointer(Node_CItr nd_it, integral_constant<int,false>) { std::cerr << *nd_it << " "; } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_TRACE_BASE #endif // #ifdef PB_DS_TREE_TRACE } // namespace detail } // namespace __gnu_pbds #endif // #ifdef PB_DS_TREE_TRACE #endif // #ifndef PB_DS_TREE_TRACE_BASE_HPP c++/8/ext/pb_ds/detail/debug_map_base.hpp 0000644 00000020771 15146341150 0014051 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file detail/debug_map_base.hpp * Contains a debug-mode base for all maps. */ #ifndef PB_DS_DEBUG_MAP_BASE_HPP #define PB_DS_DEBUG_MAP_BASE_HPP #ifdef _GLIBCXX_DEBUG #include <list> #include <utility> #include <cstdlib> #include <iostream> #include <ext/throw_allocator.h> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { // Need std::pair ostream extractor. template<typename _CharT, typename _Traits, typename _Tp1, typename _Tp2> inline std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __out, const std::pair<_Tp1, _Tp2>& p) { return (__out << '(' << p.first << ',' << p.second << ')'); } #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Eq_Fn, typename Const_Key_Reference> #define PB_DS_CLASS_C_DEC \ debug_map_base<Key, Eq_Fn, Const_Key_Reference> /// Debug base class. template<typename Key, typename Eq_Fn, typename Const_Key_Reference> class debug_map_base { private: typedef Const_Key_Reference key_const_reference; typedef std::_GLIBCXX_STD_C::list<Key> key_repository; typedef typename key_repository::size_type size_type; typedef typename key_repository::iterator iterator; typedef typename key_repository::const_iterator const_iterator; protected: debug_map_base(); debug_map_base(const PB_DS_CLASS_C_DEC&); ~debug_map_base(); inline void insert_new(key_const_reference); inline void erase_existing(key_const_reference); void clear(); inline void check_key_exists(key_const_reference, const char*, int) const; inline void check_key_does_not_exist(key_const_reference, const char*, int) const; inline void check_size(size_type, const char*, int) const; void swap(PB_DS_CLASS_C_DEC&); template<typename Cmp_Fn> void split(key_const_reference, Cmp_Fn, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&, bool with_cleanup = true); private: void assert_valid(const char*, int) const; const_iterator find(key_const_reference) const; iterator find(key_const_reference); key_repository m_keys; Eq_Fn m_eq; }; PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: debug_map_base() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: debug_map_base(const PB_DS_CLASS_C_DEC& other) : m_keys(other.m_keys), m_eq(other.m_eq) { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~debug_map_base() { PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_new(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) if (find(r_key) != m_keys.end()) { std::cerr << "insert_new key already present " << r_key << std::endl; std::abort(); } __try { m_keys.push_back(r_key); } __catch(...) { std::cerr << "insert_new " << r_key << std::endl; std::abort(); } PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: erase_existing(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) iterator it = find(r_key); if (it == m_keys.end()) { std::cerr << "erase_existing" << r_key << std::endl; std::abort(); } m_keys.erase(it); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: clear() { PB_DS_ASSERT_VALID((*this)) m_keys.clear(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: check_key_exists(key_const_reference r_key, const char* __file, int __line) const { assert_valid(__file, __line); if (find(r_key) == m_keys.end()) { std::cerr << __file << ':' << __line << ": check_key_exists " << r_key << std::endl; std::abort(); } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: check_key_does_not_exist(key_const_reference r_key, const char* __file, int __line) const { assert_valid(__file, __line); if (find(r_key) != m_keys.end()) { using std::cerr; using std::endl; cerr << __file << ':' << __line << ": check_key_does_not_exist " << r_key << endl; std::abort(); } } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: check_size(size_type size, const char* __file, int __line) const { assert_valid(__file, __line); const size_type keys_size = m_keys.size(); if (size != keys_size) { std::cerr << __file << ':' << __line << ": check_size " << size << " != " << keys_size << std::endl; std::abort(); } } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) m_keys.swap(other.m_keys); std::swap(m_eq, other.m_eq); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::const_iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) const { PB_DS_ASSERT_VALID((*this)) typedef const_iterator iterator_type; for (iterator_type it = m_keys.begin(); it != m_keys.end(); ++it) if (m_eq(*it, r_key)) return it; return m_keys.end(); } PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: find(key_const_reference r_key) { PB_DS_ASSERT_VALID((*this)) iterator it = m_keys.begin(); while (it != m_keys.end()) { if (m_eq(*it, r_key)) return it; ++it; } return it; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { const_iterator prime_it = m_keys.begin(); while (prime_it != m_keys.end()) { const_iterator sec_it = prime_it; ++sec_it; while (sec_it != m_keys.end()) { PB_DS_DEBUG_VERIFY(!m_eq(*sec_it, *prime_it)); PB_DS_DEBUG_VERIFY(!m_eq(*prime_it, *sec_it)); ++sec_it; } ++prime_it; } } PB_DS_CLASS_T_DEC template<typename Cmp_Fn> void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, Cmp_Fn cmp_fn, PB_DS_CLASS_C_DEC& other) { other.clear(); iterator it = m_keys.begin(); while (it != m_keys.end()) if (cmp_fn(r_key, *it)) { other.insert_new(*it); it = m_keys.erase(it); } else ++it; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other, bool with_cleanup) { iterator it = other.m_keys.begin(); while (it != other.m_keys.end()) { insert_new(*it); if (with_cleanup) it = other.m_keys.erase(it); else ++it; } _GLIBCXX_DEBUG_ASSERT(!with_cleanup || other.m_keys.empty()); } #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace detail } // namespace __gnu_pbds #endif #endif c++/8/ext/pb_ds/detail/branch_policy/null_node_metadata.hpp 0000644 00000004513 15146341150 0017563 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file branch_policy/null_node_metadata.hpp * Contains an implementation class for tree-like classes. */ #ifndef PB_DS_0_NODE_METADATA_HPP #define PB_DS_0_NODE_METADATA_HPP #include <ext/pb_ds/detail/types_traits.hpp> namespace __gnu_pbds { namespace detail { /// Constant node iterator. template<typename Key, typename Data, typename _Alloc> struct dumnode_const_iterator { private: typedef types_traits<Key, Data, _Alloc, false> __traits_type; typedef typename __traits_type::pointer const_iterator; public: typedef const_iterator value_type; typedef const_iterator const_reference; typedef const_reference reference; }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/branch_policy/traits.hpp 0000644 00000006266 15146341150 0015261 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file branch_policy/traits.hpp * Contains an implementation class for tree-like classes. */ #ifndef PB_DS_NODE_AND_IT_TRAITS_HPP #define PB_DS_NODE_AND_IT_TRAITS_HPP #include <ext/pb_ds/detail/types_traits.hpp> #include <ext/pb_ds/detail/bin_search_tree_/traits.hpp> #include <ext/pb_ds/detail/tree_policy/node_metadata_selector.hpp> #include <ext/pb_ds/detail/trie_policy/node_metadata_selector.hpp> #define PB_DS_DEBUG_VERIFY(_Cond) \ _GLIBCXX_DEBUG_VERIFY_AT(_Cond, \ _M_message(#_Cond" assertion from %1;:%2;") \ ._M_string(__FILE__)._M_integer(__LINE__) \ ,__file,__line) namespace __gnu_pbds { namespace detail { /// Tree traits class, primary template. template<typename Key, typename Data, typename Cmp_Fn, template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn_, typename _Alloc> class Node_Update, typename Tag, typename _Alloc> struct tree_traits; /// Trie traits class, primary template. template<typename Key, typename Data, typename _ATraits, template<typename Node_CItr, typename Node_Itr, typename _ATraits_, typename _Alloc> class Node_Update, typename Tag, typename _Alloc> struct trie_traits; } // namespace detail } // namespace __gnu_pbds #include <ext/pb_ds/detail/rb_tree_map_/traits.hpp> #include <ext/pb_ds/detail/splay_tree_/traits.hpp> #include <ext/pb_ds/detail/ov_tree_map_/traits.hpp> #include <ext/pb_ds/detail/pat_trie_/traits.hpp> #undef PB_DS_DEBUG_VERIFY #endif // #ifndef PB_DS_NODE_AND_IT_TRAITS_HPP c++/8/ext/pb_ds/detail/branch_policy/branch_policy.hpp 0000644 00000007677 15146341150 0016576 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file branch_policy/branch_policy.hpp * Contains a base class for branch policies. */ #ifndef PB_DS_BRANCH_POLICY_BASE_HPP #define PB_DS_BRANCH_POLICY_BASE_HPP #include <ext/pb_ds/tag_and_trait.hpp> namespace __gnu_pbds { namespace detail { /// Primary template, base class for branch structure policies. template<typename Node_CItr, typename Node_Itr, typename _Alloc> struct branch_policy { protected: typedef typename Node_Itr::value_type it_type; typedef typename std::iterator_traits<it_type>::value_type value_type; typedef typename value_type::first_type key_type; typedef typename remove_const<value_type>::type rcvalue_type; typedef typename remove_const<key_type>::type rckey_type; typedef typename _Alloc::template rebind<rcvalue_type>::other rebind_v; typedef typename _Alloc::template rebind<rckey_type>::other rebind_k; typedef typename rebind_v::reference reference; typedef typename rebind_v::const_reference const_reference; typedef typename rebind_v::const_pointer const_pointer; typedef typename rebind_k::const_reference key_const_reference; static inline key_const_reference extract_key(const_reference r_val) { return r_val.first; } virtual it_type end() = 0; it_type end_iterator() const { return const_cast<branch_policy*>(this)->end(); } virtual ~branch_policy() { } }; /// Specialization for const iterators. template<typename Node_CItr, typename _Alloc> struct branch_policy<Node_CItr, Node_CItr, _Alloc> { protected: typedef typename Node_CItr::value_type it_type; typedef typename std::iterator_traits<it_type>::value_type value_type; typedef typename remove_const<value_type>::type rcvalue_type; typedef typename _Alloc::template rebind<rcvalue_type>::other rebind_v; typedef typename rebind_v::reference reference; typedef typename rebind_v::const_reference const_reference; typedef typename rebind_v::const_pointer const_pointer; typedef value_type key_type; typedef typename rebind_v::const_reference key_const_reference; static inline key_const_reference extract_key(const_reference r_val) { return r_val; } virtual it_type end() const = 0; it_type end_iterator() const { return end(); } virtual ~branch_policy() { } }; } // namespace detail } // namespace __gnu_pbds #endif // #ifndef PB_DS_BRANCH_POLICY_BASE_HPP c++/8/ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp 0000644 00000012365 15146341150 0020741 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/split_join_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC template<typename Pred> void PB_DS_CLASS_C_DEC:: split(Pred pred, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) other.clear(); if (base_type::empty()) { PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) return; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); while (p_out != 0) { _GLIBCXX_DEBUG_ASSERT(base_type::m_size > 0); --base_type::m_size; ++other.m_size; node_pointer p_next = p_out->m_p_next_sibling; p_out->m_p_l_child = p_out->m_p_prev_or_parent = 0; p_out->m_metadata = 0; p_out->m_p_next_sibling = other.m_p_root; if (other.m_p_root != 0) other.m_p_root->m_p_prev_or_parent = p_out; other.m_p_root = p_out; other.m_p_root = other.fix(other.m_p_root); p_out = p_next; } PB_DS_ASSERT_VALID_COND(other,true) node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = 0; p_cur->m_metadata = 0; p_cur->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = p_cur; base_type::m_p_root = p_cur; base_type::m_p_root = fix(base_type::m_p_root); p_cur = p_next; } m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) node_pointer p_other = other.m_p_root; if (p_other != 0) do { node_pointer p_next = p_other->m_p_next_sibling; std::swap(p_other->m_p_next_sibling, p_other->m_p_prev_or_parent); p_other = p_next; } while (p_other != 0); base_type::m_p_root = join(base_type::m_p_root, other.m_p_root); base_type::m_size += other.m_size; m_p_max = 0; other.m_p_root = 0; other.m_size = 0; other.m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) PB_DS_ASSERT_VALID_COND(other,true) } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: join(node_pointer p_lhs, node_pointer p_rhs) const { node_pointer p_ret = 0; node_pointer p_cur = 0; while (p_lhs != 0 || p_rhs != 0) { if (p_rhs == 0) { if (p_cur == 0) p_ret = p_cur = p_lhs; else { p_cur->m_p_next_sibling = p_lhs; p_lhs->m_p_prev_or_parent = p_cur; } p_cur = p_lhs = 0; } else if (p_lhs == 0 || p_rhs->m_metadata < p_lhs->m_metadata) { if (p_cur == 0) { p_ret = p_cur = p_rhs; p_rhs = p_rhs->m_p_prev_or_parent; } else { p_cur->m_p_next_sibling = p_rhs; p_rhs = p_rhs->m_p_prev_or_parent; p_cur->m_p_next_sibling->m_p_prev_or_parent = p_cur; p_cur = p_cur->m_p_next_sibling; } } else if (p_lhs->m_metadata < p_rhs->m_metadata) { if (p_cur == 0) p_ret = p_cur = p_lhs; else { p_cur->m_p_next_sibling = p_lhs; p_lhs->m_p_prev_or_parent = p_cur; p_cur = p_cur->m_p_next_sibling; } p_lhs = p_cur->m_p_next_sibling; } else { node_pointer p_next_rhs = p_rhs->m_p_prev_or_parent; p_rhs->m_p_next_sibling = p_lhs; p_lhs = fix(p_rhs); p_rhs = p_next_rhs; } } if (p_cur != 0) p_cur->m_p_next_sibling = 0; if (p_ret != 0) p_ret->m_p_prev_or_parent = 0; return p_ret; } c++/8/ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp 0000644 00000005200 15146341150 0023603 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/constructors_destructor_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) push(*(first_it++)); PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap_base() : m_p_max(0) { PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap_base(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn), m_p_max(0) { PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: binomial_heap_base(const PB_DS_CLASS_C_DEC& other) : base_type(other), m_p_max(0) { PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID_COND((*this),false) base_type::swap(other); std::swap(m_p_max, other.m_p_max); PB_DS_ASSERT_VALID_COND((*this),false) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: ~binomial_heap_base() { } c++/8/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp 0000644 00000006614 15146341150 0017655 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/debug_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(bool strictly_binomial, const char* __file, int __line) const { base_type::assert_valid(__file, __line); assert_node_consistent(base_type::m_p_root, strictly_binomial, true, __file, __line); assert_max(__file, __line); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_max(const char* __file, int __line) const { if (m_p_max == 0) return; PB_DS_DEBUG_VERIFY(base_type::parent(m_p_max) == 0); for (const_iterator it = base_type::begin(); it != base_type::end(); ++it) PB_DS_DEBUG_VERIFY(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value)); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_node_consistent(node_const_pointer p_nd, bool strictly_binomial, bool increasing, const char* __file, int __line) const { PB_DS_DEBUG_VERIFY(increasing || strictly_binomial); base_type::assert_node_consistent(p_nd, false, __file, __line); if (p_nd == 0) return; PB_DS_DEBUG_VERIFY(p_nd->m_metadata == base_type::degree(p_nd)); PB_DS_DEBUG_VERIFY(base_type::size_under_node(p_nd) == static_cast<size_type>(1 << p_nd->m_metadata)); assert_node_consistent(p_nd->m_p_next_sibling, strictly_binomial, increasing, __file, __line); assert_node_consistent(p_nd->m_p_l_child, true, false, __file, __line); if (p_nd->m_p_next_sibling != 0) { if (increasing) { if (strictly_binomial) PB_DS_DEBUG_VERIFY(p_nd->m_metadata < p_nd->m_p_next_sibling->m_metadata); else PB_DS_DEBUG_VERIFY(p_nd->m_metadata <= p_nd->m_p_next_sibling->m_metadata); } else PB_DS_DEBUG_VERIFY(p_nd->m_metadata > p_nd->m_p_next_sibling->m_metadata); } } #endif c++/8/ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp 0000644 00000012227 15146341150 0020070 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/insert_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::point_iterator PB_DS_CLASS_C_DEC:: push(const_reference r_val) { PB_DS_ASSERT_VALID_COND((*this),true) node_pointer p_nd = base_type::get_new_node_for_insert(r_val); insert_node(p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) return point_iterator(p_nd); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_node(node_pointer p_nd) { if (base_type::m_p_root == 0) { p_nd->m_p_next_sibling = 0; p_nd->m_p_prev_or_parent = 0; p_nd->m_p_l_child = 0; p_nd->m_metadata = 0; base_type::m_p_root = p_nd; return; } if (base_type::m_p_root->m_metadata > 0) { p_nd->m_p_prev_or_parent = p_nd->m_p_l_child = 0; p_nd->m_p_next_sibling = base_type::m_p_root; base_type::m_p_root->m_p_prev_or_parent = p_nd; base_type::m_p_root = p_nd; p_nd->m_metadata = 0; return; } if (Cmp_Fn::operator()(base_type::m_p_root->m_value, p_nd->m_value)) { p_nd->m_p_next_sibling = base_type::m_p_root->m_p_next_sibling; p_nd->m_p_prev_or_parent = 0; p_nd->m_metadata = 1; p_nd->m_p_l_child = base_type::m_p_root; base_type::m_p_root->m_p_prev_or_parent = p_nd; base_type::m_p_root->m_p_next_sibling = 0; base_type::m_p_root = p_nd; } else { p_nd->m_p_next_sibling = 0; p_nd->m_p_l_child = 0; p_nd->m_p_prev_or_parent = base_type::m_p_root; p_nd->m_metadata = 0; _GLIBCXX_DEBUG_ASSERT(base_type::m_p_root->m_p_l_child == 0); base_type::m_p_root->m_p_l_child = p_nd; base_type::m_p_root->m_metadata = 1; } base_type::m_p_root = fix(base_type::m_p_root); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: fix(node_pointer p_nd) const { while (p_nd->m_p_next_sibling != 0 && p_nd->m_metadata == p_nd->m_p_next_sibling->m_metadata) { node_pointer p_next = p_nd->m_p_next_sibling; if (Cmp_Fn::operator()(p_nd->m_value, p_next->m_value)) { p_next->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; if (p_nd->m_p_prev_or_parent != 0) p_nd->m_p_prev_or_parent->m_p_next_sibling = p_next; base_type::make_child_of(p_nd, p_next); ++p_next->m_metadata; p_nd = p_next; } else { p_nd->m_p_next_sibling = p_next->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_next->m_p_next_sibling = 0; base_type::make_child_of(p_next, p_nd); ++p_nd->m_metadata; } } if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd; return p_nd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: modify(point_iterator it, const_reference r_new_val) { PB_DS_ASSERT_VALID_COND((*this),true) node_pointer p_nd = it.m_p_nd; _GLIBCXX_DEBUG_ASSERT(p_nd != 0); PB_DS_ASSERT_BASE_NODE_CONSISTENT(p_nd, false) const bool bubble_up = Cmp_Fn::operator()(p_nd->m_value, r_new_val); p_nd->m_value = r_new_val; if (bubble_up) { node_pointer p_parent = base_type::parent(p_nd); while (p_parent != 0 && Cmp_Fn::operator()(p_parent->m_value, p_nd->m_value)) { base_type::swap_with_parent(p_nd, p_parent); p_parent = base_type::parent(p_nd); } if (p_nd->m_p_prev_or_parent == 0) base_type::m_p_root = p_nd; m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) return; } base_type::bubble_to_top(p_nd); remove_parentless_node(p_nd); insert_node(p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) } c++/8/ext/pb_ds/detail/binomial_heap_base_/binomial_heap_base_.hpp 0000644 00000014072 15146341150 0020771 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/binomial_heap_base_.hpp * Contains an implementation class for a base of binomial heaps. */ #ifndef PB_DS_BINOMIAL_HEAP_BASE_HPP #define PB_DS_BINOMIAL_HEAP_BASE_HPP /* * Binomial heap base. * Vuillemin J is the mastah. * Modified from CLRS. */ #include <debug/debug.h> #include <ext/pb_ds/detail/cond_dealtor.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/left_child_next_sibling_heap_/left_child_next_sibling_heap_.hpp> namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template<typename Value_Type, typename Cmp_Fn, typename _Alloc> #define PB_DS_CLASS_C_DEC \ binomial_heap_base<Value_Type, Cmp_Fn, _Alloc> #ifdef _GLIBCXX_DEBUG #define PB_DS_B_HEAP_BASE \ left_child_next_sibling_heap<Value_Type, Cmp_Fn, \ typename _Alloc::size_type, _Alloc, false> #else #define PB_DS_B_HEAP_BASE \ left_child_next_sibling_heap<Value_Type, Cmp_Fn, \ typename _Alloc::size_type, _Alloc> #endif /// Base class for binomial heap. template<typename Value_Type, typename Cmp_Fn, typename _Alloc> class binomial_heap_base : public PB_DS_B_HEAP_BASE { private: typedef typename _Alloc::template rebind<Value_Type>::other __rebind_v; typedef PB_DS_B_HEAP_BASE base_type; protected: typedef typename base_type::node node; typedef typename base_type::node_pointer node_pointer; typedef typename base_type::node_const_pointer node_const_pointer; public: typedef Value_Type value_type; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename __rebind_v::pointer pointer; typedef typename __rebind_v::const_pointer const_pointer; typedef typename __rebind_v::reference reference; typedef typename __rebind_v::const_reference const_reference; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::iterator iterator; public: inline point_iterator push(const_reference); void modify(point_iterator, const_reference); inline const_reference top() const; void pop(); void erase(point_iterator); inline void clear(); template<typename Pred> size_type erase_if(Pred); template<typename Pred> void split(Pred, PB_DS_CLASS_C_DEC&); void join(PB_DS_CLASS_C_DEC&); protected: binomial_heap_base(); binomial_heap_base(const Cmp_Fn&); binomial_heap_base(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); ~binomial_heap_base(); template<typename It> void copy_from_range(It, It); inline void find_max(); #ifdef _GLIBCXX_DEBUG void assert_valid(bool, const char*, int) const; void assert_max(const char*, int) const; #endif private: inline node_pointer fix(node_pointer) const; inline void insert_node(node_pointer); inline void remove_parentless_node(node_pointer); inline node_pointer join(node_pointer, node_pointer) const; #ifdef _GLIBCXX_DEBUG void assert_node_consistent(node_const_pointer, bool, bool, const char*, int) const; #endif protected: node_pointer m_p_max; }; #define PB_DS_ASSERT_VALID_COND(X, _StrictlyBinomial) \ _GLIBCXX_DEBUG_ONLY(X.assert_valid(_StrictlyBinomial,__FILE__, __LINE__);) #define PB_DS_ASSERT_BASE_NODE_CONSISTENT(_Node, _Bool) \ _GLIBCXX_DEBUG_ONLY(base_type::assert_node_consistent(_Node, _Bool, \ __FILE__, __LINE__);) #include <ext/pb_ds/detail/binomial_heap_base_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp> #include <ext/pb_ds/detail/binomial_heap_base_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/binomial_heap_base_/split_join_fn_imps.hpp> #undef PB_DS_ASSERT_BASE_NODE_CONSISTENT #undef PB_DS_ASSERT_VALID_COND #undef PB_DS_CLASS_C_DEC #undef PB_DS_CLASS_T_DEC #undef PB_DS_B_HEAP_BASE } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/binomial_heap_base_/find_fn_imps.hpp 0000644 00000004451 15146341150 0017504 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/find_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::const_reference PB_DS_CLASS_C_DEC:: top() const { PB_DS_ASSERT_VALID_COND((*this),false) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); if (m_p_max == 0) const_cast<PB_DS_CLASS_C_DEC* >(this)->find_max(); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); return m_p_max->m_value; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: find_max() { node_pointer p_cur = base_type::m_p_root; m_p_max = p_cur; while (p_cur != 0) { if (Cmp_Fn::operator()(m_p_max->m_value, p_cur->m_value)) m_p_max = p_cur; p_cur = p_cur->m_p_next_sibling; } } c++/8/ext/pb_ds/detail/binomial_heap_base_/erase_fn_imps.hpp 0000644 00000010602 15146341150 0017656 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file binomial_heap_base_/erase_fn_imps.hpp * Contains an implementation class for a base of binomial heaps. */ PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: pop() { PB_DS_ASSERT_VALID_COND((*this),true) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); if (m_p_max == 0) find_max(); _GLIBCXX_DEBUG_ASSERT(m_p_max != 0); node_pointer p_nd = m_p_max; remove_parentless_node(m_p_max); base_type::actual_erase_node(p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_parentless_node(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); _GLIBCXX_DEBUG_ASSERT(base_type::parent(p_nd) == 0); node_pointer p_cur_root = p_nd == base_type::m_p_root? p_nd->m_p_next_sibling : base_type::m_p_root; if (p_cur_root != 0) p_cur_root->m_p_prev_or_parent = 0; if (p_nd->m_p_prev_or_parent != 0) p_nd->m_p_prev_or_parent->m_p_next_sibling = p_nd->m_p_next_sibling; if (p_nd->m_p_next_sibling != 0) p_nd->m_p_next_sibling->m_p_prev_or_parent = p_nd->m_p_prev_or_parent; node_pointer p_child = p_nd->m_p_l_child; if (p_child != 0) { p_child->m_p_prev_or_parent = 0; while (p_child->m_p_next_sibling != 0) p_child = p_child->m_p_next_sibling; } m_p_max = 0; base_type::m_p_root = join(p_cur_root, p_child); } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: clear() { base_type::clear(); m_p_max = 0; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase(point_iterator it) { PB_DS_ASSERT_VALID_COND((*this),true) _GLIBCXX_DEBUG_ASSERT(!base_type::empty()); base_type::bubble_to_top(it.m_p_nd); remove_parentless_node(it.m_p_nd); base_type::actual_erase_node(it.m_p_nd); m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) } PB_DS_CLASS_T_DEC template<typename Pred> typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID_COND((*this),true) if (base_type::empty()) { PB_DS_ASSERT_VALID_COND((*this),true) return 0; } base_type::to_linked_list(); node_pointer p_out = base_type::prune(pred); size_type ersd = 0; while (p_out != 0) { ++ersd; node_pointer p_next = p_out->m_p_next_sibling; base_type::actual_erase_node(p_out); p_out = p_next; } node_pointer p_cur = base_type::m_p_root; base_type::m_p_root = 0; while (p_cur != 0) { node_pointer p_next = p_cur->m_p_next_sibling; p_cur->m_p_l_child = p_cur->m_p_prev_or_parent = 0; p_cur->m_metadata = 0; p_cur->m_p_next_sibling = base_type::m_p_root; if (base_type::m_p_root != 0) base_type::m_p_root->m_p_prev_or_parent = p_cur; base_type::m_p_root = p_cur; base_type::m_p_root = fix(base_type::m_p_root); p_cur = p_next; } m_p_max = 0; PB_DS_ASSERT_VALID_COND((*this),true) return ersd; } c++/8/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp 0000644 00000017265 15146341150 0017443 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/split_join_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: join(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::join_prep(other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } const node_pointer p_x = other.split_min(); join_imp(p_x, other.m_p_head->m_p_parent); base_type::join_finish(other); PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: join_imp(node_pointer p_x, node_pointer p_r) { _GLIBCXX_DEBUG_ASSERT(p_x != 0); if (p_r != 0) p_r->m_red = false; const size_type h = black_height(base_type::m_p_head->m_p_parent); const size_type other_h = black_height(p_r); node_pointer p_x_l; node_pointer p_x_r; std::pair<node_pointer, node_pointer> join_pos; const bool right_join = h >= other_h; if (right_join) { join_pos = find_join_pos_right(base_type::m_p_head->m_p_parent, h, other_h); p_x_l = join_pos.first; p_x_r = p_r; } else { p_x_l = base_type::m_p_head->m_p_parent; base_type::m_p_head->m_p_parent = p_r; if (p_r != 0) p_r->m_p_parent = base_type::m_p_head; join_pos = find_join_pos_left(base_type::m_p_head->m_p_parent, h, other_h); p_x_r = join_pos.first; } node_pointer p_parent = join_pos.second; if (p_parent == base_type::m_p_head) { base_type::m_p_head->m_p_parent = p_x; p_x->m_p_parent = base_type::m_p_head; } else { p_x->m_p_parent = p_parent; if (right_join) p_x->m_p_parent->m_p_right = p_x; else p_x->m_p_parent->m_p_left = p_x; } p_x->m_p_left = p_x_l; if (p_x_l != 0) p_x_l->m_p_parent = p_x; p_x->m_p_right = p_x_r; if (p_x_r != 0) p_x_r->m_p_parent = p_x; p_x->m_red = true; base_type::initialize_min_max(); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) base_type::update_to_top(p_x, (node_update* )this); insert_fixup(p_x); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::node_pointer PB_DS_CLASS_C_DEC:: split_min() { node_pointer p_min = base_type::m_p_head->m_p_left; #ifdef _GLIBCXX_DEBUG const node_pointer p_head = base_type::m_p_head; _GLIBCXX_DEBUG_ASSERT(p_min != p_head); #endif remove_node(p_min); return p_min; } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::node_pointer, typename PB_DS_CLASS_C_DEC::node_pointer> PB_DS_CLASS_C_DEC:: find_join_pos_right(node_pointer p_l, size_type h_l, size_type h_r) { _GLIBCXX_DEBUG_ASSERT(h_l >= h_r); if (base_type::m_p_head->m_p_parent == 0) return (std::make_pair((node_pointer)0, base_type::m_p_head)); node_pointer p_l_parent = base_type::m_p_head; while (h_l > h_r) { if (p_l->m_red == false) { _GLIBCXX_DEBUG_ASSERT(h_l > 0); --h_l; } p_l_parent = p_l; p_l = p_l->m_p_right; } if (!is_effectively_black(p_l)) { p_l_parent = p_l; p_l = p_l->m_p_right; } _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_l)); _GLIBCXX_DEBUG_ASSERT(black_height(p_l) == h_r); _GLIBCXX_DEBUG_ASSERT(p_l == 0 || p_l->m_p_parent == p_l_parent); return std::make_pair(p_l, p_l_parent); } PB_DS_CLASS_T_DEC std::pair< typename PB_DS_CLASS_C_DEC::node_pointer, typename PB_DS_CLASS_C_DEC::node_pointer> PB_DS_CLASS_C_DEC:: find_join_pos_left(node_pointer p_r, size_type h_l, size_type h_r) { _GLIBCXX_DEBUG_ASSERT(h_r > h_l); if (base_type::m_p_head->m_p_parent == 0) return (std::make_pair((node_pointer)0, base_type::m_p_head)); node_pointer p_r_parent = base_type::m_p_head; while (h_r > h_l) { if (p_r->m_red == false) { _GLIBCXX_DEBUG_ASSERT(h_r > 0); --h_r; } p_r_parent = p_r; p_r = p_r->m_p_left; } if (!is_effectively_black(p_r)) { p_r_parent = p_r; p_r = p_r->m_p_left; } _GLIBCXX_DEBUG_ASSERT(is_effectively_black(p_r)); _GLIBCXX_DEBUG_ASSERT(black_height(p_r) == h_l); _GLIBCXX_DEBUG_ASSERT(p_r == 0 || p_r->m_p_parent == p_r_parent); return std::make_pair(p_r, p_r_parent); } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: black_height(node_pointer p_nd) { size_type h = 1; while (p_nd != 0) { if (p_nd->m_red == false) ++h; p_nd = p_nd->m_p_left; } return h; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) if (base_type::split_prep(r_key, other) == false) { PB_DS_ASSERT_VALID((*this)) PB_DS_ASSERT_VALID(other) return; } PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) node_pointer p_nd = this->upper_bound(r_key).m_p_nd; do { node_pointer p_next_nd = p_nd->m_p_parent; if (Cmp_Fn::operator()(r_key, PB_DS_V2F(p_nd->m_value))) split_at_node(p_nd, other); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) p_nd = p_next_nd; } while (p_nd != base_type::m_p_head); base_type::split_finish(other); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: split_at_node(node_pointer p_nd, PB_DS_CLASS_C_DEC& other) { _GLIBCXX_DEBUG_ASSERT(p_nd != 0); node_pointer p_l = p_nd->m_p_left; node_pointer p_r = p_nd->m_p_right; node_pointer p_parent = p_nd->m_p_parent; if (p_parent == base_type::m_p_head) { base_type::m_p_head->m_p_parent = p_l; if (p_l != 0) { p_l->m_p_parent = base_type::m_p_head; p_l->m_red = false; } } else { if (p_parent->m_p_left == p_nd) p_parent->m_p_left = p_l; else p_parent->m_p_right = p_l; if (p_l != 0) p_l->m_p_parent = p_parent; this->update_to_top(p_parent, (node_update* )this); if (!p_nd->m_red) remove_fixup(p_l, p_parent); } base_type::initialize_min_max(); other.join_imp(p_nd, p_r); PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) PB_DS_STRUCT_ONLY_ASSERT_VALID(other) } c++/8/ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp 0000644 00000005337 15146341150 0022314 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/constructors_destructor_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC template<typename It> void PB_DS_CLASS_C_DEC:: copy_from_range(It first_it, It last_it) { while (first_it != last_it) insert(*(first_it++)); } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME() { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME(const Cmp_Fn& r_cmp_fn) : base_type(r_cmp_fn) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME(const Cmp_Fn& r_cmp_fn, const node_update& r_node_update) : base_type(r_cmp_fn, r_node_update) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC PB_DS_CLASS_C_DEC:: PB_DS_RB_TREE_NAME(const PB_DS_CLASS_C_DEC& other) : base_type(other) { initialize(); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: swap(PB_DS_CLASS_C_DEC& other) { PB_DS_ASSERT_VALID((*this)) base_type::swap(other); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: initialize() { base_type::m_p_head->m_red = true; } c++/8/ext/pb_ds/detail/rb_tree_map_/traits.hpp 0000644 00000006323 15146341150 0015055 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/traits.hpp * Contains an implementation for rb_tree_. */ #ifndef PB_DS_RB_TREE_NODE_AND_IT_TRAITS_HPP #define PB_DS_RB_TREE_NODE_AND_IT_TRAITS_HPP #include <ext/pb_ds/detail/rb_tree_map_/node.hpp> namespace __gnu_pbds { namespace detail { /// Specialization. /// @ingroup traits template<typename Key, typename Mapped, typename Cmp_Fn, template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn_, typename _Alloc_> class Node_Update, typename _Alloc> struct tree_traits<Key, Mapped, Cmp_Fn, Node_Update, rb_tree_tag,_Alloc> : public bin_search_tree_traits< Key, Mapped, Cmp_Fn, Node_Update, rb_tree_node_< typename types_traits<Key, Mapped, _Alloc, false>::value_type, typename tree_node_metadata_dispatch<Key, Mapped, Cmp_Fn, Node_Update, _Alloc>::type, _Alloc>, _Alloc> { }; /// Specialization. /// @ingroup traits template<typename Key, typename Cmp_Fn, template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn_, typename _Alloc_> class Node_Update, typename _Alloc> struct tree_traits<Key, null_type, Cmp_Fn, Node_Update, rb_tree_tag,_Alloc> : public bin_search_tree_traits< Key, null_type, Cmp_Fn, Node_Update, rb_tree_node_< typename types_traits<Key, null_type, _Alloc, false>::value_type, typename tree_node_metadata_dispatch<Key, null_type, Cmp_Fn, Node_Update, _Alloc>::type, _Alloc>, _Alloc> { }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp 0000644 00000003461 15146341150 0016215 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/info_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: is_effectively_black(const node_pointer p_nd) { return (p_nd == 0 || !p_nd->m_red); } c++/8/ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp 0000644 00000005311 15146341150 0016344 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/debug_fn_imps.hpp * Contains an implementation for rb_tree_. */ #ifdef _GLIBCXX_DEBUG PB_DS_CLASS_T_DEC typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: assert_node_consistent(const node_pointer p_nd, const char* __file, int __line) const { if (p_nd == 0) return 1; const size_type l_height = assert_node_consistent(p_nd->m_p_left, __file, __line); const size_type r_height = assert_node_consistent(p_nd->m_p_right, __file, __line); if (p_nd->m_red) { PB_DS_DEBUG_VERIFY(is_effectively_black(p_nd->m_p_left)); PB_DS_DEBUG_VERIFY(is_effectively_black(p_nd->m_p_right)); } PB_DS_DEBUG_VERIFY(l_height == r_height); return (p_nd->m_red ? 0 : 1) + l_height; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: assert_valid(const char* __file, int __line) const { base_type::assert_valid(__file, __line); const node_pointer p_head = base_type::m_p_head; PB_DS_DEBUG_VERIFY(p_head->m_red); if (p_head->m_p_parent != 0) { PB_DS_DEBUG_VERIFY(!p_head->m_p_parent->m_red); assert_node_consistent(p_head->m_p_parent, __file, __line); } } #endif c++/8/ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp 0000644 00000007433 15146341150 0016571 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/insert_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline std::pair<typename PB_DS_CLASS_C_DEC::point_iterator, bool> PB_DS_CLASS_C_DEC:: insert(const_reference r_value) { PB_DS_ASSERT_VALID((*this)) std::pair<point_iterator, bool> ins_pair = base_type::insert_leaf(r_value); if (ins_pair.second == true) { ins_pair.first.m_p_nd->m_red = true; PB_DS_STRUCT_ONLY_ASSERT_VALID((*this)) insert_fixup(ins_pair.first.m_p_nd); } PB_DS_ASSERT_VALID((*this)) return ins_pair; } PB_DS_CLASS_T_DEC inline void PB_DS_CLASS_C_DEC:: insert_fixup(node_pointer p_nd) { _GLIBCXX_DEBUG_ASSERT(p_nd->m_red == true); while (p_nd != base_type::m_p_head->m_p_parent && p_nd->m_p_parent->m_red) { if (p_nd->m_p_parent == p_nd->m_p_parent->m_p_parent->m_p_left) { node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_right; if (p_y != 0 && p_y->m_red) { p_nd->m_p_parent->m_red = false; p_y->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; p_nd = p_nd->m_p_parent->m_p_parent; } else { if (p_nd == p_nd->m_p_parent->m_p_right) { p_nd = p_nd->m_p_parent; base_type::rotate_left(p_nd); } p_nd->m_p_parent->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; base_type::rotate_right(p_nd->m_p_parent->m_p_parent); } } else { node_pointer p_y = p_nd->m_p_parent->m_p_parent->m_p_left; if (p_y != 0 && p_y->m_red) { p_nd->m_p_parent->m_red = false; p_y->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; p_nd = p_nd->m_p_parent->m_p_parent; } else { if (p_nd == p_nd->m_p_parent->m_p_left) { p_nd = p_nd->m_p_parent; base_type::rotate_right(p_nd); } p_nd->m_p_parent->m_red = false; p_nd->m_p_parent->m_p_parent->m_red = true; base_type::rotate_left(p_nd->m_p_parent->m_p_parent); } } } base_type::update_to_top(p_nd, (node_update* )this); base_type::m_p_head->m_p_parent->m_red = false; } c++/8/ext/pb_ds/detail/rb_tree_map_/node.hpp 0000644 00000007436 15146341150 0014502 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/node.hpp * Contains an implementation for rb_tree_. */ #ifndef PB_DS_RB_TREE_NODE_HPP #define PB_DS_RB_TREE_NODE_HPP #include <ext/pb_ds/detail/branch_policy/null_node_metadata.hpp> namespace __gnu_pbds { namespace detail { /// Node for Red-Black trees. template<typename Value_Type, class Metadata, typename _Alloc> struct rb_tree_node_ { public: typedef Value_Type value_type; typedef Metadata metadata_type; typedef typename _Alloc::template rebind< rb_tree_node_< Value_Type, Metadata, _Alloc> >::other::pointer node_pointer; typedef typename _Alloc::template rebind< metadata_type>::other::reference metadata_reference; typedef typename _Alloc::template rebind< metadata_type>::other::const_reference metadata_const_reference; bool special() const { return m_red; } metadata_const_reference get_metadata() const { return m_metadata; } metadata_reference get_metadata() { return m_metadata; } #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value) <<(m_red? " <r> " : " <b> ") << "(" << m_metadata << ")"; } #endif node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; value_type m_value; bool m_red; metadata_type m_metadata; }; template<typename Value_Type, typename _Alloc> struct rb_tree_node_<Value_Type, null_type, _Alloc> { public: typedef Value_Type value_type; typedef null_type metadata_type; typedef typename _Alloc::template rebind< rb_tree_node_< Value_Type, null_type, _Alloc> >::other::pointer node_pointer; bool special() const { return m_red; } #ifdef PB_DS_BIN_SEARCH_TREE_TRACE_ void trace() const { std::cout << PB_DS_V2F(m_value) <<(m_red? " <r> " : " <b> "); } #endif node_pointer m_p_left; node_pointer m_p_right; node_pointer m_p_parent; value_type m_value; bool m_red; }; } // namespace detail } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/detail/rb_tree_map_/rb_tree_.hpp 0000644 00000017432 15146341150 0015333 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/rb_tree_.hpp * Contains an implementation for Red Black trees. */ #include <ext/pb_ds/detail/standard_policies.hpp> #include <utility> #include <vector> #include <assert.h> #include <debug/debug.h> namespace __gnu_pbds { namespace detail { #define PB_DS_CLASS_T_DEC \ template<typename Key, typename Mapped, typename Cmp_Fn, \ typename Node_And_It_Traits, typename _Alloc> #ifdef PB_DS_DATA_TRUE_INDICATOR # define PB_DS_RB_TREE_NAME rb_tree_map # define PB_DS_RB_TREE_BASE_NAME bin_search_tree_map #endif #ifdef PB_DS_DATA_FALSE_INDICATOR # define PB_DS_RB_TREE_NAME rb_tree_set # define PB_DS_RB_TREE_BASE_NAME bin_search_tree_set #endif #define PB_DS_CLASS_C_DEC \ PB_DS_RB_TREE_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, _Alloc> #define PB_DS_RB_TREE_BASE \ PB_DS_RB_TREE_BASE_NAME<Key, Mapped, Cmp_Fn, Node_And_It_Traits, _Alloc> /** * @brief Red-Black tree. * @ingroup branch-detail * * This implementation uses an idea from the SGI STL (using a * @a header node which is needed for efficient iteration). */ template<typename Key, typename Mapped, typename Cmp_Fn, typename Node_And_It_Traits, typename _Alloc> class PB_DS_RB_TREE_NAME : public PB_DS_RB_TREE_BASE { private: typedef PB_DS_RB_TREE_BASE base_type; typedef typename base_type::node_pointer node_pointer; public: typedef rb_tree_tag container_category; typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; typedef typename base_type::key_type key_type; typedef typename base_type::key_pointer key_pointer; typedef typename base_type::key_const_pointer key_const_pointer; typedef typename base_type::key_reference key_reference; typedef typename base_type::key_const_reference key_const_reference; typedef typename base_type::mapped_type mapped_type; typedef typename base_type::mapped_pointer mapped_pointer; typedef typename base_type::mapped_const_pointer mapped_const_pointer; typedef typename base_type::mapped_reference mapped_reference; typedef typename base_type::mapped_const_reference mapped_const_reference; typedef typename base_type::value_type value_type; typedef typename base_type::pointer pointer; typedef typename base_type::const_pointer const_pointer; typedef typename base_type::reference reference; typedef typename base_type::const_reference const_reference; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; typedef typename base_type::reverse_iterator reverse_iterator; typedef typename base_type::const_reverse_iterator const_reverse_iterator; typedef typename base_type::node_update node_update; PB_DS_RB_TREE_NAME(); PB_DS_RB_TREE_NAME(const Cmp_Fn&); PB_DS_RB_TREE_NAME(const Cmp_Fn&, const node_update&); PB_DS_RB_TREE_NAME(const PB_DS_CLASS_C_DEC&); void swap(PB_DS_CLASS_C_DEC&); template<typename It> void copy_from_range(It, It); inline std::pair<point_iterator, bool> insert(const_reference); inline mapped_reference operator[](key_const_reference r_key) { #ifdef PB_DS_DATA_TRUE_INDICATOR _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) std::pair<point_iterator, bool> ins_pair = base_type::insert_leaf(value_type(r_key, mapped_type())); if (ins_pair.second == true) { ins_pair.first.m_p_nd->m_red = true; _GLIBCXX_DEBUG_ONLY(this->structure_only_assert_valid(__FILE__, __LINE__);) insert_fixup(ins_pair.first.m_p_nd); } _GLIBCXX_DEBUG_ONLY(assert_valid(__FILE__, __LINE__);) return ins_pair.first.m_p_nd->m_value.second; #else insert(r_key); return base_type::s_null_type; #endif } inline bool erase(key_const_reference); inline iterator erase(iterator); inline reverse_iterator erase(reverse_iterator); template<typename Pred> inline size_type erase_if(Pred); void join(PB_DS_CLASS_C_DEC&); void split(key_const_reference, PB_DS_CLASS_C_DEC&); private: #ifdef _GLIBCXX_DEBUG void assert_valid(const char*, int) const; size_type assert_node_consistent(const node_pointer, const char*, int) const; #endif inline static bool is_effectively_black(const node_pointer); void initialize(); void insert_fixup(node_pointer); void erase_node(node_pointer); void remove_node(node_pointer); void remove_fixup(node_pointer, node_pointer); void split_imp(node_pointer, PB_DS_CLASS_C_DEC&); inline node_pointer split_min(); std::pair<node_pointer, node_pointer> split_min_imp(); void join_imp(node_pointer, node_pointer); std::pair<node_pointer, node_pointer> find_join_pos_right(node_pointer, size_type, size_type); std::pair<node_pointer, node_pointer> find_join_pos_left(node_pointer, size_type, size_type); inline size_type black_height(node_pointer); void split_at_node(node_pointer, PB_DS_CLASS_C_DEC&); }; #define PB_DS_STRUCT_ONLY_ASSERT_VALID(X) \ _GLIBCXX_DEBUG_ONLY(X.structure_only_assert_valid(__FILE__, __LINE__);) #include <ext/pb_ds/detail/rb_tree_map_/constructors_destructor_fn_imps.hpp> #include <ext/pb_ds/detail/rb_tree_map_/insert_fn_imps.hpp> #include <ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp> #include <ext/pb_ds/detail/rb_tree_map_/debug_fn_imps.hpp> #include <ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp> #include <ext/pb_ds/detail/rb_tree_map_/info_fn_imps.hpp> #undef PB_DS_STRUCT_ONLY_ASSERT_VALID #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_RB_TREE_NAME #undef PB_DS_RB_TREE_BASE_NAME #undef PB_DS_RB_TREE_BASE } // namespace detail } // namespace __gnu_pbds c++/8/ext/pb_ds/detail/rb_tree_map_/find_fn_imps.hpp 0000644 00000003247 15146341150 0016204 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/find_fn_imps.hpp * Contains an implementation for rb_tree_. */ c++/8/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp 0000644 00000015613 15146341150 0016363 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file rb_tree_map_/erase_fn_imps.hpp * Contains an implementation for rb_tree_. */ PB_DS_CLASS_T_DEC inline bool PB_DS_CLASS_C_DEC:: erase(key_const_reference r_key) { point_iterator it = this->find(r_key); if (it == base_type::end()) return false; erase(it); return true; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::iterator PB_DS_CLASS_C_DEC:: erase(iterator it) { PB_DS_ASSERT_VALID((*this)) if (it == base_type::end()) return it; iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC inline typename PB_DS_CLASS_C_DEC::reverse_iterator PB_DS_CLASS_C_DEC:: erase(reverse_iterator it) { PB_DS_ASSERT_VALID((*this)) if (it.m_p_nd == base_type::m_p_head) return it; reverse_iterator ret_it = it; ++ret_it; erase_node(it.m_p_nd); PB_DS_ASSERT_VALID((*this)) return ret_it; } PB_DS_CLASS_T_DEC template<typename Pred> inline typename PB_DS_CLASS_C_DEC::size_type PB_DS_CLASS_C_DEC:: erase_if(Pred pred) { PB_DS_ASSERT_VALID((*this)) size_type num_ersd = 0; iterator it = base_type::begin(); while (it != base_type::end()) { if (pred(*it)) { ++num_ersd; it = erase(it); } else ++it; } PB_DS_ASSERT_VALID((*this)) return num_ersd; } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: erase_node(node_pointer p_nd) { remove_node(p_nd); base_type::actual_erase_node(p_nd); PB_DS_ASSERT_VALID((*this)) } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_node(node_pointer p_z) { this->update_min_max_for_erased_node(p_z); node_pointer p_y = p_z; node_pointer p_x = 0; node_pointer p_new_x_parent = 0; if (p_y->m_p_left == 0) p_x = p_y->m_p_right; else if (p_y->m_p_right == 0) p_x = p_y->m_p_left; else { p_y = p_y->m_p_right; while (p_y->m_p_left != 0) p_y = p_y->m_p_left; p_x = p_y->m_p_right; } if (p_y == p_z) { p_new_x_parent = p_y->m_p_parent; if (p_x != 0) p_x->m_p_parent = p_y->m_p_parent; if (base_type::m_p_head->m_p_parent == p_z) base_type::m_p_head->m_p_parent = p_x; else if (p_z->m_p_parent->m_p_left == p_z) { p_y->m_p_left = p_z->m_p_parent; p_z->m_p_parent->m_p_left = p_x; } else { p_y->m_p_left = 0; p_z->m_p_parent->m_p_right = p_x; } } else { p_z->m_p_left->m_p_parent = p_y; p_y->m_p_left = p_z->m_p_left; if (p_y != p_z->m_p_right) { p_new_x_parent = p_y->m_p_parent; if (p_x != 0) p_x->m_p_parent = p_y->m_p_parent; p_y->m_p_parent->m_p_left = p_x; p_y->m_p_right = p_z->m_p_right; p_z->m_p_right->m_p_parent = p_y; } else p_new_x_parent = p_y; if (base_type::m_p_head->m_p_parent == p_z) base_type::m_p_head->m_p_parent = p_y; else if (p_z->m_p_parent->m_p_left == p_z) p_z->m_p_parent->m_p_left = p_y; else p_z->m_p_parent->m_p_right = p_y; p_y->m_p_parent = p_z->m_p_parent; std::swap(p_y->m_red, p_z->m_red); p_y = p_z; } this->update_to_top(p_new_x_parent, (node_update* )this); if (p_y->m_red) return; remove_fixup(p_x, p_new_x_parent); } PB_DS_CLASS_T_DEC void PB_DS_CLASS_C_DEC:: remove_fixup(node_pointer p_x, node_pointer p_new_x_parent) { _GLIBCXX_DEBUG_ASSERT(p_x == 0 || p_x->m_p_parent == p_new_x_parent); while (p_x != base_type::m_p_head->m_p_parent && is_effectively_black(p_x)) if (p_x == p_new_x_parent->m_p_left) { node_pointer p_w = p_new_x_parent->m_p_right; if (p_w->m_red) { p_w->m_red = false; p_new_x_parent->m_red = true; base_type::rotate_left(p_new_x_parent); p_w = p_new_x_parent->m_p_right; } if (is_effectively_black(p_w->m_p_left) && is_effectively_black(p_w->m_p_right)) { p_w->m_red = true; p_x = p_new_x_parent; p_new_x_parent = p_new_x_parent->m_p_parent; } else { if (is_effectively_black(p_w->m_p_right)) { if (p_w->m_p_left != 0) p_w->m_p_left->m_red = false; p_w->m_red = true; base_type::rotate_right(p_w); p_w = p_new_x_parent->m_p_right; } p_w->m_red = p_new_x_parent->m_red; p_new_x_parent->m_red = false; if (p_w->m_p_right != 0) p_w->m_p_right->m_red = false; base_type::rotate_left(p_new_x_parent); this->update_to_top(p_new_x_parent, (node_update* )this); break; } } else { node_pointer p_w = p_new_x_parent->m_p_left; if (p_w->m_red == true) { p_w->m_red = false; p_new_x_parent->m_red = true; base_type::rotate_right(p_new_x_parent); p_w = p_new_x_parent->m_p_left; } if (is_effectively_black(p_w->m_p_right) && is_effectively_black(p_w->m_p_left)) { p_w->m_red = true; p_x = p_new_x_parent; p_new_x_parent = p_new_x_parent->m_p_parent; } else { if (is_effectively_black(p_w->m_p_left)) { if (p_w->m_p_right != 0) p_w->m_p_right->m_red = false; p_w->m_red = true; base_type::rotate_left(p_w); p_w = p_new_x_parent->m_p_left; } p_w->m_red = p_new_x_parent->m_red; p_new_x_parent->m_red = false; if (p_w->m_p_left != 0) p_w->m_p_left->m_red = false; base_type::rotate_right(p_new_x_parent); this->update_to_top(p_new_x_parent, (node_update* )this); break; } } if (p_x != 0) p_x->m_red = false; } c++/8/ext/pb_ds/exception.hpp 0000644 00000005654 15146341150 0011673 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file exception.hpp * Contains exception classes. */ #ifndef PB_DS_EXCEPTION_HPP #define PB_DS_EXCEPTION_HPP #include <bits/c++config.h> #include <stdexcept> #include <cstdlib> namespace __gnu_pbds { /** * @defgroup exceptions-pbds Exceptions * @ingroup pbds * @{ */ /// Base class for exceptions. struct container_error : public std::logic_error { container_error() : std::logic_error(__N("__gnu_pbds::container_error")) { } }; /// An entry cannot be inserted into a container object for logical /// reasons (not, e.g., if memory is unabvailable, in which case /// the allocator_type's exception will be thrown). struct insert_error : public container_error { }; /// A join cannot be performed logical reasons (i.e., the ranges of /// the two container objects being joined overlaps. struct join_error : public container_error { }; /// A container cannot be resized. struct resize_error : public container_error { }; inline void __throw_container_error() { _GLIBCXX_THROW_OR_ABORT(container_error()); } inline void __throw_insert_error() { _GLIBCXX_THROW_OR_ABORT(insert_error()); } inline void __throw_join_error() { _GLIBCXX_THROW_OR_ABORT(join_error()); } inline void __throw_resize_error() { _GLIBCXX_THROW_OR_ABORT(resize_error()); } //@} } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/hash_policy.hpp 0000644 00000040657 15146341150 0012201 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file hash_policy.hpp * Contains hash-related policies. */ #ifndef PB_DS_HASH_POLICY_HPP #define PB_DS_HASH_POLICY_HPP #include <bits/c++config.h> #include <algorithm> #include <vector> #include <cmath> #include <ext/pb_ds/exception.hpp> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/hash_fn/mask_based_range_hashing.hpp> #include <ext/pb_ds/detail/hash_fn/mod_based_range_hashing.hpp> #include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp> namespace __gnu_pbds { #define PB_DS_CLASS_T_DEC template<typename Size_Type> #define PB_DS_CLASS_C_DEC linear_probe_fn<Size_Type> /// A probe sequence policy using fixed increments. template<typename Size_Type = std::size_t> class linear_probe_fn { public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: /// Returns the i-th offset from the hash value. inline size_type operator()(size_type i) const; }; #include <ext/pb_ds/detail/hash_fn/linear_probe_fn_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template<typename Size_Type> #define PB_DS_CLASS_C_DEC quadratic_probe_fn<Size_Type> /// A probe sequence policy using square increments. template<typename Size_Type = std::size_t> class quadratic_probe_fn { public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: /// Returns the i-th offset from the hash value. inline size_type operator()(size_type i) const; }; #include <ext/pb_ds/detail/hash_fn/quadratic_probe_fn_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template<typename Size_Type> #define PB_DS_CLASS_C_DEC direct_mask_range_hashing<Size_Type> /// A mask range-hashing class (uses a bitmask). template<typename Size_Type = std::size_t> class direct_mask_range_hashing : public detail::mask_based_range_hashing<Size_Type> { private: typedef detail::mask_based_range_hashing<Size_Type> mask_based_base; public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: void notify_resized(size_type size); /// Transforms the __hash value hash into a ranged-hash value /// (using a bit-mask). inline size_type operator()(size_type hash) const; }; #include <ext/pb_ds/detail/hash_fn/direct_mask_range_hashing_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template<typename Size_Type> #define PB_DS_CLASS_C_DEC direct_mod_range_hashing<Size_Type> /// A mod range-hashing class (uses the modulo function). template<typename Size_Type = std::size_t> class direct_mod_range_hashing : public detail::mod_based_range_hashing<Size_Type> { public: typedef Size_Type size_type; void swap(PB_DS_CLASS_C_DEC& other); protected: void notify_resized(size_type size); /// Transforms the __hash value hash into a ranged-hash value /// (using a modulo operation). inline size_type operator()(size_type hash) const; private: typedef detail::mod_based_range_hashing<size_type> mod_based_base; }; #include <ext/pb_ds/detail/hash_fn/direct_mod_range_hashing_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type> #define PB_DS_CLASS_C_DEC hash_load_check_resize_trigger<External_Load_Access, Size_Type> #define PB_DS_SIZE_BASE_C_DEC detail::hash_load_check_resize_trigger_size_base<Size_Type, External_Load_Access> /// A resize trigger policy based on a load check. It keeps the /// load factor between some load factors load_min and load_max. template<bool External_Load_Access = false, typename Size_Type = std::size_t> class hash_load_check_resize_trigger : private PB_DS_SIZE_BASE_C_DEC { public: typedef Size_Type size_type; enum { /// Specifies whether the load factor can be accessed /// externally. The two options have different trade-offs in /// terms of flexibility, genericity, and encapsulation. external_load_access = External_Load_Access }; /// Default constructor, or constructor taking load_min and /// load_max load factors between which this policy will keep the /// actual load. hash_load_check_resize_trigger(float load_min = 0.125, float load_max = 0.5); void swap(hash_load_check_resize_trigger& other); virtual ~hash_load_check_resize_trigger(); /// Returns a pair of the minimal and maximal loads, respectively. inline std::pair<float, float> get_loads() const; /// Sets the loads through a pair of the minimal and maximal /// loads, respectively. void set_loads(std::pair<float, float> load_pair); protected: inline void notify_insert_search_start(); inline void notify_insert_search_collision(); inline void notify_insert_search_end(); inline void notify_find_search_start(); inline void notify_find_search_collision(); inline void notify_find_search_end(); inline void notify_erase_search_start(); inline void notify_erase_search_collision(); inline void notify_erase_search_end(); /// Notifies an element was inserted. The total number of entries /// in the table is num_entries. inline void notify_inserted(size_type num_entries); inline void notify_erased(size_type num_entries); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized as a result of this object's /// signifying that a resize is needed. void notify_resized(size_type new_size); void notify_externally_resized(size_type new_size); inline bool is_resize_needed() const; inline bool is_grow_needed(size_type size, size_type num_entries) const; private: virtual void do_resize(size_type new_size); typedef PB_DS_SIZE_BASE_C_DEC size_base; #ifdef _GLIBCXX_DEBUG void assert_valid(const char* file, int line) const; #endif float m_load_min; float m_load_max; size_type m_next_shrink_size; size_type m_next_grow_size; bool m_resize_needed; }; #include <ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_SIZE_BASE_C_DEC #define PB_DS_CLASS_T_DEC template<bool External_Load_Access, typename Size_Type> #define PB_DS_CLASS_C_DEC cc_hash_max_collision_check_resize_trigger<External_Load_Access, Size_Type> /// A resize trigger policy based on collision checks. It keeps the /// simulated load factor lower than some given load factor. template<bool External_Load_Access = false, typename Size_Type = std::size_t> class cc_hash_max_collision_check_resize_trigger { public: typedef Size_Type size_type; enum { /// Specifies whether the load factor can be accessed /// externally. The two options have different trade-offs in /// terms of flexibility, genericity, and encapsulation. external_load_access = External_Load_Access }; /// Default constructor, or constructor taking load, a __load /// factor which it will attempt to maintain. cc_hash_max_collision_check_resize_trigger(float load = 0.5); void swap(PB_DS_CLASS_C_DEC& other); /// Returns the current load. inline float get_load() const; /// Sets the load; does not resize the container. void set_load(float load); protected: /// Notifies an insert search started. inline void notify_insert_search_start(); /// Notifies a search encountered a collision. inline void notify_insert_search_collision(); /// Notifies a search ended. inline void notify_insert_search_end(); /// Notifies a find search started. inline void notify_find_search_start(); /// Notifies a search encountered a collision. inline void notify_find_search_collision(); /// Notifies a search ended. inline void notify_find_search_end(); /// Notifies an erase search started. inline void notify_erase_search_start(); /// Notifies a search encountered a collision. inline void notify_erase_search_collision(); /// Notifies a search ended. inline void notify_erase_search_end(); /// Notifies an element was inserted. inline void notify_inserted(size_type num_entries); /// Notifies an element was erased. inline void notify_erased(size_type num_entries); /// Notifies the table was cleared. void notify_cleared(); /// Notifies the table was resized as a result of this object's /// signifying that a resize is needed. void notify_resized(size_type new_size); /// Notifies the table was resized externally. void notify_externally_resized(size_type new_size); /// Queries whether a resize is needed. inline bool is_resize_needed() const; /// Queries whether a grow is needed. This method is called only /// if this object indicated is needed. inline bool is_grow_needed(size_type size, size_type num_entries) const; private: void calc_max_num_coll(); inline void calc_resize_needed(); float m_load; size_type m_size; size_type m_num_col; size_type m_max_col; bool m_resize_needed; }; #include <ext/pb_ds/detail/resize_policy/cc_hash_max_collision_check_resize_trigger_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template<typename Size_Type> #define PB_DS_CLASS_C_DEC hash_exponential_size_policy<Size_Type> /// A size policy whose sequence of sizes form an exponential /// sequence (typically powers of 2. template<typename Size_Type = std::size_t> class hash_exponential_size_policy { public: typedef Size_Type size_type; /// Default constructor, or onstructor taking a start_size, or /// constructor taking a start size and grow_factor. The policy /// will use the sequence of sizes start_size, start_size* /// grow_factor, start_size* grow_factor^2, ... hash_exponential_size_policy(size_type start_size = 8, size_type grow_factor = 2); void swap(PB_DS_CLASS_C_DEC& other); protected: size_type get_nearest_larger_size(size_type size) const; size_type get_nearest_smaller_size(size_type size) const; private: size_type m_start_size; size_type m_grow_factor; }; #include <ext/pb_ds/detail/resize_policy/hash_exponential_size_policy_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC #define PB_DS_CLASS_C_DEC hash_prime_size_policy /// A size policy whose sequence of sizes form a nearly-exponential /// sequence of primes. class hash_prime_size_policy { public: /// Size type. typedef std::size_t size_type; /// Default constructor, or onstructor taking a start_size The /// policy will use the sequence of sizes approximately /// start_size, start_size* 2, start_size* 2^2, ... hash_prime_size_policy(size_type start_size = 8); inline void swap(PB_DS_CLASS_C_DEC& other); protected: size_type get_nearest_larger_size(size_type size) const; size_type get_nearest_smaller_size(size_type size) const; private: size_type m_start_size; }; #include <ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC template<typename Size_Policy, typename Trigger_Policy, bool External_Size_Access, typename Size_Type> #define PB_DS_CLASS_C_DEC hash_standard_resize_policy<Size_Policy, Trigger_Policy, External_Size_Access, Size_Type> /// A resize policy which delegates operations to size and trigger policies. template<typename Size_Policy = hash_exponential_size_policy<>, typename Trigger_Policy = hash_load_check_resize_trigger<>, bool External_Size_Access = false, typename Size_Type = std::size_t> class hash_standard_resize_policy : public Size_Policy, public Trigger_Policy { public: typedef Size_Type size_type; typedef Trigger_Policy trigger_policy; typedef Size_Policy size_policy; enum { external_size_access = External_Size_Access }; /// Default constructor. hash_standard_resize_policy(); /// constructor taking some policies r_size_policy will be copied /// by the Size_Policy object of this object. hash_standard_resize_policy(const Size_Policy& r_size_policy); /// constructor taking some policies. r_size_policy will be /// copied by the Size_Policy object of this /// object. r_trigger_policy will be copied by the Trigger_Policy /// object of this object. hash_standard_resize_policy(const Size_Policy& r_size_policy, const Trigger_Policy& r_trigger_policy); virtual ~hash_standard_resize_policy(); inline void swap(PB_DS_CLASS_C_DEC& other); /// Access to the Size_Policy object used. Size_Policy& get_size_policy(); /// Const access to the Size_Policy object used. const Size_Policy& get_size_policy() const; /// Access to the Trigger_Policy object used. Trigger_Policy& get_trigger_policy(); /// Access to the Trigger_Policy object used. const Trigger_Policy& get_trigger_policy() const; /// Returns the actual size of the container. inline size_type get_actual_size() const; /// Resizes the container to suggested_new_size, a suggested size /// (the actual size will be determined by the Size_Policy /// object). void resize(size_type suggested_new_size); protected: inline void notify_insert_search_start(); inline void notify_insert_search_collision(); inline void notify_insert_search_end(); inline void notify_find_search_start(); inline void notify_find_search_collision(); inline void notify_find_search_end(); inline void notify_erase_search_start(); inline void notify_erase_search_collision(); inline void notify_erase_search_end(); inline void notify_inserted(size_type num_e); inline void notify_erased(size_type num_e); void notify_cleared(); void notify_resized(size_type new_size); inline bool is_resize_needed() const; /// Queries what the new size should be, when the container is /// resized naturally. The current __size of the container is /// size, and the number of used entries within the container is /// num_used_e. size_type get_new_size(size_type size, size_type num_used_e) const; private: /// Resizes to new_size. virtual void do_resize(size_type new_size); typedef Trigger_Policy trigger_policy_base; typedef Size_Policy size_policy_base; size_type m_size; }; #include <ext/pb_ds/detail/resize_policy/hash_standard_resize_policy_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/trie_policy.hpp 0000644 00000027701 15146341150 0012214 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file trie_policy.hpp * Contains trie-related policies. */ #ifndef PB_DS_TRIE_POLICY_HPP #define PB_DS_TRIE_POLICY_HPP #include <bits/c++config.h> #include <string> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/trie_policy/trie_policy_base.hpp> namespace __gnu_pbds { #define PB_DS_CLASS_T_DEC \ template<typename String, typename String::value_type Min_E_Val, \ typename String::value_type Max_E_Val, bool Reverse, \ typename _Alloc> #define PB_DS_CLASS_C_DEC \ trie_string_access_traits<String, Min_E_Val,Max_E_Val,Reverse,_Alloc> /** * Element access traits for string types. * * @tparam String String type. * @tparam Min_E_Val Minimal element value. * @tparam Max_E_Val Maximum element value. * @tparam Reverse Reverse iteration should be used. * Default: false. * @tparam _Alloc Allocator type. */ template<typename String = std::string, typename String::value_type Min_E_Val = detail::__numeric_traits<typename String::value_type>::__min, typename String::value_type Max_E_Val = detail::__numeric_traits<typename String::value_type>::__max, bool Reverse = false, typename _Alloc = std::allocator<char> > struct trie_string_access_traits { public: typedef typename _Alloc::size_type size_type; typedef String key_type; typedef typename _Alloc::template rebind<key_type> __rebind_k; typedef typename __rebind_k::other::const_reference key_const_reference; enum { reverse = Reverse }; /// Element const iterator type. typedef typename detail::__conditional_type<Reverse, \ typename String::const_reverse_iterator, \ typename String::const_iterator>::__type const_iterator; /// Element type. typedef typename std::iterator_traits<const_iterator>::value_type e_type; enum { min_e_val = Min_E_Val, max_e_val = Max_E_Val, max_size = max_e_val - min_e_val + 1 }; PB_DS_STATIC_ASSERT(min_max_size, max_size >= 2); /// Returns a const_iterator to the first element of /// key_const_reference agumnet. inline static const_iterator begin(key_const_reference); /// Returns a const_iterator to the after-last element of /// key_const_reference argument. inline static const_iterator end(key_const_reference); /// Maps an element to a position. inline static size_type e_pos(e_type e); private: inline static const_iterator begin_imp(key_const_reference, detail::false_type); inline static const_iterator begin_imp(key_const_reference, detail::true_type); inline static const_iterator end_imp(key_const_reference, detail::false_type); inline static const_iterator end_imp(key_const_reference, detail::true_type); static detail::integral_constant<int, Reverse> s_rev_ind; }; #include <ext/pb_ds/detail/trie_policy/trie_string_access_traits_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_T_DEC \ template<typename Node_CItr,typename Node_Itr, \ typename _ATraits, typename _Alloc> #define PB_DS_CLASS_C_DEC \ trie_prefix_search_node_update<Node_CItr, Node_Itr, \ _ATraits,_Alloc> #define PB_DS_TRIE_POLICY_BASE \ detail::trie_policy_base<Node_CItr,Node_Itr,_ATraits, _Alloc> /// A node updator that allows tries to be searched for the range of /// values that match a certain prefix. template<typename Node_CItr, typename Node_Itr, typename _ATraits, typename _Alloc> class trie_prefix_search_node_update : private PB_DS_TRIE_POLICY_BASE { private: typedef PB_DS_TRIE_POLICY_BASE base_type; public: typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; /// Element access traits. typedef _ATraits access_traits; /// Const element iterator. typedef typename access_traits::const_iterator a_const_iterator; /// _Alloc type. typedef _Alloc allocator_type; /// Size type. typedef typename allocator_type::size_type size_type; typedef null_type metadata_type; typedef Node_Itr node_iterator; typedef Node_CItr node_const_iterator; typedef typename node_iterator::value_type iterator; typedef typename node_const_iterator::value_type const_iterator; /// Finds the const iterator range corresponding to all values /// whose prefixes match r_key. std::pair<const_iterator, const_iterator> prefix_range(key_const_reference) const; /// Finds the iterator range corresponding to all values whose /// prefixes match r_key. std::pair<iterator, iterator> prefix_range(key_const_reference); /// Finds the const iterator range corresponding to all values /// whose prefixes match [b, e). std::pair<const_iterator, const_iterator> prefix_range(a_const_iterator, a_const_iterator) const; /// Finds the iterator range corresponding to all values whose /// prefixes match [b, e). std::pair<iterator, iterator> prefix_range(a_const_iterator, a_const_iterator); protected: /// Called to update a node's metadata. inline void operator()(node_iterator node_it, node_const_iterator end_nd_it) const; private: node_iterator next_child(node_iterator, a_const_iterator, a_const_iterator, node_iterator, const access_traits&); /// Returns the const iterator associated with the just-after last element. virtual const_iterator end() const = 0; /// Returns the iterator associated with the just-after last element. virtual iterator end() = 0; /// Returns the node_const_iterator associated with the trie's root node. virtual node_const_iterator node_begin() const = 0; /// Returns the node_iterator associated with the trie's root node. virtual node_iterator node_begin() = 0; /// Returns the node_const_iterator associated with a just-after leaf node. virtual node_const_iterator node_end() const = 0; /// Returns the node_iterator associated with a just-after leaf node. virtual node_iterator node_end() = 0; /// Access to the cmp_fn object. virtual const access_traits& get_access_traits() const = 0; }; #include <ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp> #undef PB_DS_CLASS_C_DEC #define PB_DS_CLASS_C_DEC \ trie_order_statistics_node_update<Node_CItr, Node_Itr, \ _ATraits, _Alloc> /// Functor updating ranks of entrees. template<typename Node_CItr, typename Node_Itr, typename _ATraits, typename _Alloc> class trie_order_statistics_node_update : private PB_DS_TRIE_POLICY_BASE { private: typedef PB_DS_TRIE_POLICY_BASE base_type; public: typedef _ATraits access_traits; typedef typename access_traits::const_iterator a_const_iterator; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; typedef size_type metadata_type; typedef Node_CItr node_const_iterator; typedef Node_Itr node_iterator; typedef typename node_const_iterator::value_type const_iterator; typedef typename node_iterator::value_type iterator; /// Finds an entry by __order. Returns a const_iterator to the /// entry with the __order order, or a const_iterator to the /// container object's end if order is at least the size of the /// container object. inline const_iterator find_by_order(size_type) const; /// Finds an entry by __order. Returns an iterator to the entry /// with the __order order, or an iterator to the container /// object's end if order is at least the size of the container /// object. inline iterator find_by_order(size_type); /// Returns the order of a key within a sequence. For exapmle, if /// r_key is the smallest key, this method will return 0; if r_key /// is a key between the smallest and next key, this method will /// return 1; if r_key is a key larger than the largest key, this /// method will return the size of r_c. inline size_type order_of_key(key_const_reference) const; /// Returns the order of a prefix within a sequence. For exapmle, /// if [b, e] is the smallest prefix, this method will return 0; if /// r_key is a key between the smallest and next key, this method /// will return 1; if r_key is a key larger than the largest key, /// this method will return the size of r_c. inline size_type order_of_prefix(a_const_iterator, a_const_iterator) const; protected: /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator, node_const_iterator) const; private: typedef typename base_type::const_reference const_reference; typedef typename base_type::const_pointer const_pointer; typedef typename _Alloc::template rebind<metadata_type> __rebind_m; typedef typename __rebind_m::other __rebind_ma; typedef typename __rebind_ma::const_reference metadata_const_reference; typedef typename __rebind_ma::reference metadata_reference; /// Returns true if the container is empty. virtual bool empty() const = 0; /// Returns the iterator associated with the trie's first element. virtual iterator begin() = 0; /// Returns the iterator associated with the trie's /// just-after-last element. virtual iterator end() = 0; /// Returns the node_const_iterator associated with the trie's root node. virtual node_const_iterator node_begin() const = 0; /// Returns the node_iterator associated with the trie's root node. virtual node_iterator node_begin() = 0; /// Returns the node_const_iterator associated with a just-after /// leaf node. virtual node_const_iterator node_end() const = 0; /// Returns the node_iterator associated with a just-after leaf node. virtual node_iterator node_end() = 0; /// Access to the cmp_fn object. virtual access_traits& get_access_traits() = 0; }; #include <ext/pb_ds/detail/trie_policy/order_statistics_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_TRIE_POLICY_BASE } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/assoc_container.hpp 0000644 00000072636 15146341150 0013053 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file assoc_container.hpp * Contains associative containers. */ #ifndef PB_DS_ASSOC_CNTNR_HPP #define PB_DS_ASSOC_CNTNR_HPP #include <bits/c++config.h> #include <ext/typelist.h> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/detail/standard_policies.hpp> #include <ext/pb_ds/detail/container_base_dispatch.hpp> #include <ext/pb_ds/detail/branch_policy/traits.hpp> namespace __gnu_pbds { /** * @defgroup containers-pbds Containers * @ingroup pbds * @{ */ /** * @defgroup hash-based Hash-Based * @ingroup containers-pbds * @{ */ #define PB_DS_HASH_BASE \ detail::container_base_dispatch<Key, Mapped, _Alloc, Tag, \ typename __gnu_cxx::typelist::append< \ typename __gnu_cxx::typelist::create4<Hash_Fn, Eq_Fn, Resize_Policy, \ detail::integral_constant<int, Store_Hash> >::type, Policy_Tl>::type>::type /** * @defgroup hash-detail Base and Policy Classes * @ingroup hash-based */ /** * A hashed container abstraction. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Hash_Fn Hashing functor. * @tparam Eq_Fn Equal functor. * @tparam Resize_Policy Resizes hash. * @tparam Store_Hash Indicates whether the hash value * will be stored along with each key. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Policy_TL Policy typelist. * @tparam _Alloc Allocator type. * * Base is dispatched at compile time via Tag, from the following * choices: cc_hash_tag, gp_hash_tag, and descendants of basic_hash_tag. * * Base choices are: detail::cc_ht_map, detail::gp_ht_map */ template<typename Key, typename Mapped, typename Hash_Fn, typename Eq_Fn, typename Resize_Policy, bool Store_Hash, typename Tag, typename Policy_Tl, typename _Alloc> class basic_hash_table : public PB_DS_HASH_BASE { private: typedef typename PB_DS_HASH_BASE base_type; public: virtual ~basic_hash_table() { } protected: basic_hash_table() { } basic_hash_table(const basic_hash_table& other) : base_type((const base_type&)other) { } template<typename T0> basic_hash_table(T0 t0) : base_type(t0) { } template<typename T0, typename T1> basic_hash_table(T0 t0, T1 t1) : base_type(t0, t1) { } template<typename T0, typename T1, typename T2> basic_hash_table(T0 t0, T1 t1, T2 t2) : base_type(t0, t1, t2) { } template<typename T0, typename T1, typename T2, typename T3> basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3) : base_type(t0, t1, t2, t3) { } template<typename T0, typename T1, typename T2, typename T3, typename T4> basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) : base_type(t0, t1, t2, t3, t4) { } template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5> basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) : base_type(t0, t1, t2, t3, t4, t5) { } template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) : base_type(t0, t1, t2, t3, t4, t5, t6) { } template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) : base_type(t0, t1, t2, t3, t4, t5, t6, t7) { } template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> basic_hash_table(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) : base_type(t0, t1, t2, t3, t4, t5, t6, t7, t8) { } private: basic_hash_table& operator=(const base_type&); }; #undef PB_DS_HASH_BASE #define PB_DS_CC_HASH_BASE \ basic_hash_table<Key, Mapped, Hash_Fn, Eq_Fn, Resize_Policy, Store_Hash, \ cc_hash_tag, \ typename __gnu_cxx::typelist::create1<Comb_Hash_Fn>::type, _Alloc> /** * A collision-chaining hash-based associative container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Hash_Fn Hashing functor. * @tparam Eq_Fn Equal functor. * @tparam Comb_Hash_Fn Combining hash functor. * If Hash_Fn is not null_type, then this * is the ranged-hash functor; otherwise, * this is the range-hashing functor. * XXX(See Design::Hash-Based Containers::Hash Policies.) * @tparam Resize_Policy Resizes hash. * @tparam Store_Hash Indicates whether the hash value * will be stored along with each key. * If Hash_Fn is null_type, then the * container will not compile if this * value is true * @tparam _Alloc Allocator type. * * Base tag choices are: cc_hash_tag. * * Base is basic_hash_table. */ template<typename Key, typename Mapped, typename Hash_Fn = typename detail::default_hash_fn<Key>::type, typename Eq_Fn = typename detail::default_eq_fn<Key>::type, typename Comb_Hash_Fn = detail::default_comb_hash_fn::type, typename Resize_Policy = typename detail::default_resize_policy<Comb_Hash_Fn>::type, bool Store_Hash = detail::default_store_hash, typename _Alloc = std::allocator<char> > class cc_hash_table : public PB_DS_CC_HASH_BASE { private: typedef PB_DS_CC_HASH_BASE base_type; public: typedef cc_hash_tag container_category; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Resize_Policy resize_policy; typedef Comb_Hash_Fn comb_hash_fn; /// Default constructor. cc_hash_table() { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the Hash_Fn object of the container object. cc_hash_table(const hash_fn& h) : base_type(h) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, and /// r_eq_fn will be copied by the eq_fn object of the container /// object. cc_hash_table(const hash_fn& h, const eq_fn& e) : base_type(h, e) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// and r_comb_hash_fn will be copied by the comb_hash_fn object /// of the container object. cc_hash_table(const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch) : base_type(h, e, ch) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// r_comb_hash_fn will be copied by the comb_hash_fn object of /// the container object, and r_resize_policy will be copied by /// the resize_policy object of the container object. cc_hash_table(const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch, const resize_policy& rp) : base_type(h, e, ch, rp) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template<typename It> cc_hash_table(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. template<typename It> cc_hash_table(It first, It last, const hash_fn& h) : base_type(h) { this->copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// and r_eq_fn will be copied by the eq_fn object of the /// container object. template<typename It> cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e) : base_type(h, e) { this->copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, and r_comb_hash_fn will be copied by the comb_hash_fn /// object of the container object. template<typename It> cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch) : base_type(h, e, ch) { this->copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, r_comb_hash_fn will be copied by the comb_hash_fn /// object of the container object, and r_resize_policy will be /// copied by the resize_policy object of the container object. template<typename It> cc_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_hash_fn& ch, const resize_policy& rp) : base_type(h, e, ch, rp) { this->copy_from_range(first, last); } cc_hash_table(const cc_hash_table& other) : base_type((const base_type&)other) { } virtual ~cc_hash_table() { } cc_hash_table& operator=(const cc_hash_table& other) { if (this != &other) { cc_hash_table tmp(other); swap(tmp); } return *this; } void swap(cc_hash_table& other) { base_type::swap(other); } }; #undef PB_DS_CC_HASH_BASE #define PB_DS_GP_HASH_BASE \ basic_hash_table<Key, Mapped, Hash_Fn, Eq_Fn, Resize_Policy, Store_Hash, \ gp_hash_tag, \ typename __gnu_cxx::typelist::create2<Comb_Probe_Fn, Probe_Fn>::type, _Alloc> /** * A general-probing hash-based associative container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Hash_Fn Hashing functor. * @tparam Eq_Fn Equal functor. * @tparam Comb_Probe_Fn Combining probe functor. * If Hash_Fn is not null_type, then this * is the ranged-probe functor; otherwise, * this is the range-hashing functor. * XXX See Design::Hash-Based Containers::Hash Policies. * @tparam Probe_Fn Probe functor. * @tparam Resize_Policy Resizes hash. * @tparam Store_Hash Indicates whether the hash value * will be stored along with each key. * If Hash_Fn is null_type, then the * container will not compile if this * value is true * @tparam _Alloc Allocator type. * * Base tag choices are: gp_hash_tag. * * Base is basic_hash_table. */ template<typename Key, typename Mapped, typename Hash_Fn = typename detail::default_hash_fn<Key>::type, typename Eq_Fn = typename detail::default_eq_fn<Key>::type, typename Comb_Probe_Fn = detail::default_comb_hash_fn::type, typename Probe_Fn = typename detail::default_probe_fn<Comb_Probe_Fn>::type, typename Resize_Policy = typename detail::default_resize_policy<Comb_Probe_Fn>::type, bool Store_Hash = detail::default_store_hash, typename _Alloc = std::allocator<char> > class gp_hash_table : public PB_DS_GP_HASH_BASE { private: typedef PB_DS_GP_HASH_BASE base_type; public: typedef gp_hash_tag container_category; typedef Hash_Fn hash_fn; typedef Eq_Fn eq_fn; typedef Comb_Probe_Fn comb_probe_fn; typedef Probe_Fn probe_fn; typedef Resize_Policy resize_policy; /// Default constructor. gp_hash_table() { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object. gp_hash_table(const hash_fn& h) : base_type(h) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, and /// r_eq_fn will be copied by the eq_fn object of the container /// object. gp_hash_table(const hash_fn& h, const eq_fn& e) : base_type(h, e) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// and r_comb_probe_fn will be copied by the comb_probe_fn object /// of the container object. gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp) : base_type(h, e, cp) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// r_comb_probe_fn will be copied by the comb_probe_fn object of /// the container object, and r_probe_fn will be copied by the /// probe_fn object of the container object. gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p) : base_type(h, e, cp, p) { } /// Constructor taking some policy objects. r_hash_fn will be /// copied by the hash_fn object of the container object, r_eq_fn /// will be copied by the eq_fn object of the container object, /// r_comb_probe_fn will be copied by the comb_probe_fn object of /// the container object, r_probe_fn will be copied by the /// probe_fn object of the container object, and r_resize_policy /// will be copied by the Resize_Policy object of the container /// object. gp_hash_table(const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p, const resize_policy& rp) : base_type(h, e, cp, p, rp) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template<typename It> gp_hash_table(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object. template<typename It> gp_hash_table(It first, It last, const hash_fn& h) : base_type(h) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// and r_eq_fn will be copied by the eq_fn object of the /// container object. template<typename It> gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e) : base_type(h, e) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, and r_comb_probe_fn will be copied by the /// comb_probe_fn object of the container object. template<typename It> gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp) : base_type(h, e, cp) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, r_comb_probe_fn will be copied by the comb_probe_fn /// object of the container object, and r_probe_fn will be copied /// by the probe_fn object of the container object. template<typename It> gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p) : base_type(h, e, cp, p) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. r_hash_fn /// will be copied by the hash_fn object of the container object, /// r_eq_fn will be copied by the eq_fn object of the container /// object, r_comb_probe_fn will be copied by the comb_probe_fn /// object of the container object, r_probe_fn will be copied by /// the probe_fn object of the container object, and /// r_resize_policy will be copied by the resize_policy object of /// the container object. template<typename It> gp_hash_table(It first, It last, const hash_fn& h, const eq_fn& e, const comb_probe_fn& cp, const probe_fn& p, const resize_policy& rp) : base_type(h, e, cp, p, rp) { base_type::copy_from_range(first, last); } gp_hash_table(const gp_hash_table& other) : base_type((const base_type&)other) { } virtual ~gp_hash_table() { } gp_hash_table& operator=(const gp_hash_table& other) { if (this != &other) { gp_hash_table tmp(other); swap(tmp); } return *this; } void swap(gp_hash_table& other) { base_type::swap(other); } }; //@} hash-based #undef PB_DS_GP_HASH_BASE /** * @defgroup branch-based Branch-Based * @ingroup containers-pbds * @{ */ #define PB_DS_BRANCH_BASE \ detail::container_base_dispatch<Key, Mapped, _Alloc, Tag, Policy_Tl>::type /** * @defgroup branch-detail Base and Policy Classes * @ingroup branch-based */ /** * A branched, tree-like (tree, trie) container abstraction. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Node_Update Updates nodes, restores invariants. * @tparam Policy_TL Policy typelist. * @tparam _Alloc Allocator type. * * Base is dispatched at compile time via Tag, from the following * choices: tree_tag, trie_tag, and their descendants. * * Base choices are: detail::ov_tree_map, detail::rb_tree_map, * detail::splay_tree_map, and detail::pat_trie_map. */ template<typename Key, typename Mapped, typename Tag, typename Node_Update, typename Policy_Tl, typename _Alloc> class basic_branch : public PB_DS_BRANCH_BASE { private: typedef typename PB_DS_BRANCH_BASE base_type; public: typedef Node_Update node_update; virtual ~basic_branch() { } protected: basic_branch() { } basic_branch(const basic_branch& other) : base_type((const base_type&)other) { } template<typename T0> basic_branch(T0 t0) : base_type(t0) { } template<typename T0, typename T1> basic_branch(T0 t0, T1 t1) : base_type(t0, t1) { } template<typename T0, typename T1, typename T2> basic_branch(T0 t0, T1 t1, T2 t2) : base_type(t0, t1, t2) { } template<typename T0, typename T1, typename T2, typename T3> basic_branch(T0 t0, T1 t1, T2 t2, T3 t3) : base_type(t0, t1, t2, t3) { } template<typename T0, typename T1, typename T2, typename T3, typename T4> basic_branch(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4) : base_type(t0, t1, t2, t3, t4) { } template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5> basic_branch(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) : base_type(t0, t1, t2, t3, t4, t5) { } template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> basic_branch(T0 t0, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) : base_type(t0, t1, t2, t3, t4, t5, t6) { } }; #undef PB_DS_BRANCH_BASE #define PB_DS_TREE_NODE_AND_IT_TRAITS \ detail::tree_traits<Key, Mapped,Cmp_Fn,Node_Update,Tag,_Alloc> #define PB_DS_TREE_BASE \ basic_branch<Key,Mapped, Tag, \ typename PB_DS_TREE_NODE_AND_IT_TRAITS::node_update, \ typename __gnu_cxx::typelist::create2<Cmp_Fn, \ PB_DS_TREE_NODE_AND_IT_TRAITS>::type, _Alloc> /** * A tree-based container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Cmp_Fn Comparison functor. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Node_Update Updates tree internal-nodes, * restores invariants when invalidated. * XXX See design::tree-based-containers::node invariants. * @tparam _Alloc Allocator type. * * Base tag choices are: ov_tree_tag, rb_tree_tag, splay_tree_tag. * * Base is basic_branch. */ template<typename Key, typename Mapped, typename Cmp_Fn = std::less<Key>, typename Tag = rb_tree_tag, template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn_, typename _Alloc_> class Node_Update = null_node_update, typename _Alloc = std::allocator<char> > class tree : public PB_DS_TREE_BASE { private: typedef PB_DS_TREE_BASE base_type; public: /// Comparison functor type. typedef Cmp_Fn cmp_fn; tree() { } /// Constructor taking some policy objects. r_cmp_fn will be /// copied by the Cmp_Fn object of the container object. tree(const cmp_fn& c) : base_type(c) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template<typename It> tree(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_cmp_fn /// will be copied by the cmp_fn object of the container object. template<typename It> tree(It first, It last, const cmp_fn& c) : base_type(c) { base_type::copy_from_range(first, last); } tree(const tree& other) : base_type((const base_type&)other) { } virtual ~tree() { } tree& operator=(const tree& other) { if (this != &other) { tree tmp(other); swap(tmp); } return *this; } void swap(tree& other) { base_type::swap(other); } }; #undef PB_DS_TREE_BASE #undef PB_DS_TREE_NODE_AND_IT_TRAITS #define PB_DS_TRIE_NODE_AND_IT_TRAITS \ detail::trie_traits<Key,Mapped,_ATraits,Node_Update,Tag,_Alloc> #define PB_DS_TRIE_BASE \ basic_branch<Key,Mapped,Tag, \ typename PB_DS_TRIE_NODE_AND_IT_TRAITS::node_update, \ typename __gnu_cxx::typelist::create2<_ATraits, \ PB_DS_TRIE_NODE_AND_IT_TRAITS >::type, _Alloc> /** * A trie-based container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam _ATraits Element access traits. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam Node_Update Updates trie internal-nodes, * restores invariants when invalidated. * XXX See design::tree-based-containers::node invariants. * @tparam _Alloc Allocator type. * * Base tag choice is pat_trie_tag. * * Base is basic_branch. */ template<typename Key, typename Mapped, typename _ATraits = \ typename detail::default_trie_access_traits<Key>::type, typename Tag = pat_trie_tag, template<typename Node_CItr, typename Node_Itr, typename _ATraits_, typename _Alloc_> class Node_Update = null_node_update, typename _Alloc = std::allocator<char> > class trie : public PB_DS_TRIE_BASE { private: typedef PB_DS_TRIE_BASE base_type; public: /// Element access traits type. typedef _ATraits access_traits; trie() { } /// Constructor taking some policy objects. r_access_traits will /// be copied by the _ATraits object of the container object. trie(const access_traits& t) : base_type(t) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template<typename It> trie(It first, It last) { base_type::copy_from_range(first, last); } /// Constructor taking __iterators to a range of value_types and /// some policy objects. The value_types between first_it and /// last_it will be inserted into the container object. template<typename It> trie(It first, It last, const access_traits& t) : base_type(t) { base_type::copy_from_range(first, last); } trie(const trie& other) : base_type((const base_type&)other) { } virtual ~trie() { } trie& operator=(const trie& other) { if (this != &other) { trie tmp(other); swap(tmp); } return *this; } void swap(trie& other) { base_type::swap(other); } }; //@} branch-based #undef PB_DS_TRIE_BASE #undef PB_DS_TRIE_NODE_AND_IT_TRAITS /** * @defgroup list-based List-Based * @ingroup containers-pbds * @{ */ #define PB_DS_LU_BASE \ detail::container_base_dispatch<Key, Mapped, _Alloc, list_update_tag, \ typename __gnu_cxx::typelist::create2<Eq_Fn, Update_Policy>::type>::type /** * A list-update based associative container. * * @tparam Key Key type. * @tparam Mapped Map type. * @tparam Eq_Fn Equal functor. * @tparam Update_Policy Update policy, determines when an element * will be moved to the front of the list. * @tparam _Alloc Allocator type. * * Base is detail::lu_map. */ template<typename Key, typename Mapped, class Eq_Fn = typename detail::default_eq_fn<Key>::type, class Update_Policy = detail::default_update_policy::type, class _Alloc = std::allocator<char> > class list_update : public PB_DS_LU_BASE { private: typedef typename PB_DS_LU_BASE base_type; public: typedef list_update_tag container_category; typedef Eq_Fn eq_fn; typedef Update_Policy update_policy; list_update() { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template<typename It> list_update(It first, It last) { base_type::copy_from_range(first, last); } list_update(const list_update& other) : base_type((const base_type&)other) { } virtual ~list_update() { } list_update& operator=(const list_update& other) { if (this !=& other) { list_update tmp(other); swap(tmp); } return *this; } void swap(list_update& other) { base_type::swap(other); } }; //@} list-based #undef PB_DS_LU_BASE // @} group containers-pbds } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/tree_policy.hpp 0000644 00000012711 15146341150 0012203 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tree_policy.hpp * Contains tree-related policies. */ #ifndef PB_DS_TREE_POLICY_HPP #define PB_DS_TREE_POLICY_HPP #include <bits/c++config.h> #include <iterator> #include <ext/pb_ds/detail/type_utils.hpp> #include <ext/pb_ds/detail/branch_policy/branch_policy.hpp> namespace __gnu_pbds { #define PB_DS_CLASS_T_DEC \ template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn, \ typename _Alloc> #define PB_DS_CLASS_C_DEC \ tree_order_statistics_node_update<Node_CItr, Node_Itr, Cmp_Fn, _Alloc> #define PB_DS_BRANCH_POLICY_BASE \ detail::branch_policy<Node_CItr, Node_Itr, _Alloc> /// Functor updating ranks of entrees. template<typename Node_CItr, typename Node_Itr, typename Cmp_Fn, typename _Alloc> class tree_order_statistics_node_update : private PB_DS_BRANCH_POLICY_BASE { private: typedef PB_DS_BRANCH_POLICY_BASE base_type; public: typedef Cmp_Fn cmp_fn; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef typename base_type::key_type key_type; typedef typename base_type::key_const_reference key_const_reference; typedef size_type metadata_type; typedef Node_CItr node_const_iterator; typedef Node_Itr node_iterator; typedef typename node_const_iterator::value_type const_iterator; typedef typename node_iterator::value_type iterator; /// Finds an entry by __order. Returns a const_iterator to the /// entry with the __order order, or a const_iterator to the /// container object's end if order is at least the size of the /// container object. inline const_iterator find_by_order(size_type) const; /// Finds an entry by __order. Returns an iterator to the entry /// with the __order order, or an iterator to the container /// object's end if order is at least the size of the container /// object. inline iterator find_by_order(size_type); /// Returns the order of a key within a sequence. For exapmle, if /// r_key is the smallest key, this method will return 0; if r_key /// is a key between the smallest and next key, this method will /// return 1; if r_key is a key larger than the largest key, this /// method will return the size of r_c. inline size_type order_of_key(key_const_reference) const; private: /// Const reference to the container's value-type. typedef typename base_type::const_reference const_reference; /// Const pointer to the container's value-type. typedef typename base_type::const_pointer const_pointer; typedef typename _Alloc::template rebind<metadata_type>::other __rebind_m; /// Const metadata reference. typedef typename __rebind_m::const_reference metadata_const_reference; /// Metadata reference. typedef typename __rebind_m::reference metadata_reference; /// Returns the node_const_iterator associated with the tree's root node. virtual node_const_iterator node_begin() const = 0; /// Returns the node_iterator associated with the tree's root node. virtual node_iterator node_begin() = 0; /// Returns the node_const_iterator associated with a just-after leaf node. virtual node_const_iterator node_end() const = 0; /// Returns the node_iterator associated with a just-after leaf node. virtual node_iterator node_end() = 0; /// Access to the cmp_fn object. virtual cmp_fn& get_cmp_fn() = 0; protected: /// Updates the rank of a node through a node_iterator node_it; /// end_nd_it is the end node iterator. inline void operator()(node_iterator, node_const_iterator) const; virtual ~tree_order_statistics_node_update(); }; #include <ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp> #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef PB_DS_BRANCH_POLICY_BASE } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/tag_and_trait.hpp 0000644 00000027754 15146341150 0012502 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file tag_and_trait.hpp * Contains tags and traits, e.g., ones describing underlying * data structures. */ #ifndef PB_DS_TAG_AND_TRAIT_HPP #define PB_DS_TAG_AND_TRAIT_HPP #include <bits/c++config.h> #include <ext/pb_ds/detail/type_utils.hpp> /** * @namespace __gnu_pbds * @brief GNU extensions for policy-based data structures for public use. */ namespace __gnu_pbds { /** @defgroup pbds Policy-Based Data Structures * @ingroup extensions * * This is a library of policy-based elementary data structures: * associative containers and priority queues. It is designed for * high-performance, flexibility, semantic safety, and conformance * to the corresponding containers in std (except for some points * where it differs by design). * * For details, see: * http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/index.html * * @{ */ /** * @defgroup tags Tags * @{ */ /// A trivial iterator tag. Signifies that the iterators has none of /// std::iterators's movement abilities. struct trivial_iterator_tag { }; /// Prohibit moving trivial iterators. typedef void trivial_iterator_difference_type; /** * @defgroup invalidation_tags Invalidation Guarantees * @ingroup tags * @{ */ /** * Signifies a basic invalidation guarantee that any iterator, * pointer, or reference to a container object's mapped value type * is valid as long as the container is not modified. */ struct basic_invalidation_guarantee { }; /** * Signifies an invalidation guarantee that includes all those of * its base, and additionally, that any point-type iterator, * pointer, or reference to a container object's mapped value type * is valid as long as its corresponding entry has not be erased, * regardless of modifications to the container object. */ struct point_invalidation_guarantee : public basic_invalidation_guarantee { }; /** * Signifies an invalidation guarantee that includes all those of * its base, and additionally, that any range-type iterator * (including the returns of begin() and end()) is in the correct * relative positions to other range-type iterators as long as its * corresponding entry has not be erased, regardless of * modifications to the container object. */ struct range_invalidation_guarantee : public point_invalidation_guarantee { }; //@} /** * @defgroup ds_tags Data Structure Type * @ingroup tags * @{ */ /// Base data structure tag. struct container_tag { }; /// Basic sequence. struct sequence_tag : public container_tag { }; /// Basic string container, inclusive of strings, ropes, etc. struct string_tag : public sequence_tag { }; /// Basic associative-container. struct associative_tag : public container_tag { }; /// Basic hash structure. struct basic_hash_tag : public associative_tag { }; /// Collision-chaining hash. struct cc_hash_tag : public basic_hash_tag { }; /// General-probing hash. struct gp_hash_tag : public basic_hash_tag { }; /// Basic branch structure. struct basic_branch_tag : public associative_tag { }; /// Basic tree structure. struct tree_tag : public basic_branch_tag { }; /// Red-black tree. struct rb_tree_tag : public tree_tag { }; /// Splay tree. struct splay_tree_tag : public tree_tag { }; /// Ordered-vector tree. struct ov_tree_tag : public tree_tag { }; /// Basic trie structure. struct trie_tag : public basic_branch_tag { }; /// PATRICIA trie. struct pat_trie_tag : public trie_tag { }; /// List-update. struct list_update_tag : public associative_tag { }; /// Basic priority-queue. struct priority_queue_tag : public container_tag { }; /// Pairing-heap. struct pairing_heap_tag : public priority_queue_tag { }; /// Binomial-heap. struct binomial_heap_tag : public priority_queue_tag { }; /// Redundant-counter binomial-heap. struct rc_binomial_heap_tag : public priority_queue_tag { }; /// Binary-heap (array-based). struct binary_heap_tag : public priority_queue_tag { }; /// Thin heap. struct thin_heap_tag : public priority_queue_tag { }; //@} //@} /** * @defgroup traits Traits * @{ */ /** * @brief Represents no type, or absence of type, for template tricks. * * In a mapped-policy, indicates that an associative container is a set. * * In a list-update policy, indicates that each link does not need * metadata. * * In a hash policy, indicates that the combining hash function * is actually a ranged hash function. * * In a probe policy, indicates that the combining probe function * is actually a ranged probe function. */ struct null_type { }; /// A null node updator, indicating that no node updates are required. template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4> struct null_node_update : public null_type { }; /// Primary template, container traits base. template<typename _Tag> struct container_traits_base; /// Specialization, cc hash. template<> struct container_traits_base<cc_hash_tag> { typedef cc_hash_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, gp hash. template<> struct container_traits_base<gp_hash_tag> { typedef gp_hash_tag container_category; typedef basic_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, rb tree. template<> struct container_traits_base<rb_tree_tag> { typedef rb_tree_tag container_category; typedef range_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = true }; }; /// Specialization, splay tree. template<> struct container_traits_base<splay_tree_tag> { typedef splay_tree_tag container_category; typedef range_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = true }; }; /// Specialization, ov tree. template<> struct container_traits_base<ov_tree_tag> { typedef ov_tree_tag container_category; typedef basic_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = true, split_join_can_throw = true, reverse_iteration = false }; }; /// Specialization, pat trie. template<> struct container_traits_base<pat_trie_tag> { typedef pat_trie_tag container_category; typedef range_invalidation_guarantee invalidation_guarantee; enum { order_preserving = true, erase_can_throw = false, split_join_can_throw = true, reverse_iteration = true }; }; /// Specialization, list update. template<> struct container_traits_base<list_update_tag> { typedef list_update_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, pairing heap. template<> struct container_traits_base<pairing_heap_tag> { typedef pairing_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, thin heap. template<> struct container_traits_base<thin_heap_tag> { typedef thin_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, binomial heap. template<> struct container_traits_base<binomial_heap_tag> { typedef binomial_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, rc binomial heap. template<> struct container_traits_base<rc_binomial_heap_tag> { typedef rc_binomial_heap_tag container_category; typedef point_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = false, reverse_iteration = false }; }; /// Specialization, binary heap. template<> struct container_traits_base<binary_heap_tag> { typedef binary_heap_tag container_category; typedef basic_invalidation_guarantee invalidation_guarantee; enum { order_preserving = false, erase_can_throw = false, split_join_can_throw = true, reverse_iteration = false }; }; /// Container traits. // See Matt Austern for the name, S. Meyers MEFC++ #2, others. template<typename Cntnr> struct container_traits : public container_traits_base<typename Cntnr::container_category> { typedef Cntnr container_type; typedef typename Cntnr::container_category container_category; typedef container_traits_base<container_category> base_type; typedef typename base_type::invalidation_guarantee invalidation_guarantee; enum { /// True only if Cntnr objects guarantee storing keys by order. order_preserving = base_type::order_preserving, /// True only if erasing a key can throw. erase_can_throw = base_type::erase_can_throw, /// True only if split or join operations can throw. split_join_can_throw = base_type::split_join_can_throw, /// True only reverse iterators are supported. reverse_iteration = base_type::reverse_iteration }; }; //@} namespace detail { /// Dispatch mechanism, primary template for associative types. template<typename Key, typename Mapped, typename _Alloc, typename Tag, typename Policy_Tl = null_type> struct container_base_dispatch; } // namespace detail //@} } // namespace __gnu_pbds #endif c++/8/ext/pb_ds/priority_queue.hpp 0000644 00000012576 15146341150 0012763 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file priority_queue.hpp * Contains priority_queues. */ #ifndef PB_DS_PRIORITY_QUEUE_HPP #define PB_DS_PRIORITY_QUEUE_HPP #include <bits/c++config.h> #include <ext/pb_ds/tag_and_trait.hpp> #include <ext/pb_ds/detail/priority_queue_base_dispatch.hpp> #include <ext/pb_ds/detail/standard_policies.hpp> namespace __gnu_pbds { /** * @defgroup heap-based Heap-Based * @ingroup containers-pbds * @{ */ /** * @defgroup heap-detail Base and Policy Classes * @ingroup heap-based */ /** * A priority queue composed of one specific heap policy. * * @tparam _Tv Value type. * @tparam Cmp_Fn Comparison functor. * @tparam Tag Instantiating data structure type, * see container_tag. * @tparam _Alloc Allocator type. * * Base is dispatched at compile time via Tag, from the following * choices: binary_heap_tag, binomial_heap_tag, pairing_heap_tag, * rc_binomial_heap_tag, thin_heap_tag * * Base choices are: detail::binary_heap, detail::binomial_heap, * detail::pairing_heap, detail::rc_binomial_heap, * detail::thin_heap. */ template<typename _Tv, typename Cmp_Fn = std::less<_Tv>, typename Tag = pairing_heap_tag, typename _Alloc = std::allocator<char> > class priority_queue : public detail::container_base_dispatch<_Tv, Cmp_Fn, _Alloc, Tag>::type { public: typedef _Tv value_type; typedef Cmp_Fn cmp_fn; typedef Tag container_category; typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; typedef typename allocator_type::difference_type difference_type; private: typedef typename detail::container_base_dispatch<_Tv, Cmp_Fn, _Alloc, Tag>::type base_type; typedef typename _Alloc::template rebind<_Tv> __rebind_v; typedef typename __rebind_v::other __rebind_va; public: typedef typename __rebind_va::reference reference; typedef typename __rebind_va::const_reference const_reference; typedef typename __rebind_va::pointer pointer; typedef typename __rebind_va::const_pointer const_pointer; typedef typename base_type::point_iterator point_iterator; typedef typename base_type::point_const_iterator point_const_iterator; typedef typename base_type::iterator iterator; typedef typename base_type::const_iterator const_iterator; priority_queue() { } /// Constructor taking some policy objects. r_cmp_fn will be /// copied by the Cmp_Fn object of the container object. priority_queue(const cmp_fn& r_cmp_fn) : base_type(r_cmp_fn) { } /// Constructor taking __iterators to a range of value_types. The /// value_types between first_it and last_it will be inserted into /// the container object. template<typename It> priority_queue(It first_it, It last_it) { base_type::copy_from_range(first_it, last_it); } /// Constructor taking __iterators to a range of value_types and /// some policy objects The value_types between first_it and /// last_it will be inserted into the container object. r_cmp_fn /// will be copied by the cmp_fn object of the container object. template<typename It> priority_queue(It first_it, It last_it, const cmp_fn& r_cmp_fn) : base_type(r_cmp_fn) { base_type::copy_from_range(first_it, last_it); } priority_queue(const priority_queue& other) : base_type((const base_type& )other) { } virtual ~priority_queue() { } priority_queue& operator=(const priority_queue& other) { if (this != &other) { priority_queue tmp(other); swap(tmp); } return *this; } void swap(priority_queue& other) { base_type::swap(other); } }; } // namespace __gnu_pbds //@} heap-based #endif c++/8/ext/pb_ds/list_update_policy.hpp 0000644 00000010420 15146341150 0013554 0 ustar 00 // -*- C++ -*- // Copyright (C) 2005-2018 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) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file list_update_policy.hpp * Contains policies for list update containers. */ #ifndef PB_DS_LU_POLICY_HPP #define PB_DS_LU_POLICY_HPP #include <bits/c++config.h> #include <cstdlib> #include <ext/pb_ds/detail/list_update_policy/lu_counter_metadata.hpp> #include <ext/pb_ds/tag_and_trait.hpp> namespace __gnu_pbds { /** * A list-update policy that unconditionally moves elements to the * front of the list. A null type means that each link in a * list-based container does not actually need metadata. */ template<typename _Alloc = std::allocator<char> > class lu_move_to_front_policy { public: typedef _Alloc allocator_type; /// Metadata on which this functor operates. typedef null_type metadata_type; private: typedef typename _Alloc::template rebind<metadata_type> __rebind_m; public: /// Reference to metadata on which this functor operates. typedef typename __rebind_m::other::reference metadata_reference; /// Creates a metadata object. metadata_type operator()() const { return s_metadata; } /// Decides whether a metadata object should be moved to the front /// of the list. inline bool operator()(metadata_reference r_metadata) const { return true; } private: static null_type s_metadata; }; /** * A list-update policy that moves elements to the front of the * list based on the counter algorithm. */ template<std::size_t Max_Count = 5, typename _Alloc = std::allocator<char> > class lu_counter_policy : private detail::lu_counter_policy_base<typename _Alloc::size_type> { public: typedef _Alloc allocator_type; typedef typename allocator_type::size_type size_type; enum { /// When some element is accessed this number of times, it /// will be moved to the front of the list. max_count = Max_Count }; /// Metadata on which this functor operates. typedef detail::lu_counter_metadata<size_type> metadata_type; private: typedef detail::lu_counter_policy_base<size_type> base_type; typedef typename _Alloc::template rebind<metadata_type> __rebind_m; public: /// Reference to metadata on which this functor operates. typedef typename __rebind_m::other::reference metadata_reference; /// Creates a metadata object. metadata_type operator()() const { return base_type::operator()(max_count); } /// Decides whether a metadata object should be moved to the front /// of the list. bool operator()(metadata_reference r_data) const { return base_type::operator()(r_data, max_count); } }; } // namespace __gnu_pbds #endif c++/8/ext/rc_string_base.h 0000644 00000056267 15146341150 0011240 0 ustar 00 // Reference-counted versatile string base -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/rc_string_base.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/vstring.h} */ #ifndef _RC_STRING_BASE_H #define _RC_STRING_BASE_H 1 #include <ext/atomicity.h> #include <bits/stl_iterator_base_funcs.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * Documentation? What's that? * Nathan Myers <ncm@cantrip.org>. * * A string looks like this: * * @code * [_Rep] * _M_length * [__rc_string_base<char_type>] _M_capacity * _M_dataplus _M_refcount * _M_p ----------------> unnamed array of char_type * @endcode * * Where the _M_p points to the first character in the string, and * you cast it to a pointer-to-_Rep and subtract 1 to get a * pointer to the header. * * This approach has the enormous advantage that a string object * requires only one allocation. All the ugliness is confined * within a single pair of inline functions, which each compile to * a single @a add instruction: _Rep::_M_refdata(), and * __rc_string_base::_M_rep(); and the allocation function which gets a * block of raw bytes and with room enough and constructs a _Rep * object at the front. * * The reason you want _M_data pointing to the character array and * not the _Rep is so that the debugger can see the string * contents. (Probably we should add a non-inline member to get * the _Rep for the debugger to use, so users can check the actual * string length.) * * Note that the _Rep object is a POD so that you can have a * static <em>empty string</em> _Rep object already @a constructed before * static constructors have run. The reference-count encoding is * chosen so that a 0 indicates one reference, so you never try to * destroy the empty-string _Rep object. * * All but the last paragraph is considered pretty conventional * for a C++ string implementation. */ template<typename _CharT, typename _Traits, typename _Alloc> class __rc_string_base : protected __vstring_utility<_CharT, _Traits, _Alloc> { public: typedef _Traits traits_type; typedef typename _Traits::char_type value_type; typedef _Alloc allocator_type; typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base; typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type; typedef typename _CharT_alloc_type::size_type size_type; private: // _Rep: string representation // Invariants: // 1. String really contains _M_length + 1 characters: due to 21.3.4 // must be kept null-terminated. // 2. _M_capacity >= _M_length // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT). // 3. _M_refcount has three states: // -1: leaked, one reference, no ref-copies allowed, non-const. // 0: one reference, non-const. // n>0: n + 1 references, operations require a lock, const. // 4. All fields == 0 is an empty string, given the extra storage // beyond-the-end for a null terminator; thus, the shared // empty string representation needs no constructor. struct _Rep { union { struct { size_type _M_length; size_type _M_capacity; _Atomic_word _M_refcount; } _M_info; // Only for alignment purposes. _CharT _M_align; }; typedef typename _Alloc::template rebind<_Rep>::other _Rep_alloc_type; _CharT* _M_refdata() throw() { return reinterpret_cast<_CharT*>(this + 1); } _CharT* _M_refcopy() throw() { __atomic_add_dispatch(&_M_info._M_refcount, 1); return _M_refdata(); } // XXX MT void _M_set_length(size_type __n) { _M_info._M_refcount = 0; // One reference. _M_info._M_length = __n; // grrr. (per 21.3.4) // You cannot leave those LWG people alone for a second. traits_type::assign(_M_refdata()[__n], _CharT()); } // Create & Destroy static _Rep* _S_create(size_type, size_type, const _Alloc&); void _M_destroy(const _Alloc&) throw(); _CharT* _M_clone(const _Alloc&, size_type __res = 0); }; struct _Rep_empty : public _Rep { _CharT _M_terminal; }; static _Rep_empty _S_empty_rep; // The maximum number of individual char_type elements of an // individual string is determined by _S_max_size. This is the // value that will be returned by max_size(). (Whereas npos // is the maximum number of bytes the allocator can allocate.) // If one was to divvy up the theoretical largest size string, // with a terminating character and m _CharT elements, it'd // look like this: // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) // + sizeof(_Rep) - 1 // (NB: last two terms for rounding reasons, see _M_create below) // Solving for m: // m = ((npos - 2 * sizeof(_Rep) + 1) / sizeof(_CharT)) - 1 // In addition, this implementation halves this amount. enum { _S_max_size = (((static_cast<size_type>(-1) - 2 * sizeof(_Rep) + 1) / sizeof(_CharT)) - 1) / 2 }; // Data Member (private): mutable typename _Util_Base::template _Alloc_hider<_Alloc> _M_dataplus; void _M_data(_CharT* __p) { _M_dataplus._M_p = __p; } _Rep* _M_rep() const { return &((reinterpret_cast<_Rep*>(_M_data()))[-1]); } _CharT* _M_grab(const _Alloc& __alloc) const { return (!_M_is_leaked() && _M_get_allocator() == __alloc) ? _M_rep()->_M_refcopy() : _M_rep()->_M_clone(__alloc); } void _M_dispose() { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_rep()->_M_info. _M_refcount); if (__exchange_and_add_dispatch(&_M_rep()->_M_info._M_refcount, -1) <= 0) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_rep()->_M_info. _M_refcount); _M_rep()->_M_destroy(_M_get_allocator()); } } // XXX MT bool _M_is_leaked() const { return _M_rep()->_M_info._M_refcount < 0; } void _M_set_sharable() { _M_rep()->_M_info._M_refcount = 0; } void _M_leak_hard(); // _S_construct_aux is used to implement the 21.3.1 para 15 which // requires special behaviour if _InIterator is an integral type template<typename _InIterator> static _CharT* _S_construct_aux(_InIterator __beg, _InIterator __end, const _Alloc& __a, std::__false_type) { typedef typename iterator_traits<_InIterator>::iterator_category _Tag; return _S_construct(__beg, __end, __a, _Tag()); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> static _CharT* _S_construct_aux(_Integer __beg, _Integer __end, const _Alloc& __a, std::__true_type) { return _S_construct_aux_2(static_cast<size_type>(__beg), __end, __a); } static _CharT* _S_construct_aux_2(size_type __req, _CharT __c, const _Alloc& __a) { return _S_construct(__req, __c, __a); } template<typename _InIterator> static _CharT* _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) { typedef typename std::__is_integer<_InIterator>::__type _Integral; return _S_construct_aux(__beg, __end, __a, _Integral()); } // For Input Iterators, used in istreambuf_iterators, etc. template<typename _InIterator> static _CharT* _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, std::input_iterator_tag); // For forward_iterators up to random_access_iterators, used for // string::iterator, _CharT*, etc. template<typename _FwdIterator> static _CharT* _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, std::forward_iterator_tag); static _CharT* _S_construct(size_type __req, _CharT __c, const _Alloc& __a); public: size_type _M_max_size() const { return size_type(_S_max_size); } _CharT* _M_data() const { return _M_dataplus._M_p; } size_type _M_length() const { return _M_rep()->_M_info._M_length; } size_type _M_capacity() const { return _M_rep()->_M_info._M_capacity; } bool _M_is_shared() const { return _M_rep()->_M_info._M_refcount > 0; } void _M_set_leaked() { _M_rep()->_M_info._M_refcount = -1; } void _M_leak() // for use in begin() & non-const op[] { if (!_M_is_leaked()) _M_leak_hard(); } void _M_set_length(size_type __n) { _M_rep()->_M_set_length(__n); } __rc_string_base() : _M_dataplus(_S_empty_rep._M_refcopy()) { } __rc_string_base(const _Alloc& __a); __rc_string_base(const __rc_string_base& __rcs); #if __cplusplus >= 201103L __rc_string_base(__rc_string_base&& __rcs) : _M_dataplus(__rcs._M_dataplus) { __rcs._M_data(_S_empty_rep._M_refcopy()); } #endif __rc_string_base(size_type __n, _CharT __c, const _Alloc& __a); template<typename _InputIterator> __rc_string_base(_InputIterator __beg, _InputIterator __end, const _Alloc& __a); ~__rc_string_base() { _M_dispose(); } allocator_type& _M_get_allocator() { return _M_dataplus; } const allocator_type& _M_get_allocator() const { return _M_dataplus; } void _M_swap(__rc_string_base& __rcs); void _M_assign(const __rc_string_base& __rcs); void _M_reserve(size_type __res); void _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, size_type __len2); void _M_erase(size_type __pos, size_type __n); void _M_clear() { _M_dispose(); _M_data(_S_empty_rep._M_refcopy()); } bool _M_compare(const __rc_string_base&) const { return false; } }; template<typename _CharT, typename _Traits, typename _Alloc> typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep_empty __rc_string_base<_CharT, _Traits, _Alloc>::_S_empty_rep; template<typename _CharT, typename _Traits, typename _Alloc> typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep* __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: _S_create(size_type __capacity, size_type __old_capacity, const _Alloc& __alloc) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 83. String::npos vs. string::max_size() if (__capacity > size_type(_S_max_size)) std::__throw_length_error(__N("__rc_string_base::_Rep::_S_create")); // The standard places no restriction on allocating more memory // than is strictly needed within this layer at the moment or as // requested by an explicit application call to reserve(). // Many malloc implementations perform quite poorly when an // application attempts to allocate memory in a stepwise fashion // growing each allocation size by only 1 char. Additionally, // it makes little sense to allocate less linear memory than the // natural blocking size of the malloc implementation. // Unfortunately, we would need a somewhat low-level calculation // with tuned parameters to get this perfect for any particular // malloc implementation. Fortunately, generalizations about // common features seen among implementations seems to suffice. // __pagesize need not match the actual VM page size for good // results in practice, thus we pick a common value on the low // side. __malloc_header_size is an estimate of the amount of // overhead per memory allocation (in practice seen N * sizeof // (void*) where N is 0, 2 or 4). According to folklore, // picking this value on the high side is better than // low-balling it (especially when this algorithm is used with // malloc implementations that allocate memory blocks rounded up // to a size which is a power of 2). const size_type __pagesize = 4096; const size_type __malloc_header_size = 4 * sizeof(void*); // The below implements an exponential growth policy, necessary to // meet amortized linear time requirements of the library: see // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) { __capacity = 2 * __old_capacity; // Never allocate a string bigger than _S_max_size. if (__capacity > size_type(_S_max_size)) __capacity = size_type(_S_max_size); } // NB: Need an array of char_type[__capacity], plus a terminating // null char_type() element, plus enough for the _Rep data structure, // plus sizeof(_Rep) - 1 to upper round to a size multiple of // sizeof(_Rep). // Whew. Seemingly so needy, yet so elemental. size_type __size = ((__capacity + 1) * sizeof(_CharT) + 2 * sizeof(_Rep) - 1); const size_type __adj_size = __size + __malloc_header_size; if (__adj_size > __pagesize && __capacity > __old_capacity) { const size_type __extra = __pagesize - __adj_size % __pagesize; __capacity += __extra / sizeof(_CharT); if (__capacity > size_type(_S_max_size)) __capacity = size_type(_S_max_size); __size = (__capacity + 1) * sizeof(_CharT) + 2 * sizeof(_Rep) - 1; } // NB: Might throw, but no worries about a leak, mate: _Rep() // does not throw. _Rep* __place = _Rep_alloc_type(__alloc).allocate(__size / sizeof(_Rep)); _Rep* __p = new (__place) _Rep; __p->_M_info._M_capacity = __capacity; return __p; } template<typename _CharT, typename _Traits, typename _Alloc> void __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: _M_destroy(const _Alloc& __a) throw () { const size_type __size = ((_M_info._M_capacity + 1) * sizeof(_CharT) + 2 * sizeof(_Rep) - 1); _Rep_alloc_type(__a).deallocate(this, __size / sizeof(_Rep)); } template<typename _CharT, typename _Traits, typename _Alloc> _CharT* __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: _M_clone(const _Alloc& __alloc, size_type __res) { // Requested capacity of the clone. const size_type __requested_cap = _M_info._M_length + __res; _Rep* __r = _Rep::_S_create(__requested_cap, _M_info._M_capacity, __alloc); if (_M_info._M_length) __rc_string_base::_S_copy(__r->_M_refdata(), _M_refdata(), _M_info._M_length); __r->_M_set_length(_M_info._M_length); return __r->_M_refdata(); } template<typename _CharT, typename _Traits, typename _Alloc> __rc_string_base<_CharT, _Traits, _Alloc>:: __rc_string_base(const _Alloc& __a) : _M_dataplus(__a, _S_construct(size_type(), _CharT(), __a)) { } template<typename _CharT, typename _Traits, typename _Alloc> __rc_string_base<_CharT, _Traits, _Alloc>:: __rc_string_base(const __rc_string_base& __rcs) : _M_dataplus(__rcs._M_get_allocator(), __rcs._M_grab(__rcs._M_get_allocator())) { } template<typename _CharT, typename _Traits, typename _Alloc> __rc_string_base<_CharT, _Traits, _Alloc>:: __rc_string_base(size_type __n, _CharT __c, const _Alloc& __a) : _M_dataplus(__a, _S_construct(__n, __c, __a)) { } template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InputIterator> __rc_string_base<_CharT, _Traits, _Alloc>:: __rc_string_base(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) : _M_dataplus(__a, _S_construct(__beg, __end, __a)) { } template<typename _CharT, typename _Traits, typename _Alloc> void __rc_string_base<_CharT, _Traits, _Alloc>:: _M_leak_hard() { if (_M_is_shared()) _M_erase(0, 0); _M_set_leaked(); } // NB: This is the special case for Input Iterators, used in // istreambuf_iterators, etc. // Input Iterators have a cost structure very different from // pointers, calling for a different coding style. template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InIterator> _CharT* __rc_string_base<_CharT, _Traits, _Alloc>:: _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, std::input_iterator_tag) { if (__beg == __end && __a == _Alloc()) return _S_empty_rep._M_refcopy(); // Avoid reallocation for common case. _CharT __buf[128]; size_type __len = 0; while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) { __buf[__len++] = *__beg; ++__beg; } _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); _S_copy(__r->_M_refdata(), __buf, __len); __try { while (__beg != __end) { if (__len == __r->_M_info._M_capacity) { // Allocate more space. _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); _S_copy(__another->_M_refdata(), __r->_M_refdata(), __len); __r->_M_destroy(__a); __r = __another; } __r->_M_refdata()[__len++] = *__beg; ++__beg; } } __catch(...) { __r->_M_destroy(__a); __throw_exception_again; } __r->_M_set_length(__len); return __r->_M_refdata(); } template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InIterator> _CharT* __rc_string_base<_CharT, _Traits, _Alloc>:: _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, std::forward_iterator_tag) { if (__beg == __end && __a == _Alloc()) return _S_empty_rep._M_refcopy(); // NB: Not required, but considered best practice. if (__is_null_pointer(__beg) && __beg != __end) std::__throw_logic_error(__N("__rc_string_base::" "_S_construct null not valid")); const size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); // Check for out_of_range and length_error exceptions. _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); __try { __rc_string_base::_S_copy_chars(__r->_M_refdata(), __beg, __end); } __catch(...) { __r->_M_destroy(__a); __throw_exception_again; } __r->_M_set_length(__dnew); return __r->_M_refdata(); } template<typename _CharT, typename _Traits, typename _Alloc> _CharT* __rc_string_base<_CharT, _Traits, _Alloc>:: _S_construct(size_type __n, _CharT __c, const _Alloc& __a) { if (__n == 0 && __a == _Alloc()) return _S_empty_rep._M_refcopy(); // Check for out_of_range and length_error exceptions. _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); if (__n) __rc_string_base::_S_assign(__r->_M_refdata(), __n, __c); __r->_M_set_length(__n); return __r->_M_refdata(); } template<typename _CharT, typename _Traits, typename _Alloc> void __rc_string_base<_CharT, _Traits, _Alloc>:: _M_swap(__rc_string_base& __rcs) { if (_M_is_leaked()) _M_set_sharable(); if (__rcs._M_is_leaked()) __rcs._M_set_sharable(); _CharT* __tmp = _M_data(); _M_data(__rcs._M_data()); __rcs._M_data(__tmp); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 431. Swapping containers with unequal allocators. std::__alloc_swap<allocator_type>::_S_do_it(_M_get_allocator(), __rcs._M_get_allocator()); } template<typename _CharT, typename _Traits, typename _Alloc> void __rc_string_base<_CharT, _Traits, _Alloc>:: _M_assign(const __rc_string_base& __rcs) { if (_M_rep() != __rcs._M_rep()) { _CharT* __tmp = __rcs._M_grab(_M_get_allocator()); _M_dispose(); _M_data(__tmp); } } template<typename _CharT, typename _Traits, typename _Alloc> void __rc_string_base<_CharT, _Traits, _Alloc>:: _M_reserve(size_type __res) { // Make sure we don't shrink below the current size. if (__res < _M_length()) __res = _M_length(); if (__res != _M_capacity() || _M_is_shared()) { _CharT* __tmp = _M_rep()->_M_clone(_M_get_allocator(), __res - _M_length()); _M_dispose(); _M_data(__tmp); } } template<typename _CharT, typename _Traits, typename _Alloc> void __rc_string_base<_CharT, _Traits, _Alloc>:: _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, size_type __len2) { const size_type __how_much = _M_length() - __pos - __len1; _Rep* __r = _Rep::_S_create(_M_length() + __len2 - __len1, _M_capacity(), _M_get_allocator()); if (__pos) this->_S_copy(__r->_M_refdata(), _M_data(), __pos); if (__s && __len2) this->_S_copy(__r->_M_refdata() + __pos, __s, __len2); if (__how_much) this->_S_copy(__r->_M_refdata() + __pos + __len2, _M_data() + __pos + __len1, __how_much); _M_dispose(); _M_data(__r->_M_refdata()); } template<typename _CharT, typename _Traits, typename _Alloc> void __rc_string_base<_CharT, _Traits, _Alloc>:: _M_erase(size_type __pos, size_type __n) { const size_type __new_size = _M_length() - __n; const size_type __how_much = _M_length() - __pos - __n; if (_M_is_shared()) { // Must reallocate. _Rep* __r = _Rep::_S_create(__new_size, _M_capacity(), _M_get_allocator()); if (__pos) this->_S_copy(__r->_M_refdata(), _M_data(), __pos); if (__how_much) this->_S_copy(__r->_M_refdata() + __pos, _M_data() + __pos + __n, __how_much); _M_dispose(); _M_data(__r->_M_refdata()); } else if (__how_much && __n) { // Work in-place. this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much); } _M_rep()->_M_set_length(__new_size); } template<> inline bool __rc_string_base<char, std::char_traits<char>, std::allocator<char> >:: _M_compare(const __rc_string_base& __rcs) const { if (_M_rep() == __rcs._M_rep()) return true; return false; } #ifdef _GLIBCXX_USE_WCHAR_T template<> inline bool __rc_string_base<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >:: _M_compare(const __rc_string_base& __rcs) const { if (_M_rep() == __rcs._M_rep()) return true; return false; } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _RC_STRING_BASE_H */ c++/8/ext/rb_tree 0000644 00000006357 15146341150 0007443 0 ustar 00 // rb_tree extension -*- C++ -*- // Copyright (C) 2002-2018 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 * 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 ext/rb_tree * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _RB_TREE #define _RB_TREE 1 #pragma GCC system_header #include <bits/stl_tree.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::_Rb_tree; using std::allocator; // Class rb_tree is not part of the C++ standard. It is provided for // compatibility with the HP STL. /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template <class _Key, class _Value, class _KeyOfValue, class _Compare, class _Alloc = allocator<_Value> > struct rb_tree : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> { typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base; typedef typename _Base::allocator_type allocator_type; rb_tree(const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _Base(__comp, __a) { } ~rb_tree() { } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/aligned_buffer.h 0000644 00000007604 15146341150 0011177 0 ustar 00 // Aligned memory buffer -*- C++ -*- // Copyright (C) 2013-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/aligned_buffer.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _ALIGNED_BUFFER_H #define _ALIGNED_BUFFER_H 1 #pragma GCC system_header #if __cplusplus >= 201103L # include <type_traits> #else # include <bits/c++0x_warning.h> #endif namespace __gnu_cxx { // A utility type containing a POD object that can hold an object of type // _Tp initialized via placement new or allocator_traits::construct. // Intended for use as a data member subobject, use __aligned_buffer for // complete objects. template<typename _Tp> struct __aligned_membuf { // Target macro ADJUST_FIELD_ALIGN can produce different alignment for // types when used as class members. __aligned_membuf is intended // for use as a class member, so align the buffer as for a class member. // Since GCC 8 we could just use alignof(_Tp) instead, but older // versions of non-GNU compilers might still need this trick. struct _Tp2 { _Tp _M_t; }; alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)]; __aligned_membuf() = default; // Can be used to avoid value-initialization zeroing _M_storage. __aligned_membuf(std::nullptr_t) { } void* _M_addr() noexcept { return static_cast<void*>(&_M_storage); } const void* _M_addr() const noexcept { return static_cast<const void*>(&_M_storage); } _Tp* _M_ptr() noexcept { return static_cast<_Tp*>(_M_addr()); } const _Tp* _M_ptr() const noexcept { return static_cast<const _Tp*>(_M_addr()); } }; #if _GLIBCXX_INLINE_VERSION template<typename _Tp> using __aligned_buffer = __aligned_membuf<_Tp>; #else // Similar to __aligned_membuf but aligned for complete objects, not members. // This type is used in <forward_list>, <future>, <bits/shared_ptr_base.h> // and <bits/hashtable_policy.h>, but ideally they would use __aligned_membuf // instead, as it has smaller size for some types on some targets. // This type is still used to avoid an ABI change. template<typename _Tp> struct __aligned_buffer : std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)> { typename std::aligned_storage<sizeof(_Tp), __alignof__(_Tp)>::type _M_storage; __aligned_buffer() = default; // Can be used to avoid value-initialization __aligned_buffer(std::nullptr_t) { } void* _M_addr() noexcept { return static_cast<void*>(&_M_storage); } const void* _M_addr() const noexcept { return static_cast<const void*>(&_M_storage); } _Tp* _M_ptr() noexcept { return static_cast<_Tp*>(_M_addr()); } const _Tp* _M_ptr() const noexcept { return static_cast<const _Tp*>(_M_addr()); } }; #endif } // namespace #endif /* _ALIGNED_BUFFER_H */ c++/8/ext/sso_string_base.h 0000644 00000037672 15146341150 0011437 0 ustar 00 // Short-string-optimized versatile string base -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/sso_string_base.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/vstring.h} */ #ifndef _SSO_STRING_BASE_H #define _SSO_STRING_BASE_H 1 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits, typename _Alloc> class __sso_string_base : protected __vstring_utility<_CharT, _Traits, _Alloc> { public: typedef _Traits traits_type; typedef typename _Traits::char_type value_type; typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base; typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type; typedef typename _CharT_alloc_type::size_type size_type; private: // Data Members: typename _Util_Base::template _Alloc_hider<_CharT_alloc_type> _M_dataplus; size_type _M_string_length; enum { _S_local_capacity = 15 }; union { _CharT _M_local_data[_S_local_capacity + 1]; size_type _M_allocated_capacity; }; void _M_data(_CharT* __p) { _M_dataplus._M_p = __p; } void _M_length(size_type __length) { _M_string_length = __length; } void _M_capacity(size_type __capacity) { _M_allocated_capacity = __capacity; } bool _M_is_local() const { return _M_data() == _M_local_data; } // Create & Destroy _CharT* _M_create(size_type&, size_type); void _M_dispose() { if (!_M_is_local()) _M_destroy(_M_allocated_capacity); } void _M_destroy(size_type __size) throw() { _M_get_allocator().deallocate(_M_data(), __size + 1); } // _M_construct_aux is used to implement the 21.3.1 para 15 which // requires special behaviour if _InIterator is an integral type template<typename _InIterator> void _M_construct_aux(_InIterator __beg, _InIterator __end, std::__false_type) { typedef typename iterator_traits<_InIterator>::iterator_category _Tag; _M_construct(__beg, __end, _Tag()); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_construct_aux(_Integer __beg, _Integer __end, std::__true_type) { _M_construct_aux_2(static_cast<size_type>(__beg), __end); } void _M_construct_aux_2(size_type __req, _CharT __c) { _M_construct(__req, __c); } template<typename _InIterator> void _M_construct(_InIterator __beg, _InIterator __end) { typedef typename std::__is_integer<_InIterator>::__type _Integral; _M_construct_aux(__beg, __end, _Integral()); } // For Input Iterators, used in istreambuf_iterators, etc. template<typename _InIterator> void _M_construct(_InIterator __beg, _InIterator __end, std::input_iterator_tag); // For forward_iterators up to random_access_iterators, used for // string::iterator, _CharT*, etc. template<typename _FwdIterator> void _M_construct(_FwdIterator __beg, _FwdIterator __end, std::forward_iterator_tag); void _M_construct(size_type __req, _CharT __c); public: size_type _M_max_size() const { return (_M_get_allocator().max_size() - 1) / 2; } _CharT* _M_data() const { return _M_dataplus._M_p; } size_type _M_length() const { return _M_string_length; } size_type _M_capacity() const { return _M_is_local() ? size_type(_S_local_capacity) : _M_allocated_capacity; } bool _M_is_shared() const { return false; } void _M_set_leaked() { } void _M_leak() { } void _M_set_length(size_type __n) { _M_length(__n); traits_type::assign(_M_data()[__n], _CharT()); } __sso_string_base() : _M_dataplus(_M_local_data) { _M_set_length(0); } __sso_string_base(const _Alloc& __a); __sso_string_base(const __sso_string_base& __rcs); #if __cplusplus >= 201103L __sso_string_base(__sso_string_base&& __rcs); #endif __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a); template<typename _InputIterator> __sso_string_base(_InputIterator __beg, _InputIterator __end, const _Alloc& __a); ~__sso_string_base() { _M_dispose(); } _CharT_alloc_type& _M_get_allocator() { return _M_dataplus; } const _CharT_alloc_type& _M_get_allocator() const { return _M_dataplus; } void _M_swap(__sso_string_base& __rcs); void _M_assign(const __sso_string_base& __rcs); void _M_reserve(size_type __res); void _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, size_type __len2); void _M_erase(size_type __pos, size_type __n); void _M_clear() { _M_set_length(0); } bool _M_compare(const __sso_string_base&) const { return false; } }; template<typename _CharT, typename _Traits, typename _Alloc> void __sso_string_base<_CharT, _Traits, _Alloc>:: _M_swap(__sso_string_base& __rcs) { if (this == &__rcs) return; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 431. Swapping containers with unequal allocators. std::__alloc_swap<_CharT_alloc_type>::_S_do_it(_M_get_allocator(), __rcs._M_get_allocator()); if (_M_is_local()) if (__rcs._M_is_local()) { if (_M_length() && __rcs._M_length()) { _CharT __tmp_data[_S_local_capacity + 1]; traits_type::copy(__tmp_data, __rcs._M_local_data, _S_local_capacity + 1); traits_type::copy(__rcs._M_local_data, _M_local_data, _S_local_capacity + 1); traits_type::copy(_M_local_data, __tmp_data, _S_local_capacity + 1); } else if (__rcs._M_length()) { traits_type::copy(_M_local_data, __rcs._M_local_data, _S_local_capacity + 1); _M_length(__rcs._M_length()); __rcs._M_set_length(0); return; } else if (_M_length()) { traits_type::copy(__rcs._M_local_data, _M_local_data, _S_local_capacity + 1); __rcs._M_length(_M_length()); _M_set_length(0); return; } } else { const size_type __tmp_capacity = __rcs._M_allocated_capacity; traits_type::copy(__rcs._M_local_data, _M_local_data, _S_local_capacity + 1); _M_data(__rcs._M_data()); __rcs._M_data(__rcs._M_local_data); _M_capacity(__tmp_capacity); } else { const size_type __tmp_capacity = _M_allocated_capacity; if (__rcs._M_is_local()) { traits_type::copy(_M_local_data, __rcs._M_local_data, _S_local_capacity + 1); __rcs._M_data(_M_data()); _M_data(_M_local_data); } else { _CharT* __tmp_ptr = _M_data(); _M_data(__rcs._M_data()); __rcs._M_data(__tmp_ptr); _M_capacity(__rcs._M_allocated_capacity); } __rcs._M_capacity(__tmp_capacity); } const size_type __tmp_length = _M_length(); _M_length(__rcs._M_length()); __rcs._M_length(__tmp_length); } template<typename _CharT, typename _Traits, typename _Alloc> _CharT* __sso_string_base<_CharT, _Traits, _Alloc>:: _M_create(size_type& __capacity, size_type __old_capacity) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 83. String::npos vs. string::max_size() if (__capacity > _M_max_size()) std::__throw_length_error(__N("__sso_string_base::_M_create")); // The below implements an exponential growth policy, necessary to // meet amortized linear time requirements of the library: see // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) { __capacity = 2 * __old_capacity; // Never allocate a string bigger than max_size. if (__capacity > _M_max_size()) __capacity = _M_max_size(); } // NB: Need an array of char_type[__capacity], plus a terminating // null char_type() element. return _M_get_allocator().allocate(__capacity + 1); } template<typename _CharT, typename _Traits, typename _Alloc> __sso_string_base<_CharT, _Traits, _Alloc>:: __sso_string_base(const _Alloc& __a) : _M_dataplus(__a, _M_local_data) { _M_set_length(0); } template<typename _CharT, typename _Traits, typename _Alloc> __sso_string_base<_CharT, _Traits, _Alloc>:: __sso_string_base(const __sso_string_base& __rcs) : _M_dataplus(__rcs._M_get_allocator(), _M_local_data) { _M_construct(__rcs._M_data(), __rcs._M_data() + __rcs._M_length()); } #if __cplusplus >= 201103L template<typename _CharT, typename _Traits, typename _Alloc> __sso_string_base<_CharT, _Traits, _Alloc>:: __sso_string_base(__sso_string_base&& __rcs) : _M_dataplus(__rcs._M_get_allocator(), _M_local_data) { if (__rcs._M_is_local()) { if (__rcs._M_length()) traits_type::copy(_M_local_data, __rcs._M_local_data, _S_local_capacity + 1); } else { _M_data(__rcs._M_data()); _M_capacity(__rcs._M_allocated_capacity); } _M_set_length(__rcs._M_length()); __rcs._M_data(__rcs._M_local_data); __rcs._M_set_length(0); } #endif template<typename _CharT, typename _Traits, typename _Alloc> __sso_string_base<_CharT, _Traits, _Alloc>:: __sso_string_base(size_type __n, _CharT __c, const _Alloc& __a) : _M_dataplus(__a, _M_local_data) { _M_construct(__n, __c); } template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InputIterator> __sso_string_base<_CharT, _Traits, _Alloc>:: __sso_string_base(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) : _M_dataplus(__a, _M_local_data) { _M_construct(__beg, __end); } // NB: This is the special case for Input Iterators, used in // istreambuf_iterators, etc. // Input Iterators have a cost structure very different from // pointers, calling for a different coding style. template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InIterator> void __sso_string_base<_CharT, _Traits, _Alloc>:: _M_construct(_InIterator __beg, _InIterator __end, std::input_iterator_tag) { size_type __len = 0; size_type __capacity = size_type(_S_local_capacity); while (__beg != __end && __len < __capacity) { _M_data()[__len++] = *__beg; ++__beg; } __try { while (__beg != __end) { if (__len == __capacity) { // Allocate more space. __capacity = __len + 1; _CharT* __another = _M_create(__capacity, __len); this->_S_copy(__another, _M_data(), __len); _M_dispose(); _M_data(__another); _M_capacity(__capacity); } _M_data()[__len++] = *__beg; ++__beg; } } __catch(...) { _M_dispose(); __throw_exception_again; } _M_set_length(__len); } template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InIterator> void __sso_string_base<_CharT, _Traits, _Alloc>:: _M_construct(_InIterator __beg, _InIterator __end, std::forward_iterator_tag) { // NB: Not required, but considered best practice. if (__is_null_pointer(__beg) && __beg != __end) std::__throw_logic_error(__N("__sso_string_base::" "_M_construct null not valid")); size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); if (__dnew > size_type(_S_local_capacity)) { _M_data(_M_create(__dnew, size_type(0))); _M_capacity(__dnew); } // Check for out_of_range and length_error exceptions. __try { this->_S_copy_chars(_M_data(), __beg, __end); } __catch(...) { _M_dispose(); __throw_exception_again; } _M_set_length(__dnew); } template<typename _CharT, typename _Traits, typename _Alloc> void __sso_string_base<_CharT, _Traits, _Alloc>:: _M_construct(size_type __n, _CharT __c) { if (__n > size_type(_S_local_capacity)) { _M_data(_M_create(__n, size_type(0))); _M_capacity(__n); } if (__n) this->_S_assign(_M_data(), __n, __c); _M_set_length(__n); } template<typename _CharT, typename _Traits, typename _Alloc> void __sso_string_base<_CharT, _Traits, _Alloc>:: _M_assign(const __sso_string_base& __rcs) { if (this != &__rcs) { const size_type __rsize = __rcs._M_length(); const size_type __capacity = _M_capacity(); if (__rsize > __capacity) { size_type __new_capacity = __rsize; _CharT* __tmp = _M_create(__new_capacity, __capacity); _M_dispose(); _M_data(__tmp); _M_capacity(__new_capacity); } if (__rsize) this->_S_copy(_M_data(), __rcs._M_data(), __rsize); _M_set_length(__rsize); } } template<typename _CharT, typename _Traits, typename _Alloc> void __sso_string_base<_CharT, _Traits, _Alloc>:: _M_reserve(size_type __res) { // Make sure we don't shrink below the current size. if (__res < _M_length()) __res = _M_length(); const size_type __capacity = _M_capacity(); if (__res != __capacity) { if (__res > __capacity || __res > size_type(_S_local_capacity)) { _CharT* __tmp = _M_create(__res, __capacity); this->_S_copy(__tmp, _M_data(), _M_length() + 1); _M_dispose(); _M_data(__tmp); _M_capacity(__res); } else if (!_M_is_local()) { this->_S_copy(_M_local_data, _M_data(), _M_length() + 1); _M_destroy(__capacity); _M_data(_M_local_data); } } } template<typename _CharT, typename _Traits, typename _Alloc> void __sso_string_base<_CharT, _Traits, _Alloc>:: _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, size_type __len2) { const size_type __how_much = _M_length() - __pos - __len1; size_type __new_capacity = _M_length() + __len2 - __len1; _CharT* __r = _M_create(__new_capacity, _M_capacity()); if (__pos) this->_S_copy(__r, _M_data(), __pos); if (__s && __len2) this->_S_copy(__r + __pos, __s, __len2); if (__how_much) this->_S_copy(__r + __pos + __len2, _M_data() + __pos + __len1, __how_much); _M_dispose(); _M_data(__r); _M_capacity(__new_capacity); } template<typename _CharT, typename _Traits, typename _Alloc> void __sso_string_base<_CharT, _Traits, _Alloc>:: _M_erase(size_type __pos, size_type __n) { const size_type __how_much = _M_length() - __pos - __n; if (__how_much && __n) this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much); _M_set_length(_M_length() - __n); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _SSO_STRING_BASE_H */ c++/8/ext/stdio_filebuf.h 0000644 00000013046 15146341150 0011056 0 ustar 00 // File descriptor layer for filebuf -*- C++ -*- // Copyright (C) 2002-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/stdio_filebuf.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _STDIO_FILEBUF_H #define _STDIO_FILEBUF_H 1 #pragma GCC system_header #include <fstream> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Provides a layer of compatibility for C/POSIX. * @ingroup io * * This GNU extension provides extensions for working with standard C * FILE*'s and POSIX file descriptors. It must be instantiated by the * user with the type of character used in the file stream, e.g., * stdio_filebuf<char>. */ template<typename _CharT, typename _Traits = std::char_traits<_CharT> > class stdio_filebuf : public std::basic_filebuf<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; typedef std::size_t size_t; public: /** * deferred initialization */ stdio_filebuf() : std::basic_filebuf<_CharT, _Traits>() {} /** * @param __fd An open file descriptor. * @param __mode Same meaning as in a standard filebuf. * @param __size Optimal or preferred size of internal buffer, * in chars. * * This constructor associates a file stream buffer with an open * POSIX file descriptor. The file descriptor will be automatically * closed when the stdio_filebuf is closed/destroyed. */ stdio_filebuf(int __fd, std::ios_base::openmode __mode, size_t __size = static_cast<size_t>(BUFSIZ)); /** * @param __f An open @c FILE*. * @param __mode Same meaning as in a standard filebuf. * @param __size Optimal or preferred size of internal buffer, * in chars. Defaults to system's @c BUFSIZ. * * This constructor associates a file stream buffer with an open * C @c FILE*. The @c FILE* will not be automatically closed when the * stdio_filebuf is closed/destroyed. */ stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode, size_t __size = static_cast<size_t>(BUFSIZ)); /** * Closes the external data stream if the file descriptor constructor * was used. */ virtual ~stdio_filebuf(); #if __cplusplus >= 201103L stdio_filebuf(stdio_filebuf&&) = default; stdio_filebuf& operator=(stdio_filebuf&&) = default; void swap(stdio_filebuf& __fb) { std::basic_filebuf<_CharT, _Traits>::swap(__fb); } #endif /** * @return The underlying file descriptor. * * Once associated with an external data stream, this function can be * used to access the underlying POSIX file descriptor. Note that * there is no way for the library to track what you do with the * descriptor, so be careful. */ int fd() { return this->_M_file.fd(); } /** * @return The underlying FILE*. * * This function can be used to access the underlying "C" file pointer. * Note that there is no way for the library to track what you do * with the file, so be careful. */ std::__c_file* file() { return this->_M_file.file(); } }; template<typename _CharT, typename _Traits> stdio_filebuf<_CharT, _Traits>::~stdio_filebuf() { } template<typename _CharT, typename _Traits> stdio_filebuf<_CharT, _Traits>:: stdio_filebuf(int __fd, std::ios_base::openmode __mode, size_t __size) { this->_M_file.sys_open(__fd, __mode); if (this->is_open()) { this->_M_mode = __mode; this->_M_buf_size = __size; this->_M_allocate_internal_buffer(); this->_M_reading = false; this->_M_writing = false; this->_M_set_buffer(-1); } } template<typename _CharT, typename _Traits> stdio_filebuf<_CharT, _Traits>:: stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode, size_t __size) { this->_M_file.sys_open(__f, __mode); if (this->is_open()) { this->_M_mode = __mode; this->_M_buf_size = __size; this->_M_allocate_internal_buffer(); this->_M_reading = false; this->_M_writing = false; this->_M_set_buffer(-1); } } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/hash_map 0000644 00000042557 15146341150 0007603 0 ustar 00 // Hashing map implementation -*- C++ -*- // Copyright (C) 2001-2018 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_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(); } 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(); } 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 c++/8/ext/debug_allocator.h 0000644 00000013124 15146341150 0011363 0 ustar 00 // Allocators -*- C++ -*- // Copyright (C) 2001-2018 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 ext/debug_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _DEBUG_ALLOCATOR_H #define _DEBUG_ALLOCATOR_H 1 #include <stdexcept> #include <bits/functexcept.h> #include <ext/alloc_traits.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; /** * @brief A meta-allocator with debugging bits. * @ingroup allocators * * This is precisely the allocator defined in the C++03 Standard. */ template<typename _Alloc> class debug_allocator { template<typename> friend class debug_allocator; typedef __alloc_traits<_Alloc> _Traits; public: typedef typename _Traits::size_type size_type; typedef typename _Traits::difference_type difference_type; typedef typename _Traits::pointer pointer; typedef typename _Traits::const_pointer const_pointer; typedef typename _Traits::reference reference; typedef typename _Traits::const_reference const_reference; typedef typename _Traits::value_type value_type; template<typename _Up> class rebind { typedef typename _Traits::template rebind<_Up>::other __other; public: typedef debug_allocator<__other> other; }; private: // _M_extra is the number of objects that correspond to the // extra space where debug information is stored. size_type _M_extra; _Alloc _M_allocator; template<typename _Alloc2, typename = typename _Alloc2::template rebind<value_type>::other> struct __convertible { }; template<typename _Alloc2> struct __convertible<_Alloc2, _Alloc> { typedef void* __type; }; size_type _S_extra() { const size_t __obj_size = sizeof(value_type); return (sizeof(size_type) + __obj_size - 1) / __obj_size; } public: debug_allocator() : _M_extra(_S_extra()) { } template<typename _Alloc2> debug_allocator(const debug_allocator<_Alloc2>& __a2, typename __convertible<_Alloc2>::__type = 0) : _M_allocator(__a2._M_allocator), _M_extra(_S_extra()) { } debug_allocator(const _Alloc& __a) : _M_allocator(__a), _M_extra(_S_extra()) { } pointer allocate(size_type __n) { pointer __res = _M_allocator.allocate(__n + _M_extra); size_type* __ps = reinterpret_cast<size_type*>(__res); *__ps = __n; return __res + _M_extra; } pointer allocate(size_type __n, const void* __hint) { pointer __res = _M_allocator.allocate(__n + _M_extra, __hint); size_type* __ps = reinterpret_cast<size_type*>(__res); *__ps = __n; return __res + _M_extra; } void deallocate(pointer __p, size_type __n) { using std::__throw_runtime_error; if (__p) { pointer __real_p = __p - _M_extra; if (*reinterpret_cast<size_type*>(__real_p) != __n) __throw_runtime_error("debug_allocator::deallocate wrong size"); _M_allocator.deallocate(__real_p, __n + _M_extra); } else __throw_runtime_error("debug_allocator::deallocate null pointer"); } void construct(pointer __p, const value_type& __val) { _Traits::construct(_M_allocator, __p, __val); } #if __cplusplus >= 201103L template<typename _Tp, typename... _Args> void construct(_Tp* __p, _Args&&... __args) { _Traits::construct(_M_allocator, __p, std::forward<_Args>(__args)...); } #endif template<typename _Tp> void destroy(_Tp* __p) { _Traits::destroy(_M_allocator, __p); } size_type max_size() const throw() { return _Traits::max_size(_M_allocator) - _M_extra; } friend bool operator==(const debug_allocator& __lhs, const debug_allocator& __rhs) { return __lhs._M_allocator == __rhs._M_allocator; } }; template<typename _Alloc> inline bool operator!=(const debug_allocator<_Alloc>& __lhs, const debug_allocator<_Alloc>& __rhs) { return !(__lhs == __rhs); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/new_allocator.h 0000644 00000011305 15146341150 0011065 0 ustar 00 // Allocator that wraps operator new -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/new_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _NEW_ALLOCATOR_H #define _NEW_ALLOCATOR_H 1 #include <bits/c++config.h> #include <new> #include <bits/functexcept.h> #include <bits/move.h> #if __cplusplus >= 201103L #include <type_traits> #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; /** * @brief An allocator that uses global new, as per [20.4]. * @ingroup allocators * * This is precisely the allocator defined in the C++ Standard. * - all allocation calls operator new * - all deallocation calls operator delete * * @tparam _Tp Type of allocated object. */ template<typename _Tp> class new_allocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; template<typename _Tp1> struct rebind { typedef new_allocator<_Tp1> other; }; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; #endif new_allocator() _GLIBCXX_USE_NOEXCEPT { } new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { } template<typename _Tp1> new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { } ~new_allocator() _GLIBCXX_USE_NOEXCEPT { } pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } // NB: __n is permitted to be 0. The C++ standard says nothing // about what the return value is when __n == 0. pointer allocate(size_type __n, const void* = static_cast<const void*>(0)) { if (__n > this->max_size()) std::__throw_bad_alloc(); #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { std::align_val_t __al = std::align_val_t(alignof(_Tp)); return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al)); } #endif return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); } // __p is not permitted to be a null pointer. void deallocate(pointer __p, size_type) { #if __cpp_aligned_new if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { ::operator delete(__p, std::align_val_t(alignof(_Tp))); return; } #endif ::operator delete(__p); } size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return size_t(-1) / sizeof(_Tp); } #if __cplusplus >= 201103L template<typename _Up, typename... _Args> void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template<typename _Up> void destroy(_Up* __p) { __p->~_Up(); } #else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) _Tp(__val); } void destroy(pointer __p) { __p->~_Tp(); } #endif }; template<typename _Tp> inline bool operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&) { return true; } template<typename _Tp> inline bool operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&) { return false; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/pointer.h 0000644 00000046563 15146341150 0007732 0 ustar 00 // Custom pointer adapter and sample storage policies // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** * @file ext/pointer.h * This file is a GNU extension to the Standard C++ Library. * * @author Bob Walters * * Provides reusable _Pointer_adapter for assisting in the development of * custom pointer types that can be used with the standard containers via * the allocator::pointer and allocator::const_pointer typedefs. */ #ifndef _POINTER_H #define _POINTER_H 1 #pragma GCC system_header #include <iosfwd> #include <bits/stl_iterator_base_types.h> #include <ext/cast.h> #include <ext/type_traits.h> #if __cplusplus >= 201103L # include <bits/move.h> # include <bits/ptr_traits.h> #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief A storage policy for use with _Pointer_adapter<> which yields a * standard pointer. * * A _Storage_policy is required to provide 4 things: * 1) A get() API for returning the stored pointer value. * 2) An set() API for storing a pointer value. * 3) An element_type typedef to define the type this points to. * 4) An operator<() to support pointer comparison. * 5) An operator==() to support pointer comparison. */ template<typename _Tp> class _Std_pointer_impl { public: // the type this pointer points to. typedef _Tp element_type; // A method to fetch the pointer value as a standard T* value; inline _Tp* get() const { return _M_value; } // A method to set the pointer value, from a standard T* value; inline void set(element_type* __arg) { _M_value = __arg; } // Comparison of pointers inline bool operator<(const _Std_pointer_impl& __rarg) const { return (_M_value < __rarg._M_value); } inline bool operator==(const _Std_pointer_impl& __rarg) const { return (_M_value == __rarg._M_value); } private: element_type* _M_value; }; /** * @brief A storage policy for use with _Pointer_adapter<> which stores * the pointer's address as an offset value which is relative to * its own address. * * This is intended for pointers within shared memory regions which * might be mapped at different addresses by different processes. * For null pointers, a value of 1 is used. (0 is legitimate * sometimes for nodes in circularly linked lists) This value was * chosen as the least likely to generate an incorrect null, As * there is no reason why any normal pointer would point 1 byte into * its own pointer address. */ template<typename _Tp> class _Relative_pointer_impl { public: typedef _Tp element_type; _Tp* get() const { if (_M_diff == 1) return 0; else return reinterpret_cast<_Tp*>(reinterpret_cast<_UIntPtrType>(this) + _M_diff); } void set(_Tp* __arg) { if (!__arg) _M_diff = 1; else _M_diff = reinterpret_cast<_UIntPtrType>(__arg) - reinterpret_cast<_UIntPtrType>(this); } // Comparison of pointers inline bool operator<(const _Relative_pointer_impl& __rarg) const { return (reinterpret_cast<_UIntPtrType>(this->get()) < reinterpret_cast<_UIntPtrType>(__rarg.get())); } inline bool operator==(const _Relative_pointer_impl& __rarg) const { return (reinterpret_cast<_UIntPtrType>(this->get()) == reinterpret_cast<_UIntPtrType>(__rarg.get())); } private: #ifdef _GLIBCXX_USE_LONG_LONG typedef __gnu_cxx::__conditional_type< (sizeof(unsigned long) >= sizeof(void*)), unsigned long, unsigned long long>::__type _UIntPtrType; #else typedef unsigned long _UIntPtrType; #endif _UIntPtrType _M_diff; }; /** * Relative_pointer_impl needs a specialization for const T because of * the casting done during pointer arithmetic. */ template<typename _Tp> class _Relative_pointer_impl<const _Tp> { public: typedef const _Tp element_type; const _Tp* get() const { if (_M_diff == 1) return 0; else return reinterpret_cast<const _Tp*> (reinterpret_cast<_UIntPtrType>(this) + _M_diff); } void set(const _Tp* __arg) { if (!__arg) _M_diff = 1; else _M_diff = reinterpret_cast<_UIntPtrType>(__arg) - reinterpret_cast<_UIntPtrType>(this); } // Comparison of pointers inline bool operator<(const _Relative_pointer_impl& __rarg) const { return (reinterpret_cast<_UIntPtrType>(this->get()) < reinterpret_cast<_UIntPtrType>(__rarg.get())); } inline bool operator==(const _Relative_pointer_impl& __rarg) const { return (reinterpret_cast<_UIntPtrType>(this->get()) == reinterpret_cast<_UIntPtrType>(__rarg.get())); } private: #ifdef _GLIBCXX_USE_LONG_LONG typedef __gnu_cxx::__conditional_type< (sizeof(unsigned long) >= sizeof(void*)), unsigned long, unsigned long long>::__type _UIntPtrType; #else typedef unsigned long _UIntPtrType; #endif _UIntPtrType _M_diff; }; /** * The specialization on this type helps resolve the problem of * reference to void, and eliminates the need to specialize * _Pointer_adapter for cases of void*, const void*, and so on. */ struct _Invalid_type { }; template<typename _Tp> struct _Reference_type { typedef _Tp& reference; }; template<> struct _Reference_type<void> { typedef _Invalid_type& reference; }; template<> struct _Reference_type<const void> { typedef const _Invalid_type& reference; }; template<> struct _Reference_type<volatile void> { typedef volatile _Invalid_type& reference; }; template<> struct _Reference_type<volatile const void> { typedef const volatile _Invalid_type& reference; }; /** * This structure accommodates the way in which * std::iterator_traits<> is normally specialized for const T*, so * that value_type is still T. */ template<typename _Tp> struct _Unqualified_type { typedef _Tp type; }; template<typename _Tp> struct _Unqualified_type<const _Tp> { typedef _Tp type; }; /** * The following provides an 'alternative pointer' that works with * the containers when specified as the pointer typedef of the * allocator. * * The pointer type used with the containers doesn't have to be this * class, but it must support the implicit conversions, pointer * arithmetic, comparison operators, etc. that are supported by this * class, and avoid raising compile-time ambiguities. Because * creating a working pointer can be challenging, this pointer * template was designed to wrapper an easier storage policy type, * so that it becomes reusable for creating other pointer types. * * A key point of this class is also that it allows container * writers to 'assume' Allocator::pointer is a typedef for a normal * pointer. This class supports most of the conventions of a true * pointer, and can, for instance handle implicit conversion to * const and base class pointer types. The only impositions on * container writers to support extended pointers are: 1) use the * Allocator::pointer typedef appropriately for pointer types. 2) * if you need pointer casting, use the __pointer_cast<> functions * from ext/cast.h. This allows pointer cast operations to be * overloaded as necessary by custom pointers. * * Note: The const qualifier works with this pointer adapter as * follows: * * _Tp* == _Pointer_adapter<_Std_pointer_impl<_Tp> >; * const _Tp* == _Pointer_adapter<_Std_pointer_impl<const _Tp> >; * _Tp* const == const _Pointer_adapter<_Std_pointer_impl<_Tp> >; * const _Tp* const == const _Pointer_adapter<_Std_pointer_impl<const _Tp> >; */ template<typename _Storage_policy> class _Pointer_adapter : public _Storage_policy { public: typedef typename _Storage_policy::element_type element_type; // These are needed for iterator_traits typedef std::random_access_iterator_tag iterator_category; typedef typename _Unqualified_type<element_type>::type value_type; typedef std::ptrdiff_t difference_type; typedef _Pointer_adapter pointer; typedef typename _Reference_type<element_type>::reference reference; // Reminder: 'const' methods mean that the method is valid when the // pointer is immutable, and has nothing to do with whether the // 'pointee' is const. // Default Constructor (Convert from element_type*) _Pointer_adapter(element_type* __arg = 0) { _Storage_policy::set(__arg); } // Copy constructor from _Pointer_adapter of same type. _Pointer_adapter(const _Pointer_adapter& __arg) { _Storage_policy::set(__arg.get()); } // Convert from _Up* if conversion to element_type* is valid. template<typename _Up> _Pointer_adapter(_Up* __arg) { _Storage_policy::set(__arg); } // Conversion from another _Pointer_adapter if _Up if static cast is // valid. template<typename _Up> _Pointer_adapter(const _Pointer_adapter<_Up>& __arg) { _Storage_policy::set(__arg.get()); } // Destructor ~_Pointer_adapter() { } // Assignment operator _Pointer_adapter& operator=(const _Pointer_adapter& __arg) { _Storage_policy::set(__arg.get()); return *this; } template<typename _Up> _Pointer_adapter& operator=(const _Pointer_adapter<_Up>& __arg) { _Storage_policy::set(__arg.get()); return *this; } template<typename _Up> _Pointer_adapter& operator=(_Up* __arg) { _Storage_policy::set(__arg); return *this; } // Operator*, returns element_type& inline reference operator*() const { return *(_Storage_policy::get()); } // Operator->, returns element_type* inline element_type* operator->() const { return _Storage_policy::get(); } // Operator[], returns a element_type& to the item at that loc. inline reference operator[](std::ptrdiff_t __index) const { return _Storage_policy::get()[__index]; } // To allow implicit conversion to "bool", for "if (ptr)..." private: typedef element_type*(_Pointer_adapter::*__unspecified_bool_type)() const; public: operator __unspecified_bool_type() const { return _Storage_policy::get() == 0 ? 0 : &_Pointer_adapter::operator->; } // ! operator (for: if (!ptr)...) inline bool operator!() const { return (_Storage_policy::get() == 0); } // Pointer differences inline friend std::ptrdiff_t operator-(const _Pointer_adapter& __lhs, element_type* __rhs) { return (__lhs.get() - __rhs); } inline friend std::ptrdiff_t operator-(element_type* __lhs, const _Pointer_adapter& __rhs) { return (__lhs - __rhs.get()); } template<typename _Up> inline friend std::ptrdiff_t operator-(const _Pointer_adapter& __lhs, _Up* __rhs) { return (__lhs.get() - __rhs); } template<typename _Up> inline friend std::ptrdiff_t operator-(_Up* __lhs, const _Pointer_adapter& __rhs) { return (__lhs - __rhs.get()); } template<typename _Up> inline std::ptrdiff_t operator-(const _Pointer_adapter<_Up>& __rhs) const { return (_Storage_policy::get() - __rhs.get()); } // Pointer math // Note: There is a reason for all this overloading based on different // integer types. In some libstdc++-v3 test cases, a templated // operator+ is declared which can match any types. This operator // tends to "steal" the recognition of _Pointer_adapter's own operator+ // unless the integer type matches perfectly. #define _CXX_POINTER_ARITH_OPERATOR_SET(INT_TYPE) \ inline friend _Pointer_adapter \ operator+(const _Pointer_adapter& __lhs, INT_TYPE __offset) \ { return _Pointer_adapter(__lhs.get() + __offset); } \ \ inline friend _Pointer_adapter \ operator+(INT_TYPE __offset, const _Pointer_adapter& __rhs) \ { return _Pointer_adapter(__rhs.get() + __offset); } \ \ inline friend _Pointer_adapter \ operator-(const _Pointer_adapter& __lhs, INT_TYPE __offset) \ { return _Pointer_adapter(__lhs.get() - __offset); } \ \ inline _Pointer_adapter& \ operator+=(INT_TYPE __offset) \ { \ _Storage_policy::set(_Storage_policy::get() + __offset); \ return *this; \ } \ \ inline _Pointer_adapter& \ operator-=(INT_TYPE __offset) \ { \ _Storage_policy::set(_Storage_policy::get() - __offset); \ return *this; \ } \ // END of _CXX_POINTER_ARITH_OPERATOR_SET macro // Expand into the various pointer arithmetic operators needed. _CXX_POINTER_ARITH_OPERATOR_SET(short); _CXX_POINTER_ARITH_OPERATOR_SET(unsigned short); _CXX_POINTER_ARITH_OPERATOR_SET(int); _CXX_POINTER_ARITH_OPERATOR_SET(unsigned int); _CXX_POINTER_ARITH_OPERATOR_SET(long); _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long); #ifdef _GLIBCXX_USE_LONG_LONG _CXX_POINTER_ARITH_OPERATOR_SET(long long); _CXX_POINTER_ARITH_OPERATOR_SET(unsigned long long); #endif // Mathematical Manipulators inline _Pointer_adapter& operator++() { _Storage_policy::set(_Storage_policy::get() + 1); return *this; } inline _Pointer_adapter operator++(int) { _Pointer_adapter __tmp(*this); _Storage_policy::set(_Storage_policy::get() + 1); return __tmp; } inline _Pointer_adapter& operator--() { _Storage_policy::set(_Storage_policy::get() - 1); return *this; } inline _Pointer_adapter operator--(int) { _Pointer_adapter __tmp(*this); _Storage_policy::set(_Storage_policy::get() - 1); return __tmp; } }; // class _Pointer_adapter #define _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(OPERATOR) \ template<typename _Tp1, typename _Tp2> \ inline bool \ operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, _Tp2 __rhs) \ { return __lhs.get() OPERATOR __rhs; } \ \ template<typename _Tp1, typename _Tp2> \ inline bool \ operator OPERATOR(_Tp1 __lhs, const _Pointer_adapter<_Tp2>& __rhs) \ { return __lhs OPERATOR __rhs.get(); } \ \ template<typename _Tp1, typename _Tp2> \ inline bool \ operator OPERATOR(const _Pointer_adapter<_Tp1>& __lhs, \ const _Pointer_adapter<_Tp2>& __rhs) \ { return __lhs.get() OPERATOR __rhs.get(); } \ \ // End GCC_CXX_POINTER_COMPARISON_OPERATION_SET Macro // Expand into the various comparison operators needed. _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(==) _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(!=) _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<) _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(<=) _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>) _GCC_CXX_POINTER_COMPARISON_OPERATION_SET(>=) // These are here for expressions like "ptr == 0", "ptr != 0" template<typename _Tp> inline bool operator==(const _Pointer_adapter<_Tp>& __lhs, int __rhs) { return __lhs.get() == reinterpret_cast<void*>(__rhs); } template<typename _Tp> inline bool operator==(int __lhs, const _Pointer_adapter<_Tp>& __rhs) { return __rhs.get() == reinterpret_cast<void*>(__lhs); } template<typename _Tp> inline bool operator!=(const _Pointer_adapter<_Tp>& __lhs, int __rhs) { return __lhs.get() != reinterpret_cast<void*>(__rhs); } template<typename _Tp> inline bool operator!=(int __lhs, const _Pointer_adapter<_Tp>& __rhs) { return __rhs.get() != reinterpret_cast<void*>(__lhs); } /** * Comparison operators for _Pointer_adapter defer to the base class' * comparison operators, when possible. */ template<typename _Tp> inline bool operator==(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return __lhs._Tp::operator==(__rhs); } template<typename _Tp> inline bool operator<=(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return __lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs); } template<typename _Tp> inline bool operator!=(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return !(__lhs._Tp::operator==(__rhs)); } template<typename _Tp> inline bool operator>(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return !(__lhs._Tp::operator<(__rhs) || __lhs._Tp::operator==(__rhs)); } template<typename _Tp> inline bool operator>=(const _Pointer_adapter<_Tp>& __lhs, const _Pointer_adapter<_Tp>& __rhs) { return !(__lhs._Tp::operator<(__rhs)); } template<typename _CharT, typename _Traits, typename _StoreT> inline std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const _Pointer_adapter<_StoreT>& __p) { return (__os << __p.get()); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if __cplusplus >= 201103L namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Storage_policy> struct pointer_traits<__gnu_cxx::_Pointer_adapter<_Storage_policy>> { /// The pointer type typedef __gnu_cxx::_Pointer_adapter<_Storage_policy> pointer; /// The type pointed to typedef typename pointer::element_type element_type; /// Type used to represent the difference between two pointers typedef typename pointer::difference_type difference_type; template<typename _Up> using rebind = typename __gnu_cxx::_Pointer_adapter< typename pointer_traits<_Storage_policy>::template rebind<_Up>>; static pointer pointer_to(typename pointer::reference __r) noexcept { return pointer(std::addressof(__r)); } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif #endif // _POINTER_H c++/8/ext/alloc_traits.h 0000644 00000013106 15146341150 0010715 0 ustar 00 // Allocator traits -*- C++ -*- // Copyright (C) 2011-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/alloc_traits.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_ALLOC_TRAITS_H #define _EXT_ALLOC_TRAITS_H 1 #pragma GCC system_header #if __cplusplus >= 201103L # include <bits/move.h> # include <bits/alloc_traits.h> #else # include <bits/allocator.h> // for __alloc_swap #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Uniform interface to C++98 and C++11 allocators. * @ingroup allocators */ template<typename _Alloc, typename = typename _Alloc::value_type> struct __alloc_traits #if __cplusplus >= 201103L : std::allocator_traits<_Alloc> #endif { typedef _Alloc allocator_type; #if __cplusplus >= 201103L typedef std::allocator_traits<_Alloc> _Base_type; typedef typename _Base_type::value_type value_type; typedef typename _Base_type::pointer pointer; typedef typename _Base_type::const_pointer const_pointer; typedef typename _Base_type::size_type size_type; typedef typename _Base_type::difference_type difference_type; // C++11 allocators do not define reference or const_reference typedef value_type& reference; typedef const value_type& const_reference; using _Base_type::allocate; using _Base_type::deallocate; using _Base_type::construct; using _Base_type::destroy; using _Base_type::max_size; private: template<typename _Ptr> using __is_custom_pointer = std::__and_<std::is_same<pointer, _Ptr>, std::__not_<std::is_pointer<_Ptr>>>; public: // overload construct for non-standard pointer types template<typename _Ptr, typename... _Args> static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type construct(_Alloc& __a, _Ptr __p, _Args&&... __args) { _Base_type::construct(__a, std::__to_address(__p), std::forward<_Args>(__args)...); } // overload destroy for non-standard pointer types template<typename _Ptr> static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type destroy(_Alloc& __a, _Ptr __p) { _Base_type::destroy(__a, std::__to_address(__p)); } static _Alloc _S_select_on_copy(const _Alloc& __a) { return _Base_type::select_on_container_copy_construction(__a); } static void _S_on_swap(_Alloc& __a, _Alloc& __b) { std::__alloc_on_swap(__a, __b); } static constexpr bool _S_propagate_on_copy_assign() { return _Base_type::propagate_on_container_copy_assignment::value; } static constexpr bool _S_propagate_on_move_assign() { return _Base_type::propagate_on_container_move_assignment::value; } static constexpr bool _S_propagate_on_swap() { return _Base_type::propagate_on_container_swap::value; } static constexpr bool _S_always_equal() { return _Base_type::is_always_equal::value; } static constexpr bool _S_nothrow_move() { return _S_propagate_on_move_assign() || _S_always_equal(); } template<typename _Tp> struct rebind { typedef typename _Base_type::template rebind_alloc<_Tp> other; }; #else typedef typename _Alloc::pointer pointer; typedef typename _Alloc::const_pointer const_pointer; typedef typename _Alloc::value_type value_type; typedef typename _Alloc::reference reference; typedef typename _Alloc::const_reference const_reference; typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type; static pointer allocate(_Alloc& __a, size_type __n) { return __a.allocate(__n); } static void deallocate(_Alloc& __a, pointer __p, size_type __n) { __a.deallocate(__p, __n); } template<typename _Tp> static void construct(_Alloc& __a, pointer __p, const _Tp& __arg) { __a.construct(__p, __arg); } static void destroy(_Alloc& __a, pointer __p) { __a.destroy(__p); } static size_type max_size(const _Alloc& __a) { return __a.max_size(); } static const _Alloc& _S_select_on_copy(const _Alloc& __a) { return __a; } static void _S_on_swap(_Alloc& __a, _Alloc& __b) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 431. Swapping containers with unequal allocators. std::__alloc_swap<_Alloc>::_S_do_it(__a, __b); } template<typename _Tp> struct rebind { typedef typename _Alloc::template rebind<_Tp>::other other; }; #endif }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #endif c++/8/ext/concurrence.h 0000644 00000016673 15146341150 0010557 0 ustar 00 // Support for concurrent programing -*- C++ -*- // Copyright (C) 2003-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/concurrence.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _CONCURRENCE_H #define _CONCURRENCE_H 1 #pragma GCC system_header #include <exception> #include <bits/gthr.h> #include <bits/functexcept.h> #include <bits/cpp_type_traits.h> #include <ext/type_traits.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Available locking policies: // _S_single single-threaded code that doesn't need to be locked. // _S_mutex multi-threaded code that requires additional support // from gthr.h or abstraction layers in concurrence.h. // _S_atomic multi-threaded code using atomic operations. enum _Lock_policy { _S_single, _S_mutex, _S_atomic }; // Compile time constant that indicates prefered locking policy in // the current configuration. static const _Lock_policy __default_lock_policy = #ifdef __GTHREADS #if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) \ && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) _S_atomic; #else _S_mutex; #endif #else _S_single; #endif // NB: As this is used in libsupc++, need to only depend on // exception. No stdexception classes, no use of std::string. class __concurrence_lock_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_lock_error"; } }; class __concurrence_unlock_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_unlock_error"; } }; class __concurrence_broadcast_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_broadcast_error"; } }; class __concurrence_wait_error : public std::exception { public: virtual char const* what() const throw() { return "__gnu_cxx::__concurrence_wait_error"; } }; // Substitute for concurrence_error object in the case of -fno-exceptions. inline void __throw_concurrence_lock_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_lock_error()); } inline void __throw_concurrence_unlock_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_unlock_error()); } #ifdef __GTHREAD_HAS_COND inline void __throw_concurrence_broadcast_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_broadcast_error()); } inline void __throw_concurrence_wait_error() { _GLIBCXX_THROW_OR_ABORT(__concurrence_wait_error()); } #endif class __mutex { private: #if __GTHREADS && defined __GTHREAD_MUTEX_INIT __gthread_mutex_t _M_mutex = __GTHREAD_MUTEX_INIT; #else __gthread_mutex_t _M_mutex; #endif __mutex(const __mutex&); __mutex& operator=(const __mutex&); public: __mutex() { #if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT if (__gthread_active_p()) __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex); #endif } #if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT ~__mutex() { if (__gthread_active_p()) __gthread_mutex_destroy(&_M_mutex); } #endif void lock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_mutex_lock(&_M_mutex) != 0) __throw_concurrence_lock_error(); } #endif } void unlock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_mutex_unlock(&_M_mutex) != 0) __throw_concurrence_unlock_error(); } #endif } __gthread_mutex_t* gthread_mutex(void) { return &_M_mutex; } }; class __recursive_mutex { private: #if __GTHREADS && defined __GTHREAD_RECURSIVE_MUTEX_INIT __gthread_recursive_mutex_t _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT; #else __gthread_recursive_mutex_t _M_mutex; #endif __recursive_mutex(const __recursive_mutex&); __recursive_mutex& operator=(const __recursive_mutex&); public: __recursive_mutex() { #if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT if (__gthread_active_p()) __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); #endif } #if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT ~__recursive_mutex() { if (__gthread_active_p()) __gthread_recursive_mutex_destroy(&_M_mutex); } #endif void lock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_recursive_mutex_lock(&_M_mutex) != 0) __throw_concurrence_lock_error(); } #endif } void unlock() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0) __throw_concurrence_unlock_error(); } #endif } __gthread_recursive_mutex_t* gthread_recursive_mutex(void) { return &_M_mutex; } }; /// Scoped lock idiom. // Acquire the mutex here with a constructor call, then release with // the destructor call in accordance with RAII style. class __scoped_lock { public: typedef __mutex __mutex_type; private: __mutex_type& _M_device; __scoped_lock(const __scoped_lock&); __scoped_lock& operator=(const __scoped_lock&); public: explicit __scoped_lock(__mutex_type& __name) : _M_device(__name) { _M_device.lock(); } ~__scoped_lock() throw() { _M_device.unlock(); } }; #ifdef __GTHREAD_HAS_COND class __cond { private: #if __GTHREADS && defined __GTHREAD_COND_INIT __gthread_cond_t _M_cond = __GTHREAD_COND_INIT; #else __gthread_cond_t _M_cond; #endif __cond(const __cond&); __cond& operator=(const __cond&); public: __cond() { #if __GTHREADS && ! defined __GTHREAD_COND_INIT if (__gthread_active_p()) __GTHREAD_COND_INIT_FUNCTION(&_M_cond); #endif } #if __GTHREADS && ! defined __GTHREAD_COND_INIT ~__cond() { if (__gthread_active_p()) __gthread_cond_destroy(&_M_cond); } #endif void broadcast() { #if __GTHREADS if (__gthread_active_p()) { if (__gthread_cond_broadcast(&_M_cond) != 0) __throw_concurrence_broadcast_error(); } #endif } void wait(__mutex *mutex) { #if __GTHREADS { if (__gthread_cond_wait(&_M_cond, mutex->gthread_mutex()) != 0) __throw_concurrence_wait_error(); } #endif } void wait_recursive(__recursive_mutex *mutex) { #if __GTHREADS { if (__gthread_cond_wait_recursive(&_M_cond, mutex->gthread_recursive_mutex()) != 0) __throw_concurrence_wait_error(); } #endif } }; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/random 0000644 00000331443 15146341150 0007276 0 ustar 00 // Random number extensions -*- C++ -*- // Copyright (C) 2012-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/random * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_RANDOM #define _EXT_RANDOM 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <random> #include <algorithm> #include <array> #include <ext/cmath> #ifdef __SSE2__ # include <emmintrin.h> #endif #if defined(_GLIBCXX_USE_C99_STDINT_TR1) && defined(UINT32_C) namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Mersenne twister implementation optimized for vector operations. * * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/ */ template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> class simd_fast_mersenne_twister_engine { static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); static_assert(__sr1 < 32, "first right shift too large"); static_assert(__sr2 < 16, "second right shift too large"); static_assert(__sl1 < 32, "first left shift too large"); static_assert(__sl2 < 16, "second left shift too large"); public: typedef _UIntType result_type; private: static constexpr size_t m_w = sizeof(result_type) * 8; static constexpr size_t _M_nstate = __m / 128 + 1; static constexpr size_t _M_nstate32 = _M_nstate * 4; static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size"); static_assert(16 % sizeof(_UIntType) == 0, "UIntType size must divide 16"); public: static constexpr size_t state_size = _M_nstate * (16 / sizeof(result_type)); static constexpr result_type default_seed = 5489u; // constructors and member function explicit simd_fast_mersenne_twister_engine(result_type __sd = default_seed) { seed(__sd); } template<typename _Sseq, typename = typename std::enable_if<!std::is_same<_Sseq, simd_fast_mersenne_twister_engine>::value> ::type> explicit simd_fast_mersenne_twister_engine(_Sseq& __q) { seed(__q); } void seed(result_type __sd = default_seed); template<typename _Sseq> typename std::enable_if<std::is_class<_Sseq>::value>::type seed(_Sseq& __q); static constexpr result_type min() { return 0; } static constexpr result_type max() { return std::numeric_limits<result_type>::max(); } void discard(unsigned long long __z); result_type operator()() { if (__builtin_expect(_M_pos >= state_size, 0)) _M_gen_rand(); return _M_stateT[_M_pos++]; } template<typename _UIntType_2, size_t __m_2, size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, size_t __sr1_2, size_t __sr2_2, uint32_t __msk1_2, uint32_t __msk2_2, uint32_t __msk3_2, uint32_t __msk4_2, uint32_t __parity1_2, uint32_t __parity2_2, uint32_t __parity3_2, uint32_t __parity4_2> friend bool operator==(const simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __lhs, const simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __rhs); template<typename _UIntType_2, size_t __m_2, size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, size_t __sr1_2, size_t __sr2_2, uint32_t __msk1_2, uint32_t __msk2_2, uint32_t __msk3_2, uint32_t __msk4_2, uint32_t __parity1_2, uint32_t __parity2_2, uint32_t __parity3_2, uint32_t __parity4_2, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::simd_fast_mersenne_twister_engine <_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); template<typename _UIntType_2, size_t __m_2, size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, size_t __sr1_2, size_t __sr2_2, uint32_t __msk1_2, uint32_t __msk2_2, uint32_t __msk3_2, uint32_t __msk4_2, uint32_t __parity1_2, uint32_t __parity2_2, uint32_t __parity3_2, uint32_t __parity4_2, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2, __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, __msk1_2, __msk2_2, __msk3_2, __msk4_2, __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); private: union { #ifdef __SSE2__ __m128i _M_state[_M_nstate]; #endif #ifdef __ARM_NEON #ifdef __aarch64__ __Uint32x4_t _M_state[_M_nstate]; #endif #endif uint32_t _M_state32[_M_nstate32]; result_type _M_stateT[state_size]; } __attribute__ ((__aligned__ (16))); size_t _M_pos; void _M_gen_rand(void); void _M_period_certification(); }; template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> inline bool operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) { return !(__lhs == __rhs); } /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined * in the C implementation by Daito and Matsumoto, as both a 32-bit * and 64-bit version. */ typedef simd_fast_mersenne_twister_engine<uint32_t, 607, 2, 15, 3, 13, 3, 0xfdff37ffU, 0xef7f3f7dU, 0xff777b7dU, 0x7ff7fb2fU, 0x00000001U, 0x00000000U, 0x00000000U, 0x5986f054U> sfmt607; typedef simd_fast_mersenne_twister_engine<uint64_t, 607, 2, 15, 3, 13, 3, 0xfdff37ffU, 0xef7f3f7dU, 0xff777b7dU, 0x7ff7fb2fU, 0x00000001U, 0x00000000U, 0x00000000U, 0x5986f054U> sfmt607_64; typedef simd_fast_mersenne_twister_engine<uint32_t, 1279, 7, 14, 3, 5, 1, 0xf7fefffdU, 0x7fefcfffU, 0xaff3ef3fU, 0xb5ffff7fU, 0x00000001U, 0x00000000U, 0x00000000U, 0x20000000U> sfmt1279; typedef simd_fast_mersenne_twister_engine<uint64_t, 1279, 7, 14, 3, 5, 1, 0xf7fefffdU, 0x7fefcfffU, 0xaff3ef3fU, 0xb5ffff7fU, 0x00000001U, 0x00000000U, 0x00000000U, 0x20000000U> sfmt1279_64; typedef simd_fast_mersenne_twister_engine<uint32_t, 2281, 12, 19, 1, 5, 1, 0xbff7ffbfU, 0xfdfffffeU, 0xf7ffef7fU, 0xf2f7cbbfU, 0x00000001U, 0x00000000U, 0x00000000U, 0x41dfa600U> sfmt2281; typedef simd_fast_mersenne_twister_engine<uint64_t, 2281, 12, 19, 1, 5, 1, 0xbff7ffbfU, 0xfdfffffeU, 0xf7ffef7fU, 0xf2f7cbbfU, 0x00000001U, 0x00000000U, 0x00000000U, 0x41dfa600U> sfmt2281_64; typedef simd_fast_mersenne_twister_engine<uint32_t, 4253, 17, 20, 1, 7, 1, 0x9f7bffffU, 0x9fffff5fU, 0x3efffffbU, 0xfffff7bbU, 0xa8000001U, 0xaf5390a3U, 0xb740b3f8U, 0x6c11486dU> sfmt4253; typedef simd_fast_mersenne_twister_engine<uint64_t, 4253, 17, 20, 1, 7, 1, 0x9f7bffffU, 0x9fffff5fU, 0x3efffffbU, 0xfffff7bbU, 0xa8000001U, 0xaf5390a3U, 0xb740b3f8U, 0x6c11486dU> sfmt4253_64; typedef simd_fast_mersenne_twister_engine<uint32_t, 11213, 68, 14, 3, 7, 3, 0xeffff7fbU, 0xffffffefU, 0xdfdfbfffU, 0x7fffdbfdU, 0x00000001U, 0x00000000U, 0xe8148000U, 0xd0c7afa3U> sfmt11213; typedef simd_fast_mersenne_twister_engine<uint64_t, 11213, 68, 14, 3, 7, 3, 0xeffff7fbU, 0xffffffefU, 0xdfdfbfffU, 0x7fffdbfdU, 0x00000001U, 0x00000000U, 0xe8148000U, 0xd0c7afa3U> sfmt11213_64; typedef simd_fast_mersenne_twister_engine<uint32_t, 19937, 122, 18, 1, 11, 1, 0xdfffffefU, 0xddfecb7fU, 0xbffaffffU, 0xbffffff6U, 0x00000001U, 0x00000000U, 0x00000000U, 0x13c9e684U> sfmt19937; typedef simd_fast_mersenne_twister_engine<uint64_t, 19937, 122, 18, 1, 11, 1, 0xdfffffefU, 0xddfecb7fU, 0xbffaffffU, 0xbffffff6U, 0x00000001U, 0x00000000U, 0x00000000U, 0x13c9e684U> sfmt19937_64; typedef simd_fast_mersenne_twister_engine<uint32_t, 44497, 330, 5, 3, 9, 3, 0xeffffffbU, 0xdfbebfffU, 0xbfbf7befU, 0x9ffd7bffU, 0x00000001U, 0x00000000U, 0xa3ac4000U, 0xecc1327aU> sfmt44497; typedef simd_fast_mersenne_twister_engine<uint64_t, 44497, 330, 5, 3, 9, 3, 0xeffffffbU, 0xdfbebfffU, 0xbfbf7befU, 0x9ffd7bffU, 0x00000001U, 0x00000000U, 0xa3ac4000U, 0xecc1327aU> sfmt44497_64; typedef simd_fast_mersenne_twister_engine<uint32_t, 86243, 366, 6, 7, 19, 1, 0xfdbffbffU, 0xbff7ff3fU, 0xfd77efffU, 0xbf9ff3ffU, 0x00000001U, 0x00000000U, 0x00000000U, 0xe9528d85U> sfmt86243; typedef simd_fast_mersenne_twister_engine<uint64_t, 86243, 366, 6, 7, 19, 1, 0xfdbffbffU, 0xbff7ff3fU, 0xfd77efffU, 0xbf9ff3ffU, 0x00000001U, 0x00000000U, 0x00000000U, 0xe9528d85U> sfmt86243_64; typedef simd_fast_mersenne_twister_engine<uint32_t, 132049, 110, 19, 1, 21, 1, 0xffffbb5fU, 0xfb6ebf95U, 0xfffefffaU, 0xcff77fffU, 0x00000001U, 0x00000000U, 0xcb520000U, 0xc7e91c7dU> sfmt132049; typedef simd_fast_mersenne_twister_engine<uint64_t, 132049, 110, 19, 1, 21, 1, 0xffffbb5fU, 0xfb6ebf95U, 0xfffefffaU, 0xcff77fffU, 0x00000001U, 0x00000000U, 0xcb520000U, 0xc7e91c7dU> sfmt132049_64; typedef simd_fast_mersenne_twister_engine<uint32_t, 216091, 627, 11, 3, 10, 1, 0xbff7bff7U, 0xbfffffffU, 0xbffffa7fU, 0xffddfbfbU, 0xf8000001U, 0x89e80709U, 0x3bd2b64bU, 0x0c64b1e4U> sfmt216091; typedef simd_fast_mersenne_twister_engine<uint64_t, 216091, 627, 11, 3, 10, 1, 0xbff7bff7U, 0xbfffffffU, 0xbffffa7fU, 0xffddfbfbU, 0xf8000001U, 0x89e80709U, 0x3bd2b64bU, 0x0c64b1e4U> sfmt216091_64; #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /** * @brief A beta continuous distribution for random numbers. * * The formula for the beta probability density function is: * @f[ * p(x|\alpha,\beta) = \frac{1}{B(\alpha,\beta)} * x^{\alpha - 1} (1 - x)^{\beta - 1} * @f] */ template<typename _RealType = double> class beta_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef beta_distribution<_RealType> distribution_type; friend class beta_distribution<_RealType>; explicit param_type(_RealType __alpha_val = _RealType(1), _RealType __beta_val = _RealType(1)) : _M_alpha(__alpha_val), _M_beta(__beta_val) { __glibcxx_assert(_M_alpha > _RealType(0)); __glibcxx_assert(_M_beta > _RealType(0)); } _RealType alpha() const { return _M_alpha; } _RealType beta() const { return _M_beta; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_alpha == __p2._M_alpha && __p1._M_beta == __p2._M_beta); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); _RealType _M_alpha; _RealType _M_beta; }; public: /** * @brief Constructs a beta distribution with parameters * @f$\alpha@f$ and @f$\beta@f$. */ explicit beta_distribution(_RealType __alpha_val = _RealType(1), _RealType __beta_val = _RealType(1)) : _M_param(__alpha_val, __beta_val) { } explicit beta_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the @f$\alpha@f$ of the distribution. */ _RealType alpha() const { return _M_param.alpha(); } /** * @brief Returns the @f$\beta@f$ of the distribution. */ _RealType beta() const { return _M_param.beta(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return result_type(1); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two beta distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const beta_distribution& __d1, const beta_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %beta_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %beta_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::beta_distribution<_RealType1>& __x); /** * @brief Extracts a %beta_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %beta_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::beta_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two beta distributions are different. */ template<typename _RealType> inline bool operator!=(const __gnu_cxx::beta_distribution<_RealType>& __d1, const __gnu_cxx::beta_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A multi-variate normal continuous distribution for random numbers. * * The formula for the normal probability density function is * @f[ * p(\overrightarrow{x}|\overrightarrow{\mu },\Sigma) = * \frac{1}{\sqrt{(2\pi )^k\det(\Sigma))}} * e^{-\frac{1}{2}(\overrightarrow{x}-\overrightarrow{\mu})^\text{T} * \Sigma ^{-1}(\overrightarrow{x}-\overrightarrow{\mu})} * @f] * * where @f$\overrightarrow{x}@f$ and @f$\overrightarrow{\mu}@f$ are * vectors of dimension @f$k@f$ and @f$\Sigma@f$ is the covariance * matrix (which must be positive-definite). */ template<std::size_t _Dimen, typename _RealType = double> class normal_mv_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); static_assert(_Dimen != 0, "dimension is zero"); public: /** The type of the range of the distribution. */ typedef std::array<_RealType, _Dimen> result_type; /** Parameter type. */ class param_type { static constexpr size_t _M_t_size = _Dimen * (_Dimen + 1) / 2; public: typedef normal_mv_distribution<_Dimen, _RealType> distribution_type; friend class normal_mv_distribution<_Dimen, _RealType>; param_type() { std::fill(_M_mean.begin(), _M_mean.end(), _RealType(0)); auto __it = _M_t.begin(); for (size_t __i = 0; __i < _Dimen; ++__i) { std::fill_n(__it, __i, _RealType(0)); __it += __i; *__it++ = _RealType(1); } } template<typename _ForwardIterator1, typename _ForwardIterator2> param_type(_ForwardIterator1 __meanbegin, _ForwardIterator1 __meanend, _ForwardIterator2 __varcovbegin, _ForwardIterator2 __varcovend) { __glibcxx_function_requires(_ForwardIteratorConcept< _ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept< _ForwardIterator2>) _GLIBCXX_DEBUG_ASSERT(std::distance(__meanbegin, __meanend) <= _Dimen); const auto __dist = std::distance(__varcovbegin, __varcovend); _GLIBCXX_DEBUG_ASSERT(__dist == _Dimen * _Dimen || __dist == _Dimen * (_Dimen + 1) / 2 || __dist == _Dimen); if (__dist == _Dimen * _Dimen) _M_init_full(__meanbegin, __meanend, __varcovbegin, __varcovend); else if (__dist == _Dimen * (_Dimen + 1) / 2) _M_init_lower(__meanbegin, __meanend, __varcovbegin, __varcovend); else { __glibcxx_assert(__dist == _Dimen); _M_init_diagonal(__meanbegin, __meanend, __varcovbegin, __varcovend); } } param_type(std::initializer_list<_RealType> __mean, std::initializer_list<_RealType> __varcov) { _GLIBCXX_DEBUG_ASSERT(__mean.size() <= _Dimen); _GLIBCXX_DEBUG_ASSERT(__varcov.size() == _Dimen * _Dimen || __varcov.size() == _Dimen * (_Dimen + 1) / 2 || __varcov.size() == _Dimen); if (__varcov.size() == _Dimen * _Dimen) _M_init_full(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); else if (__varcov.size() == _Dimen * (_Dimen + 1) / 2) _M_init_lower(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); else { __glibcxx_assert(__varcov.size() == _Dimen); _M_init_diagonal(__mean.begin(), __mean.end(), __varcov.begin(), __varcov.end()); } } std::array<_RealType, _Dimen> mean() const { return _M_mean; } std::array<_RealType, _M_t_size> varcov() const { return _M_t; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mean == __p2._M_mean && __p1._M_t == __p2._M_t; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: template <typename _InputIterator1, typename _InputIterator2> void _M_init_full(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend); template <typename _InputIterator1, typename _InputIterator2> void _M_init_lower(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varcovbegin, _InputIterator2 __varcovend); template <typename _InputIterator1, typename _InputIterator2> void _M_init_diagonal(_InputIterator1 __meanbegin, _InputIterator1 __meanend, _InputIterator2 __varbegin, _InputIterator2 __varend); std::array<_RealType, _Dimen> _M_mean; std::array<_RealType, _M_t_size> _M_t; }; public: normal_mv_distribution() : _M_param(), _M_nd() { } template<typename _ForwardIterator1, typename _ForwardIterator2> normal_mv_distribution(_ForwardIterator1 __meanbegin, _ForwardIterator1 __meanend, _ForwardIterator2 __varcovbegin, _ForwardIterator2 __varcovend) : _M_param(__meanbegin, __meanend, __varcovbegin, __varcovend), _M_nd() { } normal_mv_distribution(std::initializer_list<_RealType> __mean, std::initializer_list<_RealType> __varcov) : _M_param(__mean, __varcov), _M_nd() { } explicit normal_mv_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * @brief Returns the mean of the distribution. */ result_type mean() const { return _M_param.mean(); } /** * @brief Returns the compact form of the variance/covariance * matrix of the distribution. */ std::array<_RealType, _Dimen * (_Dimen + 1) / 2> varcov() const { return _M_param.varcov(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { result_type __res; __res.fill(std::numeric_limits<_RealType>::lowest()); return __res; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { result_type __res; __res.fill(std::numeric_limits<_RealType>::max()); return __res; } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { return this->__generate_impl(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { return this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two multi-variant normal distributions have * the same parameters and the sequences that would * be generated are equal. */ template<size_t _Dimen1, typename _RealType1> friend bool operator==(const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __d2); /** * @brief Inserts a %normal_mv_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %normal_mv_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<size_t _Dimen1, typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __x); /** * @brief Extracts a %normal_mv_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %normal_mv_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error * state. */ template<size_t _Dimen1, typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<_RealType> _M_nd; }; /** * @brief Return true if two multi-variate normal distributions are * different. */ template<size_t _Dimen, typename _RealType> inline bool operator!=(const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::normal_mv_distribution<_Dimen, _RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Rice continuous distribution for random numbers. * * The formula for the Rice probability density function is * @f[ * p(x|\nu,\sigma) = \frac{x}{\sigma^2} * \exp\left(-\frac{x^2+\nu^2}{2\sigma^2}\right) * I_0\left(\frac{x \nu}{\sigma^2}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the first kind * of order 0 and @f$\nu >= 0@f$ and @f$\sigma > 0@f$. * * <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Distribution Statistics</caption> * <tr><td>Mean</td><td>@f$\sqrt{\pi/2}L_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr> * <tr><td>Variance</td><td>@f$2\sigma^2 + \nu^2 * + (\pi\sigma^2/2)L^2_{1/2}(-\nu^2/2\sigma^2)@f$</td></tr> * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr> * </table> * where @f$L_{1/2}(x)@f$ is the Laguerre polynomial of order 1/2. */ template<typename _RealType = double> class rice_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef rice_distribution<result_type> distribution_type; param_type(result_type __nu_val = result_type(0), result_type __sigma_val = result_type(1)) : _M_nu(__nu_val), _M_sigma(__sigma_val) { __glibcxx_assert(_M_nu >= result_type(0)); __glibcxx_assert(_M_sigma > result_type(0)); } result_type nu() const { return _M_nu; } result_type sigma() const { return _M_sigma; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_nu == __p2._M_nu && __p1._M_sigma == __p2._M_sigma; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_nu; result_type _M_sigma; }; /** * @brief Constructors. */ explicit rice_distribution(result_type __nu_val = result_type(0), result_type __sigma_val = result_type(1)) : _M_param(__nu_val, __sigma_val), _M_ndx(__nu_val, __sigma_val), _M_ndy(result_type(0), __sigma_val) { } explicit rice_distribution(const param_type& __p) : _M_param(__p), _M_ndx(__p.nu(), __p.sigma()), _M_ndy(result_type(0), __p.sigma()) { } /** * @brief Resets the distribution state. */ void reset() { _M_ndx.reset(); _M_ndy.reset(); } /** * @brief Return the parameters of the distribution. */ result_type nu() const { return _M_param.nu(); } result_type sigma() const { return _M_param.sigma(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = this->_M_ndx(__urng); result_type __y = this->_M_ndy(__urng); #if _GLIBCXX_USE_C99_MATH_TR1 return std::hypot(__x, __y); #else return std::sqrt(__x * __x + __y * __y); #endif } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::normal_distribution<result_type>::param_type __px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma()); result_type __x = this->_M_ndx(__px, __urng); result_type __y = this->_M_ndy(__py, __urng); #if _GLIBCXX_USE_C99_MATH_TR1 return std::hypot(__x, __y); #else return std::sqrt(__x * __x + __y * __y); #endif } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Rice distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const rice_distribution& __d1, const rice_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ndx == __d2._M_ndx && __d1._M_ndy == __d2._M_ndy); } /** * @brief Inserts a %rice_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %rice_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const rice_distribution<_RealType1>&); /** * @brief Extracts a %rice_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %rice_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, rice_distribution<_RealType1>&); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<result_type> _M_ndx; std::normal_distribution<result_type> _M_ndy; }; /** * @brief Return true if two Rice distributions are not equal. */ template<typename _RealType1> inline bool operator!=(const rice_distribution<_RealType1>& __d1, const rice_distribution<_RealType1>& __d2) { return !(__d1 == __d2); } /** * @brief A Nakagami continuous distribution for random numbers. * * The formula for the Nakagami probability density function is * @f[ * p(x|\mu,\omega) = \frac{2\mu^\mu}{\Gamma(\mu)\omega^\mu} * x^{2\mu-1}e^{-\mu x / \omega} * @f] * where @f$\Gamma(z)@f$ is the gamma function and @f$\mu >= 0.5@f$ * and @f$\omega > 0@f$. */ template<typename _RealType = double> class nakagami_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef nakagami_distribution<result_type> distribution_type; param_type(result_type __mu_val = result_type(1), result_type __omega_val = result_type(1)) : _M_mu(__mu_val), _M_omega(__omega_val) { __glibcxx_assert(_M_mu >= result_type(0.5L)); __glibcxx_assert(_M_omega > result_type(0)); } result_type mu() const { return _M_mu; } result_type omega() const { return _M_omega; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mu == __p2._M_mu && __p1._M_omega == __p2._M_omega; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_mu; result_type _M_omega; }; /** * @brief Constructors. */ explicit nakagami_distribution(result_type __mu_val = result_type(1), result_type __omega_val = result_type(1)) : _M_param(__mu_val, __omega_val), _M_gd(__mu_val, __omega_val / __mu_val) { } explicit nakagami_distribution(const param_type& __p) : _M_param(__p), _M_gd(__p.mu(), __p.omega() / __p.mu()) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd.reset(); } /** * @brief Return the parameters of the distribution. */ result_type mu() const { return _M_param.mu(); } result_type omega() const { return _M_param.omega(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return std::sqrt(this->_M_gd(__urng)); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::gamma_distribution<result_type>::param_type __pg(__p.mu(), __p.omega() / __p.mu()); return std::sqrt(this->_M_gd(__pg, __urng)); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Nakagami distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const nakagami_distribution& __d1, const nakagami_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd); } /** * @brief Inserts a %nakagami_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %nakagami_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const nakagami_distribution<_RealType1>&); /** * @brief Extracts a %nakagami_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %nakagami_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, nakagami_distribution<_RealType1>&); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::gamma_distribution<result_type> _M_gd; }; /** * @brief Return true if two Nakagami distributions are not equal. */ template<typename _RealType> inline bool operator!=(const nakagami_distribution<_RealType>& __d1, const nakagami_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Pareto continuous distribution for random numbers. * * The formula for the Pareto cumulative probability function is * @f[ * P(x|\alpha,\mu) = 1 - \left(\frac{\mu}{x}\right)^\alpha * @f] * The formula for the Pareto probability density function is * @f[ * p(x|\alpha,\mu) = \frac{\alpha + 1}{\mu} * \left(\frac{\mu}{x}\right)^{\alpha + 1} * @f] * where @f$x >= \mu@f$ and @f$\mu > 0@f$, @f$\alpha > 0@f$. * * <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Distribution Statistics</caption> * <tr><td>Mean</td><td>@f$\alpha \mu / (\alpha - 1)@f$ * for @f$\alpha > 1@f$</td></tr> * <tr><td>Variance</td><td>@f$\alpha \mu^2 / [(\alpha - 1)^2(\alpha - 2)]@f$ * for @f$\alpha > 2@f$</td></tr> * <tr><td>Range</td><td>@f$[\mu, \infty)@f$</td></tr> * </table> */ template<typename _RealType = double> class pareto_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef pareto_distribution<result_type> distribution_type; param_type(result_type __alpha_val = result_type(1), result_type __mu_val = result_type(1)) : _M_alpha(__alpha_val), _M_mu(__mu_val) { __glibcxx_assert(_M_alpha > result_type(0)); __glibcxx_assert(_M_mu > result_type(0)); } result_type alpha() const { return _M_alpha; } result_type mu() const { return _M_mu; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_alpha == __p2._M_alpha && __p1._M_mu == __p2._M_mu; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_alpha; result_type _M_mu; }; /** * @brief Constructors. */ explicit pareto_distribution(result_type __alpha_val = result_type(1), result_type __mu_val = result_type(1)) : _M_param(__alpha_val, __mu_val), _M_ud() { } explicit pareto_distribution(const param_type& __p) : _M_param(__p), _M_ud() { } /** * @brief Resets the distribution state. */ void reset() { _M_ud.reset(); } /** * @brief Return the parameters of the distribution. */ result_type alpha() const { return _M_param.alpha(); } result_type mu() const { return _M_param.mu(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return this->mu(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->mu() * std::pow(this->_M_ud(__urng), -result_type(1) / this->alpha()); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { return __p.mu() * std::pow(this->_M_ud(__urng), -result_type(1) / __p.alpha()); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Pareto distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const pareto_distribution& __d1, const pareto_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ud == __d2._M_ud); } /** * @brief Inserts a %pareto_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %pareto_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const pareto_distribution<_RealType1>&); /** * @brief Extracts a %pareto_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %pareto_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, pareto_distribution<_RealType1>&); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::uniform_real_distribution<result_type> _M_ud; }; /** * @brief Return true if two Pareto distributions are not equal. */ template<typename _RealType> inline bool operator!=(const pareto_distribution<_RealType>& __d1, const pareto_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A K continuous distribution for random numbers. * * The formula for the K probability density function is * @f[ * p(x|\lambda, \mu, \nu) = \frac{2}{x} * \left(\frac{\lambda\nu x}{\mu}\right)^{\frac{\lambda + \nu}{2}} * \frac{1}{\Gamma(\lambda)\Gamma(\nu)} * K_{\nu - \lambda}\left(2\sqrt{\frac{\lambda\nu x}{\mu}}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the second kind * of order @f$\nu - \lambda@f$ and @f$\lambda > 0@f$, @f$\mu > 0@f$ * and @f$\nu > 0@f$. * * <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Distribution Statistics</caption> * <tr><td>Mean</td><td>@f$\mu@f$</td></tr> * <tr><td>Variance</td><td>@f$\mu^2\frac{\lambda + \nu + 1}{\lambda\nu}@f$</td></tr> * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr> * </table> */ template<typename _RealType = double> class k_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef k_distribution<result_type> distribution_type; param_type(result_type __lambda_val = result_type(1), result_type __mu_val = result_type(1), result_type __nu_val = result_type(1)) : _M_lambda(__lambda_val), _M_mu(__mu_val), _M_nu(__nu_val) { __glibcxx_assert(_M_lambda > result_type(0)); __glibcxx_assert(_M_mu > result_type(0)); __glibcxx_assert(_M_nu > result_type(0)); } result_type lambda() const { return _M_lambda; } result_type mu() const { return _M_mu; } result_type nu() const { return _M_nu; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_lambda == __p2._M_lambda && __p1._M_mu == __p2._M_mu && __p1._M_nu == __p2._M_nu; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_lambda; result_type _M_mu; result_type _M_nu; }; /** * @brief Constructors. */ explicit k_distribution(result_type __lambda_val = result_type(1), result_type __mu_val = result_type(1), result_type __nu_val = result_type(1)) : _M_param(__lambda_val, __mu_val, __nu_val), _M_gd1(__lambda_val, result_type(1) / __lambda_val), _M_gd2(__nu_val, __mu_val / __nu_val) { } explicit k_distribution(const param_type& __p) : _M_param(__p), _M_gd1(__p.lambda(), result_type(1) / __p.lambda()), _M_gd2(__p.nu(), __p.mu() / __p.nu()) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd1.reset(); _M_gd2.reset(); } /** * @brief Return the parameters of the distribution. */ result_type lambda() const { return _M_param.lambda(); } result_type mu() const { return _M_param.mu(); } result_type nu() const { return _M_param.nu(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator&); template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator&, const param_type&); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two K distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const k_distribution& __d1, const k_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_gd1 == __d2._M_gd1 && __d1._M_gd2 == __d2._M_gd2); } /** * @brief Inserts a %k_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %k_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const k_distribution<_RealType1>&); /** * @brief Extracts a %k_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %k_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, k_distribution<_RealType1>&); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::gamma_distribution<result_type> _M_gd1; std::gamma_distribution<result_type> _M_gd2; }; /** * @brief Return true if two K distributions are not equal. */ template<typename _RealType> inline bool operator!=(const k_distribution<_RealType>& __d1, const k_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief An arcsine continuous distribution for random numbers. * * The formula for the arcsine probability density function is * @f[ * p(x|a,b) = \frac{1}{\pi \sqrt{(x - a)(b - x)}} * @f] * where @f$x >= a@f$ and @f$x <= b@f$. * * <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Distribution Statistics</caption> * <tr><td>Mean</td><td>@f$ (a + b) / 2 @f$</td></tr> * <tr><td>Variance</td><td>@f$ (b - a)^2 / 8 @f$</td></tr> * <tr><td>Range</td><td>@f$[a, b]@f$</td></tr> * </table> */ template<typename _RealType = double> class arcsine_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef arcsine_distribution<result_type> distribution_type; param_type(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_a(__a), _M_b(__b) { __glibcxx_assert(_M_a <= _M_b); } result_type a() const { return _M_a; } result_type b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_a; result_type _M_b; }; /** * @brief Constructors. */ explicit arcsine_distribution(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_param(__a, __b), _M_ud(-1.5707963267948966192313216916397514L, +1.5707963267948966192313216916397514L) { } explicit arcsine_distribution(const param_type& __p) : _M_param(__p), _M_ud(-1.5707963267948966192313216916397514L, +1.5707963267948966192313216916397514L) { } /** * @brief Resets the distribution state. */ void reset() { _M_ud.reset(); } /** * @brief Return the parameters of the distribution. */ result_type a() const { return _M_param.a(); } result_type b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return this->a(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return this->b(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { result_type __x = std::sin(this->_M_ud(__urng)); return (__x * (this->b() - this->a()) + this->a() + this->b()) / result_type(2); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { result_type __x = std::sin(this->_M_ud(__urng)); return (__x * (__p.b() - __p.a()) + __p.a() + __p.b()) / result_type(2); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two arcsine distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const arcsine_distribution& __d1, const arcsine_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ud == __d2._M_ud); } /** * @brief Inserts a %arcsine_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %arcsine_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const arcsine_distribution<_RealType1>&); /** * @brief Extracts a %arcsine_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %arcsine_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, arcsine_distribution<_RealType1>&); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::uniform_real_distribution<result_type> _M_ud; }; /** * @brief Return true if two arcsine distributions are not equal. */ template<typename _RealType> inline bool operator!=(const arcsine_distribution<_RealType>& __d1, const arcsine_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A Hoyt continuous distribution for random numbers. * * The formula for the Hoyt probability density function is * @f[ * p(x|q,\omega) = \frac{(1 + q^2)x}{q\omega} * \exp\left(-\frac{(1 + q^2)^2 x^2}{4 q^2 \omega}\right) * I_0\left(\frac{(1 - q^4) x^2}{4 q^2 \omega}\right) * @f] * where @f$I_0(z)@f$ is the modified Bessel function of the first kind * of order 0 and @f$0 < q < 1@f$. * * <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Distribution Statistics</caption> * <tr><td>Mean</td><td>@f$ \sqrt{\frac{2}{\pi}} \sqrt{\frac{\omega}{1 + q^2}} * E(1 - q^2) @f$</td></tr> * <tr><td>Variance</td><td>@f$ \omega \left(1 - \frac{2E^2(1 - q^2)} * {\pi (1 + q^2)}\right) @f$</td></tr> * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr> * </table> * where @f$E(x)@f$ is the elliptic function of the second kind. */ template<typename _RealType = double> class hoyt_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef hoyt_distribution<result_type> distribution_type; param_type(result_type __q = result_type(0.5L), result_type __omega = result_type(1)) : _M_q(__q), _M_omega(__omega) { __glibcxx_assert(_M_q > result_type(0)); __glibcxx_assert(_M_q < result_type(1)); } result_type q() const { return _M_q; } result_type omega() const { return _M_omega; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_q == __p2._M_q && __p1._M_omega == __p2._M_omega; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_q; result_type _M_omega; }; /** * @brief Constructors. */ explicit hoyt_distribution(result_type __q = result_type(0.5L), result_type __omega = result_type(1)) : _M_param(__q, __omega), _M_ad(result_type(0.5L) * (result_type(1) + __q * __q), result_type(0.5L) * (result_type(1) + __q * __q) / (__q * __q)), _M_ed(result_type(1)) { } explicit hoyt_distribution(const param_type& __p) : _M_param(__p), _M_ad(result_type(0.5L) * (result_type(1) + __p.q() * __p.q()), result_type(0.5L) * (result_type(1) + __p.q() * __p.q()) / (__p.q() * __p.q())), _M_ed(result_type(1)) { } /** * @brief Resets the distribution state. */ void reset() { _M_ad.reset(); _M_ed.reset(); } /** * @brief Return the parameters of the distribution. */ result_type q() const { return _M_param.q(); } result_type omega() const { return _M_param.omega(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng); template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Hoyt distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const hoyt_distribution& __d1, const hoyt_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_ad == __d2._M_ad && __d1._M_ed == __d2._M_ed); } /** * @brief Inserts a %hoyt_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %hoyt_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const hoyt_distribution<_RealType1>&); /** * @brief Extracts a %hoyt_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %hoyt_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, hoyt_distribution<_RealType1>&); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; __gnu_cxx::arcsine_distribution<result_type> _M_ad; std::exponential_distribution<result_type> _M_ed; }; /** * @brief Return true if two Hoyt distributions are not equal. */ template<typename _RealType> inline bool operator!=(const hoyt_distribution<_RealType>& __d1, const hoyt_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A triangular distribution for random numbers. * * The formula for the triangular probability density function is * @f[ * / 0 for x < a * p(x|a,b,c) = | \frac{2(x-a)}{(c-a)(b-a)} for a <= x <= b * | \frac{2(c-x)}{(c-a)(c-b)} for b < x <= c * \ 0 for c < x * @f] * * <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Distribution Statistics</caption> * <tr><td>Mean</td><td>@f$ \frac{a+b+c}{2} @f$</td></tr> * <tr><td>Variance</td><td>@f$ \frac{a^2+b^2+c^2-ab-ac-bc} * {18}@f$</td></tr> * <tr><td>Range</td><td>@f$[a, c]@f$</td></tr> * </table> */ template<typename _RealType = double> class triangular_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { friend class triangular_distribution<_RealType>; explicit param_type(_RealType __a = _RealType(0), _RealType __b = _RealType(0.5), _RealType __c = _RealType(1)) : _M_a(__a), _M_b(__b), _M_c(__c) { __glibcxx_assert(_M_a <= _M_b); __glibcxx_assert(_M_b <= _M_c); __glibcxx_assert(_M_a < _M_c); _M_r_ab = (_M_b - _M_a) / (_M_c - _M_a); _M_f_ab_ac = (_M_b - _M_a) * (_M_c - _M_a); _M_f_bc_ac = (_M_c - _M_b) * (_M_c - _M_a); } _RealType a() const { return _M_a; } _RealType b() const { return _M_b; } _RealType c() const { return _M_c; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b && __p1._M_c == __p2._M_c); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_a; _RealType _M_b; _RealType _M_c; _RealType _M_r_ab; _RealType _M_f_ab_ac; _RealType _M_f_bc_ac; }; /** * @brief Constructs a triangle distribution with parameters * @f$ a @f$, @f$ b @f$ and @f$ c @f$. */ explicit triangular_distribution(result_type __a = result_type(0), result_type __b = result_type(0.5), result_type __c = result_type(1)) : _M_param(__a, __b, __c) { } explicit triangular_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the @f$ a @f$ of the distribution. */ result_type a() const { return _M_param.a(); } /** * @brief Returns the @f$ b @f$ of the distribution. */ result_type b() const { return _M_param.b(); } /** * @brief Returns the @f$ c @f$ of the distribution. */ result_type c() const { return _M_param.c(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return _M_param._M_a; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return _M_param._M_c; } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { std::__detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __rnd = __aurng(); if (__rnd <= __p._M_r_ab) return __p.a() + std::sqrt(__rnd * __p._M_f_ab_ac); else return __p.c() - std::sqrt((result_type(1) - __rnd) * __p._M_f_bc_ac); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two triangle distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const triangular_distribution& __d1, const triangular_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %triangular_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %triangular_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::triangular_distribution<_RealType1>& __x); /** * @brief Extracts a %triangular_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %triangular_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::triangular_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two triangle distributions are different. */ template<typename _RealType> inline bool operator!=(const __gnu_cxx::triangular_distribution<_RealType>& __d1, const __gnu_cxx::triangular_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A von Mises distribution for random numbers. * * The formula for the von Mises probability density function is * @f[ * p(x|\mu,\kappa) = \frac{e^{\kappa \cos(x-\mu)}} * {2\pi I_0(\kappa)} * @f] * * The generating functions use the method according to: * * D. J. Best and N. I. Fisher, 1979. "Efficient Simulation of the * von Mises Distribution", Journal of the Royal Statistical Society. * Series C (Applied Statistics), Vol. 28, No. 2, pp. 152-157. * * <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Distribution Statistics</caption> * <tr><td>Mean</td><td>@f$ \mu @f$</td></tr> * <tr><td>Variance</td><td>@f$ 1-I_1(\kappa)/I_0(\kappa) @f$</td></tr> * <tr><td>Range</td><td>@f$[-\pi, \pi]@f$</td></tr> * </table> */ template<typename _RealType = double> class von_mises_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { friend class von_mises_distribution<_RealType>; explicit param_type(_RealType __mu = _RealType(0), _RealType __kappa = _RealType(1)) : _M_mu(__mu), _M_kappa(__kappa) { const _RealType __pi = __gnu_cxx::__math_constants<_RealType>::__pi; __glibcxx_assert(_M_mu >= -__pi && _M_mu <= __pi); __glibcxx_assert(_M_kappa >= _RealType(0)); auto __tau = std::sqrt(_RealType(4) * _M_kappa * _M_kappa + _RealType(1)) + _RealType(1); auto __rho = ((__tau - std::sqrt(_RealType(2) * __tau)) / (_RealType(2) * _M_kappa)); _M_r = (_RealType(1) + __rho * __rho) / (_RealType(2) * __rho); } _RealType mu() const { return _M_mu; } _RealType kappa() const { return _M_kappa; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mu == __p2._M_mu && __p1._M_kappa == __p2._M_kappa; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_mu; _RealType _M_kappa; _RealType _M_r; }; /** * @brief Constructs a von Mises distribution with parameters * @f$\mu@f$ and @f$\kappa@f$. */ explicit von_mises_distribution(result_type __mu = result_type(0), result_type __kappa = result_type(1)) : _M_param(__mu, __kappa) { } explicit von_mises_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the @f$ \mu @f$ of the distribution. */ result_type mu() const { return _M_param.mu(); } /** * @brief Returns the @f$ \kappa @f$ of the distribution. */ result_type kappa() const { return _M_param.kappa(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return -__gnu_cxx::__math_constants<result_type>::__pi; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return __gnu_cxx::__math_constants<result_type>::__pi; } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two von Mises distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const von_mises_distribution& __d1, const von_mises_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %von_mises_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %von_mises_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::von_mises_distribution<_RealType1>& __x); /** * @brief Extracts a %von_mises_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %von_mises_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::von_mises_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two von Mises distributions are different. */ template<typename _RealType> inline bool operator!=(const __gnu_cxx::von_mises_distribution<_RealType>& __d1, const __gnu_cxx::von_mises_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A discrete hypergeometric random number distribution. * * The hypergeometric distribution is a discrete probability distribution * that describes the probability of @p k successes in @p n draws @a without * replacement from a finite population of size @p N containing exactly @p K * successes. * * The formula for the hypergeometric probability density function is * @f[ * p(k|N,K,n) = \frac{\binom{K}{k} \binom{N-K}{n-k}}{\binom{N}{n}} * @f] * where @f$N@f$ is the total population of the distribution, * @f$K@f$ is the total population of the distribution. * * <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Distribution Statistics</caption> * <tr><td>Mean</td><td>@f$ n\frac{K}{N} @f$</td></tr> * <tr><td>Variance</td><td>@f$ n\frac{K}{N}\frac{N-K}{N}\frac{N-n}{N-1} * @f$</td></tr> * <tr><td>Range</td><td>@f$[max(0, n+K-N), min(K, n)]@f$</td></tr> * </table> */ template<typename _UIntType = unsigned int> class hypergeometric_distribution { static_assert(std::is_unsigned<_UIntType>::value, "template argument " "substituting _UIntType not an unsigned integral type"); public: /** The type of the range of the distribution. */ typedef _UIntType result_type; /** Parameter type. */ struct param_type { typedef hypergeometric_distribution<_UIntType> distribution_type; friend class hypergeometric_distribution<_UIntType>; explicit param_type(result_type __N = 10, result_type __K = 5, result_type __n = 1) : _M_N{__N}, _M_K{__K}, _M_n{__n} { __glibcxx_assert(_M_N >= _M_K); __glibcxx_assert(_M_N >= _M_n); } result_type total_size() const { return _M_N; } result_type successful_size() const { return _M_K; } result_type unsuccessful_size() const { return _M_N - _M_K; } result_type total_draws() const { return _M_n; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_N == __p2._M_N) && (__p1._M_K == __p2._M_K) && (__p1._M_n == __p2._M_n); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: result_type _M_N; result_type _M_K; result_type _M_n; }; // constructors and member function explicit hypergeometric_distribution(result_type __N = 10, result_type __K = 5, result_type __n = 1) : _M_param{__N, __K, __n} { } explicit hypergeometric_distribution(const param_type& __p) : _M_param{__p} { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the distribution parameter @p N, * the total number of items. */ result_type total_size() const { return this->_M_param.total_size(); } /** * @brief Returns the distribution parameter @p K, * the total number of successful items. */ result_type successful_size() const { return this->_M_param.successful_size(); } /** * @brief Returns the total number of unsuccessful items @f$ N - K @f$. */ result_type unsuccessful_size() const { return this->_M_param.unsuccessful_size(); } /** * @brief Returns the distribution parameter @p n, * the total number of draws. */ result_type total_draws() const { return this->_M_param.total_draws(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return this->_M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { this->_M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { using _IntType = typename std::make_signed<result_type>::type; return static_cast<result_type>(std::max(static_cast<_IntType>(0), static_cast<_IntType>(this->total_draws() - this->unsuccessful_size()))); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::min(this->successful_size(), this->total_draws()); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, this->_M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->_M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two hypergeometric distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const hypergeometric_distribution& __d1, const hypergeometric_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %hypergeometric_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %hypergeometric_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _UIntType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x); /** * @brief Extracts a %hypergeometric_distribution random number * distribution @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %hypergeometric_distribution random number generator * distribution. * * @returns The input stream with @p __x extracted or in an error * state. */ template<typename _UIntType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::hypergeometric_distribution<_UIntType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two hypergeometric distributions are different. */ template<typename _UIntType> inline bool operator!=(const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d1, const __gnu_cxx::hypergeometric_distribution<_UIntType>& __d2) { return !(__d1 == __d2); } /** * @brief A logistic continuous distribution for random numbers. * * The formula for the logistic probability density function is * @f[ * p(x|\a,\b) = \frac{e^{(x - a)/b}}{b[1 + e^{(x - a)/b}]^2} * @f] * where @f$b > 0@f$. * * The formula for the logistic probability function is * @f[ * cdf(x|\a,\b) = \frac{e^{(x - a)/b}}{1 + e^{(x - a)/b}} * @f] * where @f$b > 0@f$. * * <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Distribution Statistics</caption> * <tr><td>Mean</td><td>@f$a@f$</td></tr> * <tr><td>Variance</td><td>@f$b^2\pi^2/3@f$</td></tr> * <tr><td>Range</td><td>@f$[0, \infty)@f$</td></tr> * </table> */ template<typename _RealType = double> class logistic_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef logistic_distribution<result_type> distribution_type; param_type(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_a(__a), _M_b(__b) { __glibcxx_assert(_M_b > result_type(0)); } result_type a() const { return _M_a; } result_type b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); result_type _M_a; result_type _M_b; }; /** * @brief Constructors. */ explicit logistic_distribution(result_type __a = result_type(0), result_type __b = result_type(1)) : _M_param(__a, __b) { } explicit logistic_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Return the parameters of the distribution. */ result_type a() const { return _M_param.a(); } result_type b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return -std::numeric_limits<result_type>::max(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, this->_M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator&, const param_type&); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two logistic distributions have * the same parameters and the sequences that would * be generated are equal. */ template<typename _RealType1> friend bool operator==(const logistic_distribution<_RealType1>& __d1, const logistic_distribution<_RealType1>& __d2) { return __d1.param() == __d2.param(); } /** * @brief Inserts a %logistic_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %logistic_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const logistic_distribution<_RealType1>&); /** * @brief Extracts a %logistic_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %logistic_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, logistic_distribution<_RealType1>&); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two logistic distributions are not equal. */ template<typename _RealType1> inline bool operator!=(const logistic_distribution<_RealType1>& __d1, const logistic_distribution<_RealType1>& __d2) { return !(__d1 == __d2); } /** * @brief A distribution for random coordinates on a unit sphere. * * The method used in the generation function is attributed by Donald Knuth * to G. W. Brown, Modern Mathematics for the Engineer (1956). */ template<std::size_t _Dimen, typename _RealType = double> class uniform_on_sphere_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); static_assert(_Dimen != 0, "dimension is zero"); public: /** The type of the range of the distribution. */ typedef std::array<_RealType, _Dimen> result_type; /** Parameter type. */ struct param_type { explicit param_type() { } friend bool operator==(const param_type&, const param_type&) { return true; } friend bool operator!=(const param_type&, const param_type&) { return false; } }; /** * @brief Constructs a uniform on sphere distribution. */ explicit uniform_on_sphere_distribution() : _M_param(), _M_nd() { } explicit uniform_on_sphere_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. * This function makes no sense for this distribution. */ result_type min() const { result_type __res; __res.fill(0); return __res; } /** * @brief Returns the least upper bound value of the distribution. * This function makes no sense for this distribution. */ result_type max() const { result_type __res; __res.fill(0); return __res; } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two uniform on sphere distributions have * the same parameters and the sequences that would be * generated are equal. */ friend bool operator==(const uniform_on_sphere_distribution& __d1, const uniform_on_sphere_distribution& __d2) { return __d1._M_nd == __d2._M_nd; } /** * @brief Inserts a %uniform_on_sphere_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %uniform_on_sphere_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<size_t _Dimen1, typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_on_sphere_distribution<_Dimen1, _RealType1>& __x); /** * @brief Extracts a %uniform_on_sphere_distribution random number * distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %uniform_on_sphere_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<std::size_t _Dimen1, typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_on_sphere_distribution<_Dimen1, _RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<_RealType> _M_nd; }; /** * @brief Return true if two uniform on sphere distributions are different. */ template<std::size_t _Dimen, typename _RealType> inline bool operator!=(const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::uniform_on_sphere_distribution<_Dimen, _RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A distribution for random coordinates inside a unit sphere. */ template<std::size_t _Dimen, typename _RealType = double> class uniform_inside_sphere_distribution { static_assert(std::is_floating_point<_RealType>::value, "template argument not a floating point type"); static_assert(_Dimen != 0, "dimension is zero"); public: /** The type of the range of the distribution. */ using result_type = std::array<_RealType, _Dimen>; /** Parameter type. */ struct param_type { using distribution_type = uniform_inside_sphere_distribution<_Dimen, _RealType>; friend class uniform_inside_sphere_distribution<_Dimen, _RealType>; explicit param_type(_RealType __radius = _RealType(1)) : _M_radius(__radius) { __glibcxx_assert(_M_radius > _RealType(0)); } _RealType radius() const { return _M_radius; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_radius == __p2._M_radius; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_radius; }; /** * @brief Constructors. */ explicit uniform_inside_sphere_distribution(_RealType __radius = _RealType(1)) : _M_param(__radius), _M_uosd() { } explicit uniform_inside_sphere_distribution(const param_type& __p) : _M_param(__p), _M_uosd() { } /** * @brief Resets the distribution state. */ void reset() { _M_uosd.reset(); } /** * @brief Returns the @f$radius@f$ of the distribution. */ _RealType radius() const { return _M_param.radius(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. * This function makes no sense for this distribution. */ result_type min() const { result_type __res; __res.fill(0); return __res; } /** * @brief Returns the least upper bound value of the distribution. * This function makes no sense for this distribution. */ result_type max() const { result_type __res; __res.fill(0); return __res; } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, this->param()); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two uniform on sphere distributions have * the same parameters and the sequences that would be * generated are equal. */ friend bool operator==(const uniform_inside_sphere_distribution& __d1, const uniform_inside_sphere_distribution& __d2) { return __d1._M_param == __d2._M_param && __d1._M_uosd == __d2._M_uosd; } /** * @brief Inserts a %uniform_inside_sphere_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %uniform_inside_sphere_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<size_t _Dimen1, typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1, _RealType1>& ); /** * @brief Extracts a %uniform_inside_sphere_distribution random number * distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %uniform_inside_sphere_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<std::size_t _Dimen1, typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, __gnu_cxx::uniform_inside_sphere_distribution<_Dimen1, _RealType1>&); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; uniform_on_sphere_distribution<_Dimen, _RealType> _M_uosd; }; /** * @brief Return true if two uniform on sphere distributions are different. */ template<std::size_t _Dimen, typename _RealType> inline bool operator!=(const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __d1, const __gnu_cxx::uniform_inside_sphere_distribution<_Dimen, _RealType>& __d2) { return !(__d1 == __d2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #include <ext/opt_random.h> #include <ext/random.tcc> #endif // _GLIBCXX_USE_C99_STDINT_TR1 && UINT32_C #endif // C++11 #endif // _EXT_RANDOM c++/8/ext/mt_allocator.h 0000644 00000055723 15146341150 0010730 0 ustar 00 // MT-optimized allocator -*- C++ -*- // Copyright (C) 2003-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/mt_allocator.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _MT_ALLOCATOR_H #define _MT_ALLOCATOR_H 1 #include <new> #include <cstdlib> #include <bits/functexcept.h> #include <ext/atomicity.h> #include <bits/move.h> #if __cplusplus >= 201103L #include <type_traits> #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; typedef void (*__destroy_handler)(void*); /// Base class for pool object. struct __pool_base { // Using short int as type for the binmap implies we are never // caching blocks larger than 32768 with this allocator. typedef unsigned short int _Binmap_type; // Variables used to configure the behavior of the allocator, // assigned and explained in detail below. struct _Tune { // Compile time constants for the default _Tune values. enum { _S_align = 8 }; enum { _S_max_bytes = 128 }; enum { _S_min_bin = 8 }; enum { _S_chunk_size = 4096 - 4 * sizeof(void*) }; enum { _S_max_threads = 4096 }; enum { _S_freelist_headroom = 10 }; // Alignment needed. // NB: In any case must be >= sizeof(_Block_record), that // is 4 on 32 bit machines and 8 on 64 bit machines. size_t _M_align; // Allocation requests (after round-up to power of 2) below // this value will be handled by the allocator. A raw new/ // call will be used for requests larger than this value. // NB: Must be much smaller than _M_chunk_size and in any // case <= 32768. size_t _M_max_bytes; // Size in bytes of the smallest bin. // NB: Must be a power of 2 and >= _M_align (and of course // much smaller than _M_max_bytes). size_t _M_min_bin; // In order to avoid fragmenting and minimize the number of // new() calls we always request new memory using this // value. Based on previous discussions on the libstdc++ // mailing list we have chosen the value below. // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html // NB: At least one order of magnitude > _M_max_bytes. size_t _M_chunk_size; // The maximum number of supported threads. For // single-threaded operation, use one. Maximum values will // vary depending on details of the underlying system. (For // instance, Linux 2.4.18 reports 4070 in // /proc/sys/kernel/threads-max, while Linux 2.6.6 reports // 65534) size_t _M_max_threads; // Each time a deallocation occurs in a threaded application // we make sure that there are no more than // _M_freelist_headroom % of used memory on the freelist. If // the number of additional records is more than // _M_freelist_headroom % of the freelist, we move these // records back to the global pool. size_t _M_freelist_headroom; // Set to true forces all allocations to use new(). bool _M_force_new; explicit _Tune() : _M_align(_S_align), _M_max_bytes(_S_max_bytes), _M_min_bin(_S_min_bin), _M_chunk_size(_S_chunk_size), _M_max_threads(_S_max_threads), _M_freelist_headroom(_S_freelist_headroom), _M_force_new(std::getenv("GLIBCXX_FORCE_NEW") ? true : false) { } explicit _Tune(size_t __align, size_t __maxb, size_t __minbin, size_t __chunk, size_t __maxthreads, size_t __headroom, bool __force) : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin), _M_chunk_size(__chunk), _M_max_threads(__maxthreads), _M_freelist_headroom(__headroom), _M_force_new(__force) { } }; struct _Block_address { void* _M_initial; _Block_address* _M_next; }; const _Tune& _M_get_options() const { return _M_options; } void _M_set_options(_Tune __t) { if (!_M_init) _M_options = __t; } bool _M_check_threshold(size_t __bytes) { return __bytes > _M_options._M_max_bytes || _M_options._M_force_new; } size_t _M_get_binmap(size_t __bytes) { return _M_binmap[__bytes]; } size_t _M_get_align() { return _M_options._M_align; } explicit __pool_base() : _M_options(_Tune()), _M_binmap(0), _M_init(false) { } explicit __pool_base(const _Tune& __options) : _M_options(__options), _M_binmap(0), _M_init(false) { } private: explicit __pool_base(const __pool_base&); __pool_base& operator=(const __pool_base&); protected: // Configuration options. _Tune _M_options; _Binmap_type* _M_binmap; // Configuration of the pool object via _M_options can happen // after construction but before initialization. After // initialization is complete, this variable is set to true. bool _M_init; }; /** * @brief Data describing the underlying memory pool, parameterized on * threading support. */ template<bool _Thread> class __pool; /// Specialization for single thread. template<> class __pool<false> : public __pool_base { public: union _Block_record { // Points to the block_record of the next free block. _Block_record* _M_next; }; struct _Bin_record { // An "array" of pointers to the first free block. _Block_record** _M_first; // A list of the initial addresses of all allocated blocks. _Block_address* _M_address; }; void _M_initialize_once() { if (__builtin_expect(_M_init == false, false)) _M_initialize(); } void _M_destroy() throw(); char* _M_reserve_block(size_t __bytes, const size_t __thread_id); void _M_reclaim_block(char* __p, size_t __bytes) throw (); size_t _M_get_thread_id() { return 0; } const _Bin_record& _M_get_bin(size_t __which) { return _M_bin[__which]; } void _M_adjust_freelist(const _Bin_record&, _Block_record*, size_t) { } explicit __pool() : _M_bin(0), _M_bin_size(1) { } explicit __pool(const __pool_base::_Tune& __tune) : __pool_base(__tune), _M_bin(0), _M_bin_size(1) { } private: // An "array" of bin_records each of which represents a specific // power of 2 size. Memory to this "array" is allocated in // _M_initialize(). _Bin_record* _M_bin; // Actual value calculated in _M_initialize(). size_t _M_bin_size; void _M_initialize(); }; #ifdef __GTHREADS /// Specialization for thread enabled, via gthreads.h. template<> class __pool<true> : public __pool_base { public: // Each requesting thread is assigned an id ranging from 1 to // _S_max_threads. Thread id 0 is used as a global memory pool. // In order to get constant performance on the thread assignment // routine, we keep a list of free ids. When a thread first // requests memory we remove the first record in this list and // stores the address in a __gthread_key. When initializing the // __gthread_key we specify a destructor. When this destructor // (i.e. the thread dies) is called, we return the thread id to // the front of this list. struct _Thread_record { // Points to next free thread id record. NULL if last record in list. _Thread_record* _M_next; // Thread id ranging from 1 to _S_max_threads. size_t _M_id; }; union _Block_record { // Points to the block_record of the next free block. _Block_record* _M_next; // The thread id of the thread which has requested this block. size_t _M_thread_id; }; struct _Bin_record { // An "array" of pointers to the first free block for each // thread id. Memory to this "array" is allocated in // _S_initialize() for _S_max_threads + global pool 0. _Block_record** _M_first; // A list of the initial addresses of all allocated blocks. _Block_address* _M_address; // An "array" of counters used to keep track of the amount of // blocks that are on the freelist/used for each thread id. // - Note that the second part of the allocated _M_used "array" // actually hosts (atomic) counters of reclaimed blocks: in // _M_reserve_block and in _M_reclaim_block those numbers are // subtracted from the first ones to obtain the actual size // of the "working set" of the given thread. // - Memory to these "arrays" is allocated in _S_initialize() // for _S_max_threads + global pool 0. size_t* _M_free; size_t* _M_used; // Each bin has its own mutex which is used to ensure data // integrity while changing "ownership" on a block. The mutex // is initialized in _S_initialize(). __gthread_mutex_t* _M_mutex; }; // XXX GLIBCXX_ABI Deprecated void _M_initialize(__destroy_handler); void _M_initialize_once() { if (__builtin_expect(_M_init == false, false)) _M_initialize(); } void _M_destroy() throw(); char* _M_reserve_block(size_t __bytes, const size_t __thread_id); void _M_reclaim_block(char* __p, size_t __bytes) throw (); const _Bin_record& _M_get_bin(size_t __which) { return _M_bin[__which]; } void _M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block, size_t __thread_id) { if (__gthread_active_p()) { __block->_M_thread_id = __thread_id; --__bin._M_free[__thread_id]; ++__bin._M_used[__thread_id]; } } // XXX GLIBCXX_ABI Deprecated void _M_destroy_thread_key(void*) throw (); size_t _M_get_thread_id(); explicit __pool() : _M_bin(0), _M_bin_size(1), _M_thread_freelist(0) { } explicit __pool(const __pool_base::_Tune& __tune) : __pool_base(__tune), _M_bin(0), _M_bin_size(1), _M_thread_freelist(0) { } private: // An "array" of bin_records each of which represents a specific // power of 2 size. Memory to this "array" is allocated in // _M_initialize(). _Bin_record* _M_bin; // Actual value calculated in _M_initialize(). size_t _M_bin_size; _Thread_record* _M_thread_freelist; void* _M_thread_freelist_initial; void _M_initialize(); }; #endif template<template <bool> class _PoolTp, bool _Thread> struct __common_pool { typedef _PoolTp<_Thread> pool_type; static pool_type& _S_get_pool() { static pool_type _S_pool; return _S_pool; } }; template<template <bool> class _PoolTp, bool _Thread> struct __common_pool_base; template<template <bool> class _PoolTp> struct __common_pool_base<_PoolTp, false> : public __common_pool<_PoolTp, false> { using __common_pool<_PoolTp, false>::_S_get_pool; static void _S_initialize_once() { static bool __init; if (__builtin_expect(__init == false, false)) { _S_get_pool()._M_initialize_once(); __init = true; } } }; #ifdef __GTHREADS template<template <bool> class _PoolTp> struct __common_pool_base<_PoolTp, true> : public __common_pool<_PoolTp, true> { using __common_pool<_PoolTp, true>::_S_get_pool; static void _S_initialize() { _S_get_pool()._M_initialize_once(); } static void _S_initialize_once() { static bool __init; if (__builtin_expect(__init == false, false)) { if (__gthread_active_p()) { // On some platforms, __gthread_once_t is an aggregate. static __gthread_once_t __once = __GTHREAD_ONCE_INIT; __gthread_once(&__once, _S_initialize); } // Double check initialization. May be necessary on some // systems for proper construction when not compiling with // thread flags. _S_get_pool()._M_initialize_once(); __init = true; } } }; #endif /// Policy for shared __pool objects. template<template <bool> class _PoolTp, bool _Thread> struct __common_pool_policy : public __common_pool_base<_PoolTp, _Thread> { template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, bool _Thread1 = _Thread> struct _M_rebind { typedef __common_pool_policy<_PoolTp1, _Thread1> other; }; using __common_pool_base<_PoolTp, _Thread>::_S_get_pool; using __common_pool_base<_PoolTp, _Thread>::_S_initialize_once; }; template<typename _Tp, template <bool> class _PoolTp, bool _Thread> struct __per_type_pool { typedef _Tp value_type; typedef _PoolTp<_Thread> pool_type; static pool_type& _S_get_pool() { // Sane defaults for the _PoolTp. typedef typename pool_type::_Block_record _Block_record; const static size_t __a = (__alignof__(_Tp) >= sizeof(_Block_record) ? __alignof__(_Tp) : sizeof(_Block_record)); typedef typename __pool_base::_Tune _Tune; static _Tune _S_tune(__a, sizeof(_Tp) * 64, sizeof(_Tp) * 2 >= __a ? sizeof(_Tp) * 2 : __a, sizeof(_Tp) * size_t(_Tune::_S_chunk_size), _Tune::_S_max_threads, _Tune::_S_freelist_headroom, std::getenv("GLIBCXX_FORCE_NEW") ? true : false); static pool_type _S_pool(_S_tune); return _S_pool; } }; template<typename _Tp, template <bool> class _PoolTp, bool _Thread> struct __per_type_pool_base; template<typename _Tp, template <bool> class _PoolTp> struct __per_type_pool_base<_Tp, _PoolTp, false> : public __per_type_pool<_Tp, _PoolTp, false> { using __per_type_pool<_Tp, _PoolTp, false>::_S_get_pool; static void _S_initialize_once() { static bool __init; if (__builtin_expect(__init == false, false)) { _S_get_pool()._M_initialize_once(); __init = true; } } }; #ifdef __GTHREADS template<typename _Tp, template <bool> class _PoolTp> struct __per_type_pool_base<_Tp, _PoolTp, true> : public __per_type_pool<_Tp, _PoolTp, true> { using __per_type_pool<_Tp, _PoolTp, true>::_S_get_pool; static void _S_initialize() { _S_get_pool()._M_initialize_once(); } static void _S_initialize_once() { static bool __init; if (__builtin_expect(__init == false, false)) { if (__gthread_active_p()) { // On some platforms, __gthread_once_t is an aggregate. static __gthread_once_t __once = __GTHREAD_ONCE_INIT; __gthread_once(&__once, _S_initialize); } // Double check initialization. May be necessary on some // systems for proper construction when not compiling with // thread flags. _S_get_pool()._M_initialize_once(); __init = true; } } }; #endif /// Policy for individual __pool objects. template<typename _Tp, template <bool> class _PoolTp, bool _Thread> struct __per_type_pool_policy : public __per_type_pool_base<_Tp, _PoolTp, _Thread> { template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp, bool _Thread1 = _Thread> struct _M_rebind { typedef __per_type_pool_policy<_Tp1, _PoolTp1, _Thread1> other; }; using __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_get_pool; using __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_initialize_once; }; /// Base class for _Tp dependent member functions. template<typename _Tp> class __mt_alloc_base { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; #endif pointer address(reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT { return std::__addressof(__x); } size_type max_size() const _GLIBCXX_USE_NOEXCEPT { return size_t(-1) / sizeof(_Tp); } #if __cplusplus >= 201103L template<typename _Up, typename... _Args> void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template<typename _Up> void destroy(_Up* __p) { __p->~_Up(); } #else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_] allocator::construct void construct(pointer __p, const _Tp& __val) { ::new((void *)__p) _Tp(__val); } void destroy(pointer __p) { __p->~_Tp(); } #endif }; #ifdef __GTHREADS #define __thread_default true #else #define __thread_default false #endif /** * @brief This is a fixed size (power of 2) allocator which - when * compiled with thread support - will maintain one freelist per * size per thread plus a @a global one. Steps are taken to limit * the per thread freelist sizes (by returning excess back to * the @a global list). * @ingroup allocators * * Further details: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/mt_allocator.html */ template<typename _Tp, typename _Poolp = __common_pool_policy<__pool, __thread_default> > class __mt_alloc : public __mt_alloc_base<_Tp> { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; typedef _Poolp __policy_type; typedef typename _Poolp::pool_type __pool_type; template<typename _Tp1, typename _Poolp1 = _Poolp> struct rebind { typedef typename _Poolp1::template _M_rebind<_Tp1>::other pol_type; typedef __mt_alloc<_Tp1, pol_type> other; }; __mt_alloc() _GLIBCXX_USE_NOEXCEPT { } __mt_alloc(const __mt_alloc&) _GLIBCXX_USE_NOEXCEPT { } template<typename _Tp1, typename _Poolp1> __mt_alloc(const __mt_alloc<_Tp1, _Poolp1>&) _GLIBCXX_USE_NOEXCEPT { } ~__mt_alloc() _GLIBCXX_USE_NOEXCEPT { } pointer allocate(size_type __n, const void* = 0); void deallocate(pointer __p, size_type __n); const __pool_base::_Tune _M_get_options() { // Return a copy, not a reference, for external consumption. return __policy_type::_S_get_pool()._M_get_options(); } void _M_set_options(__pool_base::_Tune __t) { __policy_type::_S_get_pool()._M_set_options(__t); } }; template<typename _Tp, typename _Poolp> typename __mt_alloc<_Tp, _Poolp>::pointer __mt_alloc<_Tp, _Poolp>:: allocate(size_type __n, const void*) { if (__n > this->max_size()) std::__throw_bad_alloc(); #if __cpp_aligned_new // Types with extended alignment are handled by operator new/delete. if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { std::align_val_t __al = std::align_val_t(alignof(_Tp)); return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), __al)); } #endif __policy_type::_S_initialize_once(); // Requests larger than _M_max_bytes are handled by operator // new/delete directly. __pool_type& __pool = __policy_type::_S_get_pool(); const size_t __bytes = __n * sizeof(_Tp); if (__pool._M_check_threshold(__bytes)) { void* __ret = ::operator new(__bytes); return static_cast<_Tp*>(__ret); } // Round up to power of 2 and figure out which bin to use. const size_t __which = __pool._M_get_binmap(__bytes); const size_t __thread_id = __pool._M_get_thread_id(); // Find out if we have blocks on our freelist. If so, go ahead // and use them directly without having to lock anything. char* __c; typedef typename __pool_type::_Bin_record _Bin_record; const _Bin_record& __bin = __pool._M_get_bin(__which); if (__bin._M_first[__thread_id]) { // Already reserved. typedef typename __pool_type::_Block_record _Block_record; _Block_record* __block = __bin._M_first[__thread_id]; __bin._M_first[__thread_id] = __block->_M_next; __pool._M_adjust_freelist(__bin, __block, __thread_id); __c = reinterpret_cast<char*>(__block) + __pool._M_get_align(); } else { // Null, reserve. __c = __pool._M_reserve_block(__bytes, __thread_id); } return static_cast<_Tp*>(static_cast<void*>(__c)); } template<typename _Tp, typename _Poolp> void __mt_alloc<_Tp, _Poolp>:: deallocate(pointer __p, size_type __n) { if (__builtin_expect(__p != 0, true)) { #if __cpp_aligned_new // Types with extended alignment are handled by operator new/delete. if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { ::operator delete(__p, std::align_val_t(alignof(_Tp))); return; } #endif // Requests larger than _M_max_bytes are handled by // operators new/delete directly. __pool_type& __pool = __policy_type::_S_get_pool(); const size_t __bytes = __n * sizeof(_Tp); if (__pool._M_check_threshold(__bytes)) ::operator delete(__p); else __pool._M_reclaim_block(reinterpret_cast<char*>(__p), __bytes); } } template<typename _Tp, typename _Poolp> inline bool operator==(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&) { return true; } template<typename _Tp, typename _Poolp> inline bool operator!=(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&) { return false; } #undef __thread_default _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/cast.h 0000644 00000010537 15146341150 0007174 0 ustar 00 // <cast.h> -*- C++ -*- // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/cast.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/pointer.h} */ #ifndef _GLIBCXX_CAST_H #define _GLIBCXX_CAST_H 1 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * These functions are here to allow containers to support non standard * pointer types. For normal pointers, these resolve to the use of the * standard cast operation. For other types the functions will perform * the appropriate cast to/from the custom pointer class so long as that * class meets the following conditions: * 1) has a typedef element_type which names tehe type it points to. * 2) has a get() const method which returns element_type*. * 3) has a constructor which can take one element_type* argument. */ /** * This type supports the semantics of the pointer cast operators (below.) */ template<typename _ToType> struct _Caster { typedef typename _ToType::element_type* type; }; template<typename _ToType> struct _Caster<_ToType*> { typedef _ToType* type; }; /** * Casting operations for cases where _FromType is not a standard pointer. * _ToType can be a standard or non-standard pointer. Given that _FromType * is not a pointer, it must have a get() method that returns the standard * pointer equivalent of the address it points to, and must have an * element_type typedef which names the type it points to. */ template<typename _ToType, typename _FromType> inline _ToType __static_pointer_cast(const _FromType& __arg) { return _ToType(static_cast<typename _Caster<_ToType>:: type>(__arg.get())); } template<typename _ToType, typename _FromType> inline _ToType __dynamic_pointer_cast(const _FromType& __arg) { return _ToType(dynamic_cast<typename _Caster<_ToType>:: type>(__arg.get())); } template<typename _ToType, typename _FromType> inline _ToType __const_pointer_cast(const _FromType& __arg) { return _ToType(const_cast<typename _Caster<_ToType>:: type>(__arg.get())); } template<typename _ToType, typename _FromType> inline _ToType __reinterpret_pointer_cast(const _FromType& __arg) { return _ToType(reinterpret_cast<typename _Caster<_ToType>:: type>(__arg.get())); } /** * Casting operations for cases where _FromType is a standard pointer. * _ToType can be a standard or non-standard pointer. */ template<typename _ToType, typename _FromType> inline _ToType __static_pointer_cast(_FromType* __arg) { return _ToType(static_cast<typename _Caster<_ToType>:: type>(__arg)); } template<typename _ToType, typename _FromType> inline _ToType __dynamic_pointer_cast(_FromType* __arg) { return _ToType(dynamic_cast<typename _Caster<_ToType>:: type>(__arg)); } template<typename _ToType, typename _FromType> inline _ToType __const_pointer_cast(_FromType* __arg) { return _ToType(const_cast<typename _Caster<_ToType>:: type>(__arg)); } template<typename _ToType, typename _FromType> inline _ToType __reinterpret_pointer_cast(_FromType* __arg) { return _ToType(reinterpret_cast<typename _Caster<_ToType>:: type>(__arg)); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_CAST_H c++/8/ext/algorithm 0000644 00000045532 15146341150 0010005 0 ustar 00 // Algorithm extensions -*- C++ -*- // Copyright (C) 2001-2018 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 * 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 ext/algorithm * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_ALGORITHM #define _EXT_ALGORITHM 1 #pragma GCC system_header #include <algorithm> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::ptrdiff_t; using std::min; using std::pair; using std::input_iterator_tag; using std::random_access_iterator_tag; using std::iterator_traits; //-------------------------------------------------- // copy_n (not part of the C++ standard) template<typename _InputIterator, typename _Size, typename _OutputIterator> pair<_InputIterator, _OutputIterator> __copy_n(_InputIterator __first, _Size __count, _OutputIterator __result, input_iterator_tag) { for ( ; __count > 0; --__count) { *__result = *__first; ++__first; ++__result; } return pair<_InputIterator, _OutputIterator>(__first, __result); } template<typename _RAIterator, typename _Size, typename _OutputIterator> inline pair<_RAIterator, _OutputIterator> __copy_n(_RAIterator __first, _Size __count, _OutputIterator __result, random_access_iterator_tag) { _RAIterator __last = __first + __count; return pair<_RAIterator, _OutputIterator>(__last, std::copy(__first, __last, __result)); } /** * @brief Copies the range [first,first+count) into [result,result+count). * @param __first An input iterator. * @param __count The number of elements to copy. * @param __result An output iterator. * @return A std::pair composed of first+count and result+count. * * This is an SGI extension. * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). * @ingroup SGIextensions */ template<typename _InputIterator, typename _Size, typename _OutputIterator> inline pair<_InputIterator, _OutputIterator> copy_n(_InputIterator __first, _Size __count, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) return __gnu_cxx::__copy_n(__first, __count, __result, std::__iterator_category(__first)); } template<typename _InputIterator1, typename _InputIterator2> int __lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { while (__first1 != __last1 && __first2 != __last2) { if (*__first1 < *__first2) return -1; if (*__first2 < *__first1) return 1; ++__first1; ++__first2; } if (__first2 == __last2) return !(__first1 == __last1); else return -1; } inline int __lexicographical_compare_3way(const unsigned char* __first1, const unsigned char* __last1, const unsigned char* __first2, const unsigned char* __last2) { const ptrdiff_t __len1 = __last1 - __first1; const ptrdiff_t __len2 = __last2 - __first2; const int __result = __builtin_memcmp(__first1, __first2, min(__len1, __len2)); return __result != 0 ? __result : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); } inline int __lexicographical_compare_3way(const char* __first1, const char* __last1, const char* __first2, const char* __last2) { #if CHAR_MAX == SCHAR_MAX return __lexicographical_compare_3way((const signed char*) __first1, (const signed char*) __last1, (const signed char*) __first2, (const signed char*) __last2); #else return __lexicographical_compare_3way((const unsigned char*) __first1, (const unsigned char*) __last1, (const unsigned char*) __first2, (const unsigned char*) __last2); #endif } /** * @brief @c memcmp on steroids. * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @return An int, as with @c memcmp. * * The return value will be less than zero if the first range is * <em>lexigraphically less than</em> the second, greater than zero * if the second range is <em>lexigraphically less than</em> the * first, and zero otherwise. * This is an SGI extension. * @ingroup SGIextensions */ template<typename _InputIterator1, typename _InputIterator2> int lexicographical_compare_3way(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); } // count and count_if: this version, whose return type is void, was present // in the HP STL, and is retained as an extension for backward compatibility. template<typename _InputIterator, typename _Tp, typename _Size> void count(_InputIterator __first, _InputIterator __last, const _Tp& __value, _Size& __n) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_InputIterator>::value_type >) __glibcxx_function_requires(_EqualityComparableConcept<_Tp>) __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (*__first == __value) ++__n; } template<typename _InputIterator, typename _Predicate, typename _Size> void count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred, _Size& __n) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); for ( ; __first != __last; ++__first) if (__pred(*__first)) ++__n; } // random_sample and random_sample_n (extensions, not part of the standard). /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template<typename _ForwardIterator, typename _OutputIterator, typename _Distance> _OutputIterator random_sample_n(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __out, const _Distance __n) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); while (__m > 0) { if ((std::rand() % __remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template<typename _ForwardIterator, typename _OutputIterator, typename _Distance, typename _RandomNumberGenerator> _OutputIterator random_sample_n(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __out, const _Distance __n, _RandomNumberGenerator& __rand) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_function_requires(_UnaryFunctionConcept< _RandomNumberGenerator, _Distance, _Distance>) __glibcxx_requires_valid_range(__first, __last); _Distance __remaining = std::distance(__first, __last); _Distance __m = min(__n, __remaining); while (__m > 0) { if (__rand(__remaining) < __m) { *__out = *__first; ++__out; --__m; } --__remaining; ++__first; } return __out; } template<typename _InputIterator, typename _RandomAccessIterator, typename _Distance> _RandomAccessIterator __random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out, const _Distance __n) { _Distance __m = 0; _Distance __t = __n; for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; _Distance __M = std::rand() % (__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } template<typename _InputIterator, typename _RandomAccessIterator, typename _RandomNumberGenerator, typename _Distance> _RandomAccessIterator __random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out, _RandomNumberGenerator& __rand, const _Distance __n) { // concept requirements __glibcxx_function_requires(_UnaryFunctionConcept< _RandomNumberGenerator, _Distance, _Distance>) _Distance __m = 0; _Distance __t = __n; for ( ; __first != __last && __m < __n; ++__m, ++__first) __out[__m] = *__first; while (__first != __last) { ++__t; _Distance __M = __rand(__t); if (__M < __n) __out[__M] = *__first; ++__first; } return __out + __m; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template<typename _InputIterator, typename _RandomAccessIterator> inline _RandomAccessIterator random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out_first, _RandomAccessIterator __out_last) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_valid_range(__out_first, __out_last); return __random_sample(__first, __last, __out_first, __out_last - __out_first); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template<typename _InputIterator, typename _RandomAccessIterator, typename _RandomNumberGenerator> inline _RandomAccessIterator random_sample(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __out_first, _RandomAccessIterator __out_last, _RandomNumberGenerator& __rand) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_valid_range(__out_first, __out_last); return __random_sample(__first, __last, __out_first, __rand, __out_last - __out_first); } #if __cplusplus >= 201103L using std::is_heap; #else /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template<typename _RandomAccessIterator> inline bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__is_heap(__first, __last - __first); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template<typename _RandomAccessIterator, typename _StrictWeakOrdering> inline bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _StrictWeakOrdering __comp) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__is_heap(__first, __comp, __last - __first); } #endif #if __cplusplus >= 201103L using std::is_sorted; #else // is_sorted, a predicated testing whether a range is sorted in // nondescending order. This is an extension, not part of the C++ // standard. /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template<typename _ForwardIterator> bool is_sorted(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return true; _ForwardIterator __next = __first; for (++__next; __next != __last; __first = __next, ++__next) if (*__next < *__first) return false; return true; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template<typename _ForwardIterator, typename _StrictWeakOrdering> bool is_sorted(_ForwardIterator __first, _ForwardIterator __last, _StrictWeakOrdering __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_StrictWeakOrdering, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return true; _ForwardIterator __next = __first; for (++__next; __next != __last; __first = __next, ++__next) if (__comp(*__next, *__first)) return false; return true; } #endif // C++11 /** * @brief Find the median of three values. * @param __a A value. * @param __b A value. * @param __c A value. * @return One of @p a, @p b or @p c. * * If @c {l,m,n} is some convolution of @p {a,b,c} such that @c l<=m<=n * then the value returned will be @c m. * This is an SGI extension. * @ingroup SGIextensions */ template<typename _Tp> const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { // concept requirements __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) if (__a < __b) if (__b < __c) return __b; else if (__a < __c) return __c; else return __a; else if (__a < __c) return __a; else if (__b < __c) return __c; else return __b; } /** * @brief Find the median of three values using a predicate for comparison. * @param __a A value. * @param __b A value. * @param __c A value. * @param __comp A binary predicate. * @return One of @p a, @p b or @p c. * * If @c {l,m,n} is some convolution of @p {a,b,c} such that @p comp(l,m) * and @p comp(m,n) are both true then the value returned will be @c m. * This is an SGI extension. * @ingroup SGIextensions */ template<typename _Tp, typename _Compare> const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { // concept requirements __glibcxx_function_requires(_BinaryFunctionConcept<_Compare, bool, _Tp, _Tp>) if (__comp(__a, __b)) if (__comp(__b, __c)) return __b; else if (__comp(__a, __c)) return __c; else return __a; else if (__comp(__a, __c)) return __a; else if (__comp(__b, __c)) return __c; else return __b; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _EXT_ALGORITHM */ c++/8/ext/pod_char_traits.h 0000644 00000012664 15146341150 0011412 0 ustar 00 // POD character, std::char_traits specialization -*- C++ -*- // Copyright (C) 2002-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/pod_char_traits.h * This file is a GNU extension to the Standard C++ Library. */ // Gabriel Dos Reis <gdr@integrable-solutions.net> // Benjamin Kosnik <bkoz@redhat.com> #ifndef _POD_CHAR_TRAITS_H #define _POD_CHAR_TRAITS_H 1 #pragma GCC system_header #include <string> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // POD character abstraction. // NB: The char_type parameter is a subset of int_type, as to allow // int_type to properly hold the full range of char_type values as // well as EOF. /// @brief A POD class that serves as a character abstraction class. template<typename _Value, typename _Int, typename _St = std::mbstate_t> struct character { typedef _Value value_type; typedef _Int int_type; typedef _St state_type; typedef character<_Value, _Int, _St> char_type; value_type value; template<typename V2> static char_type from(const V2& v) { char_type ret = { static_cast<value_type>(v) }; return ret; } template<typename V2> static V2 to(const char_type& c) { V2 ret = { static_cast<V2>(c.value) }; return ret; } }; template<typename _Value, typename _Int, typename _St> inline bool operator==(const character<_Value, _Int, _St>& lhs, const character<_Value, _Int, _St>& rhs) { return lhs.value == rhs.value; } template<typename _Value, typename _Int, typename _St> inline bool operator<(const character<_Value, _Int, _St>& lhs, const character<_Value, _Int, _St>& rhs) { return lhs.value < rhs.value; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// char_traits<__gnu_cxx::character> specialization. template<typename _Value, typename _Int, typename _St> struct char_traits<__gnu_cxx::character<_Value, _Int, _St> > { typedef __gnu_cxx::character<_Value, _Int, _St> char_type; typedef typename char_type::int_type int_type; typedef typename char_type::state_type state_type; typedef fpos<state_type> pos_type; typedef streamoff off_type; static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } static bool eq(const char_type& __c1, const char_type& __c2) { return __c1 == __c2; } static bool lt(const char_type& __c1, const char_type& __c2) { return __c1 < __c2; } static int compare(const char_type* __s1, const char_type* __s2, size_t __n) { for (size_t __i = 0; __i < __n; ++__i) if (!eq(__s1[__i], __s2[__i])) return lt(__s1[__i], __s2[__i]) ? -1 : 1; return 0; } static size_t length(const char_type* __s) { const char_type* __p = __s; while (__p->value) ++__p; return (__p - __s); } static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { for (const char_type* __p = __s; size_t(__p - __s) < __n; ++__p) if (*__p == __a) return __p; return 0; } static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; return static_cast<char_type*> (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))); } static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; std::copy(__s2, __s2 + __n, __s1); return __s1; } static char_type* assign(char_type* __s, size_t __n, char_type __a) { std::fill_n(__s, __n, __a); return __s; } static char_type to_char_type(const int_type& __i) { return char_type::template from(__i); } static int_type to_int_type(const char_type& __c) { return char_type::template to<int_type>(__c); } static bool eq_int_type(const int_type& __c1, const int_type& __c2) { return __c1 == __c2; } static int_type eof() { int_type __r = { static_cast<typename __gnu_cxx::__conditional_type <std::__is_integer<int_type>::__value, int_type, int>::__type>(-1) }; return __r; } static int_type not_eof(const int_type& __c) { return eq_int_type(__c, eof()) ? int_type() : __c; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/vstring_util.h 0000644 00000013207 15146341150 0010770 0 ustar 00 // Versatile string utility -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/vstring_util.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/vstring.h} */ #ifndef _VSTRING_UTIL_H #define _VSTRING_UTIL_H 1 #pragma GCC system_header #include <ext/vstring_fwd.h> #include <debug/debug.h> #include <bits/stl_function.h> // For less #include <bits/functexcept.h> #include <bits/localefwd.h> #include <bits/ostream_insert.h> #include <bits/stl_iterator.h> #include <ext/numeric_traits.h> #include <bits/move.h> #include <bits/range_access.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits, typename _Alloc> struct __vstring_utility { typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; typedef _Traits traits_type; typedef typename _Traits::char_type value_type; typedef typename _CharT_alloc_type::size_type size_type; typedef typename _CharT_alloc_type::difference_type difference_type; typedef typename _CharT_alloc_type::pointer pointer; typedef typename _CharT_alloc_type::const_pointer const_pointer; // For __sso_string. typedef __gnu_cxx:: __normal_iterator<pointer, __gnu_cxx:: __versa_string<_CharT, _Traits, _Alloc, __sso_string_base> > __sso_iterator; typedef __gnu_cxx:: __normal_iterator<const_pointer, __gnu_cxx:: __versa_string<_CharT, _Traits, _Alloc, __sso_string_base> > __const_sso_iterator; // For __rc_string. typedef __gnu_cxx:: __normal_iterator<pointer, __gnu_cxx:: __versa_string<_CharT, _Traits, _Alloc, __rc_string_base> > __rc_iterator; typedef __gnu_cxx:: __normal_iterator<const_pointer, __gnu_cxx:: __versa_string<_CharT, _Traits, _Alloc, __rc_string_base> > __const_rc_iterator; // NB: When the allocator is empty, deriving from it saves space // (http://www.cantrip.org/emptyopt.html). template<typename _Alloc1> struct _Alloc_hider : public _Alloc1 { _Alloc_hider(_CharT* __ptr) : _Alloc1(), _M_p(__ptr) { } _Alloc_hider(const _Alloc1& __a, _CharT* __ptr) : _Alloc1(__a), _M_p(__ptr) { } _CharT* _M_p; // The actual data. }; // When __n = 1 way faster than the general multichar // traits_type::copy/move/assign. static void _S_copy(_CharT* __d, const _CharT* __s, size_type __n) { if (__n == 1) traits_type::assign(*__d, *__s); else traits_type::copy(__d, __s, __n); } static void _S_move(_CharT* __d, const _CharT* __s, size_type __n) { if (__n == 1) traits_type::assign(*__d, *__s); else traits_type::move(__d, __s, __n); } static void _S_assign(_CharT* __d, size_type __n, _CharT __c) { if (__n == 1) traits_type::assign(*__d, __c); else traits_type::assign(__d, __n, __c); } // _S_copy_chars is a separate template to permit specialization // to optimize for the common case of pointers as iterators. template<typename _Iterator> static void _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) { for (; __k1 != __k2; ++__k1, ++__p) traits_type::assign(*__p, *__k1); // These types are off. } static void _S_copy_chars(_CharT* __p, __sso_iterator __k1, __sso_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, __const_sso_iterator __k1, __const_sso_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, __rc_iterator __k1, __rc_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, __const_rc_iterator __k1, __const_rc_iterator __k2) { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) { _S_copy(__p, __k1, __k2 - __k1); } static void _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) { _S_copy(__p, __k1, __k2 - __k1); } static int _S_compare(size_type __n1, size_type __n2) { const difference_type __d = difference_type(__n1 - __n2); if (__d > __numeric_traits_integer<int>::__max) return __numeric_traits_integer<int>::__max; else if (__d < __numeric_traits_integer<int>::__min) return __numeric_traits_integer<int>::__min; else return int(__d); } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _VSTRING_UTIL_H */ c++/8/ext/iterator 0000644 00000007677 15146341150 0007660 0 ustar 00 // HP/SGI iterator extensions -*- C++ -*- // Copyright (C) 2001-2018 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 ext/iterator * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_ITERATOR #define _EXT_ITERATOR 1 #pragma GCC system_header #include <bits/concept_check.h> #include <iterator> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // There are two signatures for distance. In addition to the one // taking two iterators and returning a result, there is another // taking two iterators and a reference-to-result variable, and // returning nothing. The latter seems to be an SGI extension. // -- pedwards template<typename _InputIterator, typename _Distance> inline void __distance(_InputIterator __first, _InputIterator __last, _Distance& __n, std::input_iterator_tag) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) while (__first != __last) { ++__first; ++__n; } } template<typename _RandomAccessIterator, typename _Distance> inline void __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance& __n, std::random_access_iterator_tag) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __n += __last - __first; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template<typename _InputIterator, typename _Distance> inline void distance(_InputIterator __first, _InputIterator __last, _Distance& __n) { // concept requirements -- taken care of in __distance __distance(__first, __last, __n, std::__iterator_category(__first)); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/vstring_fwd.h 0000644 00000006226 15146341150 0010576 0 ustar 00 // <vstring.h> Forward declarations -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/vstring_fwd.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/vstring.h} */ #ifndef _VSTRING_FWD_H #define _VSTRING_FWD_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/char_traits.h> #include <bits/allocator.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits, typename _Alloc> class __sso_string_base; template<typename _CharT, typename _Traits, typename _Alloc> class __rc_string_base; template<typename _CharT, typename _Traits = std::char_traits<_CharT>, typename _Alloc = std::allocator<_CharT>, template <typename, typename, typename> class _Base = __sso_string_base> class __versa_string; typedef __versa_string<char> __vstring; typedef __vstring __sso_string; typedef __versa_string<char, std::char_traits<char>, std::allocator<char>, __rc_string_base> __rc_string; #ifdef _GLIBCXX_USE_WCHAR_T typedef __versa_string<wchar_t> __wvstring; typedef __wvstring __wsso_string; typedef __versa_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>, __rc_string_base> __wrc_string; #endif #if ((__cplusplus >= 201103L) \ && defined(_GLIBCXX_USE_C99_STDINT_TR1)) typedef __versa_string<char16_t> __u16vstring; typedef __u16vstring __u16sso_string; typedef __versa_string<char16_t, std::char_traits<char16_t>, std::allocator<char16_t>, __rc_string_base> __u16rc_string; typedef __versa_string<char32_t> __u32vstring; typedef __u32vstring __u32sso_string; typedef __versa_string<char32_t, std::char_traits<char32_t>, std::allocator<char32_t>, __rc_string_base> __u32rc_string; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _VSTRING_FWD_H */ c++/8/ext/slist 0000644 00000071643 15146341150 0007157 0 ustar 00 // Singly-linked list implementation -*- C++ -*- // Copyright (C) 2001-2018 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) 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 ext/slist * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _SLIST #define _SLIST 1 #include <algorithm> #include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> #include <bits/concept_check.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using std::size_t; using std::ptrdiff_t; using std::_Construct; using std::_Destroy; using std::allocator; using std::__true_type; using std::__false_type; struct _Slist_node_base { _Slist_node_base* _M_next; }; inline _Slist_node_base* __slist_make_link(_Slist_node_base* __prev_node, _Slist_node_base* __new_node) { __new_node->_M_next = __prev_node->_M_next; __prev_node->_M_next = __new_node; return __new_node; } inline _Slist_node_base* __slist_previous(_Slist_node_base* __head, const _Slist_node_base* __node) { while (__head && __head->_M_next != __node) __head = __head->_M_next; return __head; } inline const _Slist_node_base* __slist_previous(const _Slist_node_base* __head, const _Slist_node_base* __node) { while (__head && __head->_M_next != __node) __head = __head->_M_next; return __head; } inline void __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __before_first, _Slist_node_base* __before_last) { if (__pos != __before_first && __pos != __before_last) { _Slist_node_base* __first = __before_first->_M_next; _Slist_node_base* __after = __pos->_M_next; __before_first->_M_next = __before_last->_M_next; __pos->_M_next = __first; __before_last->_M_next = __after; } } inline void __slist_splice_after(_Slist_node_base* __pos, _Slist_node_base* __head) { _Slist_node_base* __before_last = __slist_previous(__head, 0); if (__before_last != __head) { _Slist_node_base* __after = __pos->_M_next; __pos->_M_next = __head->_M_next; __head->_M_next = 0; __before_last->_M_next = __after; } } inline _Slist_node_base* __slist_reverse(_Slist_node_base* __node) { _Slist_node_base* __result = __node; __node = __node->_M_next; __result->_M_next = 0; while(__node) { _Slist_node_base* __next = __node->_M_next; __node->_M_next = __result; __result = __node; __node = __next; } return __result; } inline size_t __slist_size(_Slist_node_base* __node) { size_t __result = 0; for (; __node != 0; __node = __node->_M_next) ++__result; return __result; } template <class _Tp> struct _Slist_node : public _Slist_node_base { _Tp _M_data; }; struct _Slist_iterator_base { typedef size_t size_type; typedef ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; _Slist_node_base* _M_node; _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {} void _M_incr() { _M_node = _M_node->_M_next; } bool operator==(const _Slist_iterator_base& __x) const { return _M_node == __x._M_node; } bool operator!=(const _Slist_iterator_base& __x) const { return _M_node != __x._M_node; } }; template <class _Tp, class _Ref, class _Ptr> struct _Slist_iterator : public _Slist_iterator_base { typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; typedef _Slist_iterator<_Tp, _Ref, _Ptr> _Self; typedef _Tp value_type; typedef _Ptr pointer; typedef _Ref reference; typedef _Slist_node<_Tp> _Node; explicit _Slist_iterator(_Node* __x) : _Slist_iterator_base(__x) {} _Slist_iterator() : _Slist_iterator_base(0) {} _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {} reference operator*() const { return ((_Node*) _M_node)->_M_data; } pointer operator->() const { return &(operator*()); } _Self& operator++() { _M_incr(); return *this; } _Self operator++(int) { _Self __tmp = *this; _M_incr(); return __tmp; } }; template <class _Tp, class _Alloc> struct _Slist_base : public _Alloc::template rebind<_Slist_node<_Tp> >::other { typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other _Node_alloc; typedef _Alloc allocator_type; allocator_type get_allocator() const { return *static_cast<const _Node_alloc*>(this); } _Slist_base(const allocator_type& __a) : _Node_alloc(__a) { this->_M_head._M_next = 0; } ~_Slist_base() { _M_erase_after(&this->_M_head, 0); } protected: _Slist_node_base _M_head; _Slist_node<_Tp>* _M_get_node() { return _Node_alloc::allocate(1); } void _M_put_node(_Slist_node<_Tp>* __p) { _Node_alloc::deallocate(__p, 1); } protected: _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) { _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); _Slist_node_base* __next_next = __next->_M_next; __pos->_M_next = __next_next; get_allocator().destroy(&__next->_M_data); _M_put_node(__next); return __next_next; } _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); }; template <class _Tp, class _Alloc> _Slist_node_base* _Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first, _Slist_node_base* __last_node) { _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next); while (__cur != __last_node) { _Slist_node<_Tp>* __tmp = __cur; __cur = (_Slist_node<_Tp>*) __cur->_M_next; get_allocator().destroy(&__tmp->_M_data); _M_put_node(__tmp); } __before_first->_M_next = __last_node; return __last_node; } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template <class _Tp, class _Alloc = allocator<_Tp> > class slist : private _Slist_base<_Tp,_Alloc> { // concept requirements __glibcxx_class_requires(_Tp, _SGIAssignableConcept) private: typedef _Slist_base<_Tp,_Alloc> _Base; public: 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 size_t size_type; typedef ptrdiff_t difference_type; typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; typedef typename _Base::allocator_type allocator_type; allocator_type get_allocator() const { return _Base::get_allocator(); } private: typedef _Slist_node<_Tp> _Node; typedef _Slist_node_base _Node_base; typedef _Slist_iterator_base _Iterator_base; _Node* _M_create_node(const value_type& __x) { _Node* __node = this->_M_get_node(); __try { get_allocator().construct(&__node->_M_data, __x); __node->_M_next = 0; } __catch(...) { this->_M_put_node(__node); __throw_exception_again; } return __node; } _Node* _M_create_node() { _Node* __node = this->_M_get_node(); __try { get_allocator().construct(&__node->_M_data, value_type()); __node->_M_next = 0; } __catch(...) { this->_M_put_node(__node); __throw_exception_again; } return __node; } public: explicit slist(const allocator_type& __a = allocator_type()) : _Base(__a) {} slist(size_type __n, const value_type& __x, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_insert_after_fill(&this->_M_head, __n, __x); } explicit slist(size_type __n) : _Base(allocator_type()) { _M_insert_after_fill(&this->_M_head, __n, value_type()); } // We don't need any dispatching tricks here, because // _M_insert_after_range already does them. template <class _InputIterator> slist(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_insert_after_range(&this->_M_head, __first, __last); } slist(const slist& __x) : _Base(__x.get_allocator()) { _M_insert_after_range(&this->_M_head, __x.begin(), __x.end()); } slist& operator= (const slist& __x); ~slist() {} public: // assign(), a generalized assignment member function. Two // versions: one that takes a count, and one that takes a range. // The range version is a member template, so we dispatch on whether // or not the type is an integer. void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); } void _M_fill_assign(size_type __n, const _Tp& __val); template <class _InputIterator> void assign(_InputIterator __first, _InputIterator __last) { typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_assign_dispatch(__first, __last, _Integral()); } template <class _Integer> void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign((size_type) __n, (_Tp) __val); } template <class _InputIterator> void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type); public: iterator begin() { return iterator((_Node*)this->_M_head._M_next); } const_iterator begin() const { return const_iterator((_Node*)this->_M_head._M_next);} iterator end() { return iterator(0); } const_iterator end() const { return const_iterator(0); } // Experimental new feature: before_begin() returns a // non-dereferenceable iterator that, when incremented, yields // begin(). This iterator may be used as the argument to // insert_after, erase_after, etc. Note that even for an empty // slist, before_begin() is not the same iterator as end(). It // is always necessary to increment before_begin() at least once to // obtain end(). iterator before_begin() { return iterator((_Node*) &this->_M_head); } const_iterator before_begin() const { return const_iterator((_Node*) &this->_M_head); } size_type size() const { return __slist_size(this->_M_head._M_next); } size_type max_size() const { return size_type(-1); } bool empty() const { return this->_M_head._M_next == 0; } void swap(slist& __x) { std::swap(this->_M_head._M_next, __x._M_head._M_next); } public: reference front() { return ((_Node*) this->_M_head._M_next)->_M_data; } const_reference front() const { return ((_Node*) this->_M_head._M_next)->_M_data; } void push_front(const value_type& __x) { __slist_make_link(&this->_M_head, _M_create_node(__x)); } void push_front() { __slist_make_link(&this->_M_head, _M_create_node()); } void pop_front() { _Node* __node = (_Node*) this->_M_head._M_next; this->_M_head._M_next = __node->_M_next; get_allocator().destroy(&__node->_M_data); this->_M_put_node(__node); } iterator previous(const_iterator __pos) { return iterator((_Node*) __slist_previous(&this->_M_head, __pos._M_node)); } const_iterator previous(const_iterator __pos) const { return const_iterator((_Node*) __slist_previous(&this->_M_head, __pos._M_node)); } private: _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) { return (_Node*) (__slist_make_link(__pos, _M_create_node(__x))); } _Node* _M_insert_after(_Node_base* __pos) { return (_Node*) (__slist_make_link(__pos, _M_create_node())); } void _M_insert_after_fill(_Node_base* __pos, size_type __n, const value_type& __x) { for (size_type __i = 0; __i < __n; ++__i) __pos = __slist_make_link(__pos, _M_create_node(__x)); } // Check whether it's an integral type. If so, it's not an iterator. template <class _InIterator> void _M_insert_after_range(_Node_base* __pos, _InIterator __first, _InIterator __last) { typedef typename std::__is_integer<_InIterator>::__type _Integral; _M_insert_after_range(__pos, __first, __last, _Integral()); } template <class _Integer> void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, __true_type) { _M_insert_after_fill(__pos, __n, __x); } template <class _InIterator> void _M_insert_after_range(_Node_base* __pos, _InIterator __first, _InIterator __last, __false_type) { while (__first != __last) { __pos = __slist_make_link(__pos, _M_create_node(*__first)); ++__first; } } public: iterator insert_after(iterator __pos, const value_type& __x) { return iterator(_M_insert_after(__pos._M_node, __x)); } iterator insert_after(iterator __pos) { return insert_after(__pos, value_type()); } void insert_after(iterator __pos, size_type __n, const value_type& __x) { _M_insert_after_fill(__pos._M_node, __n, __x); } // We don't need any dispatching tricks here, because // _M_insert_after_range already does them. template <class _InIterator> void insert_after(iterator __pos, _InIterator __first, _InIterator __last) { _M_insert_after_range(__pos._M_node, __first, __last); } iterator insert(iterator __pos, const value_type& __x) { return iterator(_M_insert_after(__slist_previous(&this->_M_head, __pos._M_node), __x)); } iterator insert(iterator __pos) { return iterator(_M_insert_after(__slist_previous(&this->_M_head, __pos._M_node), value_type())); } void insert(iterator __pos, size_type __n, const value_type& __x) { _M_insert_after_fill(__slist_previous(&this->_M_head, __pos._M_node), __n, __x); } // We don't need any dispatching tricks here, because // _M_insert_after_range already does them. template <class _InIterator> void insert(iterator __pos, _InIterator __first, _InIterator __last) { _M_insert_after_range(__slist_previous(&this->_M_head, __pos._M_node), __first, __last); } public: iterator erase_after(iterator __pos) { return iterator((_Node*) this->_M_erase_after(__pos._M_node)); } iterator erase_after(iterator __before_first, iterator __last) { return iterator((_Node*) this->_M_erase_after(__before_first._M_node, __last._M_node)); } iterator erase(iterator __pos) { return iterator((_Node*) this->_M_erase_after (__slist_previous(&this->_M_head, __pos._M_node))); } iterator erase(iterator __first, iterator __last) { return iterator((_Node*) this->_M_erase_after (__slist_previous(&this->_M_head, __first._M_node), __last._M_node)); } void resize(size_type new_size, const _Tp& __x); void resize(size_type new_size) { resize(new_size, _Tp()); } void clear() { this->_M_erase_after(&this->_M_head, 0); } public: // Moves the range [__before_first + 1, __before_last + 1) to *this, // inserting it immediately after __pos. This is constant time. void splice_after(iterator __pos, iterator __before_first, iterator __before_last) { if (__before_first != __before_last) __slist_splice_after(__pos._M_node, __before_first._M_node, __before_last._M_node); } // Moves the element that follows __prev to *this, inserting it // immediately after __pos. This is constant time. void splice_after(iterator __pos, iterator __prev) { __slist_splice_after(__pos._M_node, __prev._M_node, __prev._M_node->_M_next); } // Removes all of the elements from the list __x to *this, inserting // them immediately after __pos. __x must not be *this. Complexity: // linear in __x.size(). void splice_after(iterator __pos, slist& __x) { __slist_splice_after(__pos._M_node, &__x._M_head); } // Linear in distance(begin(), __pos), and linear in __x.size(). void splice(iterator __pos, slist& __x) { if (__x._M_head._M_next) __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), &__x._M_head, __slist_previous(&__x._M_head, 0)); } // Linear in distance(begin(), __pos), and in distance(__x.begin(), __i). void splice(iterator __pos, slist& __x, iterator __i) { __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), __slist_previous(&__x._M_head, __i._M_node), __i._M_node); } // Linear in distance(begin(), __pos), in distance(__x.begin(), __first), // and in distance(__first, __last). void splice(iterator __pos, slist& __x, iterator __first, iterator __last) { if (__first != __last) __slist_splice_after(__slist_previous(&this->_M_head, __pos._M_node), __slist_previous(&__x._M_head, __first._M_node), __slist_previous(__first._M_node, __last._M_node)); } public: void reverse() { if (this->_M_head._M_next) this->_M_head._M_next = __slist_reverse(this->_M_head._M_next); } void remove(const _Tp& __val); void unique(); void merge(slist& __x); void sort(); template <class _Predicate> void remove_if(_Predicate __pred); template <class _BinaryPredicate> void unique(_BinaryPredicate __pred); template <class _StrictWeakOrdering> void merge(slist&, _StrictWeakOrdering); template <class _StrictWeakOrdering> void sort(_StrictWeakOrdering __comp); }; template <class _Tp, class _Alloc> slist<_Tp, _Alloc>& slist<_Tp, _Alloc>::operator=(const slist<_Tp, _Alloc>& __x) { if (&__x != this) { _Node_base* __p1 = &this->_M_head; _Node* __n1 = (_Node*) this->_M_head._M_next; const _Node* __n2 = (const _Node*) __x._M_head._M_next; while (__n1 && __n2) { __n1->_M_data = __n2->_M_data; __p1 = __n1; __n1 = (_Node*) __n1->_M_next; __n2 = (const _Node*) __n2->_M_next; } if (__n2 == 0) this->_M_erase_after(__p1, 0); else _M_insert_after_range(__p1, const_iterator((_Node*)__n2), const_iterator(0)); } return *this; } template <class _Tp, class _Alloc> void slist<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { _Node_base* __prev = &this->_M_head; _Node* __node = (_Node*) this->_M_head._M_next; for (; __node != 0 && __n > 0; --__n) { __node->_M_data = __val; __prev = __node; __node = (_Node*) __node->_M_next; } if (__n > 0) _M_insert_after_fill(__prev, __n, __val); else this->_M_erase_after(__prev, 0); } template <class _Tp, class _Alloc> template <class _InputIterator> void slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { _Node_base* __prev = &this->_M_head; _Node* __node = (_Node*) this->_M_head._M_next; while (__node != 0 && __first != __last) { __node->_M_data = *__first; __prev = __node; __node = (_Node*) __node->_M_next; ++__first; } if (__first != __last) _M_insert_after_range(__prev, __first, __last); else this->_M_erase_after(__prev, 0); } template <class _Tp, class _Alloc> inline bool operator==(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) { typedef typename slist<_Tp,_Alloc>::const_iterator const_iterator; const_iterator __end1 = _SL1.end(); const_iterator __end2 = _SL2.end(); const_iterator __i1 = _SL1.begin(); const_iterator __i2 = _SL2.begin(); while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { ++__i1; ++__i2; } return __i1 == __end1 && __i2 == __end2; } template <class _Tp, class _Alloc> inline bool operator<(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) { return std::lexicographical_compare(_SL1.begin(), _SL1.end(), _SL2.begin(), _SL2.end()); } template <class _Tp, class _Alloc> inline bool operator!=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) { return !(_SL1 == _SL2); } template <class _Tp, class _Alloc> inline bool operator>(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) { return _SL2 < _SL1; } template <class _Tp, class _Alloc> inline bool operator<=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) { return !(_SL2 < _SL1); } template <class _Tp, class _Alloc> inline bool operator>=(const slist<_Tp, _Alloc>& _SL1, const slist<_Tp, _Alloc>& _SL2) { return !(_SL1 < _SL2); } template <class _Tp, class _Alloc> inline void swap(slist<_Tp, _Alloc>& __x, slist<_Tp, _Alloc>& __y) { __x.swap(__y); } template <class _Tp, class _Alloc> void slist<_Tp, _Alloc>::resize(size_type __len, const _Tp& __x) { _Node_base* __cur = &this->_M_head; while (__cur->_M_next != 0 && __len > 0) { --__len; __cur = __cur->_M_next; } if (__cur->_M_next) this->_M_erase_after(__cur, 0); else _M_insert_after_fill(__cur, __len, __x); } template <class _Tp, class _Alloc> void slist<_Tp, _Alloc>::remove(const _Tp& __val) { _Node_base* __cur = &this->_M_head; while (__cur && __cur->_M_next) { if (((_Node*) __cur->_M_next)->_M_data == __val) this->_M_erase_after(__cur); else __cur = __cur->_M_next; } } template <class _Tp, class _Alloc> void slist<_Tp, _Alloc>::unique() { _Node_base* __cur = this->_M_head._M_next; if (__cur) { while (__cur->_M_next) { if (((_Node*)__cur)->_M_data == ((_Node*)(__cur->_M_next))->_M_data) this->_M_erase_after(__cur); else __cur = __cur->_M_next; } } } template <class _Tp, class _Alloc> void slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x) { _Node_base* __n1 = &this->_M_head; while (__n1->_M_next && __x._M_head._M_next) { if (((_Node*) __x._M_head._M_next)->_M_data < ((_Node*) __n1->_M_next)->_M_data) __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); __n1 = __n1->_M_next; } if (__x._M_head._M_next) { __n1->_M_next = __x._M_head._M_next; __x._M_head._M_next = 0; } } template <class _Tp, class _Alloc> void slist<_Tp, _Alloc>::sort() { if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { slist __carry; slist __counter[64]; int __fill = 0; while (!empty()) { __slist_splice_after(&__carry._M_head, &this->_M_head, this->_M_head._M_next); int __i = 0; while (__i < __fill && !__counter[__i].empty()) { __counter[__i].merge(__carry); __carry.swap(__counter[__i]); ++__i; } __carry.swap(__counter[__i]); if (__i == __fill) ++__fill; } for (int __i = 1; __i < __fill; ++__i) __counter[__i].merge(__counter[__i-1]); this->swap(__counter[__fill-1]); } } template <class _Tp, class _Alloc> template <class _Predicate> void slist<_Tp, _Alloc>::remove_if(_Predicate __pred) { _Node_base* __cur = &this->_M_head; while (__cur->_M_next) { if (__pred(((_Node*) __cur->_M_next)->_M_data)) this->_M_erase_after(__cur); else __cur = __cur->_M_next; } } template <class _Tp, class _Alloc> template <class _BinaryPredicate> void slist<_Tp, _Alloc>::unique(_BinaryPredicate __pred) { _Node* __cur = (_Node*) this->_M_head._M_next; if (__cur) { while (__cur->_M_next) { if (__pred(((_Node*)__cur)->_M_data, ((_Node*)(__cur->_M_next))->_M_data)) this->_M_erase_after(__cur); else __cur = (_Node*) __cur->_M_next; } } } template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> void slist<_Tp, _Alloc>::merge(slist<_Tp, _Alloc>& __x, _StrictWeakOrdering __comp) { _Node_base* __n1 = &this->_M_head; while (__n1->_M_next && __x._M_head._M_next) { if (__comp(((_Node*) __x._M_head._M_next)->_M_data, ((_Node*) __n1->_M_next)->_M_data)) __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); __n1 = __n1->_M_next; } if (__x._M_head._M_next) { __n1->_M_next = __x._M_head._M_next; __x._M_head._M_next = 0; } } template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> void slist<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) { if (this->_M_head._M_next && this->_M_head._M_next->_M_next) { slist __carry; slist __counter[64]; int __fill = 0; while (!empty()) { __slist_splice_after(&__carry._M_head, &this->_M_head, this->_M_head._M_next); int __i = 0; while (__i < __fill && !__counter[__i].empty()) { __counter[__i].merge(__carry, __comp); __carry.swap(__counter[__i]); ++__i; } __carry.swap(__counter[__i]); if (__i == __fill) ++__fill; } for (int __i = 1; __i < __fill; ++__i) __counter[__i].merge(__counter[__i-1], __comp); this->swap(__counter[__fill-1]); } } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Specialization of insert_iterator so that insertions will be constant // time rather than linear time. template <class _Tp, class _Alloc> class insert_iterator<__gnu_cxx::slist<_Tp, _Alloc> > { protected: typedef __gnu_cxx::slist<_Tp, _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, typename _Container::iterator __i) : container(&__x) { if (__i == __x.begin()) iter = __x.before_begin(); else iter = __x.previous(__i); } insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { iter = container->insert_after(iter, __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 c++/8/ext/codecvt_specializations.h 0000644 00000037741 15146341150 0013160 0 ustar 00 // Locale support (codecvt) -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. // // ISO C++ 14882: 22.2.1.5 Template class codecvt // // Written by Benjamin Kosnik <bkoz@redhat.com> /** @file ext/codecvt_specializations.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _EXT_CODECVT_SPECIALIZATIONS_H #define _EXT_CODECVT_SPECIALIZATIONS_H 1 #include <bits/c++config.h> #include <locale> #include <iconv.h> namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CXX11 /// Extension to use iconv for dealing with character encodings. // This includes conversions and comparisons between various character // sets. This object encapsulates data that may need to be shared between // char_traits, codecvt and ctype. class encoding_state { public: // Types: // NB: A conversion descriptor subsumes and enhances the // functionality of a simple state type such as mbstate_t. typedef iconv_t descriptor_type; protected: // Name of internal character set encoding. std::string _M_int_enc; // Name of external character set encoding. std::string _M_ext_enc; // Conversion descriptor between external encoding to internal encoding. descriptor_type _M_in_desc; // Conversion descriptor between internal encoding to external encoding. descriptor_type _M_out_desc; // The byte-order marker for the external encoding, if necessary. int _M_ext_bom; // The byte-order marker for the internal encoding, if necessary. int _M_int_bom; // Number of external bytes needed to construct one complete // character in the internal encoding. // NB: -1 indicates variable, or stateful, encodings. int _M_bytes; public: explicit encoding_state() : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(0), _M_int_bom(0), _M_bytes(0) { } explicit encoding_state(const char* __int, const char* __ext, int __ibom = 0, int __ebom = 0, int __bytes = 1) : _M_int_enc(__int), _M_ext_enc(__ext), _M_in_desc(0), _M_out_desc(0), _M_ext_bom(__ebom), _M_int_bom(__ibom), _M_bytes(__bytes) { init(); } // 21.1.2 traits typedefs // p4 // typedef STATE_T state_type // requires: state_type shall meet the requirements of // CopyConstructible types (20.1.3) // NB: This does not preserve the actual state of the conversion // descriptor member, but it does duplicate the encoding // information. encoding_state(const encoding_state& __obj) : _M_in_desc(0), _M_out_desc(0) { construct(__obj); } // Need assignment operator as well. encoding_state& operator=(const encoding_state& __obj) { construct(__obj); return *this; } ~encoding_state() { destroy(); } bool good() const throw() { const descriptor_type __err = (iconv_t)(-1); bool __test = _M_in_desc && _M_in_desc != __err; __test &= _M_out_desc && _M_out_desc != __err; return __test; } int character_ratio() const { return _M_bytes; } const std::string internal_encoding() const { return _M_int_enc; } int internal_bom() const { return _M_int_bom; } const std::string external_encoding() const { return _M_ext_enc; } int external_bom() const { return _M_ext_bom; } const descriptor_type& in_descriptor() const { return _M_in_desc; } const descriptor_type& out_descriptor() const { return _M_out_desc; } protected: void init() { const descriptor_type __err = (iconv_t)(-1); const bool __have_encodings = _M_int_enc.size() && _M_ext_enc.size(); if (!_M_in_desc && __have_encodings) { _M_in_desc = iconv_open(_M_int_enc.c_str(), _M_ext_enc.c_str()); if (_M_in_desc == __err) std::__throw_runtime_error(__N("encoding_state::_M_init " "creating iconv input descriptor failed")); } if (!_M_out_desc && __have_encodings) { _M_out_desc = iconv_open(_M_ext_enc.c_str(), _M_int_enc.c_str()); if (_M_out_desc == __err) std::__throw_runtime_error(__N("encoding_state::_M_init " "creating iconv output descriptor failed")); } } void construct(const encoding_state& __obj) { destroy(); _M_int_enc = __obj._M_int_enc; _M_ext_enc = __obj._M_ext_enc; _M_ext_bom = __obj._M_ext_bom; _M_int_bom = __obj._M_int_bom; _M_bytes = __obj._M_bytes; init(); } void destroy() throw() { const descriptor_type __err = (iconv_t)(-1); if (_M_in_desc && _M_in_desc != __err) { iconv_close(_M_in_desc); _M_in_desc = 0; } if (_M_out_desc && _M_out_desc != __err) { iconv_close(_M_out_desc); _M_out_desc = 0; } } }; /// encoding_char_traits // Custom traits type with encoding_state for the state type, and the // associated fpos<encoding_state> for the position type, all other // bits equivalent to the required char_traits instantiations. template<typename _CharT> struct encoding_char_traits : public std::char_traits<_CharT> { typedef encoding_state state_type; typedef typename std::fpos<state_type> pos_type; }; _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using __gnu_cxx::encoding_state; /// codecvt<InternT, _ExternT, encoding_state> specialization. // This partial specialization takes advantage of iconv to provide // code conversions between a large number of character encodings. template<typename _InternT, typename _ExternT> class codecvt<_InternT, _ExternT, encoding_state> : public __codecvt_abstract_base<_InternT, _ExternT, encoding_state> { public: // Types: typedef codecvt_base::result result; typedef _InternT intern_type; typedef _ExternT extern_type; typedef __gnu_cxx::encoding_state state_type; typedef state_type::descriptor_type descriptor_type; // Data Members: static locale::id id; explicit codecvt(size_t __refs = 0) : __codecvt_abstract_base<intern_type, extern_type, state_type>(__refs) { } explicit codecvt(state_type& __enc, size_t __refs = 0) : __codecvt_abstract_base<intern_type, extern_type, state_type>(__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(); }; template<typename _InternT, typename _ExternT> locale::id codecvt<_InternT, _ExternT, encoding_state>::id; // This adaptor works around the signature problems of the second // argument to iconv(): SUSv2 and others use 'const char**', but glibc 2.2 // uses 'char**', which matches the POSIX 1003.1-2001 standard. // Using this adaptor, g++ will do the work for us. template<typename _Tp> inline size_t __iconv_adaptor(size_t(*__func)(iconv_t, _Tp, size_t*, char**, size_t*), iconv_t __cd, char** __inbuf, size_t* __inbytes, char** __outbuf, size_t* __outbytes) { return __func(__cd, (_Tp)__inbuf, __inbytes, __outbuf, __outbytes); } template<typename _InternT, typename _ExternT> codecvt_base::result codecvt<_InternT, _ExternT, encoding_state>:: 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 { result __ret = codecvt_base::error; if (__state.good()) { const descriptor_type& __desc = __state.out_descriptor(); const size_t __fmultiple = sizeof(intern_type); size_t __fbytes = __fmultiple * (__from_end - __from); const size_t __tmultiple = sizeof(extern_type); size_t __tbytes = __tmultiple * (__to_end - __to); // Argument list for iconv specifies a byte sequence. Thus, // all to/from arrays must be brutally casted to char*. char* __cto = reinterpret_cast<char*>(__to); char* __cfrom; size_t __conv; // Some encodings need a byte order marker as the first item // in the byte stream, to designate endian-ness. The default // value for the byte order marker is NULL, so if this is // the case, it's not necessary and we can just go on our // merry way. int __int_bom = __state.internal_bom(); if (__int_bom) { size_t __size = __from_end - __from; intern_type* __cfixed = static_cast<intern_type*> (__builtin_alloca(sizeof(intern_type) * (__size + 1))); __cfixed[0] = static_cast<intern_type>(__int_bom); char_traits<intern_type>::copy(__cfixed + 1, __from, __size); __cfrom = reinterpret_cast<char*>(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__fbytes, &__cto, &__tbytes); } else { intern_type* __cfixed = const_cast<intern_type*>(__from); __cfrom = reinterpret_cast<char*>(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__fbytes, &__cto, &__tbytes); } if (__conv != size_t(-1)) { __from_next = reinterpret_cast<const intern_type*>(__cfrom); __to_next = reinterpret_cast<extern_type*>(__cto); __ret = codecvt_base::ok; } else { if (__fbytes < __fmultiple * (__from_end - __from)) { __from_next = reinterpret_cast<const intern_type*>(__cfrom); __to_next = reinterpret_cast<extern_type*>(__cto); __ret = codecvt_base::partial; } else __ret = codecvt_base::error; } } return __ret; } template<typename _InternT, typename _ExternT> codecvt_base::result codecvt<_InternT, _ExternT, encoding_state>:: do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const { result __ret = codecvt_base::error; if (__state.good()) { const descriptor_type& __desc = __state.in_descriptor(); const size_t __tmultiple = sizeof(intern_type); size_t __tlen = __tmultiple * (__to_end - __to); // Argument list for iconv specifies a byte sequence. Thus, // all to/from arrays must be brutally casted to char*. char* __cto = reinterpret_cast<char*>(__to); size_t __conv = __iconv_adaptor(iconv,__desc, 0, 0, &__cto, &__tlen); if (__conv != size_t(-1)) { __to_next = reinterpret_cast<extern_type*>(__cto); if (__tlen == __tmultiple * (__to_end - __to)) __ret = codecvt_base::noconv; else if (__tlen == 0) __ret = codecvt_base::ok; else __ret = codecvt_base::partial; } else __ret = codecvt_base::error; } return __ret; } template<typename _InternT, typename _ExternT> codecvt_base::result codecvt<_InternT, _ExternT, encoding_state>:: 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 { result __ret = codecvt_base::error; if (__state.good()) { const descriptor_type& __desc = __state.in_descriptor(); const size_t __fmultiple = sizeof(extern_type); size_t __flen = __fmultiple * (__from_end - __from); const size_t __tmultiple = sizeof(intern_type); size_t __tlen = __tmultiple * (__to_end - __to); // Argument list for iconv specifies a byte sequence. Thus, // all to/from arrays must be brutally casted to char*. char* __cto = reinterpret_cast<char*>(__to); char* __cfrom; size_t __conv; // Some encodings need a byte order marker as the first item // in the byte stream, to designate endian-ness. The default // value for the byte order marker is NULL, so if this is // the case, it's not necessary and we can just go on our // merry way. int __ext_bom = __state.external_bom(); if (__ext_bom) { size_t __size = __from_end - __from; extern_type* __cfixed = static_cast<extern_type*> (__builtin_alloca(sizeof(extern_type) * (__size + 1))); __cfixed[0] = static_cast<extern_type>(__ext_bom); char_traits<extern_type>::copy(__cfixed + 1, __from, __size); __cfrom = reinterpret_cast<char*>(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__flen, &__cto, &__tlen); } else { extern_type* __cfixed = const_cast<extern_type*>(__from); __cfrom = reinterpret_cast<char*>(__cfixed); __conv = __iconv_adaptor(iconv, __desc, &__cfrom, &__flen, &__cto, &__tlen); } if (__conv != size_t(-1)) { __from_next = reinterpret_cast<const extern_type*>(__cfrom); __to_next = reinterpret_cast<intern_type*>(__cto); __ret = codecvt_base::ok; } else { if (__flen < static_cast<size_t>(__from_end - __from)) { __from_next = reinterpret_cast<const extern_type*>(__cfrom); __to_next = reinterpret_cast<intern_type*>(__cto); __ret = codecvt_base::partial; } else __ret = codecvt_base::error; } } return __ret; } template<typename _InternT, typename _ExternT> int codecvt<_InternT, _ExternT, encoding_state>:: do_encoding() const throw() { int __ret = 0; if (sizeof(_ExternT) <= sizeof(_InternT)) __ret = sizeof(_InternT) / sizeof(_ExternT); return __ret; } template<typename _InternT, typename _ExternT> bool codecvt<_InternT, _ExternT, encoding_state>:: do_always_noconv() const throw() { return false; } template<typename _InternT, typename _ExternT> int codecvt<_InternT, _ExternT, encoding_state>:: do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const { return std::min(__max, static_cast<size_t>(__end - __from)); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 74. Garbled text for codecvt::do_max_length template<typename _InternT, typename _ExternT> int codecvt<_InternT, _ExternT, encoding_state>:: do_max_length() const throw() { return 1; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/numeric 0000644 00000011173 15146341150 0007453 0 ustar 00 // Numeric extensions -*- C++ -*- // Copyright (C) 2002-2018 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 * 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 ext/numeric * This file is a GNU extension to the Standard C++ Library (possibly * containing extensions from the HP/SGI STL subset). */ #ifndef _EXT_NUMERIC #define _EXT_NUMERIC 1 #pragma GCC system_header #include <bits/concept_check.h> #include <numeric> #include <ext/functional> // For identity_element namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Returns __x ** __n, where __n >= 0. _Note that "multiplication" // is required to be associative, but not necessarily commutative. template<typename _Tp, typename _Integer, typename _MonoidOperation> _Tp __power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) { if (__n == 0) return identity_element(__monoid_op); else { while ((__n & 1) == 0) { __n >>= 1; __x = __monoid_op(__x, __x); } _Tp __result = __x; __n >>= 1; while (__n != 0) { __x = __monoid_op(__x, __x); if ((__n & 1) != 0) __result = __monoid_op(__result, __x); __n >>= 1; } return __result; } } template<typename _Tp, typename _Integer> inline _Tp __power(_Tp __x, _Integer __n) { return __power(__x, __n, std::multiplies<_Tp>()); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ // Alias for the internal name __power. Note that power is an extension, // not part of the C++ standard. template<typename _Tp, typename _Integer, typename _MonoidOperation> inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __monoid_op) { return __power(__x, __n, __monoid_op); } /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ template<typename _Tp, typename _Integer> inline _Tp power(_Tp __x, _Integer __n) { return __power(__x, __n); } #if __cplusplus >= 201103L using std::iota; #else /** * This is an SGI extension. * @ingroup SGIextensions * @doctodo */ // iota is not part of the C++ standard. It is an extension. template<typename _ForwardIter, typename _Tp> void iota(_ForwardIter __first, _ForwardIter __last, _Tp __value) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<_ForwardIter>) __glibcxx_function_requires(_ConvertibleConcept<_Tp, typename std::iterator_traits<_ForwardIter>::value_type>) while (__first != __last) *__first++ = __value++; } #endif // C++11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/ext/hash_set 0000644 00000041453 15146341150 0007613 0 ustar 00 // Hashing set implementation -*- C++ -*- // Copyright (C) 2001-2018 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_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) 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_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(); } 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(); } 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 c++/8/list 0000644 00000005042 15146341150 0006162 0 ustar 00 // <list> -*- C++ -*- // Copyright (C) 2001-2018 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/list * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_LIST #define _GLIBCXX_LIST 1 #pragma GCC system_header #include <bits/stl_algobase.h> #include <bits/allocator.h> #include <bits/range_access.h> #include <bits/stl_list.h> #include <bits/list.tcc> #ifdef _GLIBCXX_DEBUG # include <debug/list> #endif #ifdef _GLIBCXX_PROFILE # include <profile/list> #endif #endif /* _GLIBCXX_LIST */ c++/8/ratio 0000644 00000046656 15146341150 0006345 0 ustar 00 // ratio -*- C++ -*- // Copyright (C) 2008-2018 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/ratio * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_RATIO #define _GLIBCXX_RATIO 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <type_traits> #include <cstdint> #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup ratio Rational Arithmetic * @ingroup utilities * * Compile time representation of finite rational numbers. * @{ */ template<intmax_t _Pn> struct __static_sign : integral_constant<intmax_t, (_Pn < 0) ? -1 : 1> { }; template<intmax_t _Pn> struct __static_abs : integral_constant<intmax_t, _Pn * __static_sign<_Pn>::value> { }; template<intmax_t _Pn, intmax_t _Qn> struct __static_gcd : __static_gcd<_Qn, (_Pn % _Qn)> { }; template<intmax_t _Pn> struct __static_gcd<_Pn, 0> : integral_constant<intmax_t, __static_abs<_Pn>::value> { }; template<intmax_t _Qn> struct __static_gcd<0, _Qn> : integral_constant<intmax_t, __static_abs<_Qn>::value> { }; // Let c = 2^(half # of bits in an intmax_t) // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0 // The multiplication of N and M becomes, // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0 // Multiplication is safe if each term and the sum of the terms // is representable by intmax_t. template<intmax_t _Pn, intmax_t _Qn> struct __safe_multiply { private: static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); static const uintmax_t __a0 = __static_abs<_Pn>::value % __c; static const uintmax_t __a1 = __static_abs<_Pn>::value / __c; static const uintmax_t __b0 = __static_abs<_Qn>::value % __c; static const uintmax_t __b1 = __static_abs<_Qn>::value / __c; static_assert(__a1 == 0 || __b1 == 0, "overflow in multiplication"); static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1), "overflow in multiplication"); static_assert(__b0 * __a0 <= __INTMAX_MAX__, "overflow in multiplication"); static_assert((__a0 * __b1 + __b0 * __a1) * __c <= __INTMAX_MAX__ - __b0 * __a0, "overflow in multiplication"); public: static const intmax_t value = _Pn * _Qn; }; // Some double-precision utilities, where numbers are represented as // __hi*2^(8*sizeof(uintmax_t)) + __lo. template<uintmax_t __hi1, uintmax_t __lo1, uintmax_t __hi2, uintmax_t __lo2> struct __big_less : integral_constant<bool, (__hi1 < __hi2 || (__hi1 == __hi2 && __lo1 < __lo2))> { }; template<uintmax_t __hi1, uintmax_t __lo1, uintmax_t __hi2, uintmax_t __lo2> struct __big_add { static constexpr uintmax_t __lo = __lo1 + __lo2; static constexpr uintmax_t __hi = (__hi1 + __hi2 + (__lo1 + __lo2 < __lo1)); // carry }; // Subtract a number from a bigger one. template<uintmax_t __hi1, uintmax_t __lo1, uintmax_t __hi2, uintmax_t __lo2> struct __big_sub { static_assert(!__big_less<__hi1, __lo1, __hi2, __lo2>::value, "Internal library error"); static constexpr uintmax_t __lo = __lo1 - __lo2; static constexpr uintmax_t __hi = (__hi1 - __hi2 - (__lo1 < __lo2)); // carry }; // Same principle as __safe_multiply. template<uintmax_t __x, uintmax_t __y> struct __big_mul { private: static constexpr uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); static constexpr uintmax_t __x0 = __x % __c; static constexpr uintmax_t __x1 = __x / __c; static constexpr uintmax_t __y0 = __y % __c; static constexpr uintmax_t __y1 = __y / __c; static constexpr uintmax_t __x0y0 = __x0 * __y0; static constexpr uintmax_t __x0y1 = __x0 * __y1; static constexpr uintmax_t __x1y0 = __x1 * __y0; static constexpr uintmax_t __x1y1 = __x1 * __y1; static constexpr uintmax_t __mix = __x0y1 + __x1y0; // possible carry... static constexpr uintmax_t __mix_lo = __mix * __c; static constexpr uintmax_t __mix_hi = __mix / __c + ((__mix < __x0y1) ? __c : 0); // ... added here typedef __big_add<__mix_hi, __mix_lo, __x1y1, __x0y0> _Res; public: static constexpr uintmax_t __hi = _Res::__hi; static constexpr uintmax_t __lo = _Res::__lo; }; // Adapted from __udiv_qrnnd_c in longlong.h // This version assumes that the high bit of __d is 1. template<uintmax_t __n1, uintmax_t __n0, uintmax_t __d> struct __big_div_impl { private: static_assert(__d >= (uintmax_t(1) << (sizeof(intmax_t) * 8 - 1)), "Internal library error"); static_assert(__n1 < __d, "Internal library error"); static constexpr uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); static constexpr uintmax_t __d1 = __d / __c; static constexpr uintmax_t __d0 = __d % __c; static constexpr uintmax_t __q1x = __n1 / __d1; static constexpr uintmax_t __r1x = __n1 % __d1; static constexpr uintmax_t __m = __q1x * __d0; static constexpr uintmax_t __r1y = __r1x * __c + __n0 / __c; static constexpr uintmax_t __r1z = __r1y + __d; static constexpr uintmax_t __r1 = ((__r1y < __m) ? ((__r1z >= __d) && (__r1z < __m)) ? (__r1z + __d) : __r1z : __r1y) - __m; static constexpr uintmax_t __q1 = __q1x - ((__r1y < __m) ? ((__r1z >= __d) && (__r1z < __m)) ? 2 : 1 : 0); static constexpr uintmax_t __q0x = __r1 / __d1; static constexpr uintmax_t __r0x = __r1 % __d1; static constexpr uintmax_t __n = __q0x * __d0; static constexpr uintmax_t __r0y = __r0x * __c + __n0 % __c; static constexpr uintmax_t __r0z = __r0y + __d; static constexpr uintmax_t __r0 = ((__r0y < __n) ? ((__r0z >= __d) && (__r0z < __n)) ? (__r0z + __d) : __r0z : __r0y) - __n; static constexpr uintmax_t __q0 = __q0x - ((__r0y < __n) ? ((__r0z >= __d) && (__r0z < __n)) ? 2 : 1 : 0); public: static constexpr uintmax_t __quot = __q1 * __c + __q0; static constexpr uintmax_t __rem = __r0; private: typedef __big_mul<__quot, __d> _Prod; typedef __big_add<_Prod::__hi, _Prod::__lo, 0, __rem> _Sum; static_assert(_Sum::__hi == __n1 && _Sum::__lo == __n0, "Internal library error"); }; template<uintmax_t __n1, uintmax_t __n0, uintmax_t __d> struct __big_div { private: static_assert(__d != 0, "Internal library error"); static_assert(sizeof (uintmax_t) == sizeof (unsigned long long), "This library calls __builtin_clzll on uintmax_t, which " "is unsafe on your platform. Please complain to " "http://gcc.gnu.org/bugzilla/"); static constexpr int __shift = __builtin_clzll(__d); static constexpr int __coshift_ = sizeof(uintmax_t) * 8 - __shift; static constexpr int __coshift = (__shift != 0) ? __coshift_ : 0; static constexpr uintmax_t __c1 = uintmax_t(1) << __shift; static constexpr uintmax_t __c2 = uintmax_t(1) << __coshift; static constexpr uintmax_t __new_d = __d * __c1; static constexpr uintmax_t __new_n0 = __n0 * __c1; static constexpr uintmax_t __n1_shifted = (__n1 % __d) * __c1; static constexpr uintmax_t __n0_top = (__shift != 0) ? (__n0 / __c2) : 0; static constexpr uintmax_t __new_n1 = __n1_shifted + __n0_top; typedef __big_div_impl<__new_n1, __new_n0, __new_d> _Res; public: static constexpr uintmax_t __quot_hi = __n1 / __d; static constexpr uintmax_t __quot_lo = _Res::__quot; static constexpr uintmax_t __rem = _Res::__rem / __c1; private: typedef __big_mul<__quot_lo, __d> _P0; typedef __big_mul<__quot_hi, __d> _P1; typedef __big_add<_P0::__hi, _P0::__lo, _P1::__lo, __rem> _Sum; // No overflow. static_assert(_P1::__hi == 0, "Internal library error"); static_assert(_Sum::__hi >= _P0::__hi, "Internal library error"); // Matches the input data. static_assert(_Sum::__hi == __n1 && _Sum::__lo == __n0, "Internal library error"); static_assert(__rem < __d, "Internal library error"); }; /** * @brief Provides compile-time rational arithmetic. * * This class template represents any finite rational number with a * numerator and denominator representable by compile-time constants of * type intmax_t. The ratio is simplified when instantiated. * * For example: * @code * std::ratio<7,-21>::num == -1; * std::ratio<7,-21>::den == 3; * @endcode * */ template<intmax_t _Num, intmax_t _Den = 1> struct ratio { static_assert(_Den != 0, "denominator cannot be zero"); static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__, "out of range"); // Note: sign(N) * abs(N) == N static constexpr intmax_t num = _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value; static constexpr intmax_t den = __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value; typedef ratio<num, den> type; }; template<intmax_t _Num, intmax_t _Den> constexpr intmax_t ratio<_Num, _Den>::num; template<intmax_t _Num, intmax_t _Den> constexpr intmax_t ratio<_Num, _Den>::den; template<typename _R1, typename _R2> struct __ratio_multiply { private: static const intmax_t __gcd1 = __static_gcd<_R1::num, _R2::den>::value; static const intmax_t __gcd2 = __static_gcd<_R2::num, _R1::den>::value; public: typedef ratio< __safe_multiply<(_R1::num / __gcd1), (_R2::num / __gcd2)>::value, __safe_multiply<(_R1::den / __gcd2), (_R2::den / __gcd1)>::value> type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template<typename _R1, typename _R2> constexpr intmax_t __ratio_multiply<_R1, _R2>::num; template<typename _R1, typename _R2> constexpr intmax_t __ratio_multiply<_R1, _R2>::den; /// ratio_multiply template<typename _R1, typename _R2> using ratio_multiply = typename __ratio_multiply<_R1, _R2>::type; template<typename _R1, typename _R2> struct __ratio_divide { static_assert(_R2::num != 0, "division by 0"); typedef typename __ratio_multiply< _R1, ratio<_R2::den, _R2::num>>::type type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template<typename _R1, typename _R2> constexpr intmax_t __ratio_divide<_R1, _R2>::num; template<typename _R1, typename _R2> constexpr intmax_t __ratio_divide<_R1, _R2>::den; /// ratio_divide template<typename _R1, typename _R2> using ratio_divide = typename __ratio_divide<_R1, _R2>::type; /// ratio_equal template<typename _R1, typename _R2> struct ratio_equal : integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den> { }; /// ratio_not_equal template<typename _R1, typename _R2> struct ratio_not_equal : integral_constant<bool, !ratio_equal<_R1, _R2>::value> { }; // Both numbers are positive. template<typename _R1, typename _R2, typename _Left = __big_mul<_R1::num,_R2::den>, typename _Right = __big_mul<_R2::num,_R1::den> > struct __ratio_less_impl_1 : integral_constant<bool, __big_less<_Left::__hi, _Left::__lo, _Right::__hi, _Right::__lo>::value> { }; template<typename _R1, typename _R2, bool = (_R1::num == 0 || _R2::num == 0 || (__static_sign<_R1::num>::value != __static_sign<_R2::num>::value)), bool = (__static_sign<_R1::num>::value == -1 && __static_sign<_R2::num>::value == -1)> struct __ratio_less_impl : __ratio_less_impl_1<_R1, _R2>::type { }; template<typename _R1, typename _R2> struct __ratio_less_impl<_R1, _R2, true, false> : integral_constant<bool, _R1::num < _R2::num> { }; template<typename _R1, typename _R2> struct __ratio_less_impl<_R1, _R2, false, true> : __ratio_less_impl_1<ratio<-_R2::num, _R2::den>, ratio<-_R1::num, _R1::den> >::type { }; /// ratio_less template<typename _R1, typename _R2> struct ratio_less : __ratio_less_impl<_R1, _R2>::type { }; /// ratio_less_equal template<typename _R1, typename _R2> struct ratio_less_equal : integral_constant<bool, !ratio_less<_R2, _R1>::value> { }; /// ratio_greater template<typename _R1, typename _R2> struct ratio_greater : integral_constant<bool, ratio_less<_R2, _R1>::value> { }; /// ratio_greater_equal template<typename _R1, typename _R2> struct ratio_greater_equal : integral_constant<bool, !ratio_less<_R1, _R2>::value> { }; #if __cplusplus > 201402L template <typename _R1, typename _R2> inline constexpr bool ratio_equal_v = ratio_equal<_R1, _R2>::value; template <typename _R1, typename _R2> inline constexpr bool ratio_not_equal_v = ratio_not_equal<_R1, _R2>::value; template <typename _R1, typename _R2> inline constexpr bool ratio_less_v = ratio_less<_R1, _R2>::value; template <typename _R1, typename _R2> inline constexpr bool ratio_less_equal_v = ratio_less_equal<_R1, _R2>::value; template <typename _R1, typename _R2> inline constexpr bool ratio_greater_v = ratio_greater<_R1, _R2>::value; template <typename _R1, typename _R2> inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<_R1, _R2>::value; #endif // C++17 template<typename _R1, typename _R2, bool = (_R1::num >= 0), bool = (_R2::num >= 0), bool = ratio_less<ratio<__static_abs<_R1::num>::value, _R1::den>, ratio<__static_abs<_R2::num>::value, _R2::den> >::value> struct __ratio_add_impl { private: typedef typename __ratio_add_impl< ratio<-_R1::num, _R1::den>, ratio<-_R2::num, _R2::den> >::type __t; public: typedef ratio<-__t::num, __t::den> type; }; // True addition of nonnegative numbers. template<typename _R1, typename _R2, bool __b> struct __ratio_add_impl<_R1, _R2, true, true, __b> { private: static constexpr uintmax_t __g = __static_gcd<_R1::den, _R2::den>::value; static constexpr uintmax_t __d2 = _R2::den / __g; typedef __big_mul<_R1::den, __d2> __d; typedef __big_mul<_R1::num, _R2::den / __g> __x; typedef __big_mul<_R2::num, _R1::den / __g> __y; typedef __big_add<__x::__hi, __x::__lo, __y::__hi, __y::__lo> __n; static_assert(__n::__hi >= __x::__hi, "Internal library error"); typedef __big_div<__n::__hi, __n::__lo, __g> __ng; static constexpr uintmax_t __g2 = __static_gcd<__ng::__rem, __g>::value; typedef __big_div<__n::__hi, __n::__lo, __g2> __n_final; static_assert(__n_final::__rem == 0, "Internal library error"); static_assert(__n_final::__quot_hi == 0 && __n_final::__quot_lo <= __INTMAX_MAX__, "overflow in addition"); typedef __big_mul<_R1::den / __g2, __d2> __d_final; static_assert(__d_final::__hi == 0 && __d_final::__lo <= __INTMAX_MAX__, "overflow in addition"); public: typedef ratio<__n_final::__quot_lo, __d_final::__lo> type; }; template<typename _R1, typename _R2> struct __ratio_add_impl<_R1, _R2, false, true, true> : __ratio_add_impl<_R2, _R1> { }; // True subtraction of nonnegative numbers yielding a nonnegative result. template<typename _R1, typename _R2> struct __ratio_add_impl<_R1, _R2, true, false, false> { private: static constexpr uintmax_t __g = __static_gcd<_R1::den, _R2::den>::value; static constexpr uintmax_t __d2 = _R2::den / __g; typedef __big_mul<_R1::den, __d2> __d; typedef __big_mul<_R1::num, _R2::den / __g> __x; typedef __big_mul<-_R2::num, _R1::den / __g> __y; typedef __big_sub<__x::__hi, __x::__lo, __y::__hi, __y::__lo> __n; typedef __big_div<__n::__hi, __n::__lo, __g> __ng; static constexpr uintmax_t __g2 = __static_gcd<__ng::__rem, __g>::value; typedef __big_div<__n::__hi, __n::__lo, __g2> __n_final; static_assert(__n_final::__rem == 0, "Internal library error"); static_assert(__n_final::__quot_hi == 0 && __n_final::__quot_lo <= __INTMAX_MAX__, "overflow in addition"); typedef __big_mul<_R1::den / __g2, __d2> __d_final; static_assert(__d_final::__hi == 0 && __d_final::__lo <= __INTMAX_MAX__, "overflow in addition"); public: typedef ratio<__n_final::__quot_lo, __d_final::__lo> type; }; template<typename _R1, typename _R2> struct __ratio_add { typedef typename __ratio_add_impl<_R1, _R2>::type type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template<typename _R1, typename _R2> constexpr intmax_t __ratio_add<_R1, _R2>::num; template<typename _R1, typename _R2> constexpr intmax_t __ratio_add<_R1, _R2>::den; /// ratio_add template<typename _R1, typename _R2> using ratio_add = typename __ratio_add<_R1, _R2>::type; template<typename _R1, typename _R2> struct __ratio_subtract { typedef typename __ratio_add< _R1, ratio<-_R2::num, _R2::den>>::type type; static constexpr intmax_t num = type::num; static constexpr intmax_t den = type::den; }; template<typename _R1, typename _R2> constexpr intmax_t __ratio_subtract<_R1, _R2>::num; template<typename _R1, typename _R2> constexpr intmax_t __ratio_subtract<_R1, _R2>::den; /// ratio_subtract template<typename _R1, typename _R2> using ratio_subtract = typename __ratio_subtract<_R1, _R2>::type; typedef ratio<1, 1000000000000000000> atto; typedef ratio<1, 1000000000000000> femto; typedef ratio<1, 1000000000000> pico; typedef ratio<1, 1000000000> nano; typedef ratio<1, 1000000> micro; typedef ratio<1, 1000> milli; typedef ratio<1, 100> centi; typedef ratio<1, 10> deci; typedef ratio< 10, 1> deca; typedef ratio< 100, 1> hecto; typedef ratio< 1000, 1> kilo; typedef ratio< 1000000, 1> mega; typedef ratio< 1000000000, 1> giga; typedef ratio< 1000000000000, 1> tera; typedef ratio< 1000000000000000, 1> peta; typedef ratio< 1000000000000000000, 1> exa; // @} group ratio _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif //_GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif //_GLIBCXX_RATIO c++/8/cstdbool 0000644 00000002571 15146341150 0007024 0 ustar 00 // <cstdbool> -*- C++ -*- // Copyright (C) 2007-2018 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/cstdbool * This is a Standard C++ Library header. */ #pragma GCC system_header #ifndef _GLIBCXX_CSTDBOOL #define _GLIBCXX_CSTDBOOL 1 #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else # include <bits/c++config.h> # if _GLIBCXX_HAVE_STDBOOL_H # include <stdbool.h> # endif #endif #endif c++/8/cstdlib 0000644 00000014265 15146341150 0006642 0 ustar 00 // -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cstdlib * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c stdlib.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.4.6 C library // #pragma GCC system_header #include <bits/c++config.h> #ifndef _GLIBCXX_CSTDLIB #define _GLIBCXX_CSTDLIB 1 #if !_GLIBCXX_HOSTED // The C standard does not require a freestanding implementation to // provide <stdlib.h>. However, the C++ standard does still require // <cstdlib> -- but only the functionality mentioned in // [lib.support.start.term]. #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 namespace std { extern "C" void abort(void) throw () _GLIBCXX_NORETURN; extern "C" int atexit(void (*)(void)) throw (); extern "C" void exit(int) throw () _GLIBCXX_NORETURN; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT extern "C" int at_quick_exit(void (*)(void)) throw (); # endif # ifdef _GLIBCXX_HAVE_QUICK_EXIT extern "C" void quick_exit(int) throw() _GLIBCXX_NORETURN; # endif #endif } // namespace std #else // Need to ensure this finds the C library's <stdlib.h> not a libstdc++ // wrapper that might already be installed later in the include search path. #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include_next <stdlib.h> #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include <bits/std_abs.h> // Get rid of those macros defined in <stdlib.h> in lieu of real functions. #undef abort #if __cplusplus >= 201703L && defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) # undef aligned_alloc #endif #undef atexit #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT # undef at_quick_exit # endif #endif #undef atof #undef atoi #undef atol #undef bsearch #undef calloc #undef div #undef exit #undef free #undef getenv #undef labs #undef ldiv #undef malloc #undef mblen #undef mbstowcs #undef mbtowc #undef qsort #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_QUICK_EXIT # undef quick_exit # endif #endif #undef rand #undef realloc #undef srand #undef strtod #undef strtol #undef strtoul #undef system #undef wcstombs #undef wctomb extern "C++" { namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::div_t; using ::ldiv_t; using ::abort; #if __cplusplus >= 201703L && defined(_GLIBCXX_HAVE_ALIGNED_ALLOC) using ::aligned_alloc; #endif using ::atexit; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT using ::at_quick_exit; # endif #endif using ::atof; using ::atoi; using ::atol; using ::bsearch; using ::calloc; using ::div; using ::exit; using ::free; using ::getenv; using ::labs; using ::ldiv; using ::malloc; #ifdef _GLIBCXX_HAVE_MBSTATE_T using ::mblen; using ::mbstowcs; using ::mbtowc; #endif // _GLIBCXX_HAVE_MBSTATE_T using ::qsort; #if __cplusplus >= 201103L # ifdef _GLIBCXX_HAVE_QUICK_EXIT using ::quick_exit; # endif #endif using ::rand; using ::realloc; using ::srand; using ::strtod; using ::strtol; using ::strtoul; using ::system; #ifdef _GLIBCXX_USE_WCHAR_T using ::wcstombs; using ::wctomb; #endif // _GLIBCXX_USE_WCHAR_T #ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO inline ldiv_t div(long __i, long __j) { return ldiv(__i, __j); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if _GLIBCXX_USE_C99_STDLIB #undef _Exit #undef llabs #undef lldiv #undef atoll #undef strtoll #undef strtoull #undef strtof #undef strtold namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::lldiv_t; #endif #if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC extern "C" void (_Exit)(int) throw () _GLIBCXX_NORETURN; #endif #if !_GLIBCXX_USE_C99_DYNAMIC using ::_Exit; #endif #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::llabs; inline lldiv_t div(long long __n, long long __d) { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; } using ::lldiv; #endif #if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC extern "C" long long int (atoll)(const char *) throw (); extern "C" long long int (strtoll)(const char * __restrict, char ** __restrict, int) throw (); extern "C" unsigned long long int (strtoull)(const char * __restrict, char ** __restrict, int) throw (); #endif #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::atoll; using ::strtoll; using ::strtoull; #endif using ::strtof; using ::strtold; _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx namespace std { #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::__gnu_cxx::lldiv_t; #endif using ::__gnu_cxx::_Exit; #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::__gnu_cxx::llabs; using ::__gnu_cxx::div; using ::__gnu_cxx::lldiv; #endif using ::__gnu_cxx::atoll; using ::__gnu_cxx::strtof; using ::__gnu_cxx::strtoll; using ::__gnu_cxx::strtoull; using ::__gnu_cxx::strtold; } // namespace std #endif // _GLIBCXX_USE_C99_STDLIB } // extern "C++" #endif // !_GLIBCXX_HOSTED #endif c++/8/tuple 0000644 00000165676 15146341150 0006364 0 ustar 00 // <tuple> -*- C++ -*- // Copyright (C) 2007-2018 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/tuple * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_TUPLE #define _GLIBCXX_TUPLE 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <utility> #include <array> #include <bits/uses_allocator.h> #include <bits/invoke.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup utilities * @{ */ template<typename... _Elements> class tuple; template<typename _Tp> struct __is_empty_non_tuple : is_empty<_Tp> { }; // Using EBO for elements that are tuples causes ambiguous base errors. template<typename _El0, typename... _El> struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; // Use the Empty Base-class Optimization for empty, non-final types. template<typename _Tp> using __empty_not_final = typename conditional<__is_final(_Tp), false_type, __is_empty_non_tuple<_Tp>>::type; template<std::size_t _Idx, typename _Head, bool = __empty_not_final<_Head>::value> struct _Head_base; template<std::size_t _Idx, typename _Head> struct _Head_base<_Idx, _Head, true> : public _Head { constexpr _Head_base() : _Head() { } constexpr _Head_base(const _Head& __h) : _Head(__h) { } constexpr _Head_base(const _Head_base&) = default; constexpr _Head_base(_Head_base&&) = default; template<typename _UHead> constexpr _Head_base(_UHead&& __h) : _Head(std::forward<_UHead>(__h)) { } _Head_base(allocator_arg_t, __uses_alloc0) : _Head() { } template<typename _Alloc> _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) : _Head(allocator_arg, *__a._M_a) { } template<typename _Alloc> _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) : _Head(*__a._M_a) { } template<typename _UHead> _Head_base(__uses_alloc0, _UHead&& __uhead) : _Head(std::forward<_UHead>(__uhead)) { } template<typename _Alloc, typename _UHead> _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } template<typename _Alloc, typename _UHead> _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } static constexpr _Head& _M_head(_Head_base& __b) noexcept { return __b; } static constexpr const _Head& _M_head(const _Head_base& __b) noexcept { return __b; } }; template<std::size_t _Idx, typename _Head> struct _Head_base<_Idx, _Head, false> { constexpr _Head_base() : _M_head_impl() { } constexpr _Head_base(const _Head& __h) : _M_head_impl(__h) { } constexpr _Head_base(const _Head_base&) = default; constexpr _Head_base(_Head_base&&) = default; template<typename _UHead> constexpr _Head_base(_UHead&& __h) : _M_head_impl(std::forward<_UHead>(__h)) { } _Head_base(allocator_arg_t, __uses_alloc0) : _M_head_impl() { } template<typename _Alloc> _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) : _M_head_impl(allocator_arg, *__a._M_a) { } template<typename _Alloc> _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) : _M_head_impl(*__a._M_a) { } template<typename _UHead> _Head_base(__uses_alloc0, _UHead&& __uhead) : _M_head_impl(std::forward<_UHead>(__uhead)) { } template<typename _Alloc, typename _UHead> _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } template<typename _Alloc, typename _UHead> _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } static constexpr _Head& _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } static constexpr const _Head& _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } _Head _M_head_impl; }; /** * Contains the actual implementation of the @c tuple template, stored * as a recursive inheritance hierarchy from the first element (most * derived class) to the last (least derived class). The @c Idx * parameter gives the 0-based index of the element stored at this * point in the hierarchy; we use it to implement a constant-time * get() operation. */ template<std::size_t _Idx, typename... _Elements> struct _Tuple_impl; /** * Recursive tuple implementation. Here we store the @c Head element * and derive from a @c Tuple_impl containing the remaining elements * (which contains the @c Tail). */ template<std::size_t _Idx, typename _Head, typename... _Tail> struct _Tuple_impl<_Idx, _Head, _Tail...> : public _Tuple_impl<_Idx + 1, _Tail...>, private _Head_base<_Idx, _Head> { template<std::size_t, typename...> friend class _Tuple_impl; typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; typedef _Head_base<_Idx, _Head> _Base; static constexpr _Head& _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } static constexpr const _Head& _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } static constexpr _Inherited& _M_tail(_Tuple_impl& __t) noexcept { return __t; } static constexpr const _Inherited& _M_tail(const _Tuple_impl& __t) noexcept { return __t; } constexpr _Tuple_impl() : _Inherited(), _Base() { } explicit constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) : _Inherited(__tail...), _Base(__head) { } template<typename _UHead, typename... _UTail, typename = typename enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> explicit constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail) : _Inherited(std::forward<_UTail>(__tail)...), _Base(std::forward<_UHead>(__head)) { } constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr _Tuple_impl(_Tuple_impl&& __in) noexcept(__and_<is_nothrow_move_constructible<_Head>, is_nothrow_move_constructible<_Inherited>>::value) : _Inherited(std::move(_M_tail(__in))), _Base(std::forward<_Head>(_M_head(__in))) { } template<typename... _UElements> constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } template<typename _UHead, typename... _UTails> constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) : _Inherited(std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), _Base(std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } template<typename _Alloc> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a), _Base(__tag, __use_alloc<_Head>(__a)) { } template<typename _Alloc> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Head& __head, const _Tail&... __tail) : _Inherited(__tag, __a, __tail...), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } template<typename _Alloc, typename _UHead, typename... _UTail, typename = typename enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _UHead&& __head, _UTail&&... __tail) : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead>(__head)) { } template<typename _Alloc> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl& __in) : _Inherited(__tag, __a, _M_tail(__in)), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } template<typename _Alloc> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl&& __in) : _Inherited(__tag, __a, std::move(_M_tail(__in))), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), std::forward<_Head>(_M_head(__in))) { } template<typename _Alloc, typename _UHead, typename... _UTails> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl<_Idx, _UHead, _UTails...>& __in) : _Inherited(__tag, __a, _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)), _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)) { } template<typename _Alloc, typename _UHead, typename... _UTails> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) : _Inherited(__tag, __a, std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } _Tuple_impl& operator=(const _Tuple_impl& __in) { _M_head(*this) = _M_head(__in); _M_tail(*this) = _M_tail(__in); return *this; } _Tuple_impl& operator=(_Tuple_impl&& __in) noexcept(__and_<is_nothrow_move_assignable<_Head>, is_nothrow_move_assignable<_Inherited>>::value) { _M_head(*this) = std::forward<_Head>(_M_head(__in)); _M_tail(*this) = std::move(_M_tail(__in)); return *this; } template<typename... _UElements> _Tuple_impl& operator=(const _Tuple_impl<_Idx, _UElements...>& __in) { _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); return *this; } template<typename _UHead, typename... _UTails> _Tuple_impl& operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) { _M_head(*this) = std::forward<_UHead> (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); _M_tail(*this) = std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); return *this; } protected: void _M_swap(_Tuple_impl& __in) noexcept(__is_nothrow_swappable<_Head>::value && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) { using std::swap; swap(_M_head(*this), _M_head(__in)); _Inherited::_M_swap(_M_tail(__in)); } }; // Basis case of inheritance recursion. template<std::size_t _Idx, typename _Head> struct _Tuple_impl<_Idx, _Head> : private _Head_base<_Idx, _Head> { template<std::size_t, typename...> friend class _Tuple_impl; typedef _Head_base<_Idx, _Head> _Base; static constexpr _Head& _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } static constexpr const _Head& _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } constexpr _Tuple_impl() : _Base() { } explicit constexpr _Tuple_impl(const _Head& __head) : _Base(__head) { } template<typename _UHead> explicit constexpr _Tuple_impl(_UHead&& __head) : _Base(std::forward<_UHead>(__head)) { } constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr _Tuple_impl(_Tuple_impl&& __in) noexcept(is_nothrow_move_constructible<_Head>::value) : _Base(std::forward<_Head>(_M_head(__in))) { } template<typename _UHead> constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } template<typename _UHead> constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) { } template<typename _Alloc> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) : _Base(__tag, __use_alloc<_Head>(__a)) { } template<typename _Alloc> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Head& __head) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } template<typename _Alloc, typename _UHead> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _UHead&& __head) : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead>(__head)) { } template<typename _Alloc> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl& __in) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } template<typename _Alloc> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl&& __in) : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), std::forward<_Head>(_M_head(__in))) { } template<typename _Alloc, typename _UHead> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl<_Idx, _UHead>& __in) : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } template<typename _Alloc, typename _UHead> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl<_Idx, _UHead>&& __in) : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) { } _Tuple_impl& operator=(const _Tuple_impl& __in) { _M_head(*this) = _M_head(__in); return *this; } _Tuple_impl& operator=(_Tuple_impl&& __in) noexcept(is_nothrow_move_assignable<_Head>::value) { _M_head(*this) = std::forward<_Head>(_M_head(__in)); return *this; } template<typename _UHead> _Tuple_impl& operator=(const _Tuple_impl<_Idx, _UHead>& __in) { _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); return *this; } template<typename _UHead> _Tuple_impl& operator=(_Tuple_impl<_Idx, _UHead>&& __in) { _M_head(*this) = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); return *this; } protected: void _M_swap(_Tuple_impl& __in) noexcept(__is_nothrow_swappable<_Head>::value) { using std::swap; swap(_M_head(*this), _M_head(__in)); } }; // Concept utility functions, reused in conditionally-explicit // constructors. template<bool, typename... _Elements> struct _TC { template<typename... _UElements> static constexpr bool _ConstructibleTuple() { return __and_<is_constructible<_Elements, const _UElements&>...>::value; } template<typename... _UElements> static constexpr bool _ImplicitlyConvertibleTuple() { return __and_<is_convertible<const _UElements&, _Elements>...>::value; } template<typename... _UElements> static constexpr bool _MoveConstructibleTuple() { return __and_<is_constructible<_Elements, _UElements&&>...>::value; } template<typename... _UElements> static constexpr bool _ImplicitlyMoveConvertibleTuple() { return __and_<is_convertible<_UElements&&, _Elements>...>::value; } template<typename _SrcTuple> static constexpr bool _NonNestedTuple() { return __and_<__not_<is_same<tuple<_Elements...>, typename remove_cv< typename remove_reference<_SrcTuple>::type >::type>>, __not_<is_convertible<_SrcTuple, _Elements...>>, __not_<is_constructible<_Elements..., _SrcTuple>> >::value; } template<typename... _UElements> static constexpr bool _NotSameTuple() { return __not_<is_same<tuple<_Elements...>, typename remove_const< typename remove_reference<_UElements...>::type >::type>>::value; } }; template<typename... _Elements> struct _TC<false, _Elements...> { template<typename... _UElements> static constexpr bool _ConstructibleTuple() { return false; } template<typename... _UElements> static constexpr bool _ImplicitlyConvertibleTuple() { return false; } template<typename... _UElements> static constexpr bool _MoveConstructibleTuple() { return false; } template<typename... _UElements> static constexpr bool _ImplicitlyMoveConvertibleTuple() { return false; } template<typename... _UElements> static constexpr bool _NonNestedTuple() { return true; } template<typename... _UElements> static constexpr bool _NotSameTuple() { return true; } }; /// Primary class template, tuple template<typename... _Elements> class tuple : public _Tuple_impl<0, _Elements...> { typedef _Tuple_impl<0, _Elements...> _Inherited; // Used for constraining the default constructor so // that it becomes dependent on the constraints. template<typename _Dummy> struct _TC2 { static constexpr bool _DefaultConstructibleTuple() { return __and_<is_default_constructible<_Elements>...>::value; } static constexpr bool _ImplicitlyDefaultConstructibleTuple() { return __and_<__is_implicitly_default_constructible<_Elements>...> ::value; } }; public: template<typename _Dummy = void, typename enable_if<_TC2<_Dummy>:: _ImplicitlyDefaultConstructibleTuple(), bool>::type = true> constexpr tuple() : _Inherited() { } template<typename _Dummy = void, typename enable_if<_TC2<_Dummy>:: _DefaultConstructibleTuple() && !_TC2<_Dummy>:: _ImplicitlyDefaultConstructibleTuple(), bool>::type = false> explicit constexpr tuple() : _Inherited() { } // Shortcut for the cases where constructors taking _Elements... // need to be constrained. template<typename _Dummy> using _TCC = _TC<is_same<_Dummy, void>::value, _Elements...>; template<typename _Dummy = void, typename enable_if< _TCC<_Dummy>::template _ConstructibleTuple<_Elements...>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>() && (sizeof...(_Elements) >= 1), bool>::type=true> constexpr tuple(const _Elements&... __elements) : _Inherited(__elements...) { } template<typename _Dummy = void, typename enable_if< _TCC<_Dummy>::template _ConstructibleTuple<_Elements...>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>() && (sizeof...(_Elements) >= 1), bool>::type=false> explicit constexpr tuple(const _Elements&... __elements) : _Inherited(__elements...) { } // Shortcut for the cases where constructors taking _UElements... // need to be constrained. template<typename... _UElements> using _TMC = _TC<(sizeof...(_Elements) == sizeof...(_UElements)) && (_TC<(sizeof...(_UElements)==1), _Elements...>:: template _NotSameTuple<_UElements...>()), _Elements...>; // Shortcut for the cases where constructors taking tuple<_UElements...> // need to be constrained. template<typename... _UElements> using _TMCT = _TC<(sizeof...(_Elements) == sizeof...(_UElements)) && !is_same<tuple<_Elements...>, tuple<_UElements...>>::value, _Elements...>; template<typename... _UElements, typename enable_if< _TMC<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && _TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && (sizeof...(_Elements) >= 1), bool>::type=true> constexpr tuple(_UElements&&... __elements) : _Inherited(std::forward<_UElements>(__elements)...) { } template<typename... _UElements, typename enable_if< _TMC<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && !_TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && (sizeof...(_Elements) >= 1), bool>::type=false> explicit constexpr tuple(_UElements&&... __elements) : _Inherited(std::forward<_UElements>(__elements)...) { } constexpr tuple(const tuple&) = default; constexpr tuple(tuple&&) = default; // Shortcut for the cases where constructors taking tuples // must avoid creating temporaries. template<typename _Dummy> using _TNTC = _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1, _Elements...>; template<typename... _UElements, typename _Dummy = void, typename enable_if<_TMCT<_UElements...>::template _ConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple<const tuple<_UElements...>&>(), bool>::type=true> constexpr tuple(const tuple<_UElements...>& __in) : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) { } template<typename... _UElements, typename _Dummy = void, typename enable_if<_TMCT<_UElements...>::template _ConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple<const tuple<_UElements...>&>(), bool>::type=false> explicit constexpr tuple(const tuple<_UElements...>& __in) : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) { } template<typename... _UElements, typename _Dummy = void, typename enable_if<_TMCT<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple<tuple<_UElements...>&&>(), bool>::type=true> constexpr tuple(tuple<_UElements...>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } template<typename... _UElements, typename _Dummy = void, typename enable_if<_TMCT<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple<tuple<_UElements...>&&>(), bool>::type=false> explicit constexpr tuple(tuple<_UElements...>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } // Allocator-extended constructors. template<typename _Alloc> tuple(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a) { } template<typename _Alloc, typename _Dummy = void, typename enable_if< _TCC<_Dummy>::template _ConstructibleTuple<_Elements...>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, const _Elements&... __elements) : _Inherited(__tag, __a, __elements...) { } template<typename _Alloc, typename _Dummy = void, typename enable_if< _TCC<_Dummy>::template _ConstructibleTuple<_Elements...>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_Elements...>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const _Elements&... __elements) : _Inherited(__tag, __a, __elements...) { } template<typename _Alloc, typename... _UElements, typename enable_if<_TMC<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && _TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, _UElements&&... __elements) : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) { } template<typename _Alloc, typename... _UElements, typename enable_if<_TMC<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && !_TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, _UElements&&... __elements) : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) { } template<typename _Alloc> tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } template<typename _Alloc> tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } template<typename _Alloc, typename _Dummy = void, typename... _UElements, typename enable_if<_TMCT<_UElements...>::template _ConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple<tuple<_UElements...>&&>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_UElements...>& __in) : _Inherited(__tag, __a, static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) { } template<typename _Alloc, typename _Dummy = void, typename... _UElements, typename enable_if<_TMCT<_UElements...>::template _ConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple<tuple<_UElements...>&&>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_UElements...>& __in) : _Inherited(__tag, __a, static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) { } template<typename _Alloc, typename _Dummy = void, typename... _UElements, typename enable_if<_TMCT<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && _TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple<tuple<_UElements...>&&>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UElements...>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } template<typename _Alloc, typename _Dummy = void, typename... _UElements, typename enable_if<_TMCT<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && !_TMCT<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && _TNTC<_Dummy>::template _NonNestedTuple<tuple<_UElements...>&&>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_UElements...>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } tuple& operator=(const tuple& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } tuple& operator=(tuple&& __in) noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } template<typename... _UElements> typename enable_if<sizeof...(_UElements) == sizeof...(_Elements), tuple&>::type operator=(const tuple<_UElements...>& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } template<typename... _UElements> typename enable_if<sizeof...(_UElements) == sizeof...(_Elements), tuple&>::type operator=(tuple<_UElements...>&& __in) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } void swap(tuple& __in) noexcept(noexcept(__in._M_swap(__in))) { _Inherited::_M_swap(__in); } }; #if __cpp_deduction_guides >= 201606 template<typename... _UTypes> tuple(_UTypes...) -> tuple<_UTypes...>; template<typename _T1, typename _T2> tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>; template<typename _Alloc, typename... _UTypes> tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>; template<typename _Alloc, typename _T1, typename _T2> tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>; template<typename _Alloc, typename... _UTypes> tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>; #endif // Explicit specialization, zero-element tuple. template<> class tuple<> { public: void swap(tuple&) noexcept { /* no-op */ } // We need the default since we're going to define no-op // allocator constructors. tuple() = default; // No-op allocator constructors. template<typename _Alloc> tuple(allocator_arg_t, const _Alloc&) { } template<typename _Alloc> tuple(allocator_arg_t, const _Alloc&, const tuple&) { } }; /// Partial specialization, 2-element tuple. /// Includes construction and assignment from a pair. template<typename _T1, typename _T2> class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> { typedef _Tuple_impl<0, _T1, _T2> _Inherited; public: template <typename _U1 = _T1, typename _U2 = _T2, typename enable_if<__and_< __is_implicitly_default_constructible<_U1>, __is_implicitly_default_constructible<_U2>> ::value, bool>::type = true> constexpr tuple() : _Inherited() { } template <typename _U1 = _T1, typename _U2 = _T2, typename enable_if< __and_< is_default_constructible<_U1>, is_default_constructible<_U2>, __not_< __and_<__is_implicitly_default_constructible<_U1>, __is_implicitly_default_constructible<_U2>>>> ::value, bool>::type = false> explicit constexpr tuple() : _Inherited() { } // Shortcut for the cases where constructors taking _T1, _T2 // need to be constrained. template<typename _Dummy> using _TCC = _TC<is_same<_Dummy, void>::value, _T1, _T2>; template<typename _Dummy = void, typename enable_if<_TCC<_Dummy>::template _ConstructibleTuple<_T1, _T2>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type = true> constexpr tuple(const _T1& __a1, const _T2& __a2) : _Inherited(__a1, __a2) { } template<typename _Dummy = void, typename enable_if<_TCC<_Dummy>::template _ConstructibleTuple<_T1, _T2>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type = false> explicit constexpr tuple(const _T1& __a1, const _T2& __a2) : _Inherited(__a1, __a2) { } // Shortcut for the cases where constructors taking _U1, _U2 // need to be constrained. using _TMC = _TC<true, _T1, _T2>; template<typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>() && !is_same<typename decay<_U1>::type, allocator_arg_t>::value, bool>::type = true> constexpr tuple(_U1&& __a1, _U2&& __a2) : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } template<typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>() && !is_same<typename decay<_U1>::type, allocator_arg_t>::value, bool>::type = false> explicit constexpr tuple(_U1&& __a1, _U2&& __a2) : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } constexpr tuple(const tuple&) = default; constexpr tuple(tuple&&) = default; template<typename _U1, typename _U2, typename enable_if<_TMC::template _ConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(const tuple<_U1, _U2>& __in) : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } template<typename _U1, typename _U2, typename enable_if<_TMC::template _ConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(const tuple<_U1, _U2>& __in) : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } template<typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(tuple<_U1, _U2>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template<typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(tuple<_U1, _U2>&& __in) : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template<typename _U1, typename _U2, typename enable_if<_TMC::template _ConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(const pair<_U1, _U2>& __in) : _Inherited(__in.first, __in.second) { } template<typename _U1, typename _U2, typename enable_if<_TMC::template _ConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(const pair<_U1, _U2>& __in) : _Inherited(__in.first, __in.second) { } template<typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> constexpr tuple(pair<_U1, _U2>&& __in) : _Inherited(std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } template<typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit constexpr tuple(pair<_U1, _U2>&& __in) : _Inherited(std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } // Allocator-extended constructors. template<typename _Alloc> tuple(allocator_arg_t __tag, const _Alloc& __a) : _Inherited(__tag, __a) { } template<typename _Alloc, typename _Dummy = void, typename enable_if< _TCC<_Dummy>::template _ConstructibleTuple<_T1, _T2>() && _TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type=true> tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1, const _T2& __a2) : _Inherited(__tag, __a, __a1, __a2) { } template<typename _Alloc, typename _Dummy = void, typename enable_if< _TCC<_Dummy>::template _ConstructibleTuple<_T1, _T2>() && !_TCC<_Dummy>::template _ImplicitlyConvertibleTuple<_T1, _T2>(), bool>::type=false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1, const _T2& __a2) : _Inherited(__tag, __a, __a1, __a2) { } template<typename _Alloc, typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) : _Inherited(__tag, __a, std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } template<typename _Alloc, typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) : _Inherited(__tag, __a, std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } template<typename _Alloc> tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } template<typename _Alloc> tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } template<typename _Alloc, typename _U1, typename _U2, typename enable_if<_TMC::template _ConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1, _U2>& __in) : _Inherited(__tag, __a, static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } template<typename _Alloc, typename _U1, typename _U2, typename enable_if<_TMC::template _ConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1, _U2>& __in) : _Inherited(__tag, __a, static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } template<typename _Alloc, typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template<typename _Alloc, typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } template<typename _Alloc, typename _U1, typename _U2, typename enable_if<_TMC::template _ConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>& __in) : _Inherited(__tag, __a, __in.first, __in.second) { } template<typename _Alloc, typename _U1, typename _U2, typename enable_if<_TMC::template _ConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>& __in) : _Inherited(__tag, __a, __in.first, __in.second) { } template<typename _Alloc, typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && _TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = true> tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) : _Inherited(__tag, __a, std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } template<typename _Alloc, typename _U1, typename _U2, typename enable_if<_TMC::template _MoveConstructibleTuple<_U1, _U2>() && !_TMC::template _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), bool>::type = false> explicit tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) : _Inherited(__tag, __a, std::forward<_U1>(__in.first), std::forward<_U2>(__in.second)) { } tuple& operator=(const tuple& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } tuple& operator=(tuple&& __in) noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } template<typename _U1, typename _U2> tuple& operator=(const tuple<_U1, _U2>& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } template<typename _U1, typename _U2> tuple& operator=(tuple<_U1, _U2>&& __in) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; } template<typename _U1, typename _U2> tuple& operator=(const pair<_U1, _U2>& __in) { this->_M_head(*this) = __in.first; this->_M_tail(*this)._M_head(*this) = __in.second; return *this; } template<typename _U1, typename _U2> tuple& operator=(pair<_U1, _U2>&& __in) { this->_M_head(*this) = std::forward<_U1>(__in.first); this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); return *this; } void swap(tuple& __in) noexcept(noexcept(__in._M_swap(__in))) { _Inherited::_M_swap(__in); } }; /// class tuple_size template<typename... _Elements> struct tuple_size<tuple<_Elements...>> : public integral_constant<std::size_t, sizeof...(_Elements)> { }; #if __cplusplus > 201402L template <typename _Tp> inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; #endif /** * Recursive case for tuple_element: strip off the first element in * the tuple and retrieve the (i-1)th element of the remaining tuple. */ template<std::size_t __i, typename _Head, typename... _Tail> struct tuple_element<__i, tuple<_Head, _Tail...> > : tuple_element<__i - 1, tuple<_Tail...> > { }; /** * Basis case for tuple_element: The first element is the one we're seeking. */ template<typename _Head, typename... _Tail> struct tuple_element<0, tuple<_Head, _Tail...> > { typedef _Head type; }; /** * Error case for tuple_element: invalid index. */ template<size_t __i> struct tuple_element<__i, tuple<>> { static_assert(__i < tuple_size<tuple<>>::value, "tuple index is in range"); }; template<std::size_t __i, typename _Head, typename... _Tail> constexpr _Head& __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } template<std::size_t __i, typename _Head, typename... _Tail> constexpr const _Head& __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } /// Return a reference to the ith element of a tuple. template<std::size_t __i, typename... _Elements> constexpr __tuple_element_t<__i, tuple<_Elements...>>& get(tuple<_Elements...>& __t) noexcept { return std::__get_helper<__i>(__t); } /// Return a const reference to the ith element of a const tuple. template<std::size_t __i, typename... _Elements> constexpr const __tuple_element_t<__i, tuple<_Elements...>>& get(const tuple<_Elements...>& __t) noexcept { return std::__get_helper<__i>(__t); } /// Return an rvalue reference to the ith element of a tuple rvalue. template<std::size_t __i, typename... _Elements> constexpr __tuple_element_t<__i, tuple<_Elements...>>&& get(tuple<_Elements...>&& __t) noexcept { typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; return std::forward<__element_type&&>(std::get<__i>(__t)); } /// Return a const rvalue reference to the ith element of a const tuple rvalue. template<std::size_t __i, typename... _Elements> constexpr const __tuple_element_t<__i, tuple<_Elements...>>&& get(const tuple<_Elements...>&& __t) noexcept { typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; return std::forward<const __element_type&&>(std::get<__i>(__t)); } #if __cplusplus > 201103L #define __cpp_lib_tuples_by_type 201304 template<typename _Head, size_t __i, typename... _Tail> constexpr _Head& __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } template<typename _Head, size_t __i, typename... _Tail> constexpr const _Head& __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } /// Return a reference to the unique element of type _Tp of a tuple. template <typename _Tp, typename... _Types> constexpr _Tp& get(tuple<_Types...>& __t) noexcept { return std::__get_helper2<_Tp>(__t); } /// Return a reference to the unique element of type _Tp of a tuple rvalue. template <typename _Tp, typename... _Types> constexpr _Tp&& get(tuple<_Types...>&& __t) noexcept { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } /// Return a const reference to the unique element of type _Tp of a tuple. template <typename _Tp, typename... _Types> constexpr const _Tp& get(const tuple<_Types...>& __t) noexcept { return std::__get_helper2<_Tp>(__t); } /// Return a const reference to the unique element of type _Tp of /// a const tuple rvalue. template <typename _Tp, typename... _Types> constexpr const _Tp&& get(const tuple<_Types...>&& __t) noexcept { return std::forward<const _Tp&&>(std::__get_helper2<_Tp>(__t)); } #endif // This class performs the comparison operations on tuples template<typename _Tp, typename _Up, size_t __i, size_t __size> struct __tuple_compare { static constexpr bool __eq(const _Tp& __t, const _Up& __u) { return bool(std::get<__i>(__t) == std::get<__i>(__u)) && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); } static constexpr bool __less(const _Tp& __t, const _Up& __u) { return bool(std::get<__i>(__t) < std::get<__i>(__u)) || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); } }; template<typename _Tp, typename _Up, size_t __size> struct __tuple_compare<_Tp, _Up, __size, __size> { static constexpr bool __eq(const _Tp&, const _Up&) { return true; } static constexpr bool __less(const _Tp&, const _Up&) { return false; } }; template<typename... _TElements, typename... _UElements> constexpr bool operator==(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { static_assert(sizeof...(_TElements) == sizeof...(_UElements), "tuple objects can only be compared if they have equal sizes."); using __compare = __tuple_compare<tuple<_TElements...>, tuple<_UElements...>, 0, sizeof...(_TElements)>; return __compare::__eq(__t, __u); } template<typename... _TElements, typename... _UElements> constexpr bool operator<(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { static_assert(sizeof...(_TElements) == sizeof...(_UElements), "tuple objects can only be compared if they have equal sizes."); using __compare = __tuple_compare<tuple<_TElements...>, tuple<_UElements...>, 0, sizeof...(_TElements)>; return __compare::__less(__t, __u); } template<typename... _TElements, typename... _UElements> constexpr bool operator!=(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return !(__t == __u); } template<typename... _TElements, typename... _UElements> constexpr bool operator>(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return __u < __t; } template<typename... _TElements, typename... _UElements> constexpr bool operator<=(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return !(__u < __t); } template<typename... _TElements, typename... _UElements> constexpr bool operator>=(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) { return !(__t < __u); } // NB: DR 705. template<typename... _Elements> constexpr tuple<typename __decay_and_strip<_Elements>::__type...> make_tuple(_Elements&&... __args) { typedef tuple<typename __decay_and_strip<_Elements>::__type...> __result_type; return __result_type(std::forward<_Elements>(__args)...); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2275. Why is forward_as_tuple not constexpr? template<typename... _Elements> constexpr tuple<_Elements&&...> forward_as_tuple(_Elements&&... __args) noexcept { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } template<size_t, typename, typename, size_t> struct __make_tuple_impl; template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> : __make_tuple_impl<_Idx + 1, tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, _Tuple, _Nm> { }; template<std::size_t _Nm, typename _Tuple, typename... _Tp> struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> { typedef tuple<_Tp...> __type; }; template<typename _Tuple> struct __do_make_tuple : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value> { }; // Returns the std::tuple equivalent of a tuple-like type. template<typename _Tuple> struct __make_tuple : public __do_make_tuple<typename std::remove_cv <typename std::remove_reference<_Tuple>::type>::type> { }; // Combines several std::tuple's into a single one. template<typename...> struct __combine_tuples; template<> struct __combine_tuples<> { typedef tuple<> __type; }; template<typename... _Ts> struct __combine_tuples<tuple<_Ts...>> { typedef tuple<_Ts...> __type; }; template<typename... _T1s, typename... _T2s, typename... _Rem> struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> { typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, _Rem...>::__type __type; }; // Computes the result type of tuple_cat given a set of tuple-like types. template<typename... _Tpls> struct __tuple_cat_result { typedef typename __combine_tuples <typename __make_tuple<_Tpls>::__type...>::__type __type; }; // Helper to determine the index set for the first tuple-like // type of a given set. template<typename...> struct __make_1st_indices; template<> struct __make_1st_indices<> { typedef std::_Index_tuple<> __type; }; template<typename _Tp, typename... _Tpls> struct __make_1st_indices<_Tp, _Tpls...> { typedef typename std::_Build_index_tuple<std::tuple_size< typename std::remove_reference<_Tp>::type>::value>::__type __type; }; // Performs the actual concatenation by step-wise expanding tuple-like // objects into the elements, which are finally forwarded into the // result tuple. template<typename _Ret, typename _Indices, typename... _Tpls> struct __tuple_concater; template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> { template<typename... _Us> static constexpr _Ret _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) { typedef typename __make_1st_indices<_Tpls...>::__type __idx; typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; return __next::_S_do(std::forward<_Tpls>(__tps)..., std::forward<_Us>(__us)..., std::get<_Is>(std::forward<_Tp>(__tp))...); } }; template<typename _Ret> struct __tuple_concater<_Ret, std::_Index_tuple<>> { template<typename... _Us> static constexpr _Ret _S_do(_Us&&... __us) { return _Ret(std::forward<_Us>(__us)...); } }; /// tuple_cat template<typename... _Tpls, typename = typename enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> constexpr auto tuple_cat(_Tpls&&... __tpls) -> typename __tuple_cat_result<_Tpls...>::__type { typedef typename __tuple_cat_result<_Tpls...>::__type __ret; typedef typename __make_1st_indices<_Tpls...>::__type __idx; typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; return __concater::_S_do(std::forward<_Tpls>(__tpls)...); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2301. Why is tie not constexpr? /// tie template<typename... _Elements> constexpr tuple<_Elements&...> tie(_Elements&... __args) noexcept { return tuple<_Elements&...>(__args...); } /// swap template<typename... _Elements> inline #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 // Constrained free swap overload, see p0185r1 typename enable_if<__and_<__is_swappable<_Elements>...>::value >::type #else void #endif swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 template<typename... _Elements> typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete; #endif // A class (and instance) which can be used in 'tie' when an element // of a tuple is not required. // _GLIBCXX14_CONSTEXPR // 2933. PR for LWG 2773 could be clearer struct _Swallow_assign { template<class _Tp> _GLIBCXX14_CONSTEXPR const _Swallow_assign& operator=(const _Tp&) const { return *this; } }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2773. Making std::ignore constexpr _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{}; /// Partial specialization for tuples template<typename... _Types, typename _Alloc> struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; // See stl_pair.h... template<class _T1, class _T2> template<typename... _Args1, typename... _Args2> inline pair<_T1, _T2>:: pair(piecewise_construct_t, tuple<_Args1...> __first, tuple<_Args2...> __second) : pair(__first, __second, typename _Build_index_tuple<sizeof...(_Args1)>::__type(), typename _Build_index_tuple<sizeof...(_Args2)>::__type()) { } template<class _T1, class _T2> template<typename... _Args1, std::size_t... _Indexes1, typename... _Args2, std::size_t... _Indexes2> inline pair<_T1, _T2>:: pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) { } #if __cplusplus > 201402L # define __cpp_lib_apply 201603 template <typename _Fn, typename _Tuple, size_t... _Idx> constexpr decltype(auto) __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>) { return std::__invoke(std::forward<_Fn>(__f), std::get<_Idx>(std::forward<_Tuple>(__t))...); } template <typename _Fn, typename _Tuple> constexpr decltype(auto) apply(_Fn&& __f, _Tuple&& __t) { using _Indices = make_index_sequence<tuple_size_v<decay_t<_Tuple>>>; return std::__apply_impl(std::forward<_Fn>(__f), std::forward<_Tuple>(__t), _Indices{}); } #define __cpp_lib_make_from_tuple 201606 template <typename _Tp, typename _Tuple, size_t... _Idx> constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>) { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); } template <typename _Tp, typename _Tuple> constexpr _Tp make_from_tuple(_Tuple&& __t) { return __make_from_tuple_impl<_Tp>( std::forward<_Tuple>(__t), make_index_sequence<tuple_size_v<decay_t<_Tuple>>>{}); } #endif // C++17 /// @} _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_TUPLE c++/8/parallel/settings.h 0000644 00000030252 15146341150 0011072 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/settings.h * @brief Runtime settings and tuning parameters, heuristics to decide * whether to use parallelized algorithms. * This file is a GNU parallel extension to the Standard C++ Library. * * @section parallelization_decision * The decision whether to run an algorithm in parallel. * * There are several ways the user can switch on and __off the parallel * execution of an algorithm, both at compile- and run-time. * * Only sequential execution can be forced at compile-time. This * reduces code size and protects code parts that have * non-thread-safe side effects. * * Ultimately, forcing parallel execution at compile-time makes * sense. Often, the sequential algorithm implementation is used as * a subroutine, so no reduction in code size can be achieved. Also, * the machine the program is run on might have only one processor * core, so to avoid overhead, the algorithm is executed * sequentially. * * To force sequential execution of an algorithm ultimately at * compile-time, the user must add the tag * gnu_parallel::sequential_tag() to the end of the parameter list, * e. g. * * \code * std::sort(__v.begin(), __v.end(), __gnu_parallel::sequential_tag()); * \endcode * * This is compatible with all overloaded algorithm variants. No * additional code will be instantiated, at all. The same holds for * most algorithm calls with iterators not providing random access. * * If the algorithm call is not forced to be executed sequentially * at compile-time, the decision is made at run-time. * The global variable __gnu_parallel::_Settings::algorithm_strategy * is checked. _It is a tristate variable corresponding to: * * a. force_sequential, meaning the sequential algorithm is executed. * b. force_parallel, meaning the parallel algorithm is executed. * c. heuristic * * For heuristic, the parallel algorithm implementation is called * only if the input size is sufficiently large. For most * algorithms, the input size is the (combined) length of the input * sequence(__s). The threshold can be set by the user, individually * for each algorithm. The according variables are called * gnu_parallel::_Settings::[algorithm]_minimal_n . * * For some of the algorithms, there are even more tuning options, * e. g. the ability to choose from multiple algorithm variants. See * below for details. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_SETTINGS_H #define _GLIBCXX_PARALLEL_SETTINGS_H 1 #include <parallel/types.h> /** * @brief Determine at compile(?)-time if the parallel variant of an * algorithm should be called. * @param __c A condition that is convertible to bool that is overruled by * __gnu_parallel::_Settings::algorithm_strategy. Usually a decision * based on the input size. */ #define _GLIBCXX_PARALLEL_CONDITION(__c) \ (__gnu_parallel::_Settings::get().algorithm_strategy \ != __gnu_parallel::force_sequential \ && ((__gnu_parallel::__get_max_threads() > 1 && (__c)) \ || __gnu_parallel::_Settings::get().algorithm_strategy \ == __gnu_parallel::force_parallel)) /* inline bool parallel_condition(bool __c) { bool ret = false; const _Settings& __s = _Settings::get(); if (__s.algorithm_strategy != force_seqential) { if (__s.algorithm_strategy == force_parallel) ret = true; else ret = __get_max_threads() > 1 && __c; } return ret; } */ namespace __gnu_parallel { /// class _Settings /// Run-time settings for the parallel mode including all tunable parameters. struct _Settings { _AlgorithmStrategy algorithm_strategy; _SortAlgorithm sort_algorithm; _PartialSumAlgorithm partial_sum_algorithm; _MultiwayMergeAlgorithm multiway_merge_algorithm; _FindAlgorithm find_algorithm; _SplittingAlgorithm sort_splitting; _SplittingAlgorithm merge_splitting; _SplittingAlgorithm multiway_merge_splitting; // Per-algorithm settings. /// Minimal input size for accumulate. _SequenceIndex accumulate_minimal_n; /// Minimal input size for adjacent_difference. unsigned int adjacent_difference_minimal_n; /// Minimal input size for count and count_if. _SequenceIndex count_minimal_n; /// Minimal input size for fill. _SequenceIndex fill_minimal_n; /// Block size increase factor for find. double find_increasing_factor; /// Initial block size for find. _SequenceIndex find_initial_block_size; /// Maximal block size for find. _SequenceIndex find_maximum_block_size; /// Start with looking for this many elements sequentially, for find. _SequenceIndex find_sequential_search_size; /// Minimal input size for for_each. _SequenceIndex for_each_minimal_n; /// Minimal input size for generate. _SequenceIndex generate_minimal_n; /// Minimal input size for max_element. _SequenceIndex max_element_minimal_n; /// Minimal input size for merge. _SequenceIndex merge_minimal_n; /// Oversampling factor for merge. unsigned int merge_oversampling; /// Minimal input size for min_element. _SequenceIndex min_element_minimal_n; /// Minimal input size for multiway_merge. _SequenceIndex multiway_merge_minimal_n; /// Oversampling factor for multiway_merge. int multiway_merge_minimal_k; /// Oversampling factor for multiway_merge. unsigned int multiway_merge_oversampling; /// Minimal input size for nth_element. _SequenceIndex nth_element_minimal_n; /// Chunk size for partition. _SequenceIndex partition_chunk_size; /// Chunk size for partition, relative to input size. If > 0.0, /// this value overrides partition_chunk_size. double partition_chunk_share; /// Minimal input size for partition. _SequenceIndex partition_minimal_n; /// Minimal input size for partial_sort. _SequenceIndex partial_sort_minimal_n; /// Ratio for partial_sum. Assume "sum and write result" to be /// this factor slower than just "sum". float partial_sum_dilation; /// Minimal input size for partial_sum. unsigned int partial_sum_minimal_n; /// Minimal input size for random_shuffle. unsigned int random_shuffle_minimal_n; /// Minimal input size for replace and replace_if. _SequenceIndex replace_minimal_n; /// Minimal input size for set_difference. _SequenceIndex set_difference_minimal_n; /// Minimal input size for set_intersection. _SequenceIndex set_intersection_minimal_n; /// Minimal input size for set_symmetric_difference. _SequenceIndex set_symmetric_difference_minimal_n; /// Minimal input size for set_union. _SequenceIndex set_union_minimal_n; /// Minimal input size for parallel sorting. _SequenceIndex sort_minimal_n; /// Oversampling factor for parallel std::sort (MWMS). unsigned int sort_mwms_oversampling; /// Such many samples to take to find a good pivot (quicksort). unsigned int sort_qs_num_samples_preset; /// Maximal subsequence __length to switch to unbalanced __base case. /// Applies to std::sort with dynamically load-balanced quicksort. _SequenceIndex sort_qsb_base_case_maximal_n; /// Minimal input size for parallel std::transform. _SequenceIndex transform_minimal_n; /// Minimal input size for unique_copy. _SequenceIndex unique_copy_minimal_n; _SequenceIndex workstealing_chunk_size; // Hardware dependent tuning parameters. /// size of the L1 cache in bytes (underestimation). unsigned long long L1_cache_size; /// size of the L2 cache in bytes (underestimation). unsigned long long L2_cache_size; /// size of the Translation Lookaside Buffer (underestimation). unsigned int TLB_size; /// Overestimation of cache line size. Used to avoid false /// sharing, i.e. elements of different threads are at least this /// amount apart. unsigned int cache_line_size; // Statistics. /// The number of stolen ranges in load-balanced quicksort. _SequenceIndex qsb_steals; /// Minimal input size for search and search_n. _SequenceIndex search_minimal_n; /// Block size scale-down factor with respect to current position. float find_scale_factor; /// Get the global settings. _GLIBCXX_CONST static const _Settings& get() throw(); /// Set the global settings. static void set(_Settings&) throw(); explicit _Settings() : algorithm_strategy(heuristic), sort_algorithm(MWMS), partial_sum_algorithm(LINEAR), multiway_merge_algorithm(LOSER_TREE), find_algorithm(CONSTANT_SIZE_BLOCKS), sort_splitting(EXACT), merge_splitting(EXACT), multiway_merge_splitting(EXACT), accumulate_minimal_n(1000), adjacent_difference_minimal_n(1000), count_minimal_n(1000), fill_minimal_n(1000), find_increasing_factor(2.0), find_initial_block_size(256), find_maximum_block_size(8192), find_sequential_search_size(256), for_each_minimal_n(1000), generate_minimal_n(1000), max_element_minimal_n(1000), merge_minimal_n(1000), merge_oversampling(10), min_element_minimal_n(1000), multiway_merge_minimal_n(1000), multiway_merge_minimal_k(2), multiway_merge_oversampling(10), nth_element_minimal_n(1000), partition_chunk_size(1000), partition_chunk_share(0.0), partition_minimal_n(1000), partial_sort_minimal_n(1000), partial_sum_dilation(1.0f), partial_sum_minimal_n(1000), random_shuffle_minimal_n(1000), replace_minimal_n(1000), set_difference_minimal_n(1000), set_intersection_minimal_n(1000), set_symmetric_difference_minimal_n(1000), set_union_minimal_n(1000), sort_minimal_n(1000), sort_mwms_oversampling(10), sort_qs_num_samples_preset(100), sort_qsb_base_case_maximal_n(100), transform_minimal_n(1000), unique_copy_minimal_n(10000), workstealing_chunk_size(100), L1_cache_size(16 << 10), L2_cache_size(256 << 10), TLB_size(128), cache_line_size(64), qsb_steals(0), search_minimal_n(1000), find_scale_factor(0.01f) { } }; } #endif /* _GLIBCXX_PARALLEL_SETTINGS_H */ c++/8/parallel/set_operations.h 0000644 00000034376 15146341150 0012303 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/set_operations.h * @brief Parallel implementations of set operations for random-access * iterators. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Marius Elvert and Felix Bondarenko. #ifndef _GLIBCXX_PARALLEL_SET_OPERATIONS_H #define _GLIBCXX_PARALLEL_SET_OPERATIONS_H 1 #include <omp.h> #include <parallel/settings.h> #include <parallel/multiseq_selection.h> namespace __gnu_parallel { template<typename _IIter, typename _OutputIterator> _OutputIterator __copy_tail(std::pair<_IIter, _IIter> __b, std::pair<_IIter, _IIter> __e, _OutputIterator __r) { if (__b.first != __e.first) { do { *__r++ = *__b.first++; } while (__b.first != __e.first); } else { while (__b.second != __e.second) *__r++ = *__b.second++; } return __r; } template<typename _IIter, typename _OutputIterator, typename _Compare> struct __symmetric_difference_func { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; __symmetric_difference_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { *__r = *__a; ++__a; ++__r; } else if (_M_comp(*__c, *__a)) { *__r = *__c; ++__c; ++__r; } else { ++__a; ++__c; } } return std::copy(__c, __d, std::copy(__a, __b, __r)); } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; ++__counter; } else if (_M_comp(*__c, *__a)) { ++__c; ++__counter; } else { ++__a; ++__c; } } return __counter + (__b - __a) + (__d - __c); } _OutputIterator __first_empty(_IIter __c, _IIter __d, _OutputIterator __out) const { return std::copy(__c, __d, __out); } _OutputIterator __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const { return std::copy(__a, __b, __out); } }; template<typename _IIter, typename _OutputIterator, typename _Compare> struct __difference_func { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; __difference_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { *__r = *__a; ++__a; ++__r; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; } } return std::copy(__a, __b, __r); } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; ++__counter; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; } } return __counter + (__b - __a); } _OutputIterator __first_empty(_IIter, _IIter, _OutputIterator __out) const { return __out; } _OutputIterator __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const { return std::copy(__a, __b, __out); } }; template<typename _IIter, typename _OutputIterator, typename _Compare> struct __intersection_func { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; __intersection_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; } else if (_M_comp(*__c, *__a)) { ++__c; } else { *__r = *__a; ++__a; ++__c; ++__r; } } return __r; } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; ++__counter; } } return __counter; } _OutputIterator __first_empty(_IIter, _IIter, _OutputIterator __out) const { return __out; } _OutputIterator __second_empty(_IIter, _IIter, _OutputIterator __out) const { return __out; } }; template<class _IIter, class _OutputIterator, class _Compare> struct __union_func { typedef typename std::iterator_traits<_IIter>::difference_type _DifferenceType; __union_func(_Compare __comp) : _M_comp(__comp) {} _Compare _M_comp; _OutputIterator _M_invoke(_IIter __a, const _IIter __b, _IIter __c, const _IIter __d, _OutputIterator __r) const { while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { *__r = *__a; ++__a; } else if (_M_comp(*__c, *__a)) { *__r = *__c; ++__c; } else { *__r = *__a; ++__a; ++__c; } ++__r; } return std::copy(__c, __d, std::copy(__a, __b, __r)); } _DifferenceType __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const { _DifferenceType __counter = 0; while (__a != __b && __c != __d) { if (_M_comp(*__a, *__c)) { ++__a; } else if (_M_comp(*__c, *__a)) { ++__c; } else { ++__a; ++__c; } ++__counter; } __counter += (__b - __a); __counter += (__d - __c); return __counter; } _OutputIterator __first_empty(_IIter __c, _IIter __d, _OutputIterator __out) const { return std::copy(__c, __d, __out); } _OutputIterator __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const { return std::copy(__a, __b, __out); } }; template<typename _IIter, typename _OutputIterator, typename _Operation> _OutputIterator __parallel_set_operation(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Operation __op) { _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2)) typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename std::pair<_IIter, _IIter> _IteratorPair; if (__begin1 == __end1) return __op.__first_empty(__begin2, __end2, __result); if (__begin2 == __end2) return __op.__second_empty(__begin1, __end1, __result); const _DifferenceType __size = (__end1 - __begin1) + (__end2 - __begin2); const _IteratorPair __sequence[2] = { std::make_pair(__begin1, __end1), std::make_pair(__begin2, __end2) }; _OutputIterator __return_value = __result; _DifferenceType *__borders; _IteratorPair *__block_begins; _DifferenceType* __lengths; _ThreadIndex __num_threads = std::min<_DifferenceType>(__get_max_threads(), std::min(__end1 - __begin1, __end2 - __begin2)); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 2]; __equally_split(__size, __num_threads + 1, __borders); __block_begins = new _IteratorPair[__num_threads + 1]; // Very __start. __block_begins[0] = std::make_pair(__begin1, __begin2); __lengths = new _DifferenceType[__num_threads]; } //single _ThreadIndex __iam = omp_get_thread_num(); // _Result from multiseq_partition. _IIter __offset[2]; const _DifferenceType __rank = __borders[__iam + 1]; multiseq_partition(__sequence, __sequence + 2, __rank, __offset, __op._M_comp); // allowed to read? // together // *(__offset[ 0 ] - 1) == *__offset[ 1 ] if (__offset[ 0 ] != __begin1 && __offset[1] != __end2 && !__op._M_comp(*(__offset[0] - 1), *__offset[1]) && !__op._M_comp(*__offset[1], *(__offset[0] - 1))) { // Avoid split between globally equal elements: move one to // front in first sequence. --__offset[0]; } _IteratorPair __block_end = __block_begins[__iam + 1] = _IteratorPair(__offset[0], __offset[1]); // Make sure all threads have their block_begin result written out. # pragma omp barrier _IteratorPair __block_begin = __block_begins[__iam]; // Begin working for the first block, while the others except // the last start to count. if (__iam == 0) { // The first thread can copy already. __lengths[ __iam ] = __op._M_invoke(__block_begin.first, __block_end.first, __block_begin.second, __block_end.second, __result) - __result; } else { __lengths[ __iam ] = __op.__count(__block_begin.first, __block_end.first, __block_begin.second, __block_end.second); } // Make sure everyone wrote their lengths. # pragma omp barrier _OutputIterator __r = __result; if (__iam == 0) { // Do the last block. for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __r += __lengths[__i]; __block_begin = __block_begins[__num_threads]; // Return the result iterator of the last block. __return_value = __op._M_invoke(__block_begin.first, __end1, __block_begin.second, __end2, __r); } else { for (_ThreadIndex __i = 0; __i < __iam; ++__i) __r += __lengths[ __i ]; // Reset begins for copy pass. __op._M_invoke(__block_begin.first, __block_end.first, __block_begin.second, __block_end.second, __r); } } return __return_value; } template<typename _IIter, typename _OutputIterator, typename _Compare> inline _OutputIterator __parallel_set_union(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __union_func< _IIter, _OutputIterator, _Compare>(__comp)); } template<typename _IIter, typename _OutputIterator, typename _Compare> inline _OutputIterator __parallel_set_intersection(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __intersection_func<_IIter, _OutputIterator, _Compare>(__comp)); } template<typename _IIter, typename _OutputIterator, typename _Compare> inline _OutputIterator __parallel_set_difference(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __difference_func<_IIter, _OutputIterator, _Compare>(__comp)); } template<typename _IIter, typename _OutputIterator, typename _Compare> inline _OutputIterator __parallel_set_symmetric_difference(_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) { return __parallel_set_operation(__begin1, __end1, __begin2, __end2, __result, __symmetric_difference_func<_IIter, _OutputIterator, _Compare>(__comp)); } } #endif /* _GLIBCXX_PARALLEL_SET_OPERATIONS_H */ c++/8/parallel/iterator.h 0000644 00000013056 15146341150 0011066 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/iterator.h * @brief Helper iterator classes for the std::transform() functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_ITERATOR_H #define _GLIBCXX_PARALLEL_ITERATOR_H 1 #include <parallel/basic_iterator.h> #include <bits/stl_pair.h> namespace __gnu_parallel { /** @brief A pair of iterators. The usual iterator operations are * applied to both child iterators. */ template<typename _Iterator1, typename _Iterator2, typename _IteratorCategory> class _IteratorPair : public std::pair<_Iterator1, _Iterator2> { private: typedef std::pair<_Iterator1, _Iterator2> _Base; public: typedef _IteratorCategory iterator_category; typedef void value_type; typedef std::iterator_traits<_Iterator1> _TraitsType; typedef typename _TraitsType::difference_type difference_type; typedef _IteratorPair* pointer; typedef _IteratorPair& reference; _IteratorPair() { } _IteratorPair(const _Iterator1& __first, const _Iterator2& __second) : _Base(__first, __second) { } // Pre-increment operator. _IteratorPair& operator++() { ++_Base::first; ++_Base::second; return *this; } // Post-increment operator. const _IteratorPair operator++(int) { return _IteratorPair(_Base::first++, _Base::second++); } // Pre-decrement operator. _IteratorPair& operator--() { --_Base::first; --_Base::second; return *this; } // Post-decrement operator. const _IteratorPair operator--(int) { return _IteratorPair(_Base::first--, _Base::second--); } // Type conversion. operator _Iterator2() const { return _Base::second; } _IteratorPair& operator=(const _IteratorPair& __other) { _Base::first = __other.first; _Base::second = __other.second; return *this; } _IteratorPair operator+(difference_type __delta) const { return _IteratorPair(_Base::first + __delta, _Base::second + __delta); } difference_type operator-(const _IteratorPair& __other) const { return _Base::first - __other.first; } }; /** @brief A triple of iterators. The usual iterator operations are applied to all three child iterators. */ template<typename _Iterator1, typename _Iterator2, typename _Iterator3, typename _IteratorCategory> class _IteratorTriple { public: typedef _IteratorCategory iterator_category; typedef void value_type; typedef typename std::iterator_traits<_Iterator1>::difference_type difference_type; typedef _IteratorTriple* pointer; typedef _IteratorTriple& reference; _Iterator1 _M_first; _Iterator2 _M_second; _Iterator3 _M_third; _IteratorTriple() { } _IteratorTriple(const _Iterator1& __first, const _Iterator2& __second, const _Iterator3& __third) { _M_first = __first; _M_second = __second; _M_third = __third; } // Pre-increment operator. _IteratorTriple& operator++() { ++_M_first; ++_M_second; ++_M_third; return *this; } // Post-increment operator. const _IteratorTriple operator++(int) { return _IteratorTriple(_M_first++, _M_second++, _M_third++); } // Pre-decrement operator. _IteratorTriple& operator--() { --_M_first; --_M_second; --_M_third; return *this; } // Post-decrement operator. const _IteratorTriple operator--(int) { return _IteratorTriple(_M_first--, _M_second--, _M_third--); } // Type conversion. operator _Iterator3() const { return _M_third; } _IteratorTriple& operator=(const _IteratorTriple& __other) { _M_first = __other._M_first; _M_second = __other._M_second; _M_third = __other._M_third; return *this; } _IteratorTriple operator+(difference_type __delta) const { return _IteratorTriple(_M_first + __delta, _M_second + __delta, _M_third + __delta); } difference_type operator-(const _IteratorTriple& __other) const { return _M_first - __other._M_first; } }; } #endif /* _GLIBCXX_PARALLEL_ITERATOR_H */ c++/8/parallel/random_number.h 0000644 00000010203 15146341150 0012054 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/random_number.h * @brief Random number generator based on the Mersenne twister. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_RANDOM_NUMBER_H #define _GLIBCXX_PARALLEL_RANDOM_NUMBER_H 1 #include <parallel/types.h> #include <tr1/random> #include <limits> namespace __gnu_parallel { /** @brief Random number generator, based on the Mersenne twister. */ class _RandomNumber { private: std::tr1::mt19937 _M_mt; uint64_t _M_supremum; uint64_t _M_rand_sup; double _M_supremum_reciprocal; double _M_rand_sup_reciprocal; // Assumed to be twice as long as the usual random number. uint64_t __cache; // Bit results. int __bits_left; static uint32_t __scale_down(uint64_t __x, #if _GLIBCXX_SCALE_DOWN_FPU uint64_t /*_M_supremum*/, double _M_supremum_reciprocal) #else uint64_t _M_supremum, double /*_M_supremum_reciprocal*/) #endif { #if _GLIBCXX_SCALE_DOWN_FPU return uint32_t(__x * _M_supremum_reciprocal); #else return static_cast<uint32_t>(__x % _M_supremum); #endif } public: /** @brief Default constructor. Seed with 0. */ _RandomNumber() : _M_mt(0), _M_supremum(0x100000000ULL), _M_rand_sup(1ULL << std::numeric_limits<uint32_t>::digits), _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)), _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)), __cache(0), __bits_left(0) { } /** @brief Constructor. * @param __seed Random __seed. * @param _M_supremum Generate integer random numbers in the * interval @c [0,_M_supremum). */ _RandomNumber(uint32_t __seed, uint64_t _M_supremum = 0x100000000ULL) : _M_mt(__seed), _M_supremum(_M_supremum), _M_rand_sup(1ULL << std::numeric_limits<uint32_t>::digits), _M_supremum_reciprocal(double(_M_supremum) / double(_M_rand_sup)), _M_rand_sup_reciprocal(1.0 / double(_M_rand_sup)), __cache(0), __bits_left(0) { } /** @brief Generate unsigned random 32-bit integer. */ uint32_t operator()() { return __scale_down(_M_mt(), _M_supremum, _M_supremum_reciprocal); } /** @brief Generate unsigned random 32-bit integer in the interval @c [0,local_supremum). */ uint32_t operator()(uint64_t local_supremum) { return __scale_down(_M_mt(), local_supremum, double(local_supremum * _M_rand_sup_reciprocal)); } /** @brief Generate a number of random bits, run-time parameter. * @param __bits Number of bits to generate. */ unsigned long __genrand_bits(int __bits) { unsigned long __res = __cache & ((1 << __bits) - 1); __cache = __cache >> __bits; __bits_left -= __bits; if (__bits_left < 32) { __cache |= ((uint64_t(_M_mt())) << __bits_left); __bits_left += 32; } return __res; } }; } // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_RANDOM_NUMBER_H */ c++/8/parallel/partition.h 0000644 00000035161 15146341150 0011247 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/partition.h * @brief Parallel implementation of std::partition(), * std::nth_element(), and std::partial_sort(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_PARTITION_H #define _GLIBCXX_PARALLEL_PARTITION_H 1 #include <parallel/basic_iterator.h> #include <parallel/sort.h> #include <parallel/random_number.h> #include <bits/stl_algo.h> #include <parallel/parallel.h> /** @brief Decide whether to declare certain variables volatile. */ #define _GLIBCXX_VOLATILE volatile namespace __gnu_parallel { /** @brief Parallel implementation of std::partition. * @param __begin Begin iterator of input sequence to split. * @param __end End iterator of input sequence to split. * @param __pred Partition predicate, possibly including some kind * of pivot. * @param __num_threads Maximum number of threads to use for this task. * @return Number of elements not fulfilling the predicate. */ template<typename _RAIter, typename _Predicate> typename std::iterator_traits<_RAIter>::difference_type __parallel_partition(_RAIter __begin, _RAIter __end, _Predicate __pred, _ThreadIndex __num_threads) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; _GLIBCXX_CALL(__n) const _Settings& __s = _Settings::get(); // shared _GLIBCXX_VOLATILE _DifferenceType __left = 0, __right = __n - 1, __dist = __n, __leftover_left, __leftover_right, __leftnew, __rightnew; // just 0 or 1, but int to allow atomic operations int* __reserved_left = 0, * __reserved_right = 0; _DifferenceType __chunk_size = __s.partition_chunk_size; //at least two chunks per thread if (__dist >= 2 * __num_threads * __chunk_size) # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __reserved_left = new int[__num_threads]; __reserved_right = new int[__num_threads]; if (__s.partition_chunk_share > 0.0) __chunk_size = std::max<_DifferenceType> (__s.partition_chunk_size, (double)__n * __s.partition_chunk_share / (double)__num_threads); else __chunk_size = __s.partition_chunk_size; } while (__dist >= 2 * __num_threads * __chunk_size) { # pragma omp single { _DifferenceType __num_chunks = __dist / __chunk_size; for (_ThreadIndex __r = 0; __r < __num_threads; ++__r) { __reserved_left [__r] = 0; // false __reserved_right[__r] = 0; // false } __leftover_left = 0; __leftover_right = 0; } //implicit barrier // Private. _DifferenceType __thread_left, __thread_left_border, __thread_right, __thread_right_border; __thread_left = __left + 1; // Just to satisfy the condition below. __thread_left_border = __thread_left - 1; __thread_right = __n - 1; // Just to satisfy the condition below. __thread_right_border = __thread_right + 1; bool __iam_finished = false; while (!__iam_finished) { if (__thread_left > __thread_left_border) { _DifferenceType __former_dist = __fetch_and_add(&__dist, -__chunk_size); if (__former_dist < __chunk_size) { __fetch_and_add(&__dist, __chunk_size); __iam_finished = true; break; } else { __thread_left = __fetch_and_add(&__left, __chunk_size); __thread_left_border = __thread_left + (__chunk_size - 1); } } if (__thread_right < __thread_right_border) { _DifferenceType __former_dist = __fetch_and_add(&__dist, -__chunk_size); if (__former_dist < __chunk_size) { __fetch_and_add(&__dist, __chunk_size); __iam_finished = true; break; } else { __thread_right = __fetch_and_add(&__right, -__chunk_size); __thread_right_border = __thread_right - (__chunk_size - 1); } } // Swap as usual. while (__thread_left < __thread_right) { while (__pred(__begin[__thread_left]) && __thread_left <= __thread_left_border) ++__thread_left; while (!__pred(__begin[__thread_right]) && __thread_right >= __thread_right_border) --__thread_right; if (__thread_left > __thread_left_border || __thread_right < __thread_right_border) // Fetch new chunk(__s). break; std::iter_swap(__begin + __thread_left, __begin + __thread_right); ++__thread_left; --__thread_right; } } // Now swap the leftover chunks to the right places. if (__thread_left <= __thread_left_border) # pragma omp atomic ++__leftover_left; if (__thread_right >= __thread_right_border) # pragma omp atomic ++__leftover_right; # pragma omp barrier _DifferenceType __leftold = __left, __leftnew = __left - __leftover_left * __chunk_size, __rightold = __right, __rightnew = __right + __leftover_right * __chunk_size; // <=> __thread_left_border + (__chunk_size - 1) >= __leftnew if (__thread_left <= __thread_left_border && __thread_left_border >= __leftnew) { // Chunk already in place, reserve spot. __reserved_left[(__left - (__thread_left_border + 1)) / __chunk_size] = 1; } // <=> __thread_right_border - (__chunk_size - 1) <= __rightnew if (__thread_right >= __thread_right_border && __thread_right_border <= __rightnew) { // Chunk already in place, reserve spot. __reserved_right[((__thread_right_border - 1) - __right) / __chunk_size] = 1; } # pragma omp barrier if (__thread_left <= __thread_left_border && __thread_left_border < __leftnew) { // Find spot and swap. _DifferenceType __swapstart = -1; for (int __r = 0; __r < __leftover_left; ++__r) if (__reserved_left[__r] == 0 && __compare_and_swap(&(__reserved_left[__r]), 0, 1)) { __swapstart = __leftold - (__r + 1) * __chunk_size; break; } #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1); #endif std::swap_ranges(__begin + __thread_left_border - (__chunk_size - 1), __begin + __thread_left_border + 1, __begin + __swapstart); } if (__thread_right >= __thread_right_border && __thread_right_border > __rightnew) { // Find spot and swap _DifferenceType __swapstart = -1; for (int __r = 0; __r < __leftover_right; ++__r) if (__reserved_right[__r] == 0 && __compare_and_swap(&(__reserved_right[__r]), 0, 1)) { __swapstart = __rightold + __r * __chunk_size + 1; break; } #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1); #endif std::swap_ranges(__begin + __thread_right_border, __begin + __thread_right_border + __chunk_size, __begin + __swapstart); } #if _GLIBCXX_PARALLEL_ASSERTIONS # pragma omp barrier # pragma omp single { for (_DifferenceType __r = 0; __r < __leftover_left; ++__r) _GLIBCXX_PARALLEL_ASSERT(__reserved_left[__r] == 1); for (_DifferenceType __r = 0; __r < __leftover_right; ++__r) _GLIBCXX_PARALLEL_ASSERT(__reserved_right[__r] == 1); } #endif __left = __leftnew; __right = __rightnew; __dist = __right - __left + 1; } # pragma omp flush(__left, __right) } // end "recursion" //parallel _DifferenceType __final_left = __left, __final_right = __right; while (__final_left < __final_right) { // Go right until key is geq than pivot. while (__pred(__begin[__final_left]) && __final_left < __final_right) ++__final_left; // Go left until key is less than pivot. while (!__pred(__begin[__final_right]) && __final_left < __final_right) --__final_right; if (__final_left == __final_right) break; std::iter_swap(__begin + __final_left, __begin + __final_right); ++__final_left; --__final_right; } // All elements on the left side are < piv, all elements on the // right are >= piv delete[] __reserved_left; delete[] __reserved_right; // Element "between" __final_left and __final_right might not have // been regarded yet if (__final_left < __n && !__pred(__begin[__final_left])) // Really swapped. return __final_left; else return __final_left + 1; } /** * @brief Parallel implementation of std::nth_element(). * @param __begin Begin iterator of input sequence. * @param __nth _Iterator of element that must be in position afterwards. * @param __end End iterator of input sequence. * @param __comp Comparator. */ template<typename _RAIter, typename _Compare> void __parallel_nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _GLIBCXX_CALL(__end - __begin) _RAIter __split; _RandomNumber __rng; const _Settings& __s = _Settings::get(); _DifferenceType __minimum_length = std::max<_DifferenceType>(2, std::max(__s.nth_element_minimal_n, __s.partition_minimal_n)); // Break if input range to small. while (static_cast<_SequenceIndex>(__end - __begin) >= __minimum_length) { _DifferenceType __n = __end - __begin; _RAIter __pivot_pos = __begin + __rng(__n); // Swap __pivot_pos value to end. if (__pivot_pos != (__end - 1)) std::iter_swap(__pivot_pos, __end - 1); __pivot_pos = __end - 1; // _Compare must have first_value_type, second_value_type, // result_type // _Compare == // __gnu_parallel::_Lexicographic<S, int, // __gnu_parallel::_Less<S, S> > // __pivot_pos == std::pair<S, int>* __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool> __pred(__comp, *__pivot_pos); // Divide, leave pivot unchanged in last place. _RAIter __split_pos1, __split_pos2; __split_pos1 = __begin + __parallel_partition(__begin, __end - 1, __pred, __get_max_threads()); // Left side: < __pivot_pos; __right side: >= __pivot_pos // Swap pivot back to middle. if (__split_pos1 != __pivot_pos) std::iter_swap(__split_pos1, __pivot_pos); __pivot_pos = __split_pos1; // In case all elements are equal, __split_pos1 == 0 if ((__split_pos1 + 1 - __begin) < (__n >> 7) || (__end - __split_pos1) < (__n >> 7)) { // Very unequal split, one part smaller than one 128th // elements not strictly larger than the pivot. __gnu_parallel::__unary_negate<__gnu_parallel:: __binder1st<_Compare, _ValueType, _ValueType, bool>, _ValueType> __pred(__gnu_parallel::__binder1st<_Compare, _ValueType, _ValueType, bool>(__comp, *__pivot_pos)); // Find other end of pivot-equal range. __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1, __end, __pred); } else // Only skip the pivot. __split_pos2 = __split_pos1 + 1; // Compare iterators. if (__split_pos2 <= __nth) __begin = __split_pos2; else if (__nth < __split_pos1) __end = __split_pos1; else break; } // Only at most _Settings::partition_minimal_n __elements __left. __gnu_sequential::nth_element(__begin, __nth, __end, __comp); } /** @brief Parallel implementation of std::partial_sort(). * @param __begin Begin iterator of input sequence. * @param __middle Sort until this position. * @param __end End iterator of input sequence. * @param __comp Comparator. */ template<typename _RAIter, typename _Compare> void __parallel_partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp) { __parallel_nth_element(__begin, __middle, __end, __comp); std::sort(__begin, __middle, __comp); } } //namespace __gnu_parallel #undef _GLIBCXX_VOLATILE #endif /* _GLIBCXX_PARALLEL_PARTITION_H */ c++/8/parallel/multiseq_selection.h 0000644 00000053073 15146341150 0013150 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/multiseq_selection.h * @brief Functions to find elements of a certain global __rank in * multiple sorted sequences. Also serves for splitting such * sequence sets. * * The algorithm description can be found in * * P. J. Varman, S. D. Scheufler, B. R. Iyer, and G. R. Ricard. * Merging Multiple Lists on Hierarchical-Memory Multiprocessors. * Journal of Parallel and Distributed Computing, 12(2):171–177, 1991. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H #define _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H 1 #include <vector> #include <queue> #include <bits/stl_algo.h> namespace __gnu_parallel { /** @brief Compare __a pair of types lexicographically, ascending. */ template<typename _T1, typename _T2, typename _Compare> class _Lexicographic : public std::binary_function<std::pair<_T1, _T2>, std::pair<_T1, _T2>, bool> { private: _Compare& _M_comp; public: _Lexicographic(_Compare& __comp) : _M_comp(__comp) { } bool operator()(const std::pair<_T1, _T2>& __p1, const std::pair<_T1, _T2>& __p2) const { if (_M_comp(__p1.first, __p2.first)) return true; if (_M_comp(__p2.first, __p1.first)) return false; // Firsts are equal. return __p1.second < __p2.second; } }; /** @brief Compare __a pair of types lexicographically, descending. */ template<typename _T1, typename _T2, typename _Compare> class _LexicographicReverse : public std::binary_function<_T1, _T2, bool> { private: _Compare& _M_comp; public: _LexicographicReverse(_Compare& __comp) : _M_comp(__comp) { } bool operator()(const std::pair<_T1, _T2>& __p1, const std::pair<_T1, _T2>& __p2) const { if (_M_comp(__p2.first, __p1.first)) return true; if (_M_comp(__p1.first, __p2.first)) return false; // Firsts are equal. return __p2.second < __p1.second; } }; /** * @brief Splits several sorted sequences at a certain global __rank, * resulting in a splitting point for each sequence. * The sequences are passed via a sequence of random-access * iterator pairs, none of the sequences may be empty. If there * are several equal elements across the split, the ones on the * __left side will be chosen from sequences with smaller number. * @param __begin_seqs Begin of the sequence of iterator pairs. * @param __end_seqs End of the sequence of iterator pairs. * @param __rank The global rank to partition at. * @param __begin_offsets A random-access __sequence __begin where the * __result will be stored in. Each element of the sequence is an * iterator that points to the first element on the greater part of * the respective __sequence. * @param __comp The ordering functor, defaults to std::less<_Tp>. */ template<typename _RanSeqs, typename _RankType, typename _RankIterator, typename _Compare> void multiseq_partition(_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankIterator __begin_offsets, _Compare __comp = std::less< typename std::iterator_traits<typename std::iterator_traits<_RanSeqs>::value_type:: first_type>::value_type>()) // std::less<_Tp> { _GLIBCXX_CALL(__end_seqs - __begin_seqs) typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type _It; typedef typename std::iterator_traits<_RanSeqs>::difference_type _SeqNumber; typedef typename std::iterator_traits<_It>::difference_type _DifferenceType; typedef typename std::iterator_traits<_It>::value_type _ValueType; _Lexicographic<_ValueType, _SeqNumber, _Compare> __lcomp(__comp); _LexicographicReverse<_ValueType, _SeqNumber, _Compare> __lrcomp(__comp); // Number of sequences, number of elements in total (possibly // including padding). _DifferenceType __m = std::distance(__begin_seqs, __end_seqs), __nn = 0, __nmax, __n, __r; for (_SeqNumber __i = 0; __i < __m; __i++) { __nn += std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); _GLIBCXX_PARALLEL_ASSERT( std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second) > 0); } if (__rank == __nn) { for (_SeqNumber __i = 0; __i < __m; __i++) __begin_offsets[__i] = __begin_seqs[__i].second; // Very end. // Return __m - 1; return; } _GLIBCXX_PARALLEL_ASSERT(__m != 0); _GLIBCXX_PARALLEL_ASSERT(__nn != 0); _GLIBCXX_PARALLEL_ASSERT(__rank >= 0); _GLIBCXX_PARALLEL_ASSERT(__rank < __nn); _DifferenceType* __ns = new _DifferenceType[__m]; _DifferenceType* __a = new _DifferenceType[__m]; _DifferenceType* __b = new _DifferenceType[__m]; _DifferenceType __l; __ns[0] = std::distance(__begin_seqs[0].first, __begin_seqs[0].second); __nmax = __ns[0]; for (_SeqNumber __i = 0; __i < __m; __i++) { __ns[__i] = std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); __nmax = std::max(__nmax, __ns[__i]); } __r = __rd_log2(__nmax) + 1; // Pad all lists to this length, at least as long as any ns[__i], // equality iff __nmax = 2^__k - 1. __l = (1ULL << __r) - 1; for (_SeqNumber __i = 0; __i < __m; __i++) { __a[__i] = 0; __b[__i] = __l; } __n = __l / 2; // Invariants: // 0 <= __a[__i] <= __ns[__i], 0 <= __b[__i] <= __l #define __S(__i) (__begin_seqs[__i].first) // Initial partition. std::vector<std::pair<_ValueType, _SeqNumber> > __sample; for (_SeqNumber __i = 0; __i < __m; __i++) if (__n < __ns[__i]) //__sequence long enough __sample.push_back(std::make_pair(__S(__i)[__n], __i)); __gnu_sequential::sort(__sample.begin(), __sample.end(), __lcomp); for (_SeqNumber __i = 0; __i < __m; __i++) //conceptual infinity if (__n >= __ns[__i]) //__sequence too short, conceptual infinity __sample.push_back( std::make_pair(__S(__i)[0] /*__dummy element*/, __i)); _DifferenceType __localrank = __rank / __l; _SeqNumber __j; for (__j = 0; __j < __localrank && ((__n + 1) <= __ns[__sample[__j].second]); ++__j) __a[__sample[__j].second] += __n + 1; for (; __j < __m; __j++) __b[__sample[__j].second] -= __n + 1; // Further refinement. while (__n > 0) { __n /= 2; _SeqNumber __lmax_seq = -1; // to avoid warning const _ValueType* __lmax = 0; // impossible to avoid the warning? for (_SeqNumber __i = 0; __i < __m; __i++) { if (__a[__i] > 0) { if (!__lmax) { __lmax = &(__S(__i)[__a[__i] - 1]); __lmax_seq = __i; } else { // Max, favor rear sequences. if (!__comp(__S(__i)[__a[__i] - 1], *__lmax)) { __lmax = &(__S(__i)[__a[__i] - 1]); __lmax_seq = __i; } } } } _SeqNumber __i; for (__i = 0; __i < __m; __i++) { _DifferenceType __middle = (__b[__i] + __a[__i]) / 2; if (__lmax && __middle < __ns[__i] && __lcomp(std::make_pair(__S(__i)[__middle], __i), std::make_pair(*__lmax, __lmax_seq))) __a[__i] = std::min(__a[__i] + __n + 1, __ns[__i]); else __b[__i] -= __n + 1; } _DifferenceType __leftsize = 0; for (_SeqNumber __i = 0; __i < __m; __i++) __leftsize += __a[__i] / (__n + 1); _DifferenceType __skew = __rank / (__n + 1) - __leftsize; if (__skew > 0) { // Move to the left, find smallest. std::priority_queue<std::pair<_ValueType, _SeqNumber>, std::vector<std::pair<_ValueType, _SeqNumber> >, _LexicographicReverse<_ValueType, _SeqNumber, _Compare> > __pq(__lrcomp); for (_SeqNumber __i = 0; __i < __m; __i++) if (__b[__i] < __ns[__i]) __pq.push(std::make_pair(__S(__i)[__b[__i]], __i)); for (; __skew != 0 && !__pq.empty(); --__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] = std::min(__a[__source] + __n + 1, __ns[__source]); __b[__source] += __n + 1; if (__b[__source] < __ns[__source]) __pq.push( std::make_pair(__S(__source)[__b[__source]], __source)); } } else if (__skew < 0) { // Move to the right, find greatest. std::priority_queue<std::pair<_ValueType, _SeqNumber>, std::vector<std::pair<_ValueType, _SeqNumber> >, _Lexicographic<_ValueType, _SeqNumber, _Compare> > __pq(__lcomp); for (_SeqNumber __i = 0; __i < __m; __i++) if (__a[__i] > 0) __pq.push(std::make_pair(__S(__i)[__a[__i] - 1], __i)); for (; __skew != 0; ++__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] -= __n + 1; __b[__source] -= __n + 1; if (__a[__source] > 0) __pq.push(std::make_pair( __S(__source)[__a[__source] - 1], __source)); } } } // Postconditions: // __a[__i] == __b[__i] in most cases, except when __a[__i] has been // clamped because of having reached the boundary // Now return the result, calculate the offset. // Compare the keys on both edges of the border. // Maximum of left edge, minimum of right edge. _ValueType* __maxleft = 0; _ValueType* __minright = 0; for (_SeqNumber __i = 0; __i < __m; __i++) { if (__a[__i] > 0) { if (!__maxleft) __maxleft = &(__S(__i)[__a[__i] - 1]); else { // Max, favor rear sequences. if (!__comp(__S(__i)[__a[__i] - 1], *__maxleft)) __maxleft = &(__S(__i)[__a[__i] - 1]); } } if (__b[__i] < __ns[__i]) { if (!__minright) __minright = &(__S(__i)[__b[__i]]); else { // Min, favor fore sequences. if (__comp(__S(__i)[__b[__i]], *__minright)) __minright = &(__S(__i)[__b[__i]]); } } } _SeqNumber __seq = 0; for (_SeqNumber __i = 0; __i < __m; __i++) __begin_offsets[__i] = __S(__i) + __a[__i]; delete[] __ns; delete[] __a; delete[] __b; } /** * @brief Selects the element at a certain global __rank from several * sorted sequences. * * The sequences are passed via a sequence of random-access * iterator pairs, none of the sequences may be empty. * @param __begin_seqs Begin of the sequence of iterator pairs. * @param __end_seqs End of the sequence of iterator pairs. * @param __rank The global rank to partition at. * @param __offset The rank of the selected element in the global * subsequence of elements equal to the selected element. If the * selected element is unique, this number is 0. * @param __comp The ordering functor, defaults to std::less. */ template<typename _Tp, typename _RanSeqs, typename _RankType, typename _Compare> _Tp multiseq_selection(_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankType& __offset, _Compare __comp = std::less<_Tp>()) { _GLIBCXX_CALL(__end_seqs - __begin_seqs) typedef typename std::iterator_traits<_RanSeqs>::value_type::first_type _It; typedef typename std::iterator_traits<_RanSeqs>::difference_type _SeqNumber; typedef typename std::iterator_traits<_It>::difference_type _DifferenceType; _Lexicographic<_Tp, _SeqNumber, _Compare> __lcomp(__comp); _LexicographicReverse<_Tp, _SeqNumber, _Compare> __lrcomp(__comp); // Number of sequences, number of elements in total (possibly // including padding). _DifferenceType __m = std::distance(__begin_seqs, __end_seqs); _DifferenceType __nn = 0; _DifferenceType __nmax, __n, __r; for (_SeqNumber __i = 0; __i < __m; __i++) __nn += std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); if (__m == 0 || __nn == 0 || __rank < 0 || __rank >= __nn) { // result undefined if there is no data or __rank is outside bounds throw std::exception(); } _DifferenceType* __ns = new _DifferenceType[__m]; _DifferenceType* __a = new _DifferenceType[__m]; _DifferenceType* __b = new _DifferenceType[__m]; _DifferenceType __l; __ns[0] = std::distance(__begin_seqs[0].first, __begin_seqs[0].second); __nmax = __ns[0]; for (_SeqNumber __i = 0; __i < __m; ++__i) { __ns[__i] = std::distance(__begin_seqs[__i].first, __begin_seqs[__i].second); __nmax = std::max(__nmax, __ns[__i]); } __r = __rd_log2(__nmax) + 1; // Pad all lists to this length, at least as long as any ns[__i], // equality iff __nmax = 2^__k - 1 __l = __round_up_to_pow2(__r) - 1; for (_SeqNumber __i = 0; __i < __m; ++__i) { __a[__i] = 0; __b[__i] = __l; } __n = __l / 2; // Invariants: // 0 <= __a[__i] <= __ns[__i], 0 <= __b[__i] <= __l #define __S(__i) (__begin_seqs[__i].first) // Initial partition. std::vector<std::pair<_Tp, _SeqNumber> > __sample; for (_SeqNumber __i = 0; __i < __m; __i++) if (__n < __ns[__i]) __sample.push_back(std::make_pair(__S(__i)[__n], __i)); __gnu_sequential::sort(__sample.begin(), __sample.end(), __lcomp, sequential_tag()); // Conceptual infinity. for (_SeqNumber __i = 0; __i < __m; __i++) if (__n >= __ns[__i]) __sample.push_back( std::make_pair(__S(__i)[0] /*__dummy element*/, __i)); _DifferenceType __localrank = __rank / __l; _SeqNumber __j; for (__j = 0; __j < __localrank && ((__n + 1) <= __ns[__sample[__j].second]); ++__j) __a[__sample[__j].second] += __n + 1; for (; __j < __m; ++__j) __b[__sample[__j].second] -= __n + 1; // Further refinement. while (__n > 0) { __n /= 2; const _Tp* __lmax = 0; for (_SeqNumber __i = 0; __i < __m; ++__i) { if (__a[__i] > 0) { if (!__lmax) __lmax = &(__S(__i)[__a[__i] - 1]); else { if (__comp(*__lmax, __S(__i)[__a[__i] - 1])) //max __lmax = &(__S(__i)[__a[__i] - 1]); } } } _SeqNumber __i; for (__i = 0; __i < __m; __i++) { _DifferenceType __middle = (__b[__i] + __a[__i]) / 2; if (__lmax && __middle < __ns[__i] && __comp(__S(__i)[__middle], *__lmax)) __a[__i] = std::min(__a[__i] + __n + 1, __ns[__i]); else __b[__i] -= __n + 1; } _DifferenceType __leftsize = 0; for (_SeqNumber __i = 0; __i < __m; ++__i) __leftsize += __a[__i] / (__n + 1); _DifferenceType __skew = __rank / (__n + 1) - __leftsize; if (__skew > 0) { // Move to the left, find smallest. std::priority_queue<std::pair<_Tp, _SeqNumber>, std::vector<std::pair<_Tp, _SeqNumber> >, _LexicographicReverse<_Tp, _SeqNumber, _Compare> > __pq(__lrcomp); for (_SeqNumber __i = 0; __i < __m; ++__i) if (__b[__i] < __ns[__i]) __pq.push(std::make_pair(__S(__i)[__b[__i]], __i)); for (; __skew != 0 && !__pq.empty(); --__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] = std::min(__a[__source] + __n + 1, __ns[__source]); __b[__source] += __n + 1; if (__b[__source] < __ns[__source]) __pq.push( std::make_pair(__S(__source)[__b[__source]], __source)); } } else if (__skew < 0) { // Move to the right, find greatest. std::priority_queue<std::pair<_Tp, _SeqNumber>, std::vector<std::pair<_Tp, _SeqNumber> >, _Lexicographic<_Tp, _SeqNumber, _Compare> > __pq(__lcomp); for (_SeqNumber __i = 0; __i < __m; ++__i) if (__a[__i] > 0) __pq.push(std::make_pair(__S(__i)[__a[__i] - 1], __i)); for (; __skew != 0; ++__skew) { _SeqNumber __source = __pq.top().second; __pq.pop(); __a[__source] -= __n + 1; __b[__source] -= __n + 1; if (__a[__source] > 0) __pq.push(std::make_pair( __S(__source)[__a[__source] - 1], __source)); } } } // Postconditions: // __a[__i] == __b[__i] in most cases, except when __a[__i] has been // clamped because of having reached the boundary // Now return the result, calculate the offset. // Compare the keys on both edges of the border. // Maximum of left edge, minimum of right edge. bool __maxleftset = false, __minrightset = false; // Impossible to avoid the warning? _Tp __maxleft, __minright; for (_SeqNumber __i = 0; __i < __m; ++__i) { if (__a[__i] > 0) { if (!__maxleftset) { __maxleft = __S(__i)[__a[__i] - 1]; __maxleftset = true; } else { // Max. if (__comp(__maxleft, __S(__i)[__a[__i] - 1])) __maxleft = __S(__i)[__a[__i] - 1]; } } if (__b[__i] < __ns[__i]) { if (!__minrightset) { __minright = __S(__i)[__b[__i]]; __minrightset = true; } else { // Min. if (__comp(__S(__i)[__b[__i]], __minright)) __minright = __S(__i)[__b[__i]]; } } } // Minright is the __splitter, in any case. if (!__maxleftset || __comp(__minright, __maxleft)) { // Good luck, everything is split unambiguously. __offset = 0; } else { // We have to calculate an offset. __offset = 0; for (_SeqNumber __i = 0; __i < __m; ++__i) { _DifferenceType lb = std::lower_bound(__S(__i), __S(__i) + __ns[__i], __minright, __comp) - __S(__i); __offset += __a[__i] - lb; } } delete[] __ns; delete[] __a; delete[] __b; return __minright; } } #undef __S #endif /* _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H */ c++/8/parallel/multiway_merge.h 0000644 00000211607 15146341150 0012271 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/multiway_merge.h * @brief Implementation of sequential and parallel multiway merge. * * Explanations on the high-speed merging routines in the appendix of * * P. Sanders. * Fast priority queues for cached memory. * ACM Journal of Experimental Algorithmics, 5, 2000. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Manuel Holtgrewe. #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H #define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H #include <vector> #include <bits/stl_algo.h> #include <parallel/features.h> #include <parallel/parallel.h> #include <parallel/losertree.h> #include <parallel/multiseq_selection.h> #if _GLIBCXX_PARALLEL_ASSERTIONS #include <parallel/checkers.h> #endif /** @brief Length of a sequence described by a pair of iterators. */ #define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first) namespace __gnu_parallel { template<typename _RAIter1, typename _RAIter2, typename _OutputIterator, typename _DifferenceTp, typename _Compare> _OutputIterator __merge_advance(_RAIter1&, _RAIter1, _RAIter2&, _RAIter2, _OutputIterator, _DifferenceTp, _Compare); /** @brief _Iterator wrapper supporting an implicit supremum at the end * of the sequence, dominating all comparisons. * * The implicit supremum comes with a performance cost. * * Deriving from _RAIter is not possible since * _RAIter need not be a class. */ template<typename _RAIter, typename _Compare> class _GuardedIterator { private: /** @brief Current iterator __position. */ _RAIter _M_current; /** @brief End iterator of the sequence. */ _RAIter _M_end; /** @brief _Compare. */ _Compare& __comp; public: /** @brief Constructor. Sets iterator to beginning of sequence. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator provided for associated overloaded * compare operators. */ _GuardedIterator(_RAIter __begin, _RAIter __end, _Compare& __comp) : _M_current(__begin), _M_end(__end), __comp(__comp) { } /** @brief Pre-increment operator. * @return This. */ _GuardedIterator<_RAIter, _Compare>& operator++() { ++_M_current; return *this; } /** @brief Dereference operator. * @return Referenced element. */ typename std::iterator_traits<_RAIter>::value_type& operator*() { return *_M_current; } /** @brief Convert to wrapped iterator. * @return Wrapped iterator. */ operator _RAIter() { return _M_current; } /** @brief Compare two elements referenced by guarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c true if less. */ friend bool operator<(_GuardedIterator<_RAIter, _Compare>& __bi1, _GuardedIterator<_RAIter, _Compare>& __bi2) { if (__bi1._M_current == __bi1._M_end) // __bi1 is sup return __bi2._M_current == __bi2._M_end; // __bi2 is not sup if (__bi2._M_current == __bi2._M_end) // __bi2 is sup return true; return (__bi1.__comp)(*__bi1, *__bi2); // normal compare } /** @brief Compare two elements referenced by guarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c True if less equal. */ friend bool operator<=(_GuardedIterator<_RAIter, _Compare>& __bi1, _GuardedIterator<_RAIter, _Compare>& __bi2) { if (__bi2._M_current == __bi2._M_end) // __bi1 is sup return __bi1._M_current != __bi1._M_end; // __bi2 is not sup if (__bi1._M_current == __bi1._M_end) // __bi2 is sup return false; return !(__bi1.__comp)(*__bi2, *__bi1); // normal compare } }; template<typename _RAIter, typename _Compare> class _UnguardedIterator { private: /** @brief Current iterator __position. */ _RAIter _M_current; /** @brief _Compare. */ _Compare& __comp; public: /** @brief Constructor. Sets iterator to beginning of sequence. * @param __begin Begin iterator of sequence. * @param __end Unused, only for compatibility. * @param __comp Unused, only for compatibility. */ _UnguardedIterator(_RAIter __begin, _RAIter /* __end */, _Compare& __comp) : _M_current(__begin), __comp(__comp) { } /** @brief Pre-increment operator. * @return This. */ _UnguardedIterator<_RAIter, _Compare>& operator++() { ++_M_current; return *this; } /** @brief Dereference operator. * @return Referenced element. */ typename std::iterator_traits<_RAIter>::value_type& operator*() { return *_M_current; } /** @brief Convert to wrapped iterator. * @return Wrapped iterator. */ operator _RAIter() { return _M_current; } /** @brief Compare two elements referenced by unguarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c true if less. */ friend bool operator<(_UnguardedIterator<_RAIter, _Compare>& __bi1, _UnguardedIterator<_RAIter, _Compare>& __bi2) { // Normal compare. return (__bi1.__comp)(*__bi1, *__bi2); } /** @brief Compare two elements referenced by unguarded iterators. * @param __bi1 First iterator. * @param __bi2 Second iterator. * @return @c True if less equal. */ friend bool operator<=(_UnguardedIterator<_RAIter, _Compare>& __bi1, _UnguardedIterator<_RAIter, _Compare>& __bi2) { // Normal compare. return !(__bi1.__comp)(*__bi2, *__bi1); } }; /** @brief Highly efficient 3-way merging procedure. * * Merging is done with the algorithm implementation described by Peter * Sanders. Basically, the idea is to minimize the number of necessary * comparison after merging an element. The implementation trick * that makes this fast is that the order of the sequences is stored * in the instruction pointer (translated into labels in C++). * * This works well for merging up to 4 sequences. * * Note that making the merging stable does @a not come at a * performance hit. * * Whether the merging is done guarded or unguarded is selected by the * used iterator class. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template<template<typename RAI, typename C> class iterator, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> _RAIter3 multiway_merge_3_variant(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length); typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; if (__length == 0) return __target; #if _GLIBCXX_PARALLEL_ASSERTIONS _DifferenceTp __orig_length = __length; #endif iterator<_RAIter1, _Compare> __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp), __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp), __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp); if (__seq0 <= __seq1) { if (__seq1 <= __seq2) goto __s012; else if (__seq2 < __seq0) goto __s201; else goto __s021; } else { if (__seq1 <= __seq2) { if (__seq0 <= __seq2) goto __s102; else goto __s120; } else goto __s210; } #define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a, __b, __c, __c0, __c1) \ __s ## __a ## __b ## __c : \ *__target = *__seq ## __a; \ ++__target; \ --__length; \ ++__seq ## __a; \ if (__length == 0) goto __finish; \ if (__seq ## __a __c0 __seq ## __b) goto __s ## __a ## __b ## __c; \ if (__seq ## __a __c1 __seq ## __c) goto __s ## __b ## __a ## __c; \ goto __s ## __b ## __c ## __a; _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=); _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < ); _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 0, 1, < , < ); _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 0, 2, < , <=); _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 2, 1, <=, <=); _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 1, 0, < , < ); #undef _GLIBCXX_PARALLEL_MERGE_3_CASE __finish: ; #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT( ((_RAIter1)__seq0 - __seqs_begin[0].first) + ((_RAIter1)__seq1 - __seqs_begin[1].first) + ((_RAIter1)__seq2 - __seqs_begin[2].first) == __orig_length); #endif __seqs_begin[0].first = __seq0; __seqs_begin[1].first = __seq1; __seqs_begin[2].first = __seq2; return __target; } /** * @brief Highly efficient 4-way merging procedure. * * Merging is done with the algorithm implementation described by Peter * Sanders. Basically, the idea is to minimize the number of necessary * comparison after merging an element. The implementation trick * that makes this fast is that the order of the sequences is stored * in the instruction pointer (translated into goto labels in C++). * * This works well for merging up to 4 sequences. * * Note that making the merging stable does @a not come at a * performance hit. * * Whether the merging is done guarded or unguarded is selected by the * used iterator class. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template<template<typename RAI, typename C> class iterator, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> _RAIter3 multiway_merge_4_variant(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length); typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; iterator<_RAIter1, _Compare> __seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp), __seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp), __seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp), __seq3(__seqs_begin[3].first, __seqs_begin[3].second, __comp); #define _GLIBCXX_PARALLEL_DECISION(__a, __b, __c, __d) { \ if (__seq ## __d < __seq ## __a) \ goto __s ## __d ## __a ## __b ## __c; \ if (__seq ## __d < __seq ## __b) \ goto __s ## __a ## __d ## __b ## __c; \ if (__seq ## __d < __seq ## __c) \ goto __s ## __a ## __b ## __d ## __c; \ goto __s ## __a ## __b ## __c ## __d; } if (__seq0 <= __seq1) { if (__seq1 <= __seq2) _GLIBCXX_PARALLEL_DECISION(0,1,2,3) else if (__seq2 < __seq0) _GLIBCXX_PARALLEL_DECISION(2,0,1,3) else _GLIBCXX_PARALLEL_DECISION(0,2,1,3) } else { if (__seq1 <= __seq2) { if (__seq0 <= __seq2) _GLIBCXX_PARALLEL_DECISION(1,0,2,3) else _GLIBCXX_PARALLEL_DECISION(1,2,0,3) } else _GLIBCXX_PARALLEL_DECISION(2,1,0,3) } #define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a, __b, __c, __d, \ __c0, __c1, __c2) \ __s ## __a ## __b ## __c ## __d: \ if (__length == 0) goto __finish; \ *__target = *__seq ## __a; \ ++__target; \ --__length; \ ++__seq ## __a; \ if (__seq ## __a __c0 __seq ## __b) \ goto __s ## __a ## __b ## __c ## __d; \ if (__seq ## __a __c1 __seq ## __c) \ goto __s ## __b ## __a ## __c ## __d; \ if (__seq ## __a __c2 __seq ## __d) \ goto __s ## __b ## __c ## __a ## __d; \ goto __s ## __b ## __c ## __d ## __a; _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 1, 3, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 3, 1, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 1, 2, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 2, 1, <=, <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 2, 3, < , <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 3, 2, < , <=, <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 0, 3, <=, < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 3, 0, <=, <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 0, 2, <=, < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 2, 0, <=, <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 1, 3, < , < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 3, 1, < , <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 0, 3, < , < , <=); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 3, 0, < , <=, < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 0, 1, <=, < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 1, 0, <=, < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 1, 2, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 2, 1, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 0, 2, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 2, 0, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 0, 1, < , < , < ); _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 1, 0, < , < , < ); #undef _GLIBCXX_PARALLEL_MERGE_4_CASE #undef _GLIBCXX_PARALLEL_DECISION __finish: ; __seqs_begin[0].first = __seq0; __seqs_begin[1].first = __seq1; __seqs_begin[2].first = __seq2; __seqs_begin[3].first = __seq3; return __target; } /** @brief Multi-way merging procedure for a high branching factor, * guarded case. * * This merging variant uses a LoserTree class as selected by <tt>_LT</tt>. * * Stability is selected through the used LoserTree class <tt>_LT</tt>. * * At least one non-empty sequence is required. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template<typename _LT, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> _RAIter3 multiway_merge_loser_tree(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin); _LT __lt(__k, __comp); // Default value for potentially non-default-constructible types. _ValueType* __arbitrary_element = 0; for (_SeqNumber __t = 0; __t < __k; ++__t) { if(!__arbitrary_element && _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__t]) > 0) __arbitrary_element = &(*__seqs_begin[__t].first); } for (_SeqNumber __t = 0; __t < __k; ++__t) { if (__seqs_begin[__t].first == __seqs_begin[__t].second) __lt.__insert_start(*__arbitrary_element, __t, true); else __lt.__insert_start(*__seqs_begin[__t].first, __t, false); } __lt.__init(); _SeqNumber __source; for (_DifferenceType __i = 0; __i < __length; ++__i) { //take out __source = __lt.__get_min_source(); *(__target++) = *(__seqs_begin[__source].first++); // Feed. if (__seqs_begin[__source].first == __seqs_begin[__source].second) __lt.__delete_min_insert(*__arbitrary_element, true); else // Replace from same __source. __lt.__delete_min_insert(*__seqs_begin[__source].first, false); } return __target; } /** @brief Multi-way merging procedure for a high branching factor, * unguarded case. * * Merging is done using the LoserTree class <tt>_LT</tt>. * * Stability is selected by the used LoserTrees. * * @pre No input will run out of elements during the merge. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template<typename _LT, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> _RAIter3 multiway_merge_loser_tree_unguarded(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits<typename std::iterator_traits< _RAIterIterator>::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; _SeqNumber __k = __seqs_end - __seqs_begin; _LT __lt(__k, __sentinel, __comp); for (_SeqNumber __t = 0; __t < __k; ++__t) { #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first != __seqs_begin[__t].second); #endif __lt.__insert_start(*__seqs_begin[__t].first, __t, false); } __lt.__init(); _SeqNumber __source; #if _GLIBCXX_PARALLEL_ASSERTIONS _DifferenceType __i = 0; #endif _RAIter3 __target_end = __target + __length; while (__target < __target_end) { // Take out. __source = __lt.__get_min_source(); #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(0 <= __source && __source < __k); _GLIBCXX_PARALLEL_ASSERT(__i == 0 || !__comp(*(__seqs_begin[__source].first), *(__target - 1))); #endif // Feed. *(__target++) = *(__seqs_begin[__source].first++); #if _GLIBCXX_PARALLEL_ASSERTIONS ++__i; #endif // Replace from same __source. __lt.__delete_min_insert(*__seqs_begin[__source].first, false); } return __target; } /** @brief Multi-way merging procedure for a high branching factor, * requiring sentinels to exist. * * @tparam UnguardedLoserTree _Loser Tree variant to use for the unguarded * merging. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, less equal than the * total number of elements available. * * @return End iterator of output sequence. */ template<typename UnguardedLoserTree, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> _RAIter3 multiway_merge_loser_tree_sentinel(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits<typename std::iterator_traits< _RAIterIterator>::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef std::iterator_traits<_RAIterIterator> _TraitsType; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; _RAIter3 __target_end; for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) // Move the sequence ends to the sentinel. This has the // effect that the sentinel appears to be within the sequence. Then, // we can use the unguarded variant if we merge out as many // non-sentinel elements as we have. ++((*__s).second); __target_end = multiway_merge_loser_tree_unguarded<UnguardedLoserTree> (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp); #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__target_end == __target + __length); _GLIBCXX_PARALLEL_ASSERT(__is_sorted(__target, __target_end, __comp)); #endif // Restore the sequence ends so the sentinels are not contained in the // sequence any more (see comment in loop above). for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) --((*__s).second); return __target_end; } /** * @brief Traits for determining whether the loser tree should * use pointers or copies. * * The field "_M_use_pointer" is used to determine whether to use pointers * in he loser trees or whether to copy the values into the loser tree. * * The default behavior is to use pointers if the data type is 4 times as * big as the pointer to it. * * Specialize for your data type to customize the behavior. * * Example: * * template<> * struct _LoserTreeTraits<int> * { static const bool _M_use_pointer = false; }; * * template<> * struct _LoserTreeTraits<heavyweight_type> * { static const bool _M_use_pointer = true; }; * * @param _Tp type to give the loser tree traits for. */ template <typename _Tp> struct _LoserTreeTraits { /** * @brief True iff to use pointers instead of values in loser trees. * * The default behavior is to use pointers if the data type is four * times as big as the pointer to it. */ static const bool _M_use_pointer = (sizeof(_Tp) > 4 * sizeof(_Tp*)); }; /** * @brief Switch for 3-way merging with __sentinels turned off. * * Note that 3-way merging is always stable! */ template<bool __sentinels /*default == false*/, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> struct __multiway_merge_3_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_3_variant<_GuardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for 3-way merging with __sentinels turned on. * * Note that 3-way merging is always stable! */ template<typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> struct __multiway_merge_3_variant_sentinel_switch<true, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare> { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_3_variant<_UnguardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for 4-way merging with __sentinels turned off. * * Note that 4-way merging is always stable! */ template<bool __sentinels /*default == false*/, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> struct __multiway_merge_4_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_4_variant<_GuardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for 4-way merging with __sentinels turned on. * * Note that 4-way merging is always stable! */ template<typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> struct __multiway_merge_4_variant_sentinel_switch<true, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare> { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) { return multiway_merge_4_variant<_UnguardedIterator> (__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** * @brief Switch for k-way merging with __sentinels turned on. */ template<bool __sentinels, bool __stable, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> struct __multiway_merge_k_variant_sentinel_switch { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits<typename std::iterator_traits< _RAIterIterator>::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; return multiway_merge_loser_tree_sentinel< typename __gnu_cxx::__conditional_type< _LoserTreeTraits<_ValueType>::_M_use_pointer, _LoserTreePointerUnguarded<__stable, _ValueType, _Compare>, _LoserTreeUnguarded<__stable, _ValueType, _Compare> >::__type> (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp); } }; /** * @brief Switch for k-way merging with __sentinels turned off. */ template<bool __stable, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> struct __multiway_merge_k_variant_sentinel_switch<false, __stable, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare> { _RAIter3 operator()(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits<typename std::iterator_traits< _RAIterIterator>::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; return multiway_merge_loser_tree< typename __gnu_cxx::__conditional_type< _LoserTreeTraits<_ValueType>::_M_use_pointer, _LoserTreePointer<__stable, _ValueType, _Compare>, _LoserTree<__stable, _ValueType, _Compare> >::__type >(__seqs_begin, __seqs_end, __target, __length, __comp); } }; /** @brief Sequential multi-way merging switch. * * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and * runtime settings. * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * @param __sentinel The sequences have __a __sentinel element. * @return End iterator of output sequence. */ template<bool __stable, bool __sentinels, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Compare> _RAIter3 __sequential_multiway_merge(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits<typename std::iterator_traits< _RAIterIterator>::value_type::first_type>::value_type& __sentinel, _DifferenceTp __length, _Compare __comp) { _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; #if _GLIBCXX_PARALLEL_ASSERTIONS for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) { _GLIBCXX_PARALLEL_ASSERT(__is_sorted((*__s).first, (*__s).second, __comp)); } #endif _DifferenceTp __total_length = 0; for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s) __total_length += _GLIBCXX_PARALLEL_LENGTH(*__s); __length = std::min<_DifferenceTp>(__length, __total_length); if(__length == 0) return __target; _RAIter3 __return_target = __target; _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin); switch (__k) { case 0: break; case 1: __return_target = std::copy(__seqs_begin[0].first, __seqs_begin[0].first + __length, __target); __seqs_begin[0].first += __length; break; case 2: __return_target = __merge_advance(__seqs_begin[0].first, __seqs_begin[0].second, __seqs_begin[1].first, __seqs_begin[1].second, __target, __length, __comp); break; case 3: __return_target = __multiway_merge_3_variant_sentinel_switch <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>() (__seqs_begin, __seqs_end, __target, __length, __comp); break; case 4: __return_target = __multiway_merge_4_variant_sentinel_switch <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>() (__seqs_begin, __seqs_end, __target, __length, __comp); break; default: __return_target = __multiway_merge_k_variant_sentinel_switch <__sentinels, __stable, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>() (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp); break; } #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT( __is_sorted(__target, __target + __length, __comp)); #endif return __return_target; } /** * @brief Stable sorting functor. * * Used to reduce code instanciation in multiway_merge_sampling_splitting. */ template<bool __stable, class _RAIter, class _StrictWeakOrdering> struct _SamplingSorter { void operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp) { __gnu_sequential::stable_sort(__first, __last, __comp); } }; /** * @brief Non-__stable sorting functor. * * Used to reduce code instantiation in multiway_merge_sampling_splitting. */ template<class _RAIter, class _StrictWeakOrdering> struct _SamplingSorter<false, _RAIter, _StrictWeakOrdering> { void operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp) { __gnu_sequential::sort(__first, __last, __comp); } }; /** * @brief Sampling based splitting for parallel multiway-merge routine. */ template<bool __stable, typename _RAIterIterator, typename _Compare, typename _DifferenceType> void multiway_merge_sampling_splitting(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _DifferenceType __length, _DifferenceType __total_length, _Compare __comp, std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces) { typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; // __k sequences. const _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin); const _ThreadIndex __num_threads = omp_get_num_threads(); const _DifferenceType __num_samples = __gnu_parallel::_Settings::get().merge_oversampling * __num_threads; _ValueType* __samples = static_cast<_ValueType*> (::operator new(sizeof(_ValueType) * __k * __num_samples)); // Sample. for (_SeqNumber __s = 0; __s < __k; ++__s) for (_DifferenceType __i = 0; __i < __num_samples; ++__i) { _DifferenceType sample_index = static_cast<_DifferenceType> (_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__s]) * (double(__i + 1) / (__num_samples + 1)) * (double(__length) / __total_length)); new(&(__samples[__s * __num_samples + __i])) _ValueType(__seqs_begin[__s].first[sample_index]); } // Sort stable or non-stable, depending on value of template parameter // "__stable". _SamplingSorter<__stable, _ValueType*, _Compare>() (__samples, __samples + (__num_samples * __k), __comp); for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab) // For each slab / processor. for (_SeqNumber __seq = 0; __seq < __k; ++__seq) { // For each sequence. if (__slab > 0) __pieces[__slab][__seq].first = std::upper_bound (__seqs_begin[__seq].first, __seqs_begin[__seq].second, __samples[__num_samples * __k * __slab / __num_threads], __comp) - __seqs_begin[__seq].first; else // Absolute beginning. __pieces[__slab][__seq].first = 0; if ((__slab + 1) < __num_threads) __pieces[__slab][__seq].second = std::upper_bound (__seqs_begin[__seq].first, __seqs_begin[__seq].second, __samples[__num_samples * __k * (__slab + 1) / __num_threads], __comp) - __seqs_begin[__seq].first; else // Absolute end. __pieces[__slab][__seq].second = _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]); } for (_SeqNumber __s = 0; __s < __k; ++__s) for (_DifferenceType __i = 0; __i < __num_samples; ++__i) __samples[__s * __num_samples + __i].~_ValueType(); ::operator delete(__samples); } /** * @brief Exact splitting for parallel multiway-merge routine. * * None of the passed sequences may be empty. */ template<bool __stable, typename _RAIterIterator, typename _Compare, typename _DifferenceType> void multiway_merge_exact_splitting(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _DifferenceType __length, _DifferenceType __total_length, _Compare __comp, std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces) { typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; const bool __tight = (__total_length == __length); // __k sequences. const _SeqNumber __k = __seqs_end - __seqs_begin; const _ThreadIndex __num_threads = omp_get_num_threads(); // (Settings::multiway_merge_splitting // == __gnu_parallel::_Settings::EXACT). std::vector<_RAIter1>* __offsets = new std::vector<_RAIter1>[__num_threads]; std::vector<std::pair<_RAIter1, _RAIter1> > __se(__k); copy(__seqs_begin, __seqs_end, __se.begin()); _DifferenceType* __borders = new _DifferenceType[__num_threads + 1]; __equally_split(__length, __num_threads, __borders); for (_ThreadIndex __s = 0; __s < (__num_threads - 1); ++__s) { __offsets[__s].resize(__k); multiseq_partition(__se.begin(), __se.end(), __borders[__s + 1], __offsets[__s].begin(), __comp); // Last one also needed and available. if (!__tight) { __offsets[__num_threads - 1].resize(__k); multiseq_partition(__se.begin(), __se.end(), _DifferenceType(__length), __offsets[__num_threads - 1].begin(), __comp); } } delete[] __borders; for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab) { // For each slab / processor. for (_SeqNumber __seq = 0; __seq < __k; ++__seq) { // For each sequence. if (__slab == 0) { // Absolute beginning. __pieces[__slab][__seq].first = 0; } else __pieces[__slab][__seq].first = __pieces[__slab - 1][__seq].second; if (!__tight || __slab < (__num_threads - 1)) __pieces[__slab][__seq].second = __offsets[__slab][__seq] - __seqs_begin[__seq].first; else { // __slab == __num_threads - 1 __pieces[__slab][__seq].second = _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]); } } } delete[] __offsets; } /** @brief Parallel multi-way merge routine. * * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor * and runtime settings. * * Must not be called if the number of sequences is 1. * * @tparam _Splitter functor to split input (either __exact or sampling based) * @tparam __stable Stable merging incurs a performance penalty. * @tparam __sentinel Ignored. * * @param __seqs_begin Begin iterator of iterator pair input sequence. * @param __seqs_end End iterator of iterator pair input sequence. * @param __target Begin iterator of output sequence. * @param __comp Comparator. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * @return End iterator of output sequence. */ template<bool __stable, bool __sentinels, typename _RAIterIterator, typename _RAIter3, typename _DifferenceTp, typename _Splitter, typename _Compare> _RAIter3 parallel_multiway_merge(_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _Splitter __splitter, _DifferenceTp __length, _Compare __comp, _ThreadIndex __num_threads) { #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__seqs_end - __seqs_begin > 1); #endif _GLIBCXX_CALL(__length) typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIterIterator> ::difference_type _SeqNumber; typedef typename std::iterator_traits<_RAIterIterator> ::value_type::first_type _RAIter1; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; // Leave only non-empty sequences. typedef std::pair<_RAIter1, _RAIter1> seq_type; seq_type* __ne_seqs = new seq_type[__seqs_end - __seqs_begin]; _SeqNumber __k = 0; _DifferenceType __total_length = 0; for (_RAIterIterator __raii = __seqs_begin; __raii != __seqs_end; ++__raii) { _DifferenceTp __seq_length = _GLIBCXX_PARALLEL_LENGTH(*__raii); if(__seq_length > 0) { __total_length += __seq_length; __ne_seqs[__k++] = *__raii; } } _GLIBCXX_CALL(__total_length) __length = std::min<_DifferenceTp>(__length, __total_length); if (__total_length == 0 || __k == 0) { delete[] __ne_seqs; return __target; } std::vector<std::pair<_DifferenceType, _DifferenceType> >* __pieces; __num_threads = static_cast<_ThreadIndex> (std::min<_DifferenceType>(__num_threads, __total_length)); # pragma omp parallel num_threads (__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); // Thread __t will have to merge pieces[__iam][0..__k - 1] __pieces = new std::vector< std::pair<_DifferenceType, _DifferenceType> >[__num_threads]; for (_ThreadIndex __s = 0; __s < __num_threads; ++__s) __pieces[__s].resize(__k); _DifferenceType __num_samples = __gnu_parallel::_Settings::get().merge_oversampling * __num_threads; __splitter(__ne_seqs, __ne_seqs + __k, __length, __total_length, __comp, __pieces); } //single _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __target_position = 0; for (_SeqNumber __c = 0; __c < __k; ++__c) __target_position += __pieces[__iam][__c].first; seq_type* __chunks = new seq_type[__k]; for (_SeqNumber __s = 0; __s < __k; ++__s) __chunks[__s] = std::make_pair(__ne_seqs[__s].first + __pieces[__iam][__s].first, __ne_seqs[__s].first + __pieces[__iam][__s].second); if(__length > __target_position) __sequential_multiway_merge<__stable, __sentinels> (__chunks, __chunks + __k, __target + __target_position, *(__seqs_begin->second), __length - __target_position, __comp); delete[] __chunks; } // parallel #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT( __is_sorted(__target, __target + __length, __comp)); #endif __k = 0; // Update ends of sequences. for (_RAIterIterator __raii = __seqs_begin; __raii != __seqs_end; ++__raii) { _DifferenceTp __length = _GLIBCXX_PARALLEL_LENGTH(*__raii); if(__length > 0) (*__raii).first += __pieces[__num_threads - 1][__k++].second; } delete[] __pieces; delete[] __ne_seqs; return __target + __length; } /** * @brief Multiway Merge Frontend. * * Merge the sequences specified by seqs_begin and __seqs_end into * __target. __seqs_begin and __seqs_end must point to a sequence of * pairs. These pairs must contain an iterator to the beginning * of a sequence in their first entry and an iterator the _M_end of * the same sequence in their second entry. * * Ties are broken arbitrarily. See stable_multiway_merge for a variant * that breaks ties by sequence number but is slower. * * The first entries of the pairs (i.e. the begin iterators) will be moved * forward. * * The output sequence has to provide enough space for all elements * that are written to it. * * This function will merge the input sequences: * * - not stable * - parallel, depending on the input size and Settings * - using sampling for splitting * - not using sentinels * * Example: * * <pre> * int sequences[10][10]; * for (int __i = 0; __i < 10; ++__i) * for (int __j = 0; __i < 10; ++__j) * sequences[__i][__j] = __j; * * int __out[33]; * std::vector<std::pair<int*> > seqs; * for (int __i = 0; __i < 10; ++__i) * { seqs.push(std::make_pair<int*>(sequences[__i], * sequences[__i] + 10)) } * * multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33); * </pre> * * @see stable_multiway_merge * * @pre All input sequences must be sorted. * @pre Target must provide enough space to merge out length elements or * the number of elements in all sequences, whichever is smaller. * * @post [__target, return __value) contains merged __elements from the * input sequences. * @post return __value - __target = min(__length, number of elements in all * sequences). * * @tparam _RAIterPairIterator iterator over sequence * of pairs of iterators * @tparam _RAIterOut iterator over target sequence * @tparam _DifferenceTp difference type for the sequence * @tparam _Compare strict weak ordering type to compare elements * in sequences * * @param __seqs_begin __begin of sequence __sequence * @param __seqs_end _M_end of sequence __sequence * @param __target target sequence to merge to. * @param __comp strict weak ordering to use for element comparison. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * * @return _M_end iterator of output sequence */ // multiway_merge // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge </* __stable = */ false, /* __sentinels = */ false> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge </* __stable = */ false, /* __sentinels = */ false> (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting</* __stable = */ false, typename std::iterator_traits<_RAIterPairIterator> ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge </* __stable = */ false, /* __sentinels = */ false> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge </* __stable = */ false, /* __sentinels = */ false> (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting</* __stable = */ false, typename std::iterator_traits<_RAIterPairIterator> ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge </* __stable = */ false, /* __sentinels = */ false> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return multiway_merge(__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return multiway_merge(__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // stable_multiway_merge // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge </* __stable = */ true, /* __sentinels = */ false> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge </* __stable = */ true, /* __sentinels = */ false> (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting</* __stable = */ true, typename std::iterator_traits<_RAIterPairIterator> ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge </* __stable = */ true, /* __sentinels = */ false> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge </* __stable = */ true, /* __sentinels = */ false> (__seqs_begin, __seqs_end, __target, multiway_merge_sampling_splitting</* __stable = */ true, typename std::iterator_traits<_RAIterPairIterator> ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge </* __stable = */ true, /* __sentinels = */ false> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return stable_multiway_merge (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut stable_multiway_merge(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return stable_multiway_merge (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } /** * @brief Multiway Merge Frontend. * * Merge the sequences specified by seqs_begin and __seqs_end into * __target. __seqs_begin and __seqs_end must point to a sequence of * pairs. These pairs must contain an iterator to the beginning * of a sequence in their first entry and an iterator the _M_end of * the same sequence in their second entry. * * Ties are broken arbitrarily. See stable_multiway_merge for a variant * that breaks ties by sequence number but is slower. * * The first entries of the pairs (i.e. the begin iterators) will be moved * forward accordingly. * * The output sequence has to provide enough space for all elements * that are written to it. * * This function will merge the input sequences: * * - not stable * - parallel, depending on the input size and Settings * - using sampling for splitting * - using sentinels * * You have to take care that the element the _M_end iterator points to is * readable and contains a value that is greater than any other non-sentinel * value in all sequences. * * Example: * * <pre> * int sequences[10][11]; * for (int __i = 0; __i < 10; ++__i) * for (int __j = 0; __i < 11; ++__j) * sequences[__i][__j] = __j; // __last one is sentinel! * * int __out[33]; * std::vector<std::pair<int*> > seqs; * for (int __i = 0; __i < 10; ++__i) * { seqs.push(std::make_pair<int*>(sequences[__i], * sequences[__i] + 10)) } * * multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33); * </pre> * * @pre All input sequences must be sorted. * @pre Target must provide enough space to merge out length elements or * the number of elements in all sequences, whichever is smaller. * @pre For each @c __i, @c __seqs_begin[__i].second must be the end * marker of the sequence, but also reference the one more __sentinel * element. * * @post [__target, return __value) contains merged __elements from the * input sequences. * @post return __value - __target = min(__length, number of elements in all * sequences). * * @see stable_multiway_merge_sentinels * * @tparam _RAIterPairIterator iterator over sequence * of pairs of iterators * @tparam _RAIterOut iterator over target sequence * @tparam _DifferenceTp difference type for the sequence * @tparam _Compare strict weak ordering type to compare elements * in sequences * * @param __seqs_begin __begin of sequence __sequence * @param __seqs_end _M_end of sequence __sequence * @param __target target sequence to merge to. * @param __comp strict weak ordering to use for element comparison. * @param __length Maximum length to merge, possibly larger than the * number of elements available. * * @return _M_end iterator of output sequence */ // multiway_merge_sentinels // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge </* __stable = */ false, /* __sentinels = */ true> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge </* __stable = */ false, /* __sentinels = */ true> (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting</* __stable = */ false, typename std::iterator_traits<_RAIterPairIterator> ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge </* __stable = */ false, /* __sentinels = */ true> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge </* __stable = */ false, /* __sentinels = */ true> (__seqs_begin, __seqs_end, __target, multiway_merge_sampling_splitting</* __stable = */ false, typename std::iterator_traits<_RAIterPairIterator> ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge </* __stable = */false, /* __sentinels = */ true>( __seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // stable_multiway_merge_sentinels // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute multiway merge *sequentially*. return __sequential_multiway_merge </* __stable = */ true, /* __sentinels = */ true> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge </* __stable = */ true, /* __sentinels = */ true> (__seqs_begin, __seqs_end, __target, multiway_merge_exact_splitting</* __stable = */ true, typename std::iterator_traits<_RAIterPairIterator> ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge </* __stable = */ true, /* __sentinels = */ true> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, sampling_tag __tag) { typedef _DifferenceTp _DifferenceType; _GLIBCXX_CALL(__seqs_end - __seqs_begin) // catch special case: no sequences if (__seqs_begin == __seqs_end) return __target; // Execute merge; maybe parallel, depending on the number of merged // elements and the number of sequences and global thresholds in // Settings. if ((__seqs_end - __seqs_begin > 1) && _GLIBCXX_PARALLEL_CONDITION( ((__seqs_end - __seqs_begin) >= __gnu_parallel::_Settings::get().multiway_merge_minimal_k) && ((_SequenceIndex)__length >= __gnu_parallel::_Settings::get().multiway_merge_minimal_n))) return parallel_multiway_merge </* __stable = */ true, /* __sentinels = */ true> (__seqs_begin, __seqs_end, __target, multiway_merge_sampling_splitting</* __stable = */ true, typename std::iterator_traits<_RAIterPairIterator> ::value_type*, _Compare, _DifferenceTp>, static_cast<_DifferenceType>(__length), __comp, __tag.__get_num_threads()); else return __sequential_multiway_merge </* __stable = */ true, /* __sentinels = */ true> (__seqs_begin, __seqs_end, __target, *(__seqs_begin->second), __length, __comp); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag = parallel_tag(0)) { return stable_multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } // public interface template<typename _RAIterPairIterator, typename _RAIterOut, typename _DifferenceTp, typename _Compare> _RAIterOut stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag) { return stable_multiway_merge_sentinels (__seqs_begin, __seqs_end, __target, __length, __comp, exact_tag(__tag.__get_num_threads())); } }; // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H */ c++/8/parallel/partial_sum.h 0000644 00000016462 15146341150 0011561 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/partial_sum.h * @brief Parallel implementation of std::partial_sum(), i.e. prefix * sums. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_PARTIAL_SUM_H #define _GLIBCXX_PARALLEL_PARTIAL_SUM_H 1 #include <omp.h> #include <new> #include <bits/stl_algobase.h> #include <parallel/parallel.h> #include <parallel/numericfwd.h> namespace __gnu_parallel { // Problem: there is no 0-element given. /** @brief Base case prefix sum routine. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __result Begin iterator of output sequence. * @param __bin_op Associative binary function. * @param __value Start value. Must be passed since the neutral * element is unknown in general. * @return End iterator of output sequence. */ template<typename _IIter, typename _OutputIterator, typename _BinaryOperation> _OutputIterator __parallel_partial_sum_basecase(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, typename std::iterator_traits <_IIter>::value_type __value) { if (__begin == __end) return __result; while (__begin != __end) { __value = __bin_op(__value, *__begin); *__result = __value; ++__result; ++__begin; } return __result; } /** @brief Parallel partial sum implementation, two-phase approach, no recursion. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __result Begin iterator of output sequence. * @param __bin_op Associative binary function. * @param __n Length of sequence. * @return End iterator of output sequence. */ template<typename _IIter, typename _OutputIterator, typename _BinaryOperation> _OutputIterator __parallel_partial_sum_linear(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, typename std::iterator_traits<_IIter>::difference_type __n) { typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; if (__begin == __end) return __result; _ThreadIndex __num_threads = std::min<_DifferenceType>(__get_max_threads(), __n - 1); if (__num_threads < 2) { *__result = *__begin; return __parallel_partial_sum_basecase(__begin + 1, __end, __result + 1, __bin_op, *__begin); } _DifferenceType* __borders; _ValueType* __sums; const _Settings& __s = _Settings::get(); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 2]; if (__s.partial_sum_dilation == 1.0f) __equally_split(__n, __num_threads + 1, __borders); else { _DifferenceType __first_part_length = std::max<_DifferenceType>(1, __n / (1.0f + __s.partial_sum_dilation * __num_threads)); _DifferenceType __chunk_length = (__n - __first_part_length) / __num_threads; _DifferenceType __borderstart = __n - __num_threads * __chunk_length; __borders[0] = 0; for (_ThreadIndex __i = 1; __i < (__num_threads + 1); ++__i) { __borders[__i] = __borderstart; __borderstart += __chunk_length; } __borders[__num_threads + 1] = __n; } __sums = static_cast<_ValueType*>(::operator new(sizeof(_ValueType) * __num_threads)); _OutputIterator __target_end; } //single _ThreadIndex __iam = omp_get_thread_num(); if (__iam == 0) { *__result = *__begin; __parallel_partial_sum_basecase(__begin + 1, __begin + __borders[1], __result + 1, __bin_op, *__begin); ::new(&(__sums[__iam])) _ValueType(*(__result + __borders[1] - 1)); } else { ::new(&(__sums[__iam])) _ValueType(__gnu_parallel::accumulate( __begin + __borders[__iam] + 1, __begin + __borders[__iam + 1], *(__begin + __borders[__iam]), __bin_op, __gnu_parallel::sequential_tag())); } # pragma omp barrier # pragma omp single __parallel_partial_sum_basecase(__sums + 1, __sums + __num_threads, __sums + 1, __bin_op, __sums[0]); # pragma omp barrier // Still same team. __parallel_partial_sum_basecase(__begin + __borders[__iam + 1], __begin + __borders[__iam + 2], __result + __borders[__iam + 1], __bin_op, __sums[__iam]); } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __sums[__i].~_ValueType(); ::operator delete(__sums); delete[] __borders; return __result + __n; } /** @brief Parallel partial sum front-__end. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __result Begin iterator of output sequence. * @param __bin_op Associative binary function. * @return End iterator of output sequence. */ template<typename _IIter, typename _OutputIterator, typename _BinaryOperation> _OutputIterator __parallel_partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op) { _GLIBCXX_CALL(__begin - __end) typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; switch (_Settings::get().partial_sum_algorithm) { case LINEAR: // Need an initial offset. return __parallel_partial_sum_linear(__begin, __end, __result, __bin_op, __n); default: // Partial_sum algorithm not implemented. _GLIBCXX_PARALLEL_ASSERT(0); return __result + __n; } } } #endif /* _GLIBCXX_PARALLEL_PARTIAL_SUM_H */ c++/8/parallel/base.h 0000644 00000030125 15146341150 0010143 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/base.h * @brief Sequential helper functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_BASE_H #define _GLIBCXX_PARALLEL_BASE_H 1 #include <bits/c++config.h> #include <bits/stl_function.h> #include <omp.h> #include <parallel/features.h> #include <parallel/basic_iterator.h> #include <parallel/parallel.h> // Parallel mode namespaces. /** * @namespace std::__parallel * @brief GNU parallel code, replaces standard behavior with parallel behavior. */ namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { } } /** * @namespace __gnu_parallel * @brief GNU parallel code for public use. */ namespace __gnu_parallel { // Import all the parallel versions of components in namespace std. using namespace std::__parallel; } /** * @namespace __gnu_sequential * @brief GNU sequential classes for public use. */ namespace __gnu_sequential { // Import whatever is the serial version. #ifdef _GLIBCXX_PARALLEL using namespace std::_GLIBCXX_STD_A; #else using namespace std; #endif } namespace __gnu_parallel { // NB: Including this file cannot produce (unresolved) symbols from // the OpenMP runtime unless the parallel mode is actually invoked // and active, which imples that the OpenMP runtime is actually // going to be linked in. inline _ThreadIndex __get_max_threads() { _ThreadIndex __i = omp_get_max_threads(); return __i > 1 ? __i : 1; } inline bool __is_parallel(const _Parallelism __p) { return __p != sequential; } /** @brief Calculates the rounded-down logarithm of @c __n for base 2. * @param __n Argument. * @return Returns 0 for any argument <1. */ template<typename _Size> inline _Size __rd_log2(_Size __n) { _Size __k; for (__k = 0; __n > 1; __n >>= 1) ++__k; return __k; } /** @brief Encode two integers into one gnu_parallel::_CASable. * @param __a First integer, to be encoded in the most-significant @c * _CASable_bits/2 bits. * @param __b Second integer, to be encoded in the least-significant * @c _CASable_bits/2 bits. * @return value encoding @c __a and @c __b. * @see __decode2 */ inline _CASable __encode2(int __a, int __b) //must all be non-negative, actually { return (((_CASable)__a) << (_CASable_bits / 2)) | (((_CASable)__b) << 0); } /** @brief Decode two integers from one gnu_parallel::_CASable. * @param __x __gnu_parallel::_CASable to decode integers from. * @param __a First integer, to be decoded from the most-significant * @c _CASable_bits/2 bits of @c __x. * @param __b Second integer, to be encoded in the least-significant * @c _CASable_bits/2 bits of @c __x. * @see __encode2 */ inline void __decode2(_CASable __x, int& __a, int& __b) { __a = (int)((__x >> (_CASable_bits / 2)) & _CASable_mask); __b = (int)((__x >> 0 ) & _CASable_mask); } //needed for parallel "numeric", even if "algorithm" not included /** @brief Equivalent to std::min. */ template<typename _Tp> inline const _Tp& min(const _Tp& __a, const _Tp& __b) { return (__a < __b) ? __a : __b; } /** @brief Equivalent to std::max. */ template<typename _Tp> inline const _Tp& max(const _Tp& __a, const _Tp& __b) { return (__a > __b) ? __a : __b; } /** @brief Constructs predicate for equality from strict weak * ordering predicate */ template<typename _T1, typename _T2, typename _Compare> class _EqualFromLess : public std::binary_function<_T1, _T2, bool> { private: _Compare& _M_comp; public: _EqualFromLess(_Compare& __comp) : _M_comp(__comp) { } bool operator()(const _T1& __a, const _T2& __b) { return !_M_comp(__a, __b) && !_M_comp(__b, __a); } }; /** @brief Similar to std::unary_negate, * but giving the argument types explicitly. */ template<typename _Predicate, typename argument_type> class __unary_negate : public std::unary_function<argument_type, bool> { protected: _Predicate _M_pred; public: explicit __unary_negate(const _Predicate& __x) : _M_pred(__x) { } bool operator()(const argument_type& __x) { return !_M_pred(__x); } }; /** @brief Similar to std::binder1st, * but giving the argument types explicitly. */ template<typename _Operation, typename _FirstArgumentType, typename _SecondArgumentType, typename _ResultType> class __binder1st : public std::unary_function<_SecondArgumentType, _ResultType> { protected: _Operation _M_op; _FirstArgumentType _M_value; public: __binder1st(const _Operation& __x, const _FirstArgumentType& __y) : _M_op(__x), _M_value(__y) { } _ResultType operator()(const _SecondArgumentType& __x) { return _M_op(_M_value, __x); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements _ResultType operator()(_SecondArgumentType& __x) const { return _M_op(_M_value, __x); } }; /** * @brief Similar to std::binder2nd, but giving the argument types * explicitly. */ template<typename _Operation, typename _FirstArgumentType, typename _SecondArgumentType, typename _ResultType> class __binder2nd : public std::unary_function<_FirstArgumentType, _ResultType> { protected: _Operation _M_op; _SecondArgumentType _M_value; public: __binder2nd(const _Operation& __x, const _SecondArgumentType& __y) : _M_op(__x), _M_value(__y) { } _ResultType operator()(const _FirstArgumentType& __x) const { return _M_op(__x, _M_value); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 109. Missing binders for non-const sequence elements _ResultType operator()(_FirstArgumentType& __x) { return _M_op(__x, _M_value); } }; /** @brief Similar to std::equal_to, but allows two different types. */ template<typename _T1, typename _T2> struct _EqualTo : std::binary_function<_T1, _T2, bool> { bool operator()(const _T1& __t1, const _T2& __t2) const { return __t1 == __t2; } }; /** @brief Similar to std::less, but allows two different types. */ template<typename _T1, typename _T2> struct _Less : std::binary_function<_T1, _T2, bool> { bool operator()(const _T1& __t1, const _T2& __t2) const { return __t1 < __t2; } bool operator()(const _T2& __t2, const _T1& __t1) const { return __t2 < __t1; } }; // Partial specialization for one type. Same as std::less. template<typename _Tp> struct _Less<_Tp, _Tp> : public std::less<_Tp> { }; /** @brief Similar to std::plus, but allows two different types. */ template<typename _Tp1, typename _Tp2, typename _Result = __typeof__(*static_cast<_Tp1*>(0) + *static_cast<_Tp2*>(0))> struct _Plus : public std::binary_function<_Tp1, _Tp2, _Result> { _Result operator()(const _Tp1& __x, const _Tp2& __y) const { return __x + __y; } }; // Partial specialization for one type. Same as std::plus. template<typename _Tp> struct _Plus<_Tp, _Tp, _Tp> : public std::plus<_Tp> { }; /** @brief Similar to std::multiplies, but allows two different types. */ template<typename _Tp1, typename _Tp2, typename _Result = __typeof__(*static_cast<_Tp1*>(0) * *static_cast<_Tp2*>(0))> struct _Multiplies : public std::binary_function<_Tp1, _Tp2, _Result> { _Result operator()(const _Tp1& __x, const _Tp2& __y) const { return __x * __y; } }; // Partial specialization for one type. Same as std::multiplies. template<typename _Tp> struct _Multiplies<_Tp, _Tp, _Tp> : public std::multiplies<_Tp> { }; /** @brief _Iterator associated with __gnu_parallel::_PseudoSequence. * If features the usual random-access iterator functionality. * @param _Tp Sequence _M_value type. * @param _DifferenceTp Sequence difference type. */ template<typename _Tp, typename _DifferenceTp> class _PseudoSequenceIterator { public: typedef _DifferenceTp _DifferenceType; _PseudoSequenceIterator(const _Tp& __val, _DifferenceType __pos) : _M_val(__val), _M_pos(__pos) { } // Pre-increment operator. _PseudoSequenceIterator& operator++() { ++_M_pos; return *this; } // Post-increment operator. _PseudoSequenceIterator operator++(int) { return _PseudoSequenceIterator(_M_pos++); } const _Tp& operator*() const { return _M_val; } const _Tp& operator[](_DifferenceType) const { return _M_val; } bool operator==(const _PseudoSequenceIterator& __i2) { return _M_pos == __i2._M_pos; } bool operator!=(const _PseudoSequenceIterator& __i2) { return _M_pos != __i2._M_pos; } _DifferenceType operator-(const _PseudoSequenceIterator& __i2) { return _M_pos - __i2._M_pos; } private: const _Tp& _M_val; _DifferenceType _M_pos; }; /** @brief Sequence that conceptually consists of multiple copies of the same element. * The copies are not stored explicitly, of course. * @param _Tp Sequence _M_value type. * @param _DifferenceTp Sequence difference type. */ template<typename _Tp, typename _DifferenceTp> class _PseudoSequence { public: typedef _DifferenceTp _DifferenceType; // Better cast down to uint64_t, than up to _DifferenceTp. typedef _PseudoSequenceIterator<_Tp, uint64_t> iterator; /** @brief Constructor. * @param __val Element of the sequence. * @param __count Number of (virtual) copies. */ _PseudoSequence(const _Tp& __val, _DifferenceType __count) : _M_val(__val), _M_count(__count) { } /** @brief Begin iterator. */ iterator begin() const { return iterator(_M_val, 0); } /** @brief End iterator. */ iterator end() const { return iterator(_M_val, _M_count); } private: const _Tp& _M_val; _DifferenceType _M_count; }; /** @brief Compute the median of three referenced elements, according to @c __comp. * @param __a First iterator. * @param __b Second iterator. * @param __c Third iterator. * @param __comp Comparator. */ template<typename _RAIter, typename _Compare> _RAIter __median_of_three_iterators(_RAIter __a, _RAIter __b, _RAIter __c, _Compare __comp) { if (__comp(*__a, *__b)) if (__comp(*__b, *__c)) return __b; else if (__comp(*__a, *__c)) return __c; else return __a; else { // Just swap __a and __b. if (__comp(*__a, *__c)) return __a; else if (__comp(*__b, *__c)) return __c; else return __b; } } #if _GLIBCXX_PARALLEL_ASSERTIONS && defined(__glibcxx_assert_impl) #define _GLIBCXX_PARALLEL_ASSERT(_Condition) __glibcxx_assert_impl(_Condition) #else #define _GLIBCXX_PARALLEL_ASSERT(_Condition) #endif } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_BASE_H */ c++/8/parallel/compatibility.h 0000644 00000007316 15146341150 0012110 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/compatibility.h * @brief Compatibility layer, mostly concerned with atomic operations. * * This file is a GNU parallel extension to the Standard C++ Library * and contains implementation details for the library's internal use. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_COMPATIBILITY_H #define _GLIBCXX_PARALLEL_COMPATIBILITY_H 1 #include <parallel/types.h> #include <parallel/base.h> #if !defined(_WIN32) || defined (__CYGWIN__) #include <sched.h> #endif #ifdef __MINGW32__ // Including <windows.h> will drag in all the windows32 names. Since // that can cause user code portability problems, we just declare the // one needed function here. extern "C" __attribute((dllimport)) void __attribute__((stdcall)) Sleep (unsigned long); #endif namespace __gnu_parallel { template<typename _Tp> inline _Tp __add_omp(volatile _Tp* __ptr, _Tp __addend) { int64_t __res; #pragma omp critical { __res = *__ptr; *(__ptr) += __addend; } return __res; } /** @brief Add a value to a variable, atomically. * * @param __ptr Pointer to a signed integer. * @param __addend Value to add. */ template<typename _Tp> inline _Tp __fetch_and_add(volatile _Tp* __ptr, _Tp __addend) { if (__atomic_always_lock_free(sizeof(_Tp), __ptr)) return __atomic_fetch_add(__ptr, __addend, __ATOMIC_ACQ_REL); return __add_omp(__ptr, __addend); } template<typename _Tp> inline bool __cas_omp(volatile _Tp* __ptr, _Tp __comparand, _Tp __replacement) { bool __res = false; #pragma omp critical { if (*__ptr == __comparand) { *__ptr = __replacement; __res = true; } } return __res; } /** @brief Compare-and-swap * * Compare @c *__ptr and @c __comparand. If equal, let @c * *__ptr=__replacement and return @c true, return @c false otherwise. * * @param __ptr Pointer to signed integer. * @param __comparand Compare value. * @param __replacement Replacement value. */ template<typename _Tp> inline bool __compare_and_swap(volatile _Tp* __ptr, _Tp __comparand, _Tp __replacement) { if (__atomic_always_lock_free(sizeof(_Tp), __ptr)) return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, false, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); return __cas_omp(__ptr, __comparand, __replacement); } /** @brief Yield control to another thread, without waiting for * the end of the time slice. */ inline void __yield() { #if defined (_WIN32) && !defined (__CYGWIN__) Sleep(0); #else sched_yield(); #endif } } // end namespace #endif /* _GLIBCXX_PARALLEL_COMPATIBILITY_H */ c++/8/parallel/search.h 0000644 00000012417 15146341150 0010502 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/search.h * @brief Parallel implementation base for std::search() and * std::search_n(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_SEARCH_H #define _GLIBCXX_PARALLEL_SEARCH_H 1 #include <bits/stl_algobase.h> #include <parallel/parallel.h> #include <parallel/equally_split.h> namespace __gnu_parallel { /** * @brief Precalculate __advances for Knuth-Morris-Pratt algorithm. * @param __elements Begin iterator of sequence to search for. * @param __length Length of sequence to search for. * @param __off Returned __offsets. */ template<typename _RAIter, typename _DifferenceTp> void __calc_borders(_RAIter __elements, _DifferenceTp __length, _DifferenceTp* __off) { typedef _DifferenceTp _DifferenceType; __off[0] = -1; if (__length > 1) __off[1] = 0; _DifferenceType __k = 0; for (_DifferenceType __j = 2; __j <= __length; __j++) { while ((__k >= 0) && !(__elements[__k] == __elements[__j-1])) __k = __off[__k]; __off[__j] = ++__k; } } // Generic parallel find algorithm (requires random access iterator). /** @brief Parallel std::search. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __pred Find predicate. * @return Place of finding in first sequences. */ template<typename __RAIter1, typename __RAIter2, typename _Pred> __RAIter1 __search_template(__RAIter1 __begin1, __RAIter1 __end1, __RAIter2 __begin2, __RAIter2 __end2, _Pred __pred) { typedef std::iterator_traits<__RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2)); _DifferenceType __pattern_length = __end2 - __begin2; // Pattern too short. if(__pattern_length <= 0) return __end1; // Last point to start search. _DifferenceType __input_length = (__end1 - __begin1) - __pattern_length; // Where is first occurrence of pattern? defaults to end. _DifferenceType __result = (__end1 - __begin1); _DifferenceType *__splitters; // Pattern too long. if (__input_length < 0) return __end1; omp_lock_t __result_lock; omp_init_lock(&__result_lock); _ThreadIndex __num_threads = std::max<_DifferenceType> (1, std::min<_DifferenceType>(__input_length, __get_max_threads())); _DifferenceType __advances[__pattern_length]; __calc_borders(__begin2, __pattern_length, __advances); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __splitters = new _DifferenceType[__num_threads + 1]; __equally_split(__input_length, __num_threads, __splitters); } _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __start = __splitters[__iam], __stop = __splitters[__iam + 1]; _DifferenceType __pos_in_pattern = 0; bool __found_pattern = false; while (__start <= __stop && !__found_pattern) { // Get new value of result. #pragma omp flush(__result) // No chance for this thread to find first occurrence. if (__result < __start) break; while (__pred(__begin1[__start + __pos_in_pattern], __begin2[__pos_in_pattern])) { ++__pos_in_pattern; if (__pos_in_pattern == __pattern_length) { // Found new candidate for result. omp_set_lock(&__result_lock); __result = std::min(__result, __start); omp_unset_lock(&__result_lock); __found_pattern = true; break; } } // Make safe jump. __start += (__pos_in_pattern - __advances[__pos_in_pattern]); __pos_in_pattern = (__advances[__pos_in_pattern] < 0 ? 0 : __advances[__pos_in_pattern]); } } //parallel omp_destroy_lock(&__result_lock); delete[] __splitters; // Return iterator on found element. return (__begin1 + __result); } } // end namespace #endif /* _GLIBCXX_PARALLEL_SEARCH_H */ c++/8/parallel/find_selectors.h 0000644 00000015520 15146341150 0012236 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/find_selectors.h * @brief _Function objects representing different tasks to be plugged * into the parallel find algorithm. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_FIND_SELECTORS_H #define _GLIBCXX_PARALLEL_FIND_SELECTORS_H 1 #include <parallel/tags.h> #include <parallel/basic_iterator.h> #include <bits/stl_pair.h> namespace __gnu_parallel { /** @brief Base class of all __gnu_parallel::__find_template selectors. */ struct __generic_find_selector { }; /** * @brief Test predicate on a single element, used for std::find() * and std::find_if (). */ struct __find_if_selector : public __generic_find_selector { /** @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template<typename _RAIter1, typename _RAIter2, typename _Pred> bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { return __pred(*__i1); } /** @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template<typename _RAIter1, typename _RAIter2, typename _Pred> std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { return std::make_pair(find_if(__begin1, __end1, __pred, sequential_tag()), __begin2); } }; /** @brief Test predicate on two adjacent elements. */ struct __adjacent_find_selector : public __generic_find_selector { /** @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template<typename _RAIter1, typename _RAIter2, typename _Pred> bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { // Passed end iterator is one short. return __pred(*__i1, *(__i1 + 1)); } /** @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template<typename _RAIter1, typename _RAIter2, typename _Pred> std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { // Passed end iterator is one short. _RAIter1 __spot = adjacent_find(__begin1, __end1 + 1, __pred, sequential_tag()); if (__spot == (__end1 + 1)) __spot = __end1; return std::make_pair(__spot, __begin2); } }; /** @brief Test inverted predicate on a single element. */ struct __mismatch_selector : public __generic_find_selector { /** * @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template<typename _RAIter1, typename _RAIter2, typename _Pred> bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { return !__pred(*__i1, *__i2); } /** * @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template<typename _RAIter1, typename _RAIter2, typename _Pred> std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { return mismatch(__begin1, __end1, __begin2, __pred, sequential_tag()); } }; /** @brief Test predicate on several elements. */ template<typename _FIterator> struct __find_first_of_selector : public __generic_find_selector { _FIterator _M_begin; _FIterator _M_end; explicit __find_first_of_selector(_FIterator __begin, _FIterator __end) : _M_begin(__begin), _M_end(__end) { } /** @brief Test on one position. * @param __i1 _Iterator on first sequence. * @param __i2 _Iterator on second sequence (unused). * @param __pred Find predicate. */ template<typename _RAIter1, typename _RAIter2, typename _Pred> bool operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) { for (_FIterator __pos_in_candidates = _M_begin; __pos_in_candidates != _M_end; ++__pos_in_candidates) if (__pred(*__i1, *__pos_in_candidates)) return true; return false; } /** @brief Corresponding sequential algorithm on a sequence. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __pred Find predicate. */ template<typename _RAIter1, typename _RAIter2, typename _Pred> std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred) { return std::make_pair(find_first_of(__begin1, __end1, _M_begin, _M_end, __pred, sequential_tag()), __begin2); } }; } #endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */ c++/8/parallel/types.h 0000644 00000007204 15146341150 0010377 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/types.h * @brief Basic types and typedefs. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_TYPES_H #define _GLIBCXX_PARALLEL_TYPES_H 1 #include <cstdlib> #include <limits> #include <tr1/cstdint> namespace __gnu_parallel { // Enumerated types. /// Run-time equivalents for the compile-time tags. enum _Parallelism { /// Not parallel. sequential, /// Parallel unbalanced (equal-sized chunks). parallel_unbalanced, /// Parallel balanced (work-stealing). parallel_balanced, /// Parallel with OpenMP dynamic load-balancing. parallel_omp_loop, /// Parallel with OpenMP static load-balancing. parallel_omp_loop_static, /// Parallel with OpenMP taskqueue construct. parallel_taskqueue }; /// Strategies for run-time algorithm selection: // force_sequential, force_parallel, heuristic. enum _AlgorithmStrategy { heuristic, force_sequential, force_parallel }; /// Sorting algorithms: // multi-way mergesort, quicksort, load-balanced quicksort. enum _SortAlgorithm { MWMS, QS, QS_BALANCED }; /// Merging algorithms: // bubblesort-alike, loser-tree variants, enum __sentinel. enum _MultiwayMergeAlgorithm { LOSER_TREE }; /// Partial sum algorithms: recursive, linear. enum _PartialSumAlgorithm { RECURSIVE, LINEAR }; /// Sorting/merging algorithms: sampling, __exact. enum _SplittingAlgorithm { SAMPLING, EXACT }; /// Find algorithms: // growing blocks, equal-sized blocks, equal splitting. enum _FindAlgorithm { GROWING_BLOCKS, CONSTANT_SIZE_BLOCKS, EQUAL_SPLIT }; /** * @brief Unsigned integer to index __elements. * The total number of elements for each algorithm must fit into this type. */ typedef uint64_t _SequenceIndex; /** * @brief Unsigned integer to index a thread number. * The maximum thread number (for each processor) must fit into this type. */ typedef uint16_t _ThreadIndex; // XXX atomics interface? /// Longest compare-and-swappable integer type on this platform. typedef int64_t _CASable; /// Number of bits of _CASable. static const int _CASable_bits = std::numeric_limits<_CASable>::digits; /// ::_CASable with the right half of bits set to 1. static const _CASable _CASable_mask = ((_CASable(1) << (_CASable_bits / 2)) - 1); } #endif /* _GLIBCXX_PARALLEL_TYPES_H */ c++/8/parallel/omp_loop_static.h 0000644 00000010010 15146341150 0012413 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/omp_loop_static.h * @brief Parallelization of embarrassingly parallel execution by * means of an OpenMP for loop with static scheduling. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_OMP_LOOP_STATIC_H #define _GLIBCXX_PARALLEL_OMP_LOOP_STATIC_H 1 #include <omp.h> #include <parallel/settings.h> #include <parallel/basic_iterator.h> namespace __gnu_parallel { /** @brief Embarrassingly parallel algorithm for random access * iterators, using an OpenMP for loop with static scheduling. * * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __o User-supplied functor (comparator, predicate, adding * functor, ...). * @param __f Functor to @a process an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to @a add a single __result to the already processed * __elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template<typename _RAIter, typename _Op, typename _Fu, typename _Red, typename _Result> _Op __for_each_template_random_access_omp_loop_static(_RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { typedef typename std::iterator_traits<_RAIter>::difference_type _DifferenceType; _DifferenceType __length = __end - __begin; _ThreadIndex __num_threads = std::min<_DifferenceType> (__get_max_threads(), __length); _Result *__thread_results; # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __thread_results = new _Result[__num_threads]; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __thread_results[__i] = _Result(); } _ThreadIndex __iam = omp_get_thread_num(); #pragma omp for schedule(static, _Settings::get().workstealing_chunk_size) for (_DifferenceType __pos = 0; __pos < __length; ++__pos) __thread_results[__iam] = __r(__thread_results[__iam], __f(__o, __begin+__pos)); } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __output = __r(__output, __thread_results[__i]); delete [] __thread_results; // Points to last element processed (needed as return value for // some algorithms like transform). __f.finish_iterator = __begin + __length; return __o; } } // end namespace #endif /* _GLIBCXX_PARALLEL_OMP_LOOP_STATIC_H */ c++/8/parallel/checkers.h 0000644 00000004374 15146341150 0011027 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/checkers.h * @brief Routines for checking the correctness of algorithm results. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_CHECKERS_H #define _GLIBCXX_PARALLEL_CHECKERS_H 1 #include <cstdio> #include <bits/stl_algobase.h> #include <bits/stl_function.h> namespace __gnu_parallel { /** * @brief Check whether @c [__begin, @c __end) is sorted according * to @c __comp. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator. * @return @c true if sorted, @c false otherwise. */ template<typename _IIter, typename _Compare> bool __is_sorted(_IIter __begin, _IIter __end, _Compare __comp) { if (__begin == __end) return true; _IIter __current(__begin), __recent(__begin); unsigned long long __position = 1; for (__current++; __current != __end; __current++) { if (__comp(*__current, *__recent)) { return false; } __recent = __current; __position++; } return true; } } #endif /* _GLIBCXX_PARALLEL_CHECKERS_H */ c++/8/parallel/parallel.h 0000644 00000003050 15146341150 0011022 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/parallel.h * @brief End-user include file. Provides advanced settings and * tuning options. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze and Johannes Singler. #ifndef _GLIBCXX_PARALLEL_PARALLEL_H #define _GLIBCXX_PARALLEL_PARALLEL_H 1 #include <parallel/features.h> #include <parallel/compiletime_settings.h> #include <parallel/types.h> #include <parallel/tags.h> #include <parallel/settings.h> #endif /* _GLIBCXX_PARALLEL_PARALLEL_H */ c++/8/parallel/random_shuffle.h 0000644 00000044363 15146341150 0012236 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/random_shuffle.h * @brief Parallel implementation of std::random_shuffle(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H #define _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H 1 #include <limits> #include <bits/stl_numeric.h> #include <parallel/parallel.h> #include <parallel/random_number.h> namespace __gnu_parallel { /** @brief Type to hold the index of a bin. * * Since many variables of this type are allocated, it should be * chosen as small as possible. */ typedef unsigned short _BinIndex; /** @brief Data known to every thread participating in __gnu_parallel::__parallel_random_shuffle(). */ template<typename _RAIter> struct _DRandomShufflingGlobalData { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; /** @brief Begin iterator of the __source. */ _RAIter& _M_source; /** @brief Temporary arrays for each thread. */ _ValueType** _M_temporaries; /** @brief Two-dimensional array to hold the thread-bin distribution. * * Dimensions (_M_num_threads + 1) __x (_M_num_bins + 1). */ _DifferenceType** _M_dist; /** @brief Start indexes of the threads' __chunks. */ _DifferenceType* _M_starts; /** @brief Number of the thread that will further process the corresponding bin. */ _ThreadIndex* _M_bin_proc; /** @brief Number of bins to distribute to. */ int _M_num_bins; /** @brief Number of bits needed to address the bins. */ int _M_num_bits; /** @brief Constructor. */ _DRandomShufflingGlobalData(_RAIter& __source) : _M_source(__source) { } }; /** @brief Local data for a thread participating in __gnu_parallel::__parallel_random_shuffle(). */ template<typename _RAIter, typename _RandomNumberGenerator> struct _DRSSorterPU { /** @brief Number of threads participating in total. */ int _M_num_threads; /** @brief Begin index for bins taken care of by this thread. */ _BinIndex _M_bins_begin; /** @brief End index for bins taken care of by this thread. */ _BinIndex __bins_end; /** @brief Random _M_seed for this thread. */ uint32_t _M_seed; /** @brief Pointer to global data. */ _DRandomShufflingGlobalData<_RAIter>* _M_sd; }; /** @brief Generate a random number in @c [0,2^__logp). * @param __logp Logarithm (basis 2) of the upper range __bound. * @param __rng Random number generator to use. */ template<typename _RandomNumberGenerator> inline int __random_number_pow2(int __logp, _RandomNumberGenerator& __rng) { return __rng.__genrand_bits(__logp); } /** @brief Random shuffle code executed by each thread. * @param __pus Array of thread-local data records. */ template<typename _RAIter, typename _RandomNumberGenerator> void __parallel_random_shuffle_drs_pu(_DRSSorterPU<_RAIter, _RandomNumberGenerator>* __pus) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _ThreadIndex __iam = omp_get_thread_num(); _DRSSorterPU<_RAIter, _RandomNumberGenerator>* __d = &__pus[__iam]; _DRandomShufflingGlobalData<_RAIter>* __sd = __d->_M_sd; // Indexing: _M_dist[bin][processor] _DifferenceType __length = (__sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam]); _BinIndex* __oracles = new _BinIndex[__length]; _DifferenceType* __dist = new _DifferenceType[__sd->_M_num_bins + 1]; _BinIndex* __bin_proc = new _BinIndex[__sd->_M_num_bins]; _ValueType** __temporaries = new _ValueType*[__d->_M_num_threads]; // Compute oracles and count appearances. for (_BinIndex __b = 0; __b < __sd->_M_num_bins + 1; ++__b) __dist[__b] = 0; int __num_bits = __sd->_M_num_bits; _RandomNumber __rng(__d->_M_seed); // First main loop. for (_DifferenceType __i = 0; __i < __length; ++__i) { _BinIndex __oracle = __random_number_pow2(__num_bits, __rng); __oracles[__i] = __oracle; // To allow prefix (partial) sum. ++(__dist[__oracle + 1]); } for (_BinIndex __b = 0; __b < __sd->_M_num_bins + 1; ++__b) __sd->_M_dist[__b][__iam + 1] = __dist[__b]; # pragma omp barrier # pragma omp single { // Sum up bins, __sd->_M_dist[__s + 1][__d->_M_num_threads] now // contains the total number of items in bin __s for (_BinIndex __s = 0; __s < __sd->_M_num_bins; ++__s) __gnu_sequential::partial_sum(__sd->_M_dist[__s + 1], __sd->_M_dist[__s + 1] + __d->_M_num_threads + 1, __sd->_M_dist[__s + 1]); } # pragma omp barrier _SequenceIndex __offset = 0, __global_offset = 0; for (_BinIndex __s = 0; __s < __d->_M_bins_begin; ++__s) __global_offset += __sd->_M_dist[__s + 1][__d->_M_num_threads]; # pragma omp barrier for (_BinIndex __s = __d->_M_bins_begin; __s < __d->__bins_end; ++__s) { for (int __t = 0; __t < __d->_M_num_threads + 1; ++__t) __sd->_M_dist[__s + 1][__t] += __offset; __offset = __sd->_M_dist[__s + 1][__d->_M_num_threads]; } __sd->_M_temporaries[__iam] = static_cast<_ValueType*> (::operator new(sizeof(_ValueType) * __offset)); # pragma omp barrier // Draw local copies to avoid false sharing. for (_BinIndex __b = 0; __b < __sd->_M_num_bins + 1; ++__b) __dist[__b] = __sd->_M_dist[__b][__iam]; for (_BinIndex __b = 0; __b < __sd->_M_num_bins; ++__b) __bin_proc[__b] = __sd->_M_bin_proc[__b]; for (_ThreadIndex __t = 0; __t < __d->_M_num_threads; ++__t) __temporaries[__t] = __sd->_M_temporaries[__t]; _RAIter __source = __sd->_M_source; _DifferenceType __start = __sd->_M_starts[__iam]; // Distribute according to oracles, second main loop. for (_DifferenceType __i = 0; __i < __length; ++__i) { _BinIndex __target_bin = __oracles[__i]; _ThreadIndex __target_p = __bin_proc[__target_bin]; // Last column [__d->_M_num_threads] stays unchanged. ::new(&(__temporaries[__target_p][__dist[__target_bin + 1]++])) _ValueType(*(__source + __i + __start)); } delete[] __oracles; delete[] __dist; delete[] __bin_proc; delete[] __temporaries; # pragma omp barrier // Shuffle bins internally. for (_BinIndex __b = __d->_M_bins_begin; __b < __d->__bins_end; ++__b) { _ValueType* __begin = (__sd->_M_temporaries[__iam] + (__b == __d->_M_bins_begin ? 0 : __sd->_M_dist[__b][__d->_M_num_threads])), *__end = (__sd->_M_temporaries[__iam] + __sd->_M_dist[__b + 1][__d->_M_num_threads]); __sequential_random_shuffle(__begin, __end, __rng); std::copy(__begin, __end, __sd->_M_source + __global_offset + (__b == __d->_M_bins_begin ? 0 : __sd->_M_dist[__b][__d->_M_num_threads])); } for (_SequenceIndex __i = 0; __i < __offset; ++__i) __sd->_M_temporaries[__iam][__i].~_ValueType(); ::operator delete(__sd->_M_temporaries[__iam]); } /** @brief Round up to the next greater power of 2. * @param __x _Integer to round up */ template<typename _Tp> _Tp __round_up_to_pow2(_Tp __x) { if (__x <= 1) return 1; else return (_Tp)1 << (__rd_log2(__x - 1) + 1); } /** @brief Main parallel random shuffle step. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __n Length of sequence. * @param __num_threads Number of threads to use. * @param __rng Random number generator to use. */ template<typename _RAIter, typename _RandomNumberGenerator> void __parallel_random_shuffle_drs(_RAIter __begin, _RAIter __end, typename std::iterator_traits <_RAIter>::difference_type __n, _ThreadIndex __num_threads, _RandomNumberGenerator& __rng) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _GLIBCXX_CALL(__n) const _Settings& __s = _Settings::get(); if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); _BinIndex __num_bins, __num_bins_cache; #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 // Try the L1 cache first. // Must fit into L1. __num_bins_cache = std::max<_DifferenceType>(1, __n / (__s.L1_cache_size_lb / sizeof(_ValueType))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2 // Power of 2 and at least one element per bin, at most the TLB size. __num_bins = std::min<_DifferenceType>(__n, __num_bins_cache); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin. __num_bins = std::min<_DifferenceType>(__s.TLB_size / 2, __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); if (__num_bins < __num_bins_cache) { #endif // Now try the L2 cache // Must fit into L2 __num_bins_cache = static_cast<_BinIndex> (std::max<_DifferenceType>(1, __n / (__s.L2_cache_size / sizeof(_ValueType)))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2. __num_bins = static_cast<_BinIndex> (std::min(__n, static_cast<_DifferenceType>(__num_bins_cache))); // Power of 2 and at least one element per bin, at most the TLB size. #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin. __num_bins = std::min(static_cast<_DifferenceType>(__s.TLB_size / 2), __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 } #endif __num_bins = __round_up_to_pow2( std::max<_BinIndex>(__num_threads, __num_bins)); if (__num_threads <= 1) { _RandomNumber __derived_rng( __rng(std::numeric_limits<uint32_t>::max())); __sequential_random_shuffle(__begin, __end, __derived_rng); return; } _DRandomShufflingGlobalData<_RAIter> __sd(__begin); _DRSSorterPU<_RAIter, _RandomNumber >* __pus; _DifferenceType* __starts; # pragma omp parallel num_threads(__num_threads) { _ThreadIndex __num_threads = omp_get_num_threads(); # pragma omp single { __pus = new _DRSSorterPU<_RAIter, _RandomNumber>[__num_threads]; __sd._M_temporaries = new _ValueType*[__num_threads]; __sd._M_dist = new _DifferenceType*[__num_bins + 1]; __sd._M_bin_proc = new _ThreadIndex[__num_bins]; for (_BinIndex __b = 0; __b < __num_bins + 1; ++__b) __sd._M_dist[__b] = new _DifferenceType[__num_threads + 1]; for (_BinIndex __b = 0; __b < (__num_bins + 1); ++__b) { __sd._M_dist[0][0] = 0; __sd._M_dist[__b][0] = 0; } __starts = __sd._M_starts = new _DifferenceType[__num_threads + 1]; int __bin_cursor = 0; __sd._M_num_bins = __num_bins; __sd._M_num_bits = __rd_log2(__num_bins); _DifferenceType __chunk_length = __n / __num_threads, __split = __n % __num_threads, __start = 0; _DifferenceType __bin_chunk_length = __num_bins / __num_threads, __bin_split = __num_bins % __num_threads; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { __starts[__i] = __start; __start += (__i < __split ? (__chunk_length + 1) : __chunk_length); int __j = __pus[__i]._M_bins_begin = __bin_cursor; // Range of bins for this processor. __bin_cursor += (__i < __bin_split ? (__bin_chunk_length + 1) : __bin_chunk_length); __pus[__i].__bins_end = __bin_cursor; for (; __j < __bin_cursor; ++__j) __sd._M_bin_proc[__j] = __i; __pus[__i]._M_num_threads = __num_threads; __pus[__i]._M_seed = __rng(std::numeric_limits<uint32_t>::max()); __pus[__i]._M_sd = &__sd; } __starts[__num_threads] = __start; } //single // Now shuffle in parallel. __parallel_random_shuffle_drs_pu(__pus); } // parallel delete[] __starts; delete[] __sd._M_bin_proc; for (int __s = 0; __s < (__num_bins + 1); ++__s) delete[] __sd._M_dist[__s]; delete[] __sd._M_dist; delete[] __sd._M_temporaries; delete[] __pus; } /** @brief Sequential cache-efficient random shuffle. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __rng Random number generator to use. */ template<typename _RAIter, typename _RandomNumberGenerator> void __sequential_random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator& __rng) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; const _Settings& __s = _Settings::get(); _BinIndex __num_bins, __num_bins_cache; #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 // Try the L1 cache first, must fit into L1. __num_bins_cache = std::max<_DifferenceType> (1, __n / (__s.L1_cache_size_lb / sizeof(_ValueType))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2 // Power of 2 and at least one element per bin, at most the TLB size __num_bins = std::min(__n, (_DifferenceType)__num_bins_cache); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin __num_bins = std::min((_DifferenceType)__s.TLB_size / 2, __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); if (__num_bins < __num_bins_cache) { #endif // Now try the L2 cache, must fit into L2. __num_bins_cache = static_cast<_BinIndex> (std::max<_DifferenceType>(1, __n / (__s.L2_cache_size / sizeof(_ValueType)))); __num_bins_cache = __round_up_to_pow2(__num_bins_cache); // No more buckets than TLB entries, power of 2 // Power of 2 and at least one element per bin, at most the TLB size. __num_bins = static_cast<_BinIndex> (std::min(__n, static_cast<_DifferenceType>(__num_bins_cache))); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB // 2 TLB entries needed per bin __num_bins = std::min<_DifferenceType>(__s.TLB_size / 2, __num_bins); #endif __num_bins = __round_up_to_pow2(__num_bins); #if _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 } #endif int __num_bits = __rd_log2(__num_bins); if (__num_bins > 1) { _ValueType* __target = static_cast<_ValueType*>(::operator new(sizeof(_ValueType) * __n)); _BinIndex* __oracles = new _BinIndex[__n]; _DifferenceType* __dist0 = new _DifferenceType[__num_bins + 1], * __dist1 = new _DifferenceType[__num_bins + 1]; for (int __b = 0; __b < __num_bins + 1; ++__b) __dist0[__b] = 0; _RandomNumber __bitrng(__rng(0xFFFFFFFF)); for (_DifferenceType __i = 0; __i < __n; ++__i) { _BinIndex __oracle = __random_number_pow2(__num_bits, __bitrng); __oracles[__i] = __oracle; // To allow prefix (partial) sum. ++(__dist0[__oracle + 1]); } // Sum up bins. __gnu_sequential::partial_sum(__dist0, __dist0 + __num_bins + 1, __dist0); for (int __b = 0; __b < __num_bins + 1; ++__b) __dist1[__b] = __dist0[__b]; // Distribute according to oracles. for (_DifferenceType __i = 0; __i < __n; ++__i) ::new(&(__target[(__dist0[__oracles[__i]])++])) _ValueType(*(__begin + __i)); for (int __b = 0; __b < __num_bins; ++__b) __sequential_random_shuffle(__target + __dist1[__b], __target + __dist1[__b + 1], __rng); // Copy elements back. std::copy(__target, __target + __n, __begin); delete[] __dist0; delete[] __dist1; delete[] __oracles; for (_DifferenceType __i = 0; __i < __n; ++__i) __target[__i].~_ValueType(); ::operator delete(__target); } else __gnu_sequential::random_shuffle(__begin, __end, __rng); } /** @brief Parallel random public call. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __rng Random number generator to use. */ template<typename _RAIter, typename _RandomNumberGenerator> inline void __parallel_random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator __rng = _RandomNumber()) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; __parallel_random_shuffle_drs(__begin, __end, __n, __get_max_threads(), __rng); } } #endif /* _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H */ c++/8/parallel/find.h 0000644 00000032427 15146341150 0010160 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/find.h * @brief Parallel implementation base for std::find(), std::equal() * and related functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze and Johannes Singler. #ifndef _GLIBCXX_PARALLEL_FIND_H #define _GLIBCXX_PARALLEL_FIND_H 1 #include <bits/stl_algobase.h> #include <parallel/features.h> #include <parallel/parallel.h> #include <parallel/compatibility.h> #include <parallel/equally_split.h> namespace __gnu_parallel { /** * @brief Parallel std::find, switch for different algorithms. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Must have same * length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. */ template<typename _RAIter1, typename _RAIter2, typename _Pred, typename _Selector> inline std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector) { switch (_Settings::get().find_algorithm) { case GROWING_BLOCKS: return __find_template(__begin1, __end1, __begin2, __pred, __selector, growing_blocks_tag()); case CONSTANT_SIZE_BLOCKS: return __find_template(__begin1, __end1, __begin2, __pred, __selector, constant_size_blocks_tag()); case EQUAL_SPLIT: return __find_template(__begin1, __end1, __begin2, __pred, __selector, equal_split_tag()); default: _GLIBCXX_PARALLEL_ASSERT(false); return std::make_pair(__begin1, __begin2); } } #if _GLIBCXX_FIND_EQUAL_SPLIT /** * @brief Parallel std::find, equal splitting variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Second __sequence * must have same length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. */ template<typename _RAIter1, typename _RAIter2, typename _Pred, typename _Selector> std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, equal_split_tag) { _GLIBCXX_CALL(__end1 - __begin1) typedef std::iterator_traits<_RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::value_type _ValueType; _DifferenceType __length = __end1 - __begin1; _DifferenceType __result = __length; _DifferenceType* __borders; omp_lock_t __result_lock; omp_init_lock(&__result_lock); _ThreadIndex __num_threads = __get_max_threads(); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 1]; __equally_split(__length, __num_threads, __borders); } //single _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __start = __borders[__iam], __stop = __borders[__iam + 1]; _RAIter1 __i1 = __begin1 + __start; _RAIter2 __i2 = __begin2 + __start; for (_DifferenceType __pos = __start; __pos < __stop; ++__pos) { # pragma omp flush(__result) // Result has been set to something lower. if (__result < __pos) break; if (__selector(__i1, __i2, __pred)) { omp_set_lock(&__result_lock); if (__pos < __result) __result = __pos; omp_unset_lock(&__result_lock); break; } ++__i1; ++__i2; } } //parallel omp_destroy_lock(&__result_lock); delete[] __borders; return std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result); } #endif #if _GLIBCXX_FIND_GROWING_BLOCKS /** * @brief Parallel std::find, growing block size variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Second __sequence * must have same length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. * @see __gnu_parallel::_Settings::find_sequential_search_size * @see __gnu_parallel::_Settings::find_scale_factor * * There are two main differences between the growing blocks and * the constant-size blocks variants. * 1. For GB, the block size grows; for CSB, the block size is fixed. * 2. For GB, the blocks are allocated dynamically; * for CSB, the blocks are allocated in a predetermined manner, * namely spacial round-robin. */ template<typename _RAIter1, typename _RAIter2, typename _Pred, typename _Selector> std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, growing_blocks_tag) { _GLIBCXX_CALL(__end1 - __begin1) typedef std::iterator_traits<_RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::value_type _ValueType; const _Settings& __s = _Settings::get(); _DifferenceType __length = __end1 - __begin1; _DifferenceType __sequential_search_size = std::min<_DifferenceType> (__length, __s.find_sequential_search_size); // Try it sequentially first. std::pair<_RAIter1, _RAIter2> __find_seq_result = __selector._M_sequential_algorithm (__begin1, __begin1 + __sequential_search_size, __begin2, __pred); if (__find_seq_result.first != (__begin1 + __sequential_search_size)) return __find_seq_result; // Index of beginning of next free block (after sequential find). _DifferenceType __next_block_start = __sequential_search_size; _DifferenceType __result = __length; omp_lock_t __result_lock; omp_init_lock(&__result_lock); const float __scale_factor = __s.find_scale_factor; _ThreadIndex __num_threads = __get_max_threads(); # pragma omp parallel shared(__result) num_threads(__num_threads) { # pragma omp single __num_threads = omp_get_num_threads(); // Not within first __k elements -> start parallel. _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __block_size = std::max<_DifferenceType>(1, __scale_factor * __next_block_start); _DifferenceType __start = __fetch_and_add<_DifferenceType> (&__next_block_start, __block_size); // Get new block, update pointer to next block. _DifferenceType __stop = std::min<_DifferenceType>(__length, __start + __block_size); std::pair<_RAIter1, _RAIter2> __local_result; while (__start < __length) { # pragma omp flush(__result) // Get new value of result. if (__result < __start) { // No chance to find first element. break; } __local_result = __selector._M_sequential_algorithm (__begin1 + __start, __begin1 + __stop, __begin2 + __start, __pred); if (__local_result.first != (__begin1 + __stop)) { omp_set_lock(&__result_lock); if ((__local_result.first - __begin1) < __result) { __result = __local_result.first - __begin1; // Result cannot be in future blocks, stop algorithm. __fetch_and_add<_DifferenceType>(&__next_block_start, __length); } omp_unset_lock(&__result_lock); } _DifferenceType __block_size = std::max<_DifferenceType>(1, __scale_factor * __next_block_start); // Get new block, update pointer to next block. __start = __fetch_and_add<_DifferenceType>(&__next_block_start, __block_size); __stop = std::min<_DifferenceType>(__length, __start + __block_size); } } //parallel omp_destroy_lock(&__result_lock); // Return iterator on found element. return std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result); } #endif #if _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS /** * @brief Parallel std::find, constant block size variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. Second __sequence * must have same length as first sequence. * @param __pred Find predicate. * @param __selector _Functionality (e. g. std::find_if(), std::equal(),...) * @return Place of finding in both sequences. * @see __gnu_parallel::_Settings::find_sequential_search_size * @see __gnu_parallel::_Settings::find_block_size * There are two main differences between the growing blocks and the * constant-size blocks variants. * 1. For GB, the block size grows; for CSB, the block size is fixed. * 2. For GB, the blocks are allocated dynamically; for CSB, the * blocks are allocated in a predetermined manner, namely spacial * round-robin. */ template<typename _RAIter1, typename _RAIter2, typename _Pred, typename _Selector> std::pair<_RAIter1, _RAIter2> __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, constant_size_blocks_tag) { _GLIBCXX_CALL(__end1 - __begin1) typedef std::iterator_traits<_RAIter1> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; typedef typename _TraitsType::value_type _ValueType; const _Settings& __s = _Settings::get(); _DifferenceType __length = __end1 - __begin1; _DifferenceType __sequential_search_size = std::min<_DifferenceType> (__length, __s.find_sequential_search_size); // Try it sequentially first. std::pair<_RAIter1, _RAIter2> __find_seq_result = __selector._M_sequential_algorithm (__begin1, __begin1 + __sequential_search_size, __begin2, __pred); if (__find_seq_result.first != (__begin1 + __sequential_search_size)) return __find_seq_result; _DifferenceType __result = __length; omp_lock_t __result_lock; omp_init_lock(&__result_lock); // Not within first __sequential_search_size elements -> start parallel. _ThreadIndex __num_threads = __get_max_threads(); # pragma omp parallel shared(__result) num_threads(__num_threads) { # pragma omp single __num_threads = omp_get_num_threads(); _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __block_size = __s.find_initial_block_size; // First element of thread's current iteration. _DifferenceType __iteration_start = __sequential_search_size; // Where to work (initialization). _DifferenceType __start = __iteration_start + __iam * __block_size; _DifferenceType __stop = std::min<_DifferenceType>(__length, __start + __block_size); std::pair<_RAIter1, _RAIter2> __local_result; while (__start < __length) { // Get new value of result. # pragma omp flush(__result) // No chance to find first element. if (__result < __start) break; __local_result = __selector._M_sequential_algorithm (__begin1 + __start, __begin1 + __stop, __begin2 + __start, __pred); if (__local_result.first != (__begin1 + __stop)) { omp_set_lock(&__result_lock); if ((__local_result.first - __begin1) < __result) __result = __local_result.first - __begin1; omp_unset_lock(&__result_lock); // Will not find better value in its interval. break; } __iteration_start += __num_threads * __block_size; // Where to work. __start = __iteration_start + __iam * __block_size; __stop = std::min<_DifferenceType>(__length, __start + __block_size); } } //parallel omp_destroy_lock(&__result_lock); // Return iterator on found element. return std::pair<_RAIter1, _RAIter2>(__begin1 + __result, __begin2 + __result); } #endif } // end namespace #endif /* _GLIBCXX_PARALLEL_FIND_H */ c++/8/parallel/quicksort.h 0000644 00000013756 15146341150 0011270 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/quicksort.h * @brief Implementation of a unbalanced parallel quicksort (in-place). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_QUICKSORT_H #define _GLIBCXX_PARALLEL_QUICKSORT_H 1 #include <parallel/parallel.h> #include <parallel/partition.h> namespace __gnu_parallel { /** @brief Unbalanced quicksort divide step. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __pivot_rank Desired __rank of the pivot. * @param __num_samples Choose pivot from that many samples. * @param __num_threads Number of threads that are allowed to work on * this part. */ template<typename _RAIter, typename _Compare> typename std::iterator_traits<_RAIter>::difference_type __parallel_sort_qs_divide(_RAIter __begin, _RAIter __end, _Compare __comp, typename std::iterator_traits <_RAIter>::difference_type __pivot_rank, typename std::iterator_traits <_RAIter>::difference_type __num_samples, _ThreadIndex __num_threads) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; __num_samples = std::min(__num_samples, __n); // Allocate uninitialized, to avoid default constructor. _ValueType* __samples = static_cast<_ValueType*> (::operator new(__num_samples * sizeof(_ValueType))); for (_DifferenceType __s = 0; __s < __num_samples; ++__s) { const unsigned long long __index = static_cast<unsigned long long> (__s) * __n / __num_samples; ::new(&(__samples[__s])) _ValueType(__begin[__index]); } __gnu_sequential::sort(__samples, __samples + __num_samples, __comp); _ValueType& __pivot = __samples[__pivot_rank * __num_samples / __n]; __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool> __pred(__comp, __pivot); _DifferenceType __split = __parallel_partition(__begin, __end, __pred, __num_threads); for (_DifferenceType __s = 0; __s < __num_samples; ++__s) __samples[__s].~_ValueType(); ::operator delete(__samples); return __split; } /** @brief Unbalanced quicksort conquer step. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. */ template<typename _RAIter, typename _Compare> void __parallel_sort_qs_conquer(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; if (__num_threads <= 1) { __gnu_sequential::sort(__begin, __end, __comp); return; } _DifferenceType __n = __end - __begin, __pivot_rank; if (__n <= 1) return; _ThreadIndex __num_threads_left; if ((__num_threads % 2) == 1) __num_threads_left = __num_threads / 2 + 1; else __num_threads_left = __num_threads / 2; __pivot_rank = __n * __num_threads_left / __num_threads; _DifferenceType __split = __parallel_sort_qs_divide (__begin, __end, __comp, __pivot_rank, _Settings::get().sort_qs_num_samples_preset, __num_threads); #pragma omp parallel sections num_threads(2) { #pragma omp section __parallel_sort_qs_conquer(__begin, __begin + __split, __comp, __num_threads_left); #pragma omp section __parallel_sort_qs_conquer(__begin + __split, __end, __comp, __num_threads - __num_threads_left); } } /** @brief Unbalanced quicksort main call. * @param __begin Begin iterator of input sequence. * @param __end End iterator input sequence, ignored. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. */ template<typename _RAIter, typename _Compare> void __parallel_sort_qs(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_CALL(__n) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; // At least one element per processor. if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); __parallel_sort_qs_conquer( __begin, __begin + __n, __comp, __num_threads); } } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_QUICKSORT_H */ c++/8/parallel/tags.h 0000644 00000013536 15146341150 0010176 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/tags.h * @brief Tags for compile-time selection. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_TAGS_H #define _GLIBCXX_PARALLEL_TAGS_H 1 #include <omp.h> #include <parallel/types.h> namespace __gnu_parallel { /** @brief Forces sequential execution at compile time. */ struct sequential_tag { }; /** @brief Recommends parallel execution at compile time, * optionally using a user-specified number of threads. */ struct parallel_tag { private: _ThreadIndex _M_num_threads; public: /** @brief Default constructor. Use default number of threads. */ parallel_tag() { _M_num_threads = 0; } /** @brief Default constructor. Recommend number of threads to use. * @param __num_threads Desired number of threads. */ parallel_tag(_ThreadIndex __num_threads) { _M_num_threads = __num_threads; } /** @brief Find out desired number of threads. * @return Desired number of threads. */ _ThreadIndex __get_num_threads() { if(_M_num_threads == 0) return omp_get_max_threads(); else return _M_num_threads; } /** @brief Set the desired number of threads. * @param __num_threads Desired number of threads. */ void set_num_threads(_ThreadIndex __num_threads) { _M_num_threads = __num_threads; } }; /** @brief Recommends parallel execution using the default parallel algorithm. */ struct default_parallel_tag : public parallel_tag { default_parallel_tag() { } default_parallel_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Recommends parallel execution using dynamic load-balancing at compile time. */ struct balanced_tag : public parallel_tag { }; /** @brief Recommends parallel execution using static load-balancing at compile time. */ struct unbalanced_tag : public parallel_tag { }; /** @brief Recommends parallel execution using OpenMP dynamic load-balancing at compile time. */ struct omp_loop_tag : public parallel_tag { }; /** @brief Recommends parallel execution using OpenMP static load-balancing at compile time. */ struct omp_loop_static_tag : public parallel_tag { }; /** @brief Base class for for std::find() variants. */ struct find_tag { }; /** @brief Forces parallel merging * with exact splitting, at compile time. */ struct exact_tag : public parallel_tag { exact_tag() { } exact_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel merging * with exact splitting, at compile time. */ struct sampling_tag : public parallel_tag { sampling_tag() { } sampling_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using multiway mergesort * at compile time. */ struct multiway_mergesort_tag : public parallel_tag { multiway_mergesort_tag() { } multiway_mergesort_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using multiway mergesort * with exact splitting at compile time. */ struct multiway_mergesort_exact_tag : public parallel_tag { multiway_mergesort_exact_tag() { } multiway_mergesort_exact_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using multiway mergesort * with splitting by sampling at compile time. */ struct multiway_mergesort_sampling_tag : public parallel_tag { multiway_mergesort_sampling_tag() { } multiway_mergesort_sampling_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using unbalanced quicksort * at compile time. */ struct quicksort_tag : public parallel_tag { quicksort_tag() { } quicksort_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Forces parallel sorting using balanced quicksort * at compile time. */ struct balanced_quicksort_tag : public parallel_tag { balanced_quicksort_tag() { } balanced_quicksort_tag(_ThreadIndex __num_threads) : parallel_tag(__num_threads) { } }; /** @brief Selects the growing block size variant for std::find(). @see _GLIBCXX_FIND_GROWING_BLOCKS */ struct growing_blocks_tag : public find_tag { }; /** @brief Selects the constant block size variant for std::find(). @see _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS */ struct constant_size_blocks_tag : public find_tag { }; /** @brief Selects the equal splitting variant for std::find(). @see _GLIBCXX_FIND_EQUAL_SPLIT */ struct equal_split_tag : public find_tag { }; } #endif /* _GLIBCXX_PARALLEL_TAGS_H */ c++/8/parallel/features.h 0000644 00000006727 15146341150 0011062 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/features.h * @brief Defines on whether to include algorithm variants. * * Less variants reduce executable size and compile time. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_FEATURES_H #define _GLIBCXX_PARALLEL_FEATURES_H 1 #ifndef _GLIBCXX_MERGESORT /** @def _GLIBCXX_MERGESORT * @brief Include parallel multi-way mergesort. * @see __gnu_parallel::_Settings::sort_algorithm */ #define _GLIBCXX_MERGESORT 1 #endif #ifndef _GLIBCXX_QUICKSORT /** @def _GLIBCXX_QUICKSORT * @brief Include parallel unbalanced quicksort. * @see __gnu_parallel::_Settings::sort_algorithm */ #define _GLIBCXX_QUICKSORT 1 #endif #ifndef _GLIBCXX_BAL_QUICKSORT /** @def _GLIBCXX_BAL_QUICKSORT * @brief Include parallel dynamically load-balanced quicksort. * @see __gnu_parallel::_Settings::sort_algorithm */ #define _GLIBCXX_BAL_QUICKSORT 1 #endif #ifndef _GLIBCXX_FIND_GROWING_BLOCKS /** @brief Include the growing blocks variant for std::find. * @see __gnu_parallel::_Settings::find_algorithm */ #define _GLIBCXX_FIND_GROWING_BLOCKS 1 #endif #ifndef _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS /** @brief Include the equal-sized blocks variant for std::find. * @see __gnu_parallel::_Settings::find_algorithm */ #define _GLIBCXX_FIND_CONSTANT_SIZE_BLOCKS 1 #endif #ifndef _GLIBCXX_FIND_EQUAL_SPLIT /** @def _GLIBCXX_FIND_EQUAL_SPLIT * @brief Include the equal splitting variant for std::find. * @see __gnu_parallel::_Settings::find_algorithm */ #define _GLIBCXX_FIND_EQUAL_SPLIT 1 #endif #ifndef _GLIBCXX_TREE_INITIAL_SPLITTING /** @def _GLIBCXX_TREE_INITIAL_SPLITTING * @brief Include the initial splitting variant for * _Rb_tree::insert_unique(_IIter beg, _IIter __end). * @see __gnu_parallel::_Rb_tree */ #define _GLIBCXX_TREE_INITIAL_SPLITTING 1 #endif #ifndef _GLIBCXX_TREE_DYNAMIC_BALANCING /** @def _GLIBCXX_TREE_DYNAMIC_BALANCING * @brief Include the dynamic balancing variant for * _Rb_tree::insert_unique(_IIter beg, _IIter __end). * @see __gnu_parallel::_Rb_tree */ #define _GLIBCXX_TREE_DYNAMIC_BALANCING 1 #endif #ifndef _GLIBCXX_TREE_FULL_COPY /** @def _GLIBCXX_TREE_FULL_COPY * @brief In order to sort the input sequence of * _Rb_tree::insert_unique(_IIter beg, _IIter __end) a * full copy of the input elements is done. * @see __gnu_parallel::_Rb_tree */ #define _GLIBCXX_TREE_FULL_COPY 1 #endif #endif /* _GLIBCXX_PARALLEL_FEATURES_H */ c++/8/parallel/compiletime_settings.h 0000644 00000005467 15146341150 0013473 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/compiletime_settings.h * @brief Defines on options concerning debugging and performance, at * compile-time. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #include <cstdio> /** @brief Determine verbosity level of the parallel mode. * Level 1 prints a message each time a parallel-mode function is entered. */ #define _GLIBCXX_VERBOSE_LEVEL 0 /** @def _GLIBCXX_CALL * @brief Macro to produce log message when entering a function. * @param __n Input size. * @see _GLIBCXX_VERBOSE_LEVEL */ #if (_GLIBCXX_VERBOSE_LEVEL == 0) #define _GLIBCXX_CALL(__n) #endif #if (_GLIBCXX_VERBOSE_LEVEL == 1) #define _GLIBCXX_CALL(__n) \ printf(" %__s:\niam = %d, __n = %ld, __num_threads = %d\n", \ __PRETTY_FUNCTION__, omp_get_thread_num(), (__n), __get_max_threads()); #endif #ifndef _GLIBCXX_SCALE_DOWN_FPU /** @brief Use floating-point scaling instead of modulo for mapping * random numbers to a range. This can be faster on certain CPUs. */ #define _GLIBCXX_SCALE_DOWN_FPU 0 #endif #ifndef _GLIBCXX_PARALLEL_ASSERTIONS /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. * Should be switched on only locally. */ #define _GLIBCXX_PARALLEL_ASSERTIONS (_GLIBCXX_ASSERTIONS+0) #endif #ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. * Consider the size of the L1 cache for * gnu_parallel::__parallel_random_shuffle(). */ #define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_L1 0 #endif #ifndef _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB /** @brief Switch on many _GLIBCXX_PARALLEL_ASSERTions in parallel code. * Consider the size of the TLB for * gnu_parallel::__parallel_random_shuffle(). */ #define _GLIBCXX_RANDOM_SHUFFLE_CONSIDER_TLB 0 #endif c++/8/parallel/losertree.h 0000644 00000067660 15146341150 0011253 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/losertree.h * @brief Many generic loser tree variants. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_LOSERTREE_H #define _GLIBCXX_PARALLEL_LOSERTREE_H 1 #include <bits/stl_algobase.h> #include <bits/stl_function.h> #include <parallel/features.h> #include <parallel/base.h> namespace __gnu_parallel { /** * @brief Guarded loser/tournament tree. * * The smallest element is at the top. * * Guarding is done explicitly through one flag _M_sup per element, * inf is not needed due to a better initialization routine. This * is a well-performing variant. * * @param _Tp the element type * @param _Compare the comparator to use, defaults to std::less<_Tp> */ template<typename _Tp, typename _Compare> class _LoserTreeBase { protected: /** @brief Internal representation of a _LoserTree element. */ struct _Loser { /** @brief flag, true iff this is a "maximum" __sentinel. */ bool _M_sup; /** @brief __index of the __source __sequence. */ int _M_source; /** @brief _M_key of the element in the _LoserTree. */ _Tp _M_key; }; unsigned int _M_ik, _M_k, _M_offset; /** log_2{_M_k} */ unsigned int _M_log_k; /** @brief _LoserTree __elements. */ _Loser* _M_losers; /** @brief _Compare to use. */ _Compare _M_comp; /** * @brief State flag that determines whether the _LoserTree is empty. * * Only used for building the _LoserTree. */ bool _M_first_insert; public: /** * @brief The constructor. * * @param __k The number of sequences to merge. * @param __comp The comparator to use. */ _LoserTreeBase(unsigned int __k, _Compare __comp) : _M_comp(__comp) { _M_ik = __k; // Compute log_2{_M_k} for the _Loser Tree _M_log_k = __rd_log2(_M_ik - 1) + 1; // Next greater power of 2. _M_k = 1 << _M_log_k; _M_offset = _M_k; // Avoid default-constructing _M_losers[]._M_key _M_losers = static_cast<_Loser*>(::operator new(2 * _M_k * sizeof(_Loser))); for (unsigned int __i = _M_ik - 1; __i < _M_k; ++__i) _M_losers[__i + _M_k]._M_sup = true; _M_first_insert = true; } /** * @brief The destructor. */ ~_LoserTreeBase() { for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) _M_losers[__i].~_Loser(); ::operator delete(_M_losers); } /** * @brief Initializes the sequence "_M_source" with the element "__key". * * @param __key the element to insert * @param __source __index of the __source __sequence * @param __sup flag that determines whether the value to insert is an * explicit __supremum. */ void __insert_start(const _Tp& __key, int __source, bool __sup) { unsigned int __pos = _M_k + __source; if (_M_first_insert) { // Construct all keys, so we can easily destruct them. for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) ::new(&(_M_losers[__i]._M_key)) _Tp(__key); _M_first_insert = false; } else _M_losers[__pos]._M_key = __key; _M_losers[__pos]._M_sup = __sup; _M_losers[__pos]._M_source = __source; } /** * @return the index of the sequence with the smallest element. */ int __get_min_source() { return _M_losers[0]._M_source; } }; /** * @brief Stable _LoserTree variant. * * Provides the stable implementations of insert_start, __init_winner, * __init and __delete_min_insert. * * Unstable variant is done using partial specialisation below. */ template<bool __stable/* default == true */, typename _Tp, typename _Compare> class _LoserTree : public _LoserTreeBase<_Tp, _Compare> { typedef _LoserTreeBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; using _Base::_M_first_insert; public: _LoserTree(unsigned int __k, _Compare __comp) : _Base::_LoserTreeBase(__k, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } /** * @brief Delete the smallest element and insert a new element from * the previously smallest element's sequence. * * This implementation is stable. */ // Do not pass a const reference since __key will be used as // local variable. void __delete_min_insert(_Tp __key, bool __sup) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by _M_source. if ((__sup && (!_M_losers[__pos]._M_sup || _M_losers[__pos]._M_source < __source)) || (!__sup && !_M_losers[__pos]._M_sup && ((_M_comp(_M_losers[__pos]._M_key, __key)) || (!_M_comp(__key, _M_losers[__pos]._M_key) && _M_losers[__pos]._M_source < __source)))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** * @brief Unstable _LoserTree variant. * * Stability (non-stable here) is selected with partial specialization. */ template<typename _Tp, typename _Compare> class _LoserTree</* __stable == */false, _Tp, _Compare> : public _LoserTreeBase<_Tp, _Compare> { typedef _LoserTreeBase<_Tp, _Compare> _Base; using _Base::_M_log_k; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; using _Base::_M_first_insert; public: _LoserTree(unsigned int __k, _Compare __comp) : _Base::_LoserTreeBase(__k, __comp) { } /** * Computes the winner of the competition at position "__root". * * Called recursively (starting at 0) to build the initial tree. * * @param __root __index of the "game" to start. */ unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } /** * Delete the _M_key smallest element and insert the element __key * instead. * * @param __key the _M_key to insert * @param __sup true iff __key is an explicitly marked supremum */ // Do not pass a const reference since __key will be used as local // variable. void __delete_min_insert(_Tp __key, bool __sup) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (__sup || (!_M_losers[__pos]._M_sup && _M_comp(_M_losers[__pos]._M_key, __key))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** * @brief Base class of _Loser Tree implementation using pointers. */ template<typename _Tp, typename _Compare> class _LoserTreePointerBase { protected: /** @brief Internal representation of _LoserTree __elements. */ struct _Loser { bool _M_sup; int _M_source; const _Tp* _M_keyp; }; unsigned int _M_ik, _M_k, _M_offset; _Loser* _M_losers; _Compare _M_comp; public: _LoserTreePointerBase(unsigned int __k, _Compare __comp = std::less<_Tp>()) : _M_comp(__comp) { _M_ik = __k; // Next greater power of 2. _M_k = 1 << (__rd_log2(_M_ik - 1) + 1); _M_offset = _M_k; _M_losers = new _Loser[_M_k * 2]; for (unsigned int __i = _M_ik - 1; __i < _M_k; __i++) _M_losers[__i + _M_k]._M_sup = true; } ~_LoserTreePointerBase() { delete[] _M_losers; } int __get_min_source() { return _M_losers[0]._M_source; } void __insert_start(const _Tp& __key, int __source, bool __sup) { unsigned int __pos = _M_k + __source; _M_losers[__pos]._M_sup = __sup; _M_losers[__pos]._M_source = __source; _M_losers[__pos]._M_keyp = &__key; } }; /** * @brief Stable _LoserTree implementation. * * The unstable variant is implemented using partial instantiation below. */ template<bool __stable/* default == true */, typename _Tp, typename _Compare> class _LoserTreePointer : public _LoserTreePointerBase<_Tp, _Compare> { typedef _LoserTreePointerBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerBase(__k, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by __source. if ((__sup && (!_M_losers[__pos]._M_sup || _M_losers[__pos]._M_source < __source)) || (!__sup && !_M_losers[__pos]._M_sup && ((_M_comp(*_M_losers[__pos]._M_keyp, *__keyp)) || (!_M_comp(*__keyp, *_M_losers[__pos]._M_keyp) && _M_losers[__pos]._M_source < __source)))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; /** * @brief Unstable _LoserTree implementation. * * The stable variant is above. */ template<typename _Tp, typename _Compare> class _LoserTreePointer</* __stable == */false, _Tp, _Compare> : public _LoserTreePointerBase<_Tp, _Compare> { typedef _LoserTreePointerBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerBase(__k, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (_M_losers[__right]._M_sup || (!_M_losers[__left]._M_sup && !_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp))) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (__sup || (!_M_losers[__pos]._M_sup && _M_comp(*_M_losers[__pos]._M_keyp, *__keyp))) { // The other one is smaller. std::swap(_M_losers[__pos]._M_sup, __sup); std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_sup = __sup; _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; /** @brief Base class for unguarded _LoserTree implementation. * * The whole element is copied into the tree structure. * * No guarding is done, therefore not a single input sequence must * run empty. Unused __sequence heads are marked with a sentinel which * is > all elements that are to be merged. * * This is a very fast variant. */ template<typename _Tp, typename _Compare> class _LoserTreeUnguardedBase { protected: struct _Loser { int _M_source; _Tp _M_key; }; unsigned int _M_ik, _M_k, _M_offset; _Loser* _M_losers; _Compare _M_comp; public: _LoserTreeUnguardedBase(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _M_comp(__comp) { _M_ik = __k; // Next greater power of 2. _M_k = 1 << (__rd_log2(_M_ik - 1) + 1); _M_offset = _M_k; // Avoid default-constructing _M_losers[]._M_key _M_losers = static_cast<_Loser*>(::operator new(2 * _M_k * sizeof(_Loser))); for (unsigned int __i = 0; __i < _M_k; ++__i) { ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel); _M_losers[__i]._M_source = -1; } for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i) { ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel); _M_losers[__i]._M_source = -1; } } ~_LoserTreeUnguardedBase() { for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) _M_losers[__i].~_Loser(); ::operator delete(_M_losers); } int __get_min_source() { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif return _M_losers[0]._M_source; } void __insert_start(const _Tp& __key, int __source, bool) { unsigned int __pos = _M_k + __source; ::new(&(_M_losers[__pos]._M_key)) _Tp(__key); _M_losers[__pos]._M_source = __source; } }; /** * @brief Stable implementation of unguarded _LoserTree. * * Unstable variant is selected below with partial specialization. */ template<bool __stable/* default == true */, typename _Tp, typename _Compare> class _LoserTreeUnguarded : public _LoserTreeUnguardedBase<_Tp, _Compare> { typedef _LoserTreeUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreeUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (!_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } // Do not pass a const reference since __key will be used as // local variable. void __delete_min_insert(_Tp __key, bool) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by _M_source. if (_M_comp(_M_losers[__pos]._M_key, __key) || (!_M_comp(__key, _M_losers[__pos]._M_key) && _M_losers[__pos]._M_source < __source)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** * @brief Non-Stable implementation of unguarded _LoserTree. * * Stable implementation is above. */ template<typename _Tp, typename _Compare> class _LoserTreeUnguarded</* __stable == */false, _Tp, _Compare> : public _LoserTreeUnguardedBase<_Tp, _Compare> { typedef _LoserTreeUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreeUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); #if _GLIBCXX_PARALLEL_ASSERTIONS // If __left one is sentinel then __right one must be, too. if (_M_losers[__left]._M_source == -1) _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1); #endif if (!_M_comp(_M_losers[__right]._M_key, _M_losers[__left]._M_key)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } // Do not pass a const reference since __key will be used as // local variable. void __delete_min_insert(_Tp __key, bool) { using std::swap; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (_M_comp(_M_losers[__pos]._M_key, __key)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); swap(_M_losers[__pos]._M_key, __key); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_key = __key; } }; /** @brief Unguarded loser tree, keeping only pointers to the * elements in the tree structure. * * No guarding is done, therefore not a single input sequence must * run empty. This is a very fast variant. */ template<typename _Tp, typename _Compare> class _LoserTreePointerUnguardedBase { protected: struct _Loser { int _M_source; const _Tp* _M_keyp; }; unsigned int _M_ik, _M_k, _M_offset; _Loser* _M_losers; _Compare _M_comp; public: _LoserTreePointerUnguardedBase(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _M_comp(__comp) { _M_ik = __k; // Next greater power of 2. _M_k = 1 << (__rd_log2(_M_ik - 1) + 1); _M_offset = _M_k; // Avoid default-constructing _M_losers[]._M_key _M_losers = new _Loser[2 * _M_k]; for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i) { _M_losers[__i]._M_keyp = &__sentinel; _M_losers[__i]._M_source = -1; } } ~_LoserTreePointerUnguardedBase() { delete[] _M_losers; } int __get_min_source() { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif return _M_losers[0]._M_source; } void __insert_start(const _Tp& __key, int __source, bool) { unsigned int __pos = _M_k + __source; _M_losers[__pos]._M_keyp = &__key; _M_losers[__pos]._M_source = __source; } }; /** * @brief Stable unguarded _LoserTree variant storing pointers. * * Unstable variant is implemented below using partial specialization. */ template<bool __stable/* default == true */, typename _Tp, typename _Compare> class _LoserTreePointerUnguarded : public _LoserTreePointerUnguardedBase<_Tp, _Compare> { typedef _LoserTreePointerUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointerUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); if (!_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted, ties are broken by _M_source. if (_M_comp(*_M_losers[__pos]._M_keyp, *__keyp) || (!_M_comp(*__keyp, *_M_losers[__pos]._M_keyp) && _M_losers[__pos]._M_source < __source)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; /** * @brief Unstable unguarded _LoserTree variant storing pointers. * * Stable variant is above. */ template<typename _Tp, typename _Compare> class _LoserTreePointerUnguarded</* __stable == */false, _Tp, _Compare> : public _LoserTreePointerUnguardedBase<_Tp, _Compare> { typedef _LoserTreePointerUnguardedBase<_Tp, _Compare> _Base; using _Base::_M_k; using _Base::_M_comp; using _Base::_M_losers; public: _LoserTreePointerUnguarded(unsigned int __k, const _Tp& __sentinel, _Compare __comp = std::less<_Tp>()) : _Base::_LoserTreePointerUnguardedBase(__k, __sentinel, __comp) { } unsigned int __init_winner(unsigned int __root) { if (__root >= _M_k) return __root; else { unsigned int __left = __init_winner(2 * __root); unsigned int __right = __init_winner(2 * __root + 1); #if _GLIBCXX_PARALLEL_ASSERTIONS // If __left one is sentinel then __right one must be, too. if (_M_losers[__left]._M_source == -1) _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1); #endif if (!_M_comp(*_M_losers[__right]._M_keyp, *_M_losers[__left]._M_keyp)) { // Left one is less or equal. _M_losers[__root] = _M_losers[__right]; return __left; } else { // Right one is less. _M_losers[__root] = _M_losers[__left]; return __right; } } } void __init() { _M_losers[0] = _M_losers[__init_winner(1)]; #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top at the beginning // (0 sequences!) _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif } void __delete_min_insert(const _Tp& __key, bool __sup) { #if _GLIBCXX_PARALLEL_ASSERTIONS // no dummy sequence can ever be at the top! _GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1); #endif const _Tp* __keyp = &__key; int __source = _M_losers[0]._M_source; for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0; __pos /= 2) { // The smaller one gets promoted. if (_M_comp(*(_M_losers[__pos]._M_keyp), *__keyp)) { // The other one is smaller. std::swap(_M_losers[__pos]._M_source, __source); std::swap(_M_losers[__pos]._M_keyp, __keyp); } } _M_losers[0]._M_source = __source; _M_losers[0]._M_keyp = __keyp; } }; } // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_LOSERTREE_H */ c++/8/parallel/omp_loop.h 0000644 00000007677 15146341150 0011075 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/omp_loop.h * @brief Parallelization of embarrassingly parallel execution by * means of an OpenMP for loop. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_OMP_LOOP_H #define _GLIBCXX_PARALLEL_OMP_LOOP_H 1 #include <omp.h> #include <parallel/settings.h> #include <parallel/basic_iterator.h> #include <parallel/base.h> namespace __gnu_parallel { /** @brief Embarrassingly parallel algorithm for random access * iterators, using an OpenMP for loop. * * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __o User-supplied functor (comparator, predicate, adding * functor, etc.). * @param __f Functor to @a process an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to @a add a single __result to the already * processed elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template<typename _RAIter, typename _Op, typename _Fu, typename _Red, typename _Result> _Op __for_each_template_random_access_omp_loop(_RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { typedef typename std::iterator_traits<_RAIter>::difference_type _DifferenceType; _DifferenceType __length = __end - __begin; _ThreadIndex __num_threads = __gnu_parallel::min<_DifferenceType> (__get_max_threads(), __length); _Result *__thread_results; # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __thread_results = new _Result[__num_threads]; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __thread_results[__i] = _Result(); } _ThreadIndex __iam = omp_get_thread_num(); #pragma omp for schedule(dynamic, _Settings::get().workstealing_chunk_size) for (_DifferenceType __pos = 0; __pos < __length; ++__pos) __thread_results[__iam] = __r(__thread_results[__iam], __f(__o, __begin+__pos)); } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) __output = __r(__output, __thread_results[__i]); delete [] __thread_results; // Points to last element processed (needed as return value for // some algorithms like transform). __f._M_finish_iterator = __begin + __length; return __o; } } // end namespace #endif /* _GLIBCXX_PARALLEL_OMP_LOOP_H */ c++/8/parallel/basic_iterator.h 0000644 00000003062 15146341150 0012223 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/basic_iterator.h * @brief Includes the original header files concerned with iterators * except for stream iterators. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_BASIC_ITERATOR_H #define _GLIBCXX_PARALLEL_BASIC_ITERATOR_H 1 #include <bits/c++config.h> #include <bits/stl_iterator_base_types.h> #include <bits/stl_iterator_base_funcs.h> #include <bits/stl_iterator.h> #endif /* _GLIBCXX_PARALLEL_BASIC_ITERATOR_H */ c++/8/parallel/equally_split.h 0000644 00000006434 15146341150 0012126 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/equally_split.h * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H #define _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H 1 namespace __gnu_parallel { /** @brief function to split a sequence into parts of almost equal size. * * The resulting sequence __s of length __num_threads+1 contains the * splitting positions when splitting the range [0,__n) into parts of * almost equal size (plus minus 1). The first entry is 0, the last * one n. There may result empty parts. * @param __n Number of elements * @param __num_threads Number of parts * @param __s Splitters * @returns End of __splitter sequence, i.e. @c __s+__num_threads+1 */ template<typename _DifferenceType, typename _OutputIterator> _OutputIterator __equally_split(_DifferenceType __n, _ThreadIndex __num_threads, _OutputIterator __s) { _DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __num_longer_chunks = __n % __num_threads; _DifferenceType __pos = 0; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { *__s++ = __pos; __pos += ((__i < __num_longer_chunks) ? (__chunk_length + 1) : __chunk_length); } *__s++ = __n; return __s; } /** @brief function to split a sequence into parts of almost equal size. * * Returns the position of the splitting point between * thread number __thread_no (included) and * thread number __thread_no+1 (excluded). * @param __n Number of elements * @param __num_threads Number of parts * @param __thread_no Number of threads * @returns splitting point */ template<typename _DifferenceType> _DifferenceType __equally_split_point(_DifferenceType __n, _ThreadIndex __num_threads, _ThreadIndex __thread_no) { _DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __num_longer_chunks = __n % __num_threads; if (__thread_no < __num_longer_chunks) return __thread_no * (__chunk_length + 1); else return __num_longer_chunks * (__chunk_length + 1) + (__thread_no - __num_longer_chunks) * __chunk_length; } } #endif /* _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H */ c++/8/parallel/sort.h 0000644 00000017035 15146341150 0010225 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/sort.h * @brief Parallel sorting algorithm switch. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_SORT_H #define _GLIBCXX_PARALLEL_SORT_H 1 #include <parallel/basic_iterator.h> #include <parallel/features.h> #include <parallel/parallel.h> #if _GLIBCXX_PARALLEL_ASSERTIONS #include <parallel/checkers.h> #endif #if _GLIBCXX_MERGESORT #include <parallel/multiway_mergesort.h> #endif #if _GLIBCXX_QUICKSORT #include <parallel/quicksort.h> #endif #if _GLIBCXX_BAL_QUICKSORT #include <parallel/balanced_quicksort.h> #endif namespace __gnu_parallel { //prototype template<bool __stable, typename _RAIter, typename _Compare, typename _Parallelism> void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, _Parallelism __parallelism); /** * @brief Choose multiway mergesort, splitting variant at run-time, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template<bool __stable, typename _RAIter, typename _Compare> inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) if(_Settings::get().sort_splitting == EXACT) parallel_sort_mwms<__stable, true> (__begin, __end, __comp, __parallelism.__get_num_threads()); else parallel_sort_mwms<__stable, false> (__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose multiway mergesort with exact splitting, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template<bool __stable, typename _RAIter, typename _Compare> inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_exact_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) parallel_sort_mwms<__stable, true> (__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose multiway mergesort with splitting by sampling, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template<bool __stable, typename _RAIter, typename _Compare> inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_sampling_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) parallel_sort_mwms<__stable, false> (__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose quicksort for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template<bool __stable, typename _RAIter, typename _Compare> inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, quicksort_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) _GLIBCXX_PARALLEL_ASSERT(__stable == false); __parallel_sort_qs(__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose balanced quicksort for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template<bool __stable, typename _RAIter, typename _Compare> inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, balanced_quicksort_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) _GLIBCXX_PARALLEL_ASSERT(__stable == false); __parallel_sort_qsb(__begin, __end, __comp, __parallelism.__get_num_threads()); } /** * @brief Choose multiway mergesort with exact splitting, * for parallel sorting. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template<bool __stable, typename _RAIter, typename _Compare> inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, default_parallel_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) __parallel_sort<__stable> (__begin, __end, __comp, multiway_mergesort_exact_tag(__parallelism.__get_num_threads())); } /** * @brief Choose a parallel sorting algorithm. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __comp Comparator. * @tparam __stable Sort stable. * @callgraph */ template<bool __stable, typename _RAIter, typename _Compare> inline void __parallel_sort(_RAIter __begin, _RAIter __end, _Compare __comp, parallel_tag __parallelism) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; if (false) ; #if _GLIBCXX_MERGESORT else if (__stable || _Settings::get().sort_algorithm == MWMS) { if(_Settings::get().sort_splitting == EXACT) parallel_sort_mwms<__stable, true> (__begin, __end, __comp, __parallelism.__get_num_threads()); else parallel_sort_mwms<false, false> (__begin, __end, __comp, __parallelism.__get_num_threads()); } #endif #if _GLIBCXX_QUICKSORT else if (_Settings::get().sort_algorithm == QS) __parallel_sort_qs(__begin, __end, __comp, __parallelism.__get_num_threads()); #endif #if _GLIBCXX_BAL_QUICKSORT else if (_Settings::get().sort_algorithm == QS_BALANCED) __parallel_sort_qsb(__begin, __end, __comp, __parallelism.__get_num_threads()); #endif else __gnu_sequential::sort(__begin, __end, __comp); } } // end namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_SORT_H */ c++/8/parallel/queue.h 0000644 00000012646 15146341150 0010365 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/queue.h * @brief Lock-free double-ended queue. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_QUEUE_H #define _GLIBCXX_PARALLEL_QUEUE_H 1 #include <parallel/types.h> #include <parallel/base.h> #include <parallel/compatibility.h> /** @brief Decide whether to declare certain variable volatile in this file. */ #define _GLIBCXX_VOLATILE volatile namespace __gnu_parallel { /**@brief Double-ended queue of bounded size, allowing lock-free * atomic access. push_front() and pop_front() must not be called * concurrently to each other, while pop_back() can be called * concurrently at all times. * @c empty(), @c size(), and @c top() are intentionally not provided. * Calling them would not make sense in a concurrent setting. * @param _Tp Contained element type. */ template<typename _Tp> class _RestrictedBoundedConcurrentQueue { private: /** @brief Array of elements, seen as cyclic buffer. */ _Tp* _M_base; /** @brief Maximal number of elements contained at the same time. */ _SequenceIndex _M_max_size; /** @brief Cyclic __begin and __end pointers contained in one atomically changeable value. */ _GLIBCXX_VOLATILE _CASable _M_borders; public: /** @brief Constructor. Not to be called concurrent, of course. * @param __max_size Maximal number of elements to be contained. */ _RestrictedBoundedConcurrentQueue(_SequenceIndex __max_size) { _M_max_size = __max_size; _M_base = new _Tp[__max_size]; _M_borders = __encode2(0, 0); #pragma omp flush } /** @brief Destructor. Not to be called concurrent, of course. */ ~_RestrictedBoundedConcurrentQueue() { delete[] _M_base; } /** @brief Pushes one element into the queue at the front end. * Must not be called concurrently with pop_front(). */ void push_front(const _Tp& __t) { _CASable __former_borders = _M_borders; int __former_front, __former_back; __decode2(__former_borders, __former_front, __former_back); *(_M_base + __former_front % _M_max_size) = __t; #if _GLIBCXX_PARALLEL_ASSERTIONS // Otherwise: front - back > _M_max_size eventually. _GLIBCXX_PARALLEL_ASSERT(((__former_front + 1) - __former_back) <= _M_max_size); #endif __fetch_and_add(&_M_borders, __encode2(1, 0)); } /** @brief Pops one element from the queue at the front end. * Must not be called concurrently with pop_front(). */ bool pop_front(_Tp& __t) { int __former_front, __former_back; #pragma omp flush __decode2(_M_borders, __former_front, __former_back); while (__former_front > __former_back) { // Chance. _CASable __former_borders = __encode2(__former_front, __former_back); _CASable __new_borders = __encode2(__former_front - 1, __former_back); if (__compare_and_swap(&_M_borders, __former_borders, __new_borders)) { __t = *(_M_base + (__former_front - 1) % _M_max_size); return true; } #pragma omp flush __decode2(_M_borders, __former_front, __former_back); } return false; } /** @brief Pops one element from the queue at the front end. * Must not be called concurrently with pop_front(). */ bool pop_back(_Tp& __t) //queue behavior { int __former_front, __former_back; #pragma omp flush __decode2(_M_borders, __former_front, __former_back); while (__former_front > __former_back) { // Chance. _CASable __former_borders = __encode2(__former_front, __former_back); _CASable __new_borders = __encode2(__former_front, __former_back + 1); if (__compare_and_swap(&_M_borders, __former_borders, __new_borders)) { __t = *(_M_base + __former_back % _M_max_size); return true; } #pragma omp flush __decode2(_M_borders, __former_front, __former_back); } return false; } }; } //namespace __gnu_parallel #undef _GLIBCXX_VOLATILE #endif /* _GLIBCXX_PARALLEL_QUEUE_H */ c++/8/parallel/multiway_mergesort.h 0000644 00000035647 15146341150 0013211 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/multiway_mergesort.h * @brief Parallel multiway merge sort. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H #define _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H 1 #include <vector> #include <parallel/basic_iterator.h> #include <bits/stl_algo.h> #include <parallel/parallel.h> #include <parallel/multiway_merge.h> namespace __gnu_parallel { /** @brief Subsequence description. */ template<typename _DifferenceTp> struct _Piece { typedef _DifferenceTp _DifferenceType; /** @brief Begin of subsequence. */ _DifferenceType _M_begin; /** @brief End of subsequence. */ _DifferenceType _M_end; }; /** @brief Data accessed by all threads. * * PMWMS = parallel multiway mergesort */ template<typename _RAIter> struct _PMWMSSortingData { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; /** @brief Number of threads involved. */ _ThreadIndex _M_num_threads; /** @brief Input __begin. */ _RAIter _M_source; /** @brief Start indices, per thread. */ _DifferenceType* _M_starts; /** @brief Storage in which to sort. */ _ValueType** _M_temporary; /** @brief Samples. */ _ValueType* _M_samples; /** @brief Offsets to add to the found positions. */ _DifferenceType* _M_offsets; /** @brief Pieces of data to merge @c [thread][__sequence] */ std::vector<_Piece<_DifferenceType> >* _M_pieces; }; /** * @brief Select _M_samples from a sequence. * @param __sd Pointer to algorithm data. _Result will be placed in * @c __sd->_M_samples. * @param __num_samples Number of _M_samples to select. */ template<typename _RAIter, typename _DifferenceTp> void __determine_samples(_PMWMSSortingData<_RAIter>* __sd, _DifferenceTp __num_samples) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef _DifferenceTp _DifferenceType; _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType* __es = new _DifferenceType[__num_samples + 2]; __equally_split(__sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam], __num_samples + 1, __es); for (_DifferenceType __i = 0; __i < __num_samples; ++__i) ::new(&(__sd->_M_samples[__iam * __num_samples + __i])) _ValueType(__sd->_M_source[__sd->_M_starts[__iam] + __es[__i + 1]]); delete[] __es; } /** @brief Split consistently. */ template<bool __exact, typename _RAIter, typename _Compare, typename _SortingPlacesIterator> struct _SplitConsistently { }; /** @brief Split by exact splitting. */ template<typename _RAIter, typename _Compare, typename _SortingPlacesIterator> struct _SplitConsistently<true, _RAIter, _Compare, _SortingPlacesIterator> { void operator()(const _ThreadIndex __iam, _PMWMSSortingData<_RAIter>* __sd, _Compare& __comp, const typename std::iterator_traits<_RAIter>::difference_type __num_samples) const { # pragma omp barrier std::vector<std::pair<_SortingPlacesIterator, _SortingPlacesIterator> > __seqs(__sd->_M_num_threads); for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; __s++) __seqs[__s] = std::make_pair(__sd->_M_temporary[__s], __sd->_M_temporary[__s] + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s])); std::vector<_SortingPlacesIterator> __offsets(__sd->_M_num_threads); // if not last thread if (__iam < __sd->_M_num_threads - 1) multiseq_partition(__seqs.begin(), __seqs.end(), __sd->_M_starts[__iam + 1], __offsets.begin(), __comp); for (_ThreadIndex __seq = 0; __seq < __sd->_M_num_threads; __seq++) { // for each sequence if (__iam < (__sd->_M_num_threads - 1)) __sd->_M_pieces[__iam][__seq]._M_end = __offsets[__seq] - __seqs[__seq].first; else // very end of this sequence __sd->_M_pieces[__iam][__seq]._M_end = __sd->_M_starts[__seq + 1] - __sd->_M_starts[__seq]; } # pragma omp barrier for (_ThreadIndex __seq = 0; __seq < __sd->_M_num_threads; __seq++) { // For each sequence. if (__iam > 0) __sd->_M_pieces[__iam][__seq]._M_begin = __sd->_M_pieces[__iam - 1][__seq]._M_end; else // Absolute beginning. __sd->_M_pieces[__iam][__seq]._M_begin = 0; } } }; /** @brief Split by sampling. */ template<typename _RAIter, typename _Compare, typename _SortingPlacesIterator> struct _SplitConsistently<false, _RAIter, _Compare, _SortingPlacesIterator> { void operator()(const _ThreadIndex __iam, _PMWMSSortingData<_RAIter>* __sd, _Compare& __comp, const typename std::iterator_traits<_RAIter>::difference_type __num_samples) const { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; __determine_samples(__sd, __num_samples); # pragma omp barrier # pragma omp single __gnu_sequential::sort(__sd->_M_samples, __sd->_M_samples + (__num_samples * __sd->_M_num_threads), __comp); # pragma omp barrier for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; ++__s) { // For each sequence. if (__num_samples * __iam > 0) __sd->_M_pieces[__iam][__s]._M_begin = std::lower_bound(__sd->_M_temporary[__s], __sd->_M_temporary[__s] + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]), __sd->_M_samples[__num_samples * __iam], __comp) - __sd->_M_temporary[__s]; else // Absolute beginning. __sd->_M_pieces[__iam][__s]._M_begin = 0; if ((__num_samples * (__iam + 1)) < (__num_samples * __sd->_M_num_threads)) __sd->_M_pieces[__iam][__s]._M_end = std::lower_bound(__sd->_M_temporary[__s], __sd->_M_temporary[__s] + (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]), __sd->_M_samples[__num_samples * (__iam + 1)], __comp) - __sd->_M_temporary[__s]; else // Absolute end. __sd->_M_pieces[__iam][__s]._M_end = (__sd->_M_starts[__s + 1] - __sd->_M_starts[__s]); } } }; template<bool __stable, typename _RAIter, typename _Compare> struct __possibly_stable_sort { }; template<typename _RAIter, typename _Compare> struct __possibly_stable_sort<true, _RAIter, _Compare> { void operator()(const _RAIter& __begin, const _RAIter& __end, _Compare& __comp) const { __gnu_sequential::stable_sort(__begin, __end, __comp); } }; template<typename _RAIter, typename _Compare> struct __possibly_stable_sort<false, _RAIter, _Compare> { void operator()(const _RAIter __begin, const _RAIter __end, _Compare& __comp) const { __gnu_sequential::sort(__begin, __end, __comp); } }; template<bool __stable, typename Seq_RAIter, typename _RAIter, typename _Compare, typename DiffType> struct __possibly_stable_multiway_merge { }; template<typename Seq_RAIter, typename _RAIter, typename _Compare, typename _DiffType> struct __possibly_stable_multiway_merge<true, Seq_RAIter, _RAIter, _Compare, _DiffType> { void operator()(const Seq_RAIter& __seqs_begin, const Seq_RAIter& __seqs_end, const _RAIter& __target, _Compare& __comp, _DiffType __length_am) const { stable_multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __comp, sequential_tag()); } }; template<typename Seq_RAIter, typename _RAIter, typename _Compare, typename _DiffType> struct __possibly_stable_multiway_merge<false, Seq_RAIter, _RAIter, _Compare, _DiffType> { void operator()(const Seq_RAIter& __seqs_begin, const Seq_RAIter& __seqs_end, const _RAIter& __target, _Compare& __comp, _DiffType __length_am) const { multiway_merge(__seqs_begin, __seqs_end, __target, __length_am, __comp, sequential_tag()); } }; /** @brief PMWMS code executed by each thread. * @param __sd Pointer to algorithm data. * @param __comp Comparator. */ template<bool __stable, bool __exact, typename _RAIter, typename _Compare> void parallel_sort_mwms_pu(_PMWMSSortingData<_RAIter>* __sd, _Compare& __comp) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _ThreadIndex __iam = omp_get_thread_num(); // Length of this thread's chunk, before merging. _DifferenceType __length_local = __sd->_M_starts[__iam + 1] - __sd->_M_starts[__iam]; // Sort in temporary storage, leave space for sentinel. typedef _ValueType* _SortingPlacesIterator; __sd->_M_temporary[__iam] = static_cast<_ValueType*>(::operator new(sizeof(_ValueType) * (__length_local + 1))); // Copy there. std::uninitialized_copy(__sd->_M_source + __sd->_M_starts[__iam], __sd->_M_source + __sd->_M_starts[__iam] + __length_local, __sd->_M_temporary[__iam]); __possibly_stable_sort<__stable, _SortingPlacesIterator, _Compare>() (__sd->_M_temporary[__iam], __sd->_M_temporary[__iam] + __length_local, __comp); // Invariant: locally sorted subsequence in sd->_M_temporary[__iam], // __sd->_M_temporary[__iam] + __length_local. // No barrier here: Synchronization is done by the splitting routine. _DifferenceType __num_samples = _Settings::get().sort_mwms_oversampling * __sd->_M_num_threads - 1; _SplitConsistently<__exact, _RAIter, _Compare, _SortingPlacesIterator>() (__iam, __sd, __comp, __num_samples); // Offset from __target __begin, __length after merging. _DifferenceType __offset = 0, __length_am = 0; for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; __s++) { __length_am += (__sd->_M_pieces[__iam][__s]._M_end - __sd->_M_pieces[__iam][__s]._M_begin); __offset += __sd->_M_pieces[__iam][__s]._M_begin; } typedef std::vector< std::pair<_SortingPlacesIterator, _SortingPlacesIterator> > _SeqVector; _SeqVector __seqs(__sd->_M_num_threads); for (_ThreadIndex __s = 0; __s < __sd->_M_num_threads; ++__s) { __seqs[__s] = std::make_pair(__sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s]._M_begin, __sd->_M_temporary[__s] + __sd->_M_pieces[__iam][__s]._M_end); } __possibly_stable_multiway_merge< __stable, typename _SeqVector::iterator, _RAIter, _Compare, _DifferenceType>()(__seqs.begin(), __seqs.end(), __sd->_M_source + __offset, __comp, __length_am); # pragma omp barrier for (_DifferenceType __i = 0; __i < __length_local; ++__i) __sd->_M_temporary[__iam][__i].~_ValueType(); ::operator delete(__sd->_M_temporary[__iam]); } /** @brief PMWMS main call. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator. * @param __num_threads Number of threads to use. */ template<bool __stable, bool __exact, typename _RAIter, typename _Compare> void parallel_sort_mwms(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; if (__n <= 1) return; // at least one element per thread if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); // shared variables _PMWMSSortingData<_RAIter> __sd; _DifferenceType* __starts; _DifferenceType __size; # pragma omp parallel num_threads(__num_threads) { __num_threads = omp_get_num_threads(); //no more threads than requested # pragma omp single { __sd._M_num_threads = __num_threads; __sd._M_source = __begin; __sd._M_temporary = new _ValueType*[__num_threads]; if (!__exact) { __size = (_Settings::get().sort_mwms_oversampling * __num_threads - 1) * __num_threads; __sd._M_samples = static_cast<_ValueType*> (::operator new(__size * sizeof(_ValueType))); } else __sd._M_samples = 0; __sd._M_offsets = new _DifferenceType[__num_threads - 1]; __sd._M_pieces = new std::vector<_Piece<_DifferenceType> >[__num_threads]; for (_ThreadIndex __s = 0; __s < __num_threads; ++__s) __sd._M_pieces[__s].resize(__num_threads); __starts = __sd._M_starts = new _DifferenceType[__num_threads + 1]; _DifferenceType __chunk_length = __n / __num_threads; _DifferenceType __split = __n % __num_threads; _DifferenceType __pos = 0; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { __starts[__i] = __pos; __pos += ((__i < __split) ? (__chunk_length + 1) : __chunk_length); } __starts[__num_threads] = __pos; } //single // Now sort in parallel. parallel_sort_mwms_pu<__stable, __exact>(&__sd, __comp); } //parallel delete[] __starts; delete[] __sd._M_temporary; if (!__exact) { for (_DifferenceType __i = 0; __i < __size; ++__i) __sd._M_samples[__i].~_ValueType(); ::operator delete(__sd._M_samples); } delete[] __sd._M_offsets; delete[] __sd._M_pieces; } } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H */ c++/8/parallel/for_each_selectors.h 0000644 00000024505 15146341150 0013067 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/for_each_selectors.h * @brief Functors representing different tasks to be plugged into the * generic parallelization methods for embarrassingly parallel functions. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H #define _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H 1 #include <parallel/basic_iterator.h> namespace __gnu_parallel { /** @brief Generic __selector for embarrassingly parallel functions. */ template<typename _It> struct __generic_for_each_selector { /** @brief _Iterator on last element processed; needed for some * algorithms (e. g. std::transform()). */ _It _M_finish_iterator; }; /** @brief std::for_each() selector. */ template<typename _It> struct __for_each_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template<typename _Op> bool operator()(_Op& __o, _It __i) { __o(*__i); return true; } }; /** @brief std::generate() selector. */ template<typename _It> struct __generate_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template<typename _Op> bool operator()(_Op& __o, _It __i) { *__i = __o(); return true; } }; /** @brief std::fill() selector. */ template<typename _It> struct __fill_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __v Current value. * @param __i iterator referencing object. */ template<typename _ValueType> bool operator()(_ValueType& __v, _It __i) { *__i = __v; return true; } }; /** @brief std::transform() __selector, one input sequence variant. */ template<typename _It> struct __transform1_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template<typename _Op> bool operator()(_Op& __o, _It __i) { *__i.second = __o(*__i.first); return true; } }; /** @brief std::transform() __selector, two input sequences variant. */ template<typename _It> struct __transform2_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ template<typename _Op> bool operator()(_Op& __o, _It __i) { *__i._M_third = __o(*__i._M_first, *__i._M_second); return true; } }; /** @brief std::replace() selector. */ template<typename _It, typename _Tp> struct __replace_selector : public __generic_for_each_selector<_It> { /** @brief Value to replace with. */ const _Tp& __new_val; /** @brief Constructor * @param __new_val Value to replace with. */ explicit __replace_selector(const _Tp &__new_val) : __new_val(__new_val) {} /** @brief Functor execution. * @param __v Current value. * @param __i iterator referencing object. */ bool operator()(_Tp& __v, _It __i) { if (*__i == __v) *__i = __new_val; return true; } }; /** @brief std::replace() selector. */ template<typename _It, typename _Op, typename _Tp> struct __replace_if_selector : public __generic_for_each_selector<_It> { /** @brief Value to replace with. */ const _Tp& __new_val; /** @brief Constructor. * @param __new_val Value to replace with. */ explicit __replace_if_selector(const _Tp &__new_val) : __new_val(__new_val) { } /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. */ bool operator()(_Op& __o, _It __i) { if (__o(*__i)) *__i = __new_val; return true; } }; /** @brief std::count() selector. */ template<typename _It, typename _Diff> struct __count_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __v Current value. * @param __i iterator referencing object. * @return 1 if count, 0 if does not count. */ template<typename _ValueType> _Diff operator()(_ValueType& __v, _It __i) { return (__v == *__i) ? 1 : 0; } }; /** @brief std::count_if () selector. */ template<typename _It, typename _Diff> struct __count_if_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator. * @param __i iterator referencing object. * @return 1 if count, 0 if does not count. */ template<typename _Op> _Diff operator()(_Op& __o, _It __i) { return (__o(*__i)) ? 1 : 0; } }; /** @brief std::accumulate() selector. */ template<typename _It> struct __accumulate_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator (unused). * @param __i iterator referencing object. * @return The current value. */ template<typename _Op> typename std::iterator_traits<_It>::value_type operator()(_Op __o, _It __i) { return *__i; } }; /** @brief std::inner_product() selector. */ template<typename _It, typename _It2, typename _Tp> struct __inner_product_selector : public __generic_for_each_selector<_It> { /** @brief Begin iterator of first sequence. */ _It __begin1_iterator; /** @brief Begin iterator of second sequence. */ _It2 __begin2_iterator; /** @brief Constructor. * @param __b1 Begin iterator of first sequence. * @param __b2 Begin iterator of second sequence. */ explicit __inner_product_selector(_It __b1, _It2 __b2) : __begin1_iterator(__b1), __begin2_iterator(__b2) { } /** @brief Functor execution. * @param __mult Multiplication functor. * @param __current iterator referencing object. * @return Inner product elemental __result. */ template<typename _Op> _Tp operator()(_Op __mult, _It __current) { typename std::iterator_traits<_It>::difference_type __position = __current - __begin1_iterator; return __mult(*__current, *(__begin2_iterator + __position)); } }; /** @brief Selector that just returns the passed iterator. */ template<typename _It> struct __identity_selector : public __generic_for_each_selector<_It> { /** @brief Functor execution. * @param __o Operator (unused). * @param __i iterator referencing object. * @return Passed iterator. */ template<typename _Op> _It operator()(_Op __o, _It __i) { return __i; } }; /** @brief Selector that returns the difference between two adjacent * __elements. */ template<typename _It> struct __adjacent_difference_selector : public __generic_for_each_selector<_It> { template<typename _Op> bool operator()(_Op& __o, _It __i) { typename _It::first_type __go_back_one = __i.first; --__go_back_one; *__i.second = __o(*__i.first, *__go_back_one); return true; } }; /** @brief Functor doing nothing * * For some __reduction tasks (this is not a function object, but is * passed as __selector __dummy parameter. */ struct _Nothing { /** @brief Functor execution. * @param __i iterator referencing object. */ template<typename _It> void operator()(_It __i) { } }; /** @brief Reduction function doing nothing. */ struct _DummyReduct { bool operator()(bool, bool) const { return true; } }; /** @brief Reduction for finding the maximum element, using a comparator. */ template<typename _Compare, typename _It> struct __min_element_reduct { _Compare& __comp; explicit __min_element_reduct(_Compare &__c) : __comp(__c) { } _It operator()(_It __x, _It __y) { return (__comp(*__x, *__y)) ? __x : __y; } }; /** @brief Reduction for finding the maximum element, using a comparator. */ template<typename _Compare, typename _It> struct __max_element_reduct { _Compare& __comp; explicit __max_element_reduct(_Compare& __c) : __comp(__c) { } _It operator()(_It __x, _It __y) { return (__comp(*__x, *__y)) ? __y : __x; } }; /** @brief General reduction, using a binary operator. */ template<typename _BinOp> struct __accumulate_binop_reduct { _BinOp& __binop; explicit __accumulate_binop_reduct(_BinOp& __b) : __binop(__b) { } template<typename _Result, typename _Addend> _Result operator()(const _Result& __x, const _Addend& __y) { return __binop(__x, __y); } }; } #endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */ c++/8/parallel/unique_copy.h 0000644 00000014025 15146341150 0011572 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/unique_copy.h * @brief Parallel implementations of std::unique_copy(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Robert Geisberger and Robin Dapp. #ifndef _GLIBCXX_PARALLEL_UNIQUE_COPY_H #define _GLIBCXX_PARALLEL_UNIQUE_COPY_H 1 #include <parallel/parallel.h> #include <parallel/multiseq_selection.h> namespace __gnu_parallel { /** @brief Parallel std::unique_copy(), w/__o explicit equality predicate. * @param __first Begin iterator of input sequence. * @param __last End iterator of input sequence. * @param __result Begin iterator of result __sequence. * @param __binary_pred Equality predicate. * @return End iterator of result __sequence. */ template<typename _IIter, class _OutputIterator, class _BinaryPredicate> _OutputIterator __parallel_unique_copy(_IIter __first, _IIter __last, _OutputIterator __result, _BinaryPredicate __binary_pred) { _GLIBCXX_CALL(__last - __first) typedef std::iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __size = __last - __first; if (__size == 0) return __result; // Let the first thread process two parts. _DifferenceType *__counter; _DifferenceType *__borders; _ThreadIndex __num_threads = __get_max_threads(); // First part contains at least one element. # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __borders = new _DifferenceType[__num_threads + 2]; __equally_split(__size, __num_threads + 1, __borders); __counter = new _DifferenceType[__num_threads + 1]; } _ThreadIndex __iam = omp_get_thread_num(); _DifferenceType __begin, __end; // Check for length without duplicates // Needed for position in output _DifferenceType __i = 0; _OutputIterator __out = __result; if (__iam == 0) { __begin = __borders[0] + 1; // == 1 __end = __borders[__iam + 1]; ++__i; *__out++ = *__first; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (!__binary_pred(*__iter, *(__iter - 1))) { ++__i; *__out++ = *__iter; } } } else { __begin = __borders[__iam]; //one part __end = __borders[__iam + 1]; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (!__binary_pred(*__iter, *(__iter - 1))) ++__i; } } __counter[__iam] = __i; // Last part still untouched. _DifferenceType __begin_output; # pragma omp barrier // Store result in output on calculated positions. __begin_output = 0; if (__iam == 0) { for (_ThreadIndex __t = 0; __t < __num_threads; ++__t) __begin_output += __counter[__t]; __i = 0; _OutputIterator __iter_out = __result + __begin_output; __begin = __borders[__num_threads]; __end = __size; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (__iter == __first || !__binary_pred(*__iter, *(__iter - 1))) { ++__i; *__iter_out++ = *__iter; } } __counter[__num_threads] = __i; } else { for (_ThreadIndex __t = 0; __t < __iam; __t++) __begin_output += __counter[__t]; _OutputIterator __iter_out = __result + __begin_output; for (_IIter __iter = __first + __begin; __iter < __first + __end; ++__iter) { if (!__binary_pred(*__iter, *(__iter - 1))) *__iter_out++ = *__iter; } } } _DifferenceType __end_output = 0; for (_ThreadIndex __t = 0; __t < __num_threads + 1; __t++) __end_output += __counter[__t]; delete[] __borders; return __result + __end_output; } /** @brief Parallel std::unique_copy(), without explicit equality predicate * @param __first Begin iterator of input sequence. * @param __last End iterator of input sequence. * @param __result Begin iterator of result __sequence. * @return End iterator of result __sequence. */ template<typename _IIter, class _OutputIterator> inline _OutputIterator __parallel_unique_copy(_IIter __first, _IIter __last, _OutputIterator __result) { typedef typename std::iterator_traits<_IIter>::value_type _ValueType; return __parallel_unique_copy(__first, __last, __result, std::equal_to<_ValueType>()); } }//namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_UNIQUE_COPY_H */ c++/8/parallel/numericfwd.h 0000644 00000016514 15146341150 0011402 0 ustar 00 // <parallel/numeric> Forward declarations -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/numericfwd.h * This file is a GNU parallel extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PARALLEL_NUMERICFWD_H #define _GLIBCXX_PARALLEL_NUMERICFWD_H 1 #pragma GCC system_header #include <parallel/tags.h> #include <parallel/settings.h> namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { template<typename _IIter, typename _Tp> _Tp accumulate(_IIter, _IIter, _Tp); template<typename _IIter, typename _Tp> _Tp accumulate(_IIter, _IIter, _Tp, __gnu_parallel::sequential_tag); template<typename _IIter, typename _Tp> _Tp accumulate(_IIter, _IIter, _Tp, __gnu_parallel::_Parallelism); template<typename _IIter, typename _Tp, typename _Tag> _Tp __accumulate_switch(_IIter, _IIter, _Tp, _Tag); template<typename _IIter, typename _Tp, typename _BinaryOper> _Tp accumulate(_IIter, _IIter, _Tp, _BinaryOper); template<typename _IIter, typename _Tp, typename _BinaryOper> _Tp accumulate(_IIter, _IIter, _Tp, _BinaryOper, __gnu_parallel::sequential_tag); template<typename _IIter, typename _Tp, typename _BinaryOper> _Tp accumulate(_IIter, _IIter, _Tp, _BinaryOper, __gnu_parallel::_Parallelism); template<typename _IIter, typename _Tp, typename _BinaryOper, typename _Tag> _Tp __accumulate_switch(_IIter, _IIter, _Tp, _BinaryOper, _Tag); template<typename _RAIter, typename _Tp, typename _BinaryOper> _Tp __accumulate_switch(_RAIter, _RAIter, _Tp, _BinaryOper, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); template<typename _IIter, typename _OIter> _OIter adjacent_difference(_IIter, _IIter, _OIter); template<typename _IIter, typename _OIter, typename _BinaryOper> _OIter adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper); template<typename _IIter, typename _OIter> _OIter adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); template<typename _IIter, typename _OIter, typename _BinaryOper> _OIter adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag); template<typename _IIter, typename _OIter> _OIter adjacent_difference(_IIter, _IIter, _OIter, __gnu_parallel::_Parallelism); template<typename _IIter, typename _OIter, typename _BinaryOper> _OIter adjacent_difference(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::_Parallelism); template<typename _IIter, typename _OIter, typename _BinaryOper, typename _Tag1, typename _Tag2> _OIter __adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2); template<typename _IIter, typename _OIter, typename _BinaryOper> _OIter __adjacent_difference_switch(_IIter, _IIter, _OIter, _BinaryOper, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); template<typename _IIter1, typename _IIter2, typename _Tp> _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp); template<typename _IIter1, typename _IIter2, typename _Tp> _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _Tp> _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, __gnu_parallel::_Parallelism); template<typename _IIter1, typename _IIter2, typename _Tp, typename _BinaryFunction1, typename _BinaryFunction2> _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2); template<typename _IIter1, typename _IIter2, typename _Tp, typename _BinaryFunction1, typename _BinaryFunction2> _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _Tp, typename BinaryFunction1, typename BinaryFunction2> _Tp inner_product(_IIter1, _IIter1, _IIter2, _Tp, BinaryFunction1, BinaryFunction2, __gnu_parallel::_Parallelism); template<typename _RAIter1, typename _RAIter2, typename _Tp, typename BinaryFunction1, typename BinaryFunction2> _Tp __inner_product_switch(_RAIter1, _RAIter1, _RAIter2, _Tp, BinaryFunction1, BinaryFunction2, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism = __gnu_parallel::parallel_unbalanced); template<typename _IIter1, typename _IIter2, typename _Tp, typename _BinaryFunction1, typename _BinaryFunction2, typename _Tag1, typename _Tag2> _Tp __inner_product_switch(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2, _Tag1, _Tag2); template<typename _IIter, typename _OIter> _OIter partial_sum(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); template<typename _IIter, typename _OIter, typename _BinaryOper> _OIter partial_sum(_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag); template<typename _IIter, typename _OIter> _OIter partial_sum(_IIter, _IIter, _OIter __result); template<typename _IIter, typename _OIter, typename _BinaryOper> _OIter partial_sum(_IIter, _IIter, _OIter, _BinaryOper); template<typename _IIter, typename _OIter, typename _BinaryOper, typename _Tag1, typename _Tag2> _OIter __partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2); template<typename _IIter, typename _OIter, typename _BinaryOper> _OIter __partial_sum_switch(_IIter, _IIter, _OIter, _BinaryOper, random_access_iterator_tag, random_access_iterator_tag); } // end namespace } // end namespace #endif /* _GLIBCXX_PARALLEL_NUMERICFWD_H */ c++/8/parallel/algorithmfwd.h 0000644 00000076716 15146341150 0011740 0 ustar 00 // <parallel/algorithm> Forward declarations -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/algorithmfwd.h * This file is a GNU parallel extension to the Standard C++ Library. */ #ifndef _GLIBCXX_PARALLEL_ALGORITHMFWD_H #define _GLIBCXX_PARALLEL_ALGORITHMFWD_H 1 #pragma GCC system_header #include <parallel/tags.h> #include <parallel/settings.h> namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { template<typename _FIter> _FIter adjacent_find(_FIter, _FIter); template<typename _FIter> _FIter adjacent_find(_FIter, _FIter, __gnu_parallel::sequential_tag); template<typename _FIter, typename _IterTag> _FIter __adjacent_find_switch(_FIter, _FIter, _IterTag); template<typename _RAIter> _RAIter __adjacent_find_switch(_RAIter, _RAIter, random_access_iterator_tag); template<typename _FIter, typename _BiPredicate> _FIter adjacent_find(_FIter, _FIter, _BiPredicate); template<typename _FIter, typename _BiPredicate> _FIter adjacent_find(_FIter, _FIter, _BiPredicate, __gnu_parallel::sequential_tag); template<typename _FIter, typename _BiPredicate, typename _IterTag> _FIter __adjacent_find_switch(_FIter, _FIter, _BiPredicate, _IterTag); template<typename _RAIter, typename _BiPredicate> _RAIter __adjacent_find_switch(_RAIter, _RAIter, _BiPredicate, random_access_iterator_tag); template<typename _IIter, typename _Tp> typename iterator_traits<_IIter>::difference_type count(_IIter, _IIter, const _Tp&); template<typename _IIter, typename _Tp> typename iterator_traits<_IIter>::difference_type count(_IIter, _IIter, const _Tp&, __gnu_parallel::sequential_tag); template<typename _IIter, typename _Tp> typename iterator_traits<_IIter>::difference_type count(_IIter, _IIter, const _Tp&, __gnu_parallel::_Parallelism); template<typename _IIter, typename _Tp, typename _IterTag> typename iterator_traits<_IIter>::difference_type __count_switch(_IIter, _IIter, const _Tp&, _IterTag); template<typename _RAIter, typename _Tp> typename iterator_traits<_RAIter>::difference_type __count_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); template<typename _IIter, typename _Predicate> typename iterator_traits<_IIter>::difference_type count_if(_IIter, _IIter, _Predicate); template<typename _IIter, typename _Predicate> typename iterator_traits<_IIter>::difference_type count_if(_IIter, _IIter, _Predicate, __gnu_parallel::sequential_tag); template<typename _IIter, typename _Predicate> typename iterator_traits<_IIter>::difference_type count_if(_IIter, _IIter, _Predicate, __gnu_parallel::_Parallelism); template<typename _IIter, typename _Predicate, typename _IterTag> typename iterator_traits<_IIter>::difference_type __count_if_switch(_IIter, _IIter, _Predicate, _IterTag); template<typename _RAIter, typename _Predicate> typename iterator_traits<_RAIter>::difference_type __count_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_unbalanced); // algobase.h template<typename _IIter1, typename _IIter2> bool equal(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _Predicate> bool equal(_IIter1, _IIter1, _IIter2, _Predicate, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2> bool equal(_IIter1, _IIter1, _IIter2); template<typename _IIter1, typename _IIter2, typename _Predicate> bool equal(_IIter1, _IIter1, _IIter2, _Predicate); template<typename _IIter, typename _Tp> _IIter find(_IIter, _IIter, const _Tp&, __gnu_parallel::sequential_tag); template<typename _IIter, typename _Tp> _IIter find(_IIter, _IIter, const _Tp& __val); template<typename _IIter, typename _Tp, typename _IterTag> _IIter __find_switch(_IIter, _IIter, const _Tp&, _IterTag); template<typename _RAIter, typename _Tp> _RAIter __find_switch(_RAIter, _RAIter, const _Tp&, random_access_iterator_tag); template<typename _IIter, typename _Predicate> _IIter find_if(_IIter, _IIter, _Predicate, __gnu_parallel::sequential_tag); template<typename _IIter, typename _Predicate> _IIter find_if(_IIter, _IIter, _Predicate); template<typename _IIter, typename _Predicate, typename _IterTag> _IIter __find_if_switch(_IIter, _IIter, _Predicate, _IterTag); template<typename _RAIter, typename _Predicate> _RAIter __find_if_switch(_RAIter, _RAIter, _Predicate, random_access_iterator_tag); template<typename _IIter, typename _FIter> _IIter find_first_of(_IIter, _IIter, _FIter, _FIter, __gnu_parallel::sequential_tag); template<typename _IIter, typename _FIter, typename _BiPredicate> _IIter find_first_of(_IIter, _IIter, _FIter, _FIter, _BiPredicate, __gnu_parallel::sequential_tag); template<typename _IIter, typename _FIter, typename _BiPredicate> _IIter find_first_of(_IIter, _IIter, _FIter, _FIter, _BiPredicate); template<typename _IIter, typename _FIter> _IIter find_first_of(_IIter, _IIter, _FIter, _FIter); template<typename _IIter, typename _FIter, typename _IterTag1, typename _IterTag2> _IIter __find_first_of_switch( _IIter, _IIter, _FIter, _FIter, _IterTag1, _IterTag2); template<typename _RAIter, typename _FIter, typename _BiPredicate, typename _IterTag> _RAIter __find_first_of_switch(_RAIter, _RAIter, _FIter, _FIter, _BiPredicate, random_access_iterator_tag, _IterTag); template<typename _IIter, typename _FIter, typename _BiPredicate, typename _IterTag1, typename _IterTag2> _IIter __find_first_of_switch(_IIter, _IIter, _FIter, _FIter, _BiPredicate, _IterTag1, _IterTag2); template<typename _IIter, typename _Function> _Function for_each(_IIter, _IIter, _Function); template<typename _IIter, typename _Function> _Function for_each(_IIter, _IIter, _Function, __gnu_parallel::sequential_tag); template<typename _Iterator, typename _Function> _Function for_each(_Iterator, _Iterator, _Function, __gnu_parallel::_Parallelism); template<typename _IIter, typename _Function, typename _IterTag> _Function __for_each_switch(_IIter, _IIter, _Function, _IterTag); template<typename _RAIter, typename _Function> _Function __for_each_switch(_RAIter, _RAIter, _Function, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template<typename _FIter, typename _Generator> void generate(_FIter, _FIter, _Generator); template<typename _FIter, typename _Generator> void generate(_FIter, _FIter, _Generator, __gnu_parallel::sequential_tag); template<typename _FIter, typename _Generator> void generate(_FIter, _FIter, _Generator, __gnu_parallel::_Parallelism); template<typename _FIter, typename _Generator, typename _IterTag> void __generate_switch(_FIter, _FIter, _Generator, _IterTag); template<typename _RAIter, typename _Generator> void __generate_switch(_RAIter, _RAIter, _Generator, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template<typename _OIter, typename _Size, typename _Generator> _OIter generate_n(_OIter, _Size, _Generator); template<typename _OIter, typename _Size, typename _Generator> _OIter generate_n(_OIter, _Size, _Generator, __gnu_parallel::sequential_tag); template<typename _OIter, typename _Size, typename _Generator> _OIter generate_n(_OIter, _Size, _Generator, __gnu_parallel::_Parallelism); template<typename _OIter, typename _Size, typename _Generator, typename _IterTag> _OIter __generate_n_switch(_OIter, _Size, _Generator, _IterTag); template<typename _RAIter, typename _Size, typename _Generator> _RAIter __generate_n_switch(_RAIter, _Size, _Generator, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template<typename _IIter1, typename _IIter2> bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _Predicate> bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2> bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2); template<typename _IIter1, typename _IIter2, typename _Predicate> bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate); template<typename _IIter1, typename _IIter2, typename _Predicate, typename _IterTag1, typename _IterTag2> bool __lexicographical_compare_switch(_IIter1, _IIter1, _IIter2, _IIter2, _Predicate, _IterTag1, _IterTag2); template<typename _RAIter1, typename _RAIter2, typename _Predicate> bool __lexicographical_compare_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Predicate, random_access_iterator_tag, random_access_iterator_tag); // algo.h template<typename _IIter1, typename _IIter2> pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _Predicate> pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2, _Predicate, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2> pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2); template<typename _IIter1, typename _IIter2, typename _Predicate> pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2, _Predicate); template<typename _IIter1, typename _IIter2, typename _Predicate, typename _IterTag1, typename _IterTag2> pair<_IIter1, _IIter2> __mismatch_switch(_IIter1, _IIter1, _IIter2, _Predicate, _IterTag1, _IterTag2); template<typename _RAIter1, typename _RAIter2, typename _Predicate> pair<_RAIter1, _RAIter2> __mismatch_switch(_RAIter1, _RAIter1, _RAIter2, _Predicate, random_access_iterator_tag, random_access_iterator_tag); template<typename _FIter1, typename _FIter2> _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2, __gnu_parallel::sequential_tag); template<typename _FIter1, typename _FIter2> _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2); template<typename _FIter1, typename _FIter2, typename _BiPredicate> _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate, __gnu_parallel::sequential_tag); template<typename _FIter1, typename _FIter2, typename _BiPredicate> _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate); template<typename _RAIter1, typename _RAIter2> _RAIter1 __search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, random_access_iterator_tag, random_access_iterator_tag); template<typename _FIter1, typename _FIter2, typename _IterTag1, typename _IterTag2> _FIter1 __search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _IterTag1, _IterTag2); template<typename _RAIter1, typename _RAIter2, typename _BiPredicate> _RAIter1 __search_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _BiPredicate, random_access_iterator_tag, random_access_iterator_tag); template<typename _FIter1, typename _FIter2, typename _BiPredicate, typename _IterTag1, typename _IterTag2> _FIter1 __search_switch(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate, _IterTag1, _IterTag2); template<typename _FIter, typename _Integer, typename _Tp> _FIter search_n(_FIter, _FIter, _Integer, const _Tp&, __gnu_parallel::sequential_tag); template<typename _FIter, typename _Integer, typename _Tp, typename _BiPredicate> _FIter search_n(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate, __gnu_parallel::sequential_tag); template<typename _FIter, typename _Integer, typename _Tp> _FIter search_n(_FIter, _FIter, _Integer, const _Tp&); template<typename _FIter, typename _Integer, typename _Tp, typename _BiPredicate> _FIter search_n(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate); template<typename _RAIter, typename _Integer, typename _Tp, typename _BiPredicate> _RAIter __search_n_switch(_RAIter, _RAIter, _Integer, const _Tp&, _BiPredicate, random_access_iterator_tag); template<typename _FIter, typename _Integer, typename _Tp, typename _BiPredicate, typename _IterTag> _FIter __search_n_switch(_FIter, _FIter, _Integer, const _Tp&, _BiPredicate, _IterTag); template<typename _IIter, typename _OIter, typename _UnaryOperation> _OIter transform(_IIter, _IIter, _OIter, _UnaryOperation); template<typename _IIter, typename _OIter, typename _UnaryOperation> _OIter transform(_IIter, _IIter, _OIter, _UnaryOperation, __gnu_parallel::sequential_tag); template<typename _IIter, typename _OIter, typename _UnaryOperation> _OIter transform(_IIter, _IIter, _OIter, _UnaryOperation, __gnu_parallel::_Parallelism); template<typename _IIter, typename _OIter, typename _UnaryOperation, typename _IterTag1, typename _IterTag2> _OIter __transform1_switch(_IIter, _IIter, _OIter, _UnaryOperation, _IterTag1, _IterTag2); template<typename _RAIIter, typename _RAOIter, typename _UnaryOperation> _RAOIter __transform1_switch(_RAIIter, _RAIIter, _RAOIter, _UnaryOperation, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template<typename _IIter1, typename _IIter2, typename _OIter, typename _BiOperation> _OIter transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation); template<typename _IIter1, typename _IIter2, typename _OIter, typename _BiOperation> _OIter transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter, typename _BiOperation> _OIter transform(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, __gnu_parallel::_Parallelism); template<typename _RAIter1, typename _RAIter2, typename _RAIter3, typename _BiOperation> _RAIter3 __transform2_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template<typename _IIter1, typename _IIter2, typename _OIter, typename _BiOperation, typename _Tag1, typename _Tag2, typename _Tag3> _OIter __transform2_switch(_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, _Tag1, _Tag2, _Tag3); template<typename _FIter, typename _Tp> void replace(_FIter, _FIter, const _Tp&, const _Tp&); template<typename _FIter, typename _Tp> void replace(_FIter, _FIter, const _Tp&, const _Tp&, __gnu_parallel::sequential_tag); template<typename _FIter, typename _Tp> void replace(_FIter, _FIter, const _Tp&, const _Tp&, __gnu_parallel::_Parallelism); template<typename _FIter, typename _Tp, typename _IterTag> void __replace_switch(_FIter, _FIter, const _Tp&, const _Tp&, _IterTag); template<typename _RAIter, typename _Tp> void __replace_switch(_RAIter, _RAIter, const _Tp&, const _Tp&, random_access_iterator_tag, __gnu_parallel::_Parallelism); template<typename _FIter, typename _Predicate, typename _Tp> void replace_if(_FIter, _FIter, _Predicate, const _Tp&); template<typename _FIter, typename _Predicate, typename _Tp> void replace_if(_FIter, _FIter, _Predicate, const _Tp&, __gnu_parallel::sequential_tag); template<typename _FIter, typename _Predicate, typename _Tp> void replace_if(_FIter, _FIter, _Predicate, const _Tp&, __gnu_parallel::_Parallelism); template<typename _FIter, typename _Predicate, typename _Tp, typename _IterTag> void __replace_if_switch(_FIter, _FIter, _Predicate, const _Tp&, _IterTag); template<typename _RAIter, typename _Predicate, typename _Tp> void __replace_if_switch(_RAIter, _RAIter, _Predicate, const _Tp&, random_access_iterator_tag, __gnu_parallel::_Parallelism); template<typename _FIter> _FIter max_element(_FIter, _FIter); template<typename _FIter> _FIter max_element(_FIter, _FIter, __gnu_parallel::sequential_tag); template<typename _FIter> _FIter max_element(_FIter, _FIter, __gnu_parallel::_Parallelism); template<typename _FIter, typename _Compare> _FIter max_element(_FIter, _FIter, _Compare); template<typename _FIter, typename _Compare> _FIter max_element(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag); template<typename _FIter, typename _Compare> _FIter max_element(_FIter, _FIter, _Compare, __gnu_parallel::_Parallelism); template<typename _FIter, typename _Compare, typename _IterTag> _FIter __max_element_switch(_FIter, _FIter, _Compare, _IterTag); template<typename _RAIter, typename _Compare> _RAIter __max_element_switch( _RAIter, _RAIter, _Compare, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare> _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare> _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare, typename _IterTag1, typename _IterTag2, typename _IterTag3> _OIter __merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, _IterTag1, _IterTag2, _IterTag3); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare> _OIter __merge_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template<typename _FIter> _FIter min_element(_FIter, _FIter); template<typename _FIter> _FIter min_element(_FIter, _FIter, __gnu_parallel::sequential_tag); template<typename _FIter> _FIter min_element(_FIter, _FIter, __gnu_parallel::_Parallelism __parallelism_tag); template<typename _FIter, typename _Compare> _FIter min_element(_FIter, _FIter, _Compare); template<typename _FIter, typename _Compare> _FIter min_element(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag); template<typename _FIter, typename _Compare> _FIter min_element(_FIter, _FIter, _Compare, __gnu_parallel::_Parallelism); template<typename _FIter, typename _Compare, typename _IterTag> _FIter __min_element_switch(_FIter, _FIter, _Compare, _IterTag); template<typename _RAIter, typename _Compare> _RAIter __min_element_switch( _RAIter, _RAIter, _Compare, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism = __gnu_parallel::parallel_balanced); template<typename _RAIter> void nth_element(_RAIter, _RAIter, _RAIter, __gnu_parallel::sequential_tag); template<typename _RAIter, typename _Compare> void nth_element(_RAIter, _RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template<typename _RAIter, typename _Compare> void nth_element(_RAIter, _RAIter, _RAIter, _Compare); template<typename _RAIter> void nth_element(_RAIter, _RAIter, _RAIter); template<typename _RAIter, typename _Compare> void partial_sort(_RAIter, _RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template<typename _RAIter> void partial_sort(_RAIter, _RAIter, _RAIter, __gnu_parallel::sequential_tag); template<typename _RAIter, typename _Compare> void partial_sort(_RAIter, _RAIter, _RAIter, _Compare); template<typename _RAIter> void partial_sort(_RAIter, _RAIter, _RAIter); template<typename _FIter, typename _Predicate> _FIter partition(_FIter, _FIter, _Predicate, __gnu_parallel::sequential_tag); template<typename _FIter, typename _Predicate> _FIter partition(_FIter, _FIter, _Predicate); template<typename _FIter, typename _Predicate, typename _IterTag> _FIter __partition_switch(_FIter, _FIter, _Predicate, _IterTag); template<typename _RAIter, typename _Predicate> _RAIter __partition_switch( _RAIter, _RAIter, _Predicate, random_access_iterator_tag); template<typename _RAIter> void random_shuffle(_RAIter, _RAIter, __gnu_parallel::sequential_tag); template<typename _RAIter, typename _RandomNumberGenerator> void random_shuffle(_RAIter, _RAIter, _RandomNumberGenerator&, __gnu_parallel::sequential_tag); template<typename _RAIter> void random_shuffle(_RAIter, _RAIter); template<typename _RAIter, typename _RandomNumberGenerator> void random_shuffle(_RAIter, _RAIter, #if __cplusplus >= 201103L _RandomNumberGenerator&&); #else _RandomNumberGenerator&); #endif template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Predicate> _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Predicate> _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template<typename _IIter1, typename _IIter2, typename _Predicate, typename _OIter, typename _IterTag1, typename _IterTag2, typename _IterTag3> _OIter __set_union_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, typename _Predicate> _Output_RAIter __set_union_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Predicate> _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Predicate> _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template<typename _IIter1, typename _IIter2, typename _Predicate, typename _OIter, typename _IterTag1, typename _IterTag2, typename _IterTag3> _OIter __set_intersection_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, typename _Predicate> _Output_RAIter __set_intersection_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Predicate> _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Predicate> _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template<typename _IIter1, typename _IIter2, typename _Predicate, typename _OIter, typename _IterTag1, typename _IterTag2, typename _IterTag3> _OIter __set_symmetric_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, typename _Predicate> _Output_RAIter __set_symmetric_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Predicate> _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Predicate> _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate); template<typename _IIter1, typename _IIter2, typename _Predicate, typename _OIter, typename _IterTag1, typename _IterTag2, typename _IterTag3> _OIter __set_difference_switch(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3); template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, typename _Predicate> _Output_RAIter __set_difference_switch(_RAIter1, _RAIter1, _RAIter2, _RAIter2, _Output_RAIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag); template<typename _RAIter> void sort(_RAIter, _RAIter, __gnu_parallel::sequential_tag); template<typename _RAIter, typename _Compare> void sort(_RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template<typename _RAIter> void sort(_RAIter, _RAIter); template<typename _RAIter, typename _Compare> void sort(_RAIter, _RAIter, _Compare); template<typename _RAIter> void stable_sort(_RAIter, _RAIter, __gnu_parallel::sequential_tag); template<typename _RAIter, typename _Compare> void stable_sort(_RAIter, _RAIter, _Compare, __gnu_parallel::sequential_tag); template<typename _RAIter> void stable_sort(_RAIter, _RAIter); template<typename _RAIter, typename _Compare> void stable_sort(_RAIter, _RAIter, _Compare); template<typename _IIter, typename _OIter> _OIter unique_copy(_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag); template<typename _IIter, typename _OIter, typename _Predicate> _OIter unique_copy(_IIter, _IIter, _OIter, _Predicate, __gnu_parallel::sequential_tag); template<typename _IIter, typename _OIter> _OIter unique_copy(_IIter, _IIter, _OIter); template<typename _IIter, typename _OIter, typename _Predicate> _OIter unique_copy(_IIter, _IIter, _OIter, _Predicate); template<typename _IIter, typename _OIter, typename _Predicate, typename _IterTag1, typename _IterTag2> _OIter __unique_copy_switch(_IIter, _IIter, _OIter, _Predicate, _IterTag1, _IterTag2); template<typename _RAIter, typename _RandomAccess_OIter, typename _Predicate> _RandomAccess_OIter __unique_copy_switch(_RAIter, _RAIter, _RandomAccess_OIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag); } // end namespace __parallel } // end namespace std #endif /* _GLIBCXX_PARALLEL_ALGORITHMFWD_H */ c++/8/parallel/par_loop.h 0000644 00000010710 15146341150 0011042 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/par_loop.h * @brief Parallelization of embarrassingly parallel execution by * means of equal splitting. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_PAR_LOOP_H #define _GLIBCXX_PARALLEL_PAR_LOOP_H 1 #include <omp.h> #include <parallel/settings.h> #include <parallel/base.h> #include <parallel/equally_split.h> namespace __gnu_parallel { /** @brief Embarrassingly parallel algorithm for random access * iterators, using hand-crafted parallelization by equal splitting * the work. * * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __o User-supplied functor (comparator, predicate, adding * functor, ...) * @param __f Functor to "process" an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to "add" a single __result to the already * processed elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template<typename _RAIter, typename _Op, typename _Fu, typename _Red, typename _Result> _Op __for_each_template_random_access_ed(_RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; const _DifferenceType __length = __end - __begin; _Result *__thread_results; bool* __constructed; _ThreadIndex __num_threads = __gnu_parallel::min<_DifferenceType> (__get_max_threads(), __length); # pragma omp parallel num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); __thread_results = static_cast<_Result*> (::operator new(__num_threads * sizeof(_Result))); __constructed = new bool[__num_threads]; } _ThreadIndex __iam = omp_get_thread_num(); // Neutral element. _Result* __reduct; _DifferenceType __start = __equally_split_point(__length, __num_threads, __iam), __stop = __equally_split_point(__length, __num_threads, __iam + 1); if (__start < __stop) { __reduct = new _Result(__f(__o, __begin + __start)); ++__start; __constructed[__iam] = true; } else __constructed[__iam] = false; for (; __start < __stop; ++__start) *__reduct = __r(*__reduct, __f(__o, __begin + __start)); if (__constructed[__iam]) { ::new(&__thread_results[__iam]) _Result(*__reduct); delete __reduct; } } //parallel for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) if (__constructed[__i]) { __output = __r(__output, __thread_results[__i]); __thread_results[__i].~_Result(); } // Points to last element processed (needed as return value for // some algorithms like transform). __f._M_finish_iterator = __begin + __length; ::operator delete(__thread_results); delete[] __constructed; return __o; } } // end namespace #endif /* _GLIBCXX_PARALLEL_PAR_LOOP_H */ c++/8/parallel/algorithm 0000644 00000002545 15146341150 0010776 0 ustar 00 // Algorithm extensions -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/algorithm * This file is a GNU extension to the Standard C++ Library. */ #ifndef _PARALLEL_ALGORITHM #define _PARALLEL_ALGORITHM 1 #pragma GCC system_header #include <algorithm> #include <parallel/algorithmfwd.h> #include <parallel/algobase.h> #include <parallel/algo.h> #endif c++/8/parallel/balanced_quicksort.h 0000644 00000041070 15146341150 0013067 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/balanced_quicksort.h * @brief Implementation of a dynamically load-balanced parallel quicksort. * * It works in-place and needs only logarithmic extra memory. * The algorithm is similar to the one proposed in * * P. Tsigas and Y. Zhang. * A simple, fast parallel implementation of quicksort and * its performance evaluation on SUN enterprise 10000. * In 11th Euromicro Conference on Parallel, Distributed and * Network-Based Processing, page 372, 2003. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H #define _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H 1 #include <parallel/basic_iterator.h> #include <bits/stl_algo.h> #include <bits/stl_function.h> #include <parallel/settings.h> #include <parallel/partition.h> #include <parallel/random_number.h> #include <parallel/queue.h> #if _GLIBCXX_PARALLEL_ASSERTIONS #include <parallel/checkers.h> #ifdef _GLIBCXX_HAVE_UNISTD_H #include <unistd.h> #endif #endif namespace __gnu_parallel { /** @brief Information local to one thread in the parallel quicksort run. */ template<typename _RAIter> struct _QSBThreadLocal { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; /** @brief Continuous part of the sequence, described by an iterator pair. */ typedef std::pair<_RAIter, _RAIter> _Piece; /** @brief Initial piece to work on. */ _Piece _M_initial; /** @brief Work-stealing queue. */ _RestrictedBoundedConcurrentQueue<_Piece> _M_leftover_parts; /** @brief Number of threads involved in this algorithm. */ _ThreadIndex _M_num_threads; /** @brief Pointer to a counter of elements left over to sort. */ volatile _DifferenceType* _M_elements_leftover; /** @brief The complete sequence to sort. */ _Piece _M_global; /** @brief Constructor. * @param __queue_size size of the work-stealing queue. */ _QSBThreadLocal(int __queue_size) : _M_leftover_parts(__queue_size) { } }; /** @brief Balanced quicksort divide step. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. * @pre @c (__end-__begin)>=1 */ template<typename _RAIter, typename _Compare> typename std::iterator_traits<_RAIter>::difference_type __qsb_divide(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_PARALLEL_ASSERT(__num_threads > 0); typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _RAIter __pivot_pos = __median_of_three_iterators(__begin, __begin + (__end - __begin) / 2, __end - 1, __comp); #if defined(_GLIBCXX_PARALLEL_ASSERTIONS) // Must be in between somewhere. _DifferenceType __n = __end - __begin; _GLIBCXX_PARALLEL_ASSERT((!__comp(*__pivot_pos, *__begin) && !__comp(*(__begin + __n / 2), *__pivot_pos)) || (!__comp(*__pivot_pos, *__begin) && !__comp(*(__end - 1), *__pivot_pos)) || (!__comp(*__pivot_pos, *(__begin + __n / 2)) && !__comp(*__begin, *__pivot_pos)) || (!__comp(*__pivot_pos, *(__begin + __n / 2)) && !__comp(*(__end - 1), *__pivot_pos)) || (!__comp(*__pivot_pos, *(__end - 1)) && !__comp(*__begin, *__pivot_pos)) || (!__comp(*__pivot_pos, *(__end - 1)) && !__comp(*(__begin + __n / 2), *__pivot_pos))); #endif // Swap pivot value to end. if (__pivot_pos != (__end - 1)) std::iter_swap(__pivot_pos, __end - 1); __pivot_pos = __end - 1; __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool> __pred(__comp, *__pivot_pos); // Divide, returning __end - __begin - 1 in the worst case. _DifferenceType __split_pos = __parallel_partition(__begin, __end - 1, __pred, __num_threads); // Swap back pivot to middle. std::iter_swap(__begin + __split_pos, __pivot_pos); __pivot_pos = __begin + __split_pos; #if _GLIBCXX_PARALLEL_ASSERTIONS _RAIter __r; for (__r = __begin; __r != __pivot_pos; ++__r) _GLIBCXX_PARALLEL_ASSERT(__comp(*__r, *__pivot_pos)); for (; __r != __end; ++__r) _GLIBCXX_PARALLEL_ASSERT(!__comp(*__r, *__pivot_pos)); #endif return __split_pos; } /** @brief Quicksort conquer step. * @param __tls Array of thread-local storages. * @param __begin Begin iterator of subsequence. * @param __end End iterator of subsequence. * @param __comp Comparator. * @param __iam Number of the thread processing this function. * @param __num_threads * Number of threads that are allowed to work on this part. */ template<typename _RAIter, typename _Compare> void __qsb_conquer(_QSBThreadLocal<_RAIter>** __tls, _RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __iam, _ThreadIndex __num_threads, bool __parent_wait) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; _DifferenceType __n = __end - __begin; if (__num_threads <= 1 || __n <= 1) { __tls[__iam]->_M_initial.first = __begin; __tls[__iam]->_M_initial.second = __end; __qsb_local_sort_with_helping(__tls, __comp, __iam, __parent_wait); return; } // Divide step. _DifferenceType __split_pos = __qsb_divide(__begin, __end, __comp, __num_threads); #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(0 <= __split_pos && __split_pos < (__end - __begin)); #endif _ThreadIndex __num_threads_leftside = std::max<_ThreadIndex> (1, std::min<_ThreadIndex>(__num_threads - 1, __split_pos * __num_threads / __n)); # pragma omp atomic *__tls[__iam]->_M_elements_leftover -= (_DifferenceType)1; // Conquer step. # pragma omp parallel num_threads(2) { bool __wait; if(omp_get_num_threads() < 2) __wait = false; else __wait = __parent_wait; # pragma omp sections { # pragma omp section { __qsb_conquer(__tls, __begin, __begin + __split_pos, __comp, __iam, __num_threads_leftside, __wait); __wait = __parent_wait; } // The pivot_pos is left in place, to ensure termination. # pragma omp section { __qsb_conquer(__tls, __begin + __split_pos + 1, __end, __comp, __iam + __num_threads_leftside, __num_threads - __num_threads_leftside, __wait); __wait = __parent_wait; } } } } /** * @brief Quicksort step doing load-balanced local sort. * @param __tls Array of thread-local storages. * @param __comp Comparator. * @param __iam Number of the thread processing this function. */ template<typename _RAIter, typename _Compare> void __qsb_local_sort_with_helping(_QSBThreadLocal<_RAIter>** __tls, _Compare& __comp, _ThreadIndex __iam, bool __wait) { typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef std::pair<_RAIter, _RAIter> _Piece; _QSBThreadLocal<_RAIter>& __tl = *__tls[__iam]; _DifferenceType __base_case_n = _Settings::get().sort_qsb_base_case_maximal_n; if (__base_case_n < 2) __base_case_n = 2; _ThreadIndex __num_threads = __tl._M_num_threads; // Every thread has its own random number generator. _RandomNumber __rng(__iam + 1); _Piece __current = __tl._M_initial; _DifferenceType __elements_done = 0; #if _GLIBCXX_PARALLEL_ASSERTIONS _DifferenceType __total_elements_done = 0; #endif for (;;) { // Invariant: __current must be a valid (maybe empty) range. _RAIter __begin = __current.first, __end = __current.second; _DifferenceType __n = __end - __begin; if (__n > __base_case_n) { // Divide. _RAIter __pivot_pos = __begin + __rng(__n); // Swap __pivot_pos value to end. if (__pivot_pos != (__end - 1)) std::iter_swap(__pivot_pos, __end - 1); __pivot_pos = __end - 1; __gnu_parallel::__binder2nd <_Compare, _ValueType, _ValueType, bool> __pred(__comp, *__pivot_pos); // Divide, leave pivot unchanged in last place. _RAIter __split_pos1, __split_pos2; __split_pos1 = __gnu_sequential::partition(__begin, __end - 1, __pred); // Left side: < __pivot_pos; __right side: >= __pivot_pos. #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__begin <= __split_pos1 && __split_pos1 < __end); #endif // Swap pivot back to middle. if (__split_pos1 != __pivot_pos) std::iter_swap(__split_pos1, __pivot_pos); __pivot_pos = __split_pos1; // In case all elements are equal, __split_pos1 == 0. if ((__split_pos1 + 1 - __begin) < (__n >> 7) || (__end - __split_pos1) < (__n >> 7)) { // Very unequal split, one part smaller than one 128th // elements not strictly larger than the pivot. __gnu_parallel::__unary_negate<__gnu_parallel::__binder1st <_Compare, _ValueType, _ValueType, bool>, _ValueType> __pred(__gnu_parallel::__binder1st <_Compare, _ValueType, _ValueType, bool> (__comp, *__pivot_pos)); // Find other end of pivot-equal range. __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1, __end, __pred); } else // Only skip the pivot. __split_pos2 = __split_pos1 + 1; // Elements equal to pivot are done. __elements_done += (__split_pos2 - __split_pos1); #if _GLIBCXX_PARALLEL_ASSERTIONS __total_elements_done += (__split_pos2 - __split_pos1); #endif // Always push larger part onto stack. if (((__split_pos1 + 1) - __begin) < (__end - (__split_pos2))) { // Right side larger. if ((__split_pos2) != __end) __tl._M_leftover_parts.push_front (std::make_pair(__split_pos2, __end)); //__current.first = __begin; //already set anyway __current.second = __split_pos1; continue; } else { // Left side larger. if (__begin != __split_pos1) __tl._M_leftover_parts.push_front(std::make_pair (__begin, __split_pos1)); __current.first = __split_pos2; //__current.second = __end; //already set anyway continue; } } else { __gnu_sequential::sort(__begin, __end, __comp); __elements_done += __n; #if _GLIBCXX_PARALLEL_ASSERTIONS __total_elements_done += __n; #endif // Prefer own stack, small pieces. if (__tl._M_leftover_parts.pop_front(__current)) continue; # pragma omp atomic *__tl._M_elements_leftover -= __elements_done; __elements_done = 0; #if _GLIBCXX_PARALLEL_ASSERTIONS double __search_start = omp_get_wtime(); #endif // Look for new work. bool __successfully_stolen = false; while (__wait && *__tl._M_elements_leftover > 0 && !__successfully_stolen #if _GLIBCXX_PARALLEL_ASSERTIONS // Possible dead-lock. && (omp_get_wtime() < (__search_start + 1.0)) #endif ) { _ThreadIndex __victim; __victim = __rng(__num_threads); // Large pieces. __successfully_stolen = (__victim != __iam) && __tls[__victim]->_M_leftover_parts.pop_back(__current); if (!__successfully_stolen) __yield(); #if !defined(__ICC) && !defined(__ECC) # pragma omp flush #endif } #if _GLIBCXX_PARALLEL_ASSERTIONS if (omp_get_wtime() >= (__search_start + 1.0)) { sleep(1); _GLIBCXX_PARALLEL_ASSERT(omp_get_wtime() < (__search_start + 1.0)); } #endif if (!__successfully_stolen) { #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(*__tl._M_elements_leftover == 0); #endif return; } } } } /** @brief Top-level quicksort routine. * @param __begin Begin iterator of sequence. * @param __end End iterator of sequence. * @param __comp Comparator. * @param __num_threads Number of threads that are allowed to work on * this part. */ template<typename _RAIter, typename _Compare> void __parallel_sort_qsb(_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef std::pair<_RAIter, _RAIter> _Piece; typedef _QSBThreadLocal<_RAIter> _TLSType; _DifferenceType __n = __end - __begin; if (__n <= 1) return; // At least one element per processor. if (__num_threads > __n) __num_threads = static_cast<_ThreadIndex>(__n); // Initialize thread local storage _TLSType** __tls = new _TLSType*[__num_threads]; _DifferenceType __queue_size = (__num_threads * (_ThreadIndex)(__rd_log2(__n) + 1)); for (_ThreadIndex __t = 0; __t < __num_threads; ++__t) __tls[__t] = new _QSBThreadLocal<_RAIter>(__queue_size); // There can never be more than ceil(__rd_log2(__n)) ranges on the // stack, because // 1. Only one processor pushes onto the stack // 2. The largest range has at most length __n // 3. Each range is larger than half of the range remaining volatile _DifferenceType __elements_leftover = __n; for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) { __tls[__i]->_M_elements_leftover = &__elements_leftover; __tls[__i]->_M_num_threads = __num_threads; __tls[__i]->_M_global = std::make_pair(__begin, __end); // Just in case nothing is left to assign. __tls[__i]->_M_initial = std::make_pair(__end, __end); } // Main recursion call. __qsb_conquer(__tls, __begin, __begin + __n, __comp, 0, __num_threads, true); #if _GLIBCXX_PARALLEL_ASSERTIONS // All stack must be empty. _Piece __dummy; for (_ThreadIndex __i = 1; __i < __num_threads; ++__i) _GLIBCXX_PARALLEL_ASSERT( !__tls[__i]->_M_leftover_parts.pop_back(__dummy)); #endif for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) delete __tls[__i]; delete[] __tls; } } // namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H */ c++/8/parallel/algobase.h 0000644 00000041403 15146341150 0011007 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/algobase.h * @brief Parallel STL function calls corresponding to the * stl_algobase.h header. The functions defined here mainly do case * switches and call the actual parallelized versions in other files. * Inlining policy: Functions that basically only contain one * function call, are declared inline. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_ALGOBASE_H #define _GLIBCXX_PARALLEL_ALGOBASE_H 1 #include <bits/stl_algobase.h> #include <parallel/base.h> #include <parallel/algorithmfwd.h> #include <parallel/find.h> #include <parallel/find_selectors.h> namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { // NB: equal and lexicographical_compare require mismatch. // Sequential fallback template<typename _IIter1, typename _IIter2> inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _Predicate> inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } // Sequential fallback for input iterator case template<typename _IIter1, typename _IIter2, typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> inline pair<_IIter1, _IIter2> __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } // Parallel mismatch for random access iterators template<typename _RAIter1, typename _RAIter2, typename _Predicate> pair<_RAIter1, _RAIter2> __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { _RAIter1 __res = __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred, __gnu_parallel:: __mismatch_selector()).first; return make_pair(__res , __begin2 + (__res - __begin1)); } else return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } // Public interface template<typename _IIter1, typename _IIter2> inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) { typedef __gnu_parallel::_EqualTo< typename std::iterator_traits<_IIter1>::value_type, typename std::iterator_traits<_IIter2>::value_type> _EqualTo; return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(), std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Public interface template<typename _IIter1, typename _IIter2, typename _Predicate> inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred) { return __mismatch_switch(__begin1, __end1, __begin2, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } #if __cplusplus > 201103L // Sequential fallback. template<typename _InputIterator1, typename _InputIterator2> inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2); } // Sequential fallback. template<typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate> inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2, __binary_pred); } // Sequential fallback for input iterator case template<typename _IIter1, typename _IIter2, typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> inline pair<_IIter1, _IIter2> __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __end2, __pred); } // Parallel mismatch for random access iterators template<typename _RAIter1, typename _RAIter2, typename _Predicate> pair<_RAIter1, _RAIter2> __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { if ((__end2 - __begin2) < (__end1 - __begin1)) __end1 = __begin1 + (__end2 - __begin2); _RAIter1 __res = __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred, __gnu_parallel:: __mismatch_selector()).first; return make_pair(__res , __begin2 + (__res - __begin1)); } else return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __end2, __pred); } template<typename _IIter1, typename _IIter2> inline pair<_IIter1, _IIter2> mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { typedef __gnu_parallel::_EqualTo< typename std::iterator_traits<_IIter1>::value_type, typename std::iterator_traits<_IIter2>::value_type> _EqualTo; return __mismatch_switch(__begin1, __end1, __begin2, __end2, _EqualTo(), std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } template<typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate> inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __begin1, _InputIterator1 __end1, _InputIterator2 __begin2, _InputIterator2 __end2, _BinaryPredicate __binary_pred) { return __mismatch_switch(__begin1, __end1, __begin2, __end2, __binary_pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } #endif // Sequential fallback template<typename _IIter1, typename _IIter2> inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _Predicate> inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); } // Public interface template<typename _IIter1, typename _IIter2> inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) { return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first == __end1; } // Public interface template<typename _IIter1, typename _IIter2, typename _Predicate> inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _Predicate __pred) { return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first == __end1; } #if __cplusplus > 201103L // Sequential fallback template<typename _IIter1, typename _IIter2> inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, __binary_pred); } // Sequential fallback for input iterator case template<typename _IIter1, typename _IIter2, typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> inline bool __equal_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, __pred); } // Parallel equal for random access iterators template<typename _RAIter1, typename _RAIter2, typename _Predicate> inline bool __equal_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { if (std::distance(__begin1, __end1) != std::distance(__begin2, __end2)) return false; return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __end2, __pred).first == __end1; } else return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2, __pred); } template<typename _IIter1, typename _IIter2> inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { typedef __gnu_parallel::_EqualTo< typename std::iterator_traits<_IIter1>::value_type, typename std::iterator_traits<_IIter2>::value_type> _EqualTo; return __equal_switch(__begin1, __end1, __begin2, __end2, _EqualTo(), std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> inline bool equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred) { return __equal_switch(__begin1, __end1, __begin2, __end2, __binary_pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } #endif // Sequential fallback template<typename _IIter1, typename _IIter2> inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1, __begin2, __end2); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _Predicate> inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::lexicographical_compare( __begin1, __end1, __begin2, __end2, __pred); } // Sequential fallback for input iterator case template<typename _IIter1, typename _IIter2, typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> inline bool __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::lexicographical_compare( __begin1, __end1, __begin2, __end2, __pred); } // Parallel lexicographical_compare for random access iterators // Limitation: Both valuetypes must be the same template<typename _RAIter1, typename _RAIter2, typename _Predicate> bool __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) { typedef iterator_traits<_RAIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef iterator_traits<_RAIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef __gnu_parallel:: _EqualFromLess<_ValueType1, _ValueType2, _Predicate> _EqualFromLessCompare; // Longer sequence in first place. if ((__end1 - __begin1) < (__end2 - __begin2)) { typedef pair<_RAIter1, _RAIter2> _SpotType; _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2, _EqualFromLessCompare(__pred), random_access_iterator_tag(), random_access_iterator_tag()); return (__mm.first == __end1) || bool(__pred(*__mm.first, *__mm.second)); } else { typedef pair<_RAIter2, _RAIter1> _SpotType; _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1, _EqualFromLessCompare(__pred), random_access_iterator_tag(), random_access_iterator_tag()); return (__mm.first != __end2) && bool(__pred(*__mm.second, *__mm.first)); } } else return _GLIBCXX_STD_A::lexicographical_compare( __begin1, __end1, __begin2, __end2, __pred); } // Public interface template<typename _IIter1, typename _IIter2> inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType; return __lexicographical_compare_switch( __begin1, __end1, __begin2, __end2, _LessType(), _IteratorCategory1(), _IteratorCategory2()); } // Public interface template<typename _IIter1, typename _IIter2, typename _Predicate> inline bool lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; return __lexicographical_compare_switch( __begin1, __end1, __begin2, __end2, __pred, _IteratorCategory1(), _IteratorCategory2()); } } // end namespace } // end namespace #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */ c++/8/parallel/workstealing.h 0000644 00000022614 15146341150 0011746 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/workstealing.h * @brief Parallelization of embarrassingly parallel execution by * means of work-stealing. * * Work stealing is described in * * R. D. Blumofe and C. E. Leiserson. * Scheduling multithreaded computations by work stealing. * Journal of the ACM, 46(5):720–748, 1999. * * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_WORKSTEALING_H #define _GLIBCXX_PARALLEL_WORKSTEALING_H 1 #include <parallel/parallel.h> #include <parallel/random_number.h> #include <parallel/compatibility.h> namespace __gnu_parallel { #define _GLIBCXX_JOB_VOLATILE volatile /** @brief One __job for a certain thread. */ template<typename _DifferenceTp> struct _Job { typedef _DifferenceTp _DifferenceType; /** @brief First element. * * Changed by owning and stealing thread. By stealing thread, * always incremented. */ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_first; /** @brief Last element. * * Changed by owning thread only. */ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_last; /** @brief Number of elements, i.e. @c _M_last-_M_first+1. * * Changed by owning thread only. */ _GLIBCXX_JOB_VOLATILE _DifferenceType _M_load; }; /** @brief Work stealing algorithm for random access iterators. * * Uses O(1) additional memory. Synchronization at job lists is * done with atomic operations. * @param __begin Begin iterator of element sequence. * @param __end End iterator of element sequence. * @param __op User-supplied functor (comparator, predicate, adding * functor, ...). * @param __f Functor to @a process an element with __op (depends on * desired functionality, e. g. for std::for_each(), ...). * @param __r Functor to @a add a single __result to the already * processed elements (depends on functionality). * @param __base Base value for reduction. * @param __output Pointer to position where final result is written to * @param __bound Maximum number of elements processed (e. g. for * std::count_n()). * @return User-supplied functor (that may contain a part of the result). */ template<typename _RAIter, typename _Op, typename _Fu, typename _Red, typename _Result> _Op __for_each_template_random_access_workstealing(_RAIter __begin, _RAIter __end, _Op __op, _Fu& __f, _Red __r, _Result __base, _Result& __output, typename std::iterator_traits<_RAIter>::difference_type __bound) { _GLIBCXX_CALL(__end - __begin) typedef std::iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::difference_type _DifferenceType; const _Settings& __s = _Settings::get(); _DifferenceType __chunk_size = static_cast<_DifferenceType>(__s.workstealing_chunk_size); // How many jobs? _DifferenceType __length = (__bound < 0) ? (__end - __begin) : __bound; // To avoid false sharing in a cache line. const int __stride = (__s.cache_line_size * 10 / sizeof(_Job<_DifferenceType>) + 1); // Total number of threads currently working. _ThreadIndex __busy = 0; _Job<_DifferenceType> *__job; omp_lock_t __output_lock; omp_init_lock(&__output_lock); // Write base value to output. __output = __base; // No more threads than jobs, at least one thread. _ThreadIndex __num_threads = __gnu_parallel::max<_ThreadIndex> (1, __gnu_parallel::min<_DifferenceType>(__length, __get_max_threads())); # pragma omp parallel shared(__busy) num_threads(__num_threads) { # pragma omp single { __num_threads = omp_get_num_threads(); // Create job description array. __job = new _Job<_DifferenceType>[__num_threads * __stride]; } // Initialization phase. // Flags for every thread if it is doing productive work. bool __iam_working = false; // Thread id. _ThreadIndex __iam = omp_get_thread_num(); // This job. _Job<_DifferenceType>& __my_job = __job[__iam * __stride]; // Random number (for work stealing). _ThreadIndex __victim; // Local value for reduction. _Result __result = _Result(); // Number of elements to steal in one attempt. _DifferenceType __steal; // Every thread has its own random number generator // (modulo __num_threads). _RandomNumber __rand_gen(__iam, __num_threads); // This thread is currently working. # pragma omp atomic ++__busy; __iam_working = true; // How many jobs per thread? last thread gets the rest. __my_job._M_first = static_cast<_DifferenceType> (__iam * (__length / __num_threads)); __my_job._M_last = (__iam == (__num_threads - 1) ? (__length - 1) : ((__iam + 1) * (__length / __num_threads) - 1)); __my_job._M_load = __my_job._M_last - __my_job._M_first + 1; // Init result with _M_first value (to have a base value for reduction) if (__my_job._M_first <= __my_job._M_last) { // Cannot use volatile variable directly. _DifferenceType __my_first = __my_job._M_first; __result = __f(__op, __begin + __my_first); ++__my_job._M_first; --__my_job._M_load; } _RAIter __current; # pragma omp barrier // Actual work phase // Work on own or stolen current start while (__busy > 0) { // Work until no productive thread left. # pragma omp flush(__busy) // Thread has own work to do while (__my_job._M_first <= __my_job._M_last) { // fetch-and-add call // Reserve current job block (size __chunk_size) in my queue. _DifferenceType __current_job = __fetch_and_add<_DifferenceType>(&(__my_job._M_first), __chunk_size); // Update _M_load, to make the three values consistent, // _M_first might have been changed in the meantime __my_job._M_load = __my_job._M_last - __my_job._M_first + 1; for (_DifferenceType __job_counter = 0; __job_counter < __chunk_size && __current_job <= __my_job._M_last; ++__job_counter) { // Yes: process it! __current = __begin + __current_job; ++__current_job; // Do actual work. __result = __r(__result, __f(__op, __current)); } # pragma omp flush(__busy) } // After reaching this point, a thread's __job list is empty. if (__iam_working) { // This thread no longer has work. # pragma omp atomic --__busy; __iam_working = false; } _DifferenceType __supposed_first, __supposed_last, __supposed_load; do { // Find random nonempty deque (not own), do consistency check. __yield(); # pragma omp flush(__busy) __victim = __rand_gen(); __supposed_first = __job[__victim * __stride]._M_first; __supposed_last = __job[__victim * __stride]._M_last; __supposed_load = __job[__victim * __stride]._M_load; } while (__busy > 0 && ((__supposed_load <= 0) || ((__supposed_first + __supposed_load - 1) != __supposed_last))); if (__busy == 0) break; if (__supposed_load > 0) { // Has work and work to do. // Number of elements to steal (at least one). __steal = (__supposed_load < 2) ? 1 : __supposed_load / 2; // Push __victim's current start forward. _DifferenceType __stolen_first = __fetch_and_add<_DifferenceType> (&(__job[__victim * __stride]._M_first), __steal); _DifferenceType __stolen_try = (__stolen_first + __steal - _DifferenceType(1)); __my_job._M_first = __stolen_first; __my_job._M_last = __gnu_parallel::min(__stolen_try, __supposed_last); __my_job._M_load = __my_job._M_last - __my_job._M_first + 1; // Has potential work again. # pragma omp atomic ++__busy; __iam_working = true; # pragma omp flush(__busy) } # pragma omp flush(__busy) } // end while __busy > 0 // Add accumulated result to output. omp_set_lock(&__output_lock); __output = __r(__output, __result); omp_unset_lock(&__output_lock); } delete[] __job; // Points to last element processed (needed as return value for // some algorithms like transform) __f._M_finish_iterator = __begin + __length; omp_destroy_lock(&__output_lock); return __op; } } // end namespace #endif /* _GLIBCXX_PARALLEL_WORKSTEALING_H */ c++/8/parallel/numeric 0000644 00000050355 15146341150 0010454 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/numeric * * @brief Parallel STL function calls corresponding to stl_numeric.h. * The functions defined here mainly do case switches and * call the actual parallelized versions in other files. * Inlining policy: Functions that basically only contain one function call, * are declared inline. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_NUMERIC_H #define _GLIBCXX_PARALLEL_NUMERIC_H 1 #include <numeric> #include <bits/stl_function.h> #include <parallel/numericfwd.h> #include <parallel/iterator.h> #include <parallel/for_each.h> #include <parallel/for_each_selectors.h> #include <parallel/partial_sum.h> namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { // Sequential fallback. template<typename _IIter, typename _Tp> inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::accumulate(__begin, __end, __init); } template<typename _IIter, typename _Tp, typename _BinaryOperation> inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::accumulate(__begin, __end, __init, __binary_op); } // Sequential fallback for input iterator case. template<typename _IIter, typename _Tp, typename _IteratorTag> inline _Tp __accumulate_switch(_IIter __begin, _IIter __end, _Tp __init, _IteratorTag) { return accumulate(__begin, __end, __init, __gnu_parallel::sequential_tag()); } template<typename _IIter, typename _Tp, typename _BinaryOperation, typename _IteratorTag> inline _Tp __accumulate_switch(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, _IteratorTag) { return accumulate(__begin, __end, __init, __binary_op, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template<typename __RAIter, typename _Tp, typename _BinaryOperation> _Tp __accumulate_switch(__RAIter __begin, __RAIter __end, _Tp __init, _BinaryOperation __binary_op, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().accumulate_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _Tp __res = __init; __gnu_parallel::__accumulate_selector<__RAIter> __my_selector; __gnu_parallel:: __for_each_template_random_access_ed(__begin, __end, __gnu_parallel::_Nothing(), __my_selector, __gnu_parallel:: __accumulate_binop_reduct <_BinaryOperation>(__binary_op), __res, __res, -1); return __res; } else return accumulate(__begin, __end, __init, __binary_op, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _IIter, typename _Tp> inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, __gnu_parallel::_Parallelism __parallelism_tag) { typedef std::iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::value_type _ValueType; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __gnu_parallel::_Plus<_Tp, _ValueType>(), _IteratorCategory(), __parallelism_tag); } template<typename _IIter, typename _Tp> inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init) { typedef std::iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::value_type _ValueType; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __gnu_parallel::_Plus<_Tp, _ValueType>(), _IteratorCategory()); } template<typename _IIter, typename _Tp, typename _BinaryOperation> inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __binary_op, _IteratorCategory(), __parallelism_tag); } template<typename _IIter, typename _Tp, typename _BinaryOperation> inline _Tp accumulate(_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op) { typedef iterator_traits<_IIter> _IteratorTraits; typedef typename _IteratorTraits::iterator_category _IteratorCategory; return __accumulate_switch(__begin, __end, __init, __binary_op, _IteratorCategory()); } // Sequential fallback. template<typename _IIter1, typename _IIter2, typename _Tp> inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::inner_product( __first1, __last1, __first2, __init); } template<typename _IIter1, typename _IIter2, typename _Tp, typename _BinaryFunction1, typename _BinaryFunction2> inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2); } // Parallel algorithm for random access iterators. template<typename _RAIter1, typename _RAIter2, typename _Tp, typename _BinaryFunction1, typename _BinaryFunction2> _Tp __inner_product_switch(_RAIter1 __first1, _RAIter1 __last1, _RAIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION((__last1 - __first1) >= __gnu_parallel::_Settings::get(). accumulate_minimal_n && __gnu_parallel:: __is_parallel(__parallelism_tag))) { _Tp __res = __init; __gnu_parallel:: __inner_product_selector<_RAIter1, _RAIter2, _Tp> __my_selector(__first1, __first2); __gnu_parallel:: __for_each_template_random_access_ed( __first1, __last1, __binary_op2, __my_selector, __binary_op1, __res, __res, -1); return __res; } else return inner_product(__first1, __last1, __first2, __init, __gnu_parallel::sequential_tag()); } // No parallelism for input iterators. template<typename _IIter1, typename _IIter2, typename _Tp, typename _BinaryFunction1, typename _BinaryFunction2, typename _IteratorTag1, typename _IteratorTag2> inline _Tp __inner_product_switch(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, _IteratorTag1, _IteratorTag2) { return inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, __gnu_parallel::sequential_tag()); } template<typename _IIter1, typename _IIter2, typename _Tp, typename _BinaryFunction1, typename _BinaryFunction2> inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; return __inner_product_switch(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, _IteratorCategory1(), _IteratorCategory2(), __parallelism_tag); } template<typename _IIter1, typename _IIter2, typename _Tp, typename _BinaryFunction1, typename _BinaryFunction2> inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, _BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::iterator_category _IteratorCategory1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::iterator_category _IteratorCategory2; return __inner_product_switch(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, _IteratorCategory1(), _IteratorCategory2()); } template<typename _IIter1, typename _IIter2, typename _Tp> inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef typename __gnu_parallel::_Multiplies<_ValueType1, _ValueType2>::result_type _MultipliesResultType; return __gnu_parallel::inner_product(__first1, __last1, __first2, __init, __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(), __gnu_parallel:: _Multiplies<_ValueType1, _ValueType2>(), __parallelism_tag); } template<typename _IIter1, typename _IIter2, typename _Tp> inline _Tp inner_product(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init) { typedef iterator_traits<_IIter1> _TraitsType1; typedef typename _TraitsType1::value_type _ValueType1; typedef iterator_traits<_IIter2> _TraitsType2; typedef typename _TraitsType2::value_type _ValueType2; typedef typename __gnu_parallel::_Multiplies<_ValueType1, _ValueType2>::result_type _MultipliesResultType; return __gnu_parallel::inner_product(__first1, __last1, __first2, __init, __gnu_parallel::_Plus<_Tp, _MultipliesResultType>(), __gnu_parallel:: _Multiplies<_ValueType1, _ValueType2>()); } // Sequential fallback. template<typename _IIter, typename _OutputIterator> inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result); } // Sequential fallback. template<typename _IIter, typename _OutputIterator, typename _BinaryOperation> inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result, __bin_op); } // Sequential fallback for input iterator case. template<typename _IIter, typename _OutputIterator, typename _BinaryOperation, typename _IteratorTag1, typename _IteratorTag2> inline _OutputIterator __partial_sum_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::partial_sum(__begin, __end, __result, __bin_op); } // Parallel algorithm for random access iterators. template<typename _IIter, typename _OutputIterator, typename _BinaryOperation> _OutputIterator __partial_sum_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().partial_sum_minimal_n)) return __gnu_parallel::__parallel_partial_sum(__begin, __end, __result, __bin_op); else return partial_sum(__begin, __end, __result, __bin_op, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _IIter, typename _OutputIterator> inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result) { typedef typename iterator_traits<_IIter>::value_type _ValueType; return __gnu_parallel::partial_sum(__begin, __end, __result, std::plus<_ValueType>()); } // Public interface template<typename _IIter, typename _OutputIterator, typename _BinaryOperation> inline _OutputIterator partial_sum(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op) { typedef iterator_traits<_IIter> _ITraitsType; typedef typename _ITraitsType::iterator_category _IIteratorCategory; typedef iterator_traits<_OutputIterator> _OTraitsType; typedef typename _OTraitsType::iterator_category _OIterCategory; return __partial_sum_switch(__begin, __end, __result, __binary_op, _IIteratorCategory(), _OIterCategory()); } // Sequential fallback. template<typename _IIter, typename _OutputIterator> inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_difference(__begin, __end, __result); } // Sequential fallback. template<typename _IIter, typename _OutputIterator, typename _BinaryOperation> inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_difference(__begin, __end, __result, __bin_op); } // Sequential fallback for input iterator case. template<typename _IIter, typename _OutputIterator, typename _BinaryOperation, typename _IteratorTag1, typename _IteratorTag2> inline _OutputIterator __adjacent_difference_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, _IteratorTag1, _IteratorTag2) { return adjacent_difference(__begin, __end, __result, __bin_op, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template<typename _IIter, typename _OutputIterator, typename _BinaryOperation> _OutputIterator __adjacent_difference_switch(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().adjacent_difference_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy = true; typedef __gnu_parallel::_IteratorPair<_IIter, _OutputIterator, random_access_iterator_tag> _ItTrip; *__result = *__begin; _ItTrip __begin_pair(__begin + 1, __result + 1), __end_pair(__end, __result + (__end - __begin)); __gnu_parallel::__adjacent_difference_selector<_ItTrip> __functionality; __gnu_parallel:: __for_each_template_random_access_ed( __begin_pair, __end_pair, __bin_op, __functionality, __gnu_parallel::_DummyReduct(), __dummy, __dummy, -1); return __functionality._M_finish_iterator; } else return adjacent_difference(__begin, __end, __result, __bin_op, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _IIter, typename _OutputIterator> inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; return adjacent_difference(__begin, __end, __result, std::minus<_ValueType>(), __parallelism_tag); } template<typename _IIter, typename _OutputIterator> inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result) { typedef iterator_traits<_IIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; return adjacent_difference(__begin, __end, __result, std::minus<_ValueType>()); } template<typename _IIter, typename _OutputIterator, typename _BinaryOperation> inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_IIter> _ITraitsType; typedef typename _ITraitsType::iterator_category _IIteratorCategory; typedef iterator_traits<_OutputIterator> _OTraitsType; typedef typename _OTraitsType::iterator_category _OIterCategory; return __adjacent_difference_switch(__begin, __end, __result, __binary_op, _IIteratorCategory(), _OIterCategory(), __parallelism_tag); } template<typename _IIter, typename _OutputIterator, typename _BinaryOperation> inline _OutputIterator adjacent_difference(_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op) { typedef iterator_traits<_IIter> _ITraitsType; typedef typename _ITraitsType::iterator_category _IIteratorCategory; typedef iterator_traits<_OutputIterator> _OTraitsType; typedef typename _OTraitsType::iterator_category _OIterCategory; return __adjacent_difference_switch(__begin, __end, __result, __binary_op, _IIteratorCategory(), _OIterCategory()); } } // end namespace } // end namespace #endif /* _GLIBCXX_NUMERIC_H */ c++/8/parallel/for_each.h 0000644 00000007553 15146341150 0011010 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/for_each.h * @brief Main interface for embarrassingly parallel functions. * * The explicit implementation are in other header files, like * workstealing.h, par_loop.h, omp_loop.h, and omp_loop_static.h. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Felix Putze. #ifndef _GLIBCXX_PARALLEL_FOR_EACH_H #define _GLIBCXX_PARALLEL_FOR_EACH_H 1 #include <parallel/settings.h> #include <parallel/par_loop.h> #include <parallel/omp_loop.h> #include <parallel/workstealing.h> namespace __gnu_parallel { /** @brief Chose the desired algorithm by evaluating @c __parallelism_tag. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __user_op A user-specified functor (comparator, predicate, * associative operator,...) * @param __functionality functor to @a process an element with * __user_op (depends on desired functionality, e. g. accumulate, * for_each,... * @param __reduction Reduction functor. * @param __reduction_start Initial value for reduction. * @param __output Output iterator. * @param __bound Maximum number of elements processed. * @param __parallelism_tag Parallelization method */ template<typename _IIter, typename _UserOp, typename _Functionality, typename _Red, typename _Result> _UserOp __for_each_template_random_access(_IIter __begin, _IIter __end, _UserOp __user_op, _Functionality& __functionality, _Red __reduction, _Result __reduction_start, _Result& __output, typename std::iterator_traits<_IIter>:: difference_type __bound, _Parallelism __parallelism_tag) { if (__parallelism_tag == parallel_unbalanced) return __for_each_template_random_access_ed (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); else if (__parallelism_tag == parallel_omp_loop) return __for_each_template_random_access_omp_loop (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); else if (__parallelism_tag == parallel_omp_loop_static) return __for_each_template_random_access_omp_loop (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); else //e. g. parallel_balanced return __for_each_template_random_access_workstealing (__begin, __end, __user_op, __functionality, __reduction, __reduction_start, __output, __bound); } } #endif /* _GLIBCXX_PARALLEL_FOR_EACH_H */ c++/8/parallel/list_partition.h 0000644 00000014616 15146341150 0012304 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/list_partition.h * @brief _Functionality to split __sequence referenced by only input * iterators. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Leonor Frias Moya and Johannes Singler. #ifndef _GLIBCXX_PARALLEL_LIST_PARTITION_H #define _GLIBCXX_PARALLEL_LIST_PARTITION_H 1 #include <parallel/parallel.h> #include <vector> namespace __gnu_parallel { /** @brief Shrinks and doubles the ranges. * @param __os_starts Start positions worked on (oversampled). * @param __count_to_two Counts up to 2. * @param __range_length Current length of a chunk. * @param __make_twice Whether the @c __os_starts is allowed to be * grown or not */ template<typename _IIter> void __shrink_and_double(std::vector<_IIter>& __os_starts, size_t& __count_to_two, size_t& __range_length, const bool __make_twice) { ++__count_to_two; if (!__make_twice || __count_to_two < 2) __shrink(__os_starts, __count_to_two, __range_length); else { __os_starts.resize((__os_starts.size() - 1) * 2 + 1); __count_to_two = 0; } } /** @brief Combines two ranges into one and thus halves the number of ranges. * @param __os_starts Start positions worked on (oversampled). * @param __count_to_two Counts up to 2. * @param __range_length Current length of a chunk. */ template<typename _IIter> void __shrink(std::vector<_IIter>& __os_starts, size_t& __count_to_two, size_t& __range_length) { for (typename std::vector<_IIter>::size_type __i = 0; __i <= (__os_starts.size() / 2); ++__i) __os_starts[__i] = __os_starts[__i * 2]; __range_length *= 2; } /** @brief Splits a sequence given by input iterators into parts of * almost equal size * * The function needs only one pass over the sequence. * @param __begin Begin iterator of input sequence. * @param __end End iterator of input sequence. * @param __starts Start iterators for the resulting parts, dimension * @c __num_parts+1. For convenience, @c __starts @c [__num_parts] * contains the end iterator of the sequence. * @param __lengths Length of the resulting parts. * @param __num_parts Number of parts to split the sequence into. * @param __f Functor to be applied to each element by traversing __it * @param __oversampling Oversampling factor. If 0, then the * partitions will differ in at most * \f$\sqrt{\mathrm{end} - \mathrm{begin}}\f$ * elements. Otherwise, the ratio between the * longest and the shortest part is bounded by * \f$1/(\mathrm{oversampling} \cdot \mathrm{num\_parts})\f$ * @return Length of the whole sequence. */ template<typename _IIter, typename _FunctorType> size_t list_partition(const _IIter __begin, const _IIter __end, _IIter* __starts, size_t* __lengths, const int __num_parts, _FunctorType& __f, int __oversampling = 0) { bool __make_twice = false; // The resizing algorithm is chosen according to the oversampling factor. if (__oversampling == 0) { __make_twice = true; __oversampling = 1; } std::vector<_IIter> __os_starts(2 * __oversampling * __num_parts + 1); __os_starts[0] = __begin; _IIter __prev = __begin, __it = __begin; size_t __dist_limit = 0, __dist = 0; size_t __cur = 1, __next = 1; size_t __range_length = 1; size_t __count_to_two = 0; while (__it != __end) { __cur = __next; for (; __cur < __os_starts.size() and __it != __end; ++__cur) { for (__dist_limit += __range_length; __dist < __dist_limit and __it != __end; ++__dist) { __f(__it); ++__it; } __os_starts[__cur] = __it; } // Must compare for end and not __cur < __os_starts.size() , because // __cur could be == __os_starts.size() as well if (__it == __end) break; __shrink_and_double(__os_starts, __count_to_two, __range_length, __make_twice); __next = __os_starts.size() / 2 + 1; } // Calculation of the parts (one must be extracted from __current // because the partition beginning at end, consists only of // itself). size_t __size_part = (__cur - 1) / __num_parts; int __size_greater = static_cast<int>((__cur - 1) % __num_parts); __starts[0] = __os_starts[0]; size_t __index = 0; // Smallest partitions. for (int __i = 1; __i < (__num_parts + 1 - __size_greater); ++__i) { __lengths[__i - 1] = __size_part * __range_length; __index += __size_part; __starts[__i] = __os_starts[__index]; } // Biggest partitions. for (int __i = __num_parts + 1 - __size_greater; __i <= __num_parts; ++__i) { __lengths[__i - 1] = (__size_part+1) * __range_length; __index += (__size_part+1); __starts[__i] = __os_starts[__index]; } // Correction of the end size (the end iteration has not finished). __lengths[__num_parts - 1] -= (__dist_limit - __dist); return __dist; } } #endif /* _GLIBCXX_PARALLEL_LIST_PARTITION_H */ c++/8/parallel/algo.h 0000644 00000234236 15146341150 0010164 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/algo.h * @brief Parallel STL function calls corresponding to the stl_algo.h header. * * The functions defined here mainly do case switches and * call the actual parallelized versions in other files. * Inlining policy: Functions that basically only contain one function call, * are declared inline. * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler and Felix Putze. #ifndef _GLIBCXX_PARALLEL_ALGO_H #define _GLIBCXX_PARALLEL_ALGO_H 1 #include <parallel/algorithmfwd.h> #include <bits/stl_algobase.h> #include <bits/stl_algo.h> #include <parallel/iterator.h> #include <parallel/base.h> #include <parallel/sort.h> #include <parallel/workstealing.h> #include <parallel/par_loop.h> #include <parallel/omp_loop.h> #include <parallel/omp_loop_static.h> #include <parallel/for_each_selectors.h> #include <parallel/for_each.h> #include <parallel/find.h> #include <parallel/find_selectors.h> #include <parallel/search.h> #include <parallel/random_shuffle.h> #include <parallel/partition.h> #include <parallel/merge.h> #include <parallel/unique_copy.h> #include <parallel/set_operations.h> namespace std _GLIBCXX_VISIBILITY(default) { namespace __parallel { // Sequential fallback template<typename _IIter, typename _Function> inline _Function for_each(_IIter __begin, _IIter __end, _Function __f, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::for_each(__begin, __end, __f); } // Sequential fallback for input iterator case template<typename _IIter, typename _Function, typename _IteratorTag> inline _Function __for_each_switch(_IIter __begin, _IIter __end, _Function __f, _IteratorTag) { return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template<typename _RAIter, typename _Function> _Function __for_each_switch(_RAIter __begin, _RAIter __end, _Function __f, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().for_each_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy; __gnu_parallel::__for_each_selector<_RAIter> __functionality; return __gnu_parallel:: __for_each_template_random_access( __begin, __end, __f, __functionality, __gnu_parallel::_DummyReduct(), true, __dummy, -1, __parallelism_tag); } else return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); } // Public interface template<typename _Iterator, typename _Function> inline _Function for_each(_Iterator __begin, _Iterator __end, _Function __f, __gnu_parallel::_Parallelism __parallelism_tag) { return __for_each_switch(__begin, __end, __f, std::__iterator_category(__begin), __parallelism_tag); } template<typename _Iterator, typename _Function> inline _Function for_each(_Iterator __begin, _Iterator __end, _Function __f) { return __for_each_switch(__begin, __end, __f, std::__iterator_category(__begin)); } // Sequential fallback template<typename _IIter, typename _Tp> inline _IIter find(_IIter __begin, _IIter __end, const _Tp& __val, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find(__begin, __end, __val); } // Sequential fallback for input iterator case template<typename _IIter, typename _Tp, typename _IteratorTag> inline _IIter __find_switch(_IIter __begin, _IIter __end, const _Tp& __val, _IteratorTag) { return _GLIBCXX_STD_A::find(__begin, __end, __val); } // Parallel find for random access iterators template<typename _RAIter, typename _Tp> _RAIter __find_switch(_RAIter __begin, _RAIter __end, const _Tp& __val, random_access_iterator_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; if (_GLIBCXX_PARALLEL_CONDITION(true)) { __gnu_parallel::__binder2nd<__gnu_parallel::_EqualTo<_ValueType, const _Tp&>, _ValueType, const _Tp&, bool> __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val); return __gnu_parallel::__find_template( __begin, __end, __begin, __comp, __gnu_parallel::__find_if_selector()).first; } else return _GLIBCXX_STD_A::find(__begin, __end, __val); } // Public interface template<typename _IIter, typename _Tp> inline _IIter find(_IIter __begin, _IIter __end, const _Tp& __val) { return __find_switch(__begin, __end, __val, std::__iterator_category(__begin)); } // Sequential fallback template<typename _IIter, typename _Predicate> inline _IIter find_if(_IIter __begin, _IIter __end, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); } // Sequential fallback for input iterator case template<typename _IIter, typename _Predicate, typename _IteratorTag> inline _IIter __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred, _IteratorTag) { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); } // Parallel find_if for random access iterators template<typename _RAIter, typename _Predicate> _RAIter __find_if_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) return __gnu_parallel::__find_template(__begin, __end, __begin, __pred, __gnu_parallel:: __find_if_selector()).first; else return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); } // Public interface template<typename _IIter, typename _Predicate> inline _IIter find_if(_IIter __begin, _IIter __end, _Predicate __pred) { return __find_if_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // Sequential fallback template<typename _IIter, typename _FIterator> inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find_first_of(__begin1, __end1, __begin2, __end2); } // Sequential fallback template<typename _IIter, typename _FIterator, typename _BinaryPredicate> inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::find_first_of( __begin1, __end1, __begin2, __end2, __comp); } // Sequential fallback for input iterator type template<typename _IIter, typename _FIterator, typename _IteratorTag1, typename _IteratorTag2> inline _IIter __find_first_of_switch(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _IteratorTag1, _IteratorTag2) { return find_first_of(__begin1, __end1, __begin2, __end2, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template<typename _RAIter, typename _FIterator, typename _BinaryPredicate, typename _IteratorTag> inline _RAIter __find_first_of_switch(_RAIter __begin1, _RAIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp, random_access_iterator_tag, _IteratorTag) { return __gnu_parallel:: __find_template(__begin1, __end1, __begin1, __comp, __gnu_parallel::__find_first_of_selector <_FIterator>(__begin2, __end2)).first; } // Sequential fallback for input iterator type template<typename _IIter, typename _FIterator, typename _BinaryPredicate, typename _IteratorTag1, typename _IteratorTag2> inline _IIter __find_first_of_switch(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2) { return find_first_of(__begin1, __end1, __begin2, __end2, __comp, __gnu_parallel::sequential_tag()); } // Public interface template<typename _IIter, typename _FIterator, typename _BinaryPredicate> inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp) { return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Public interface, insert default comparator template<typename _IIter, typename _FIterator> inline _IIter find_first_of(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2) { typedef typename std::iterator_traits<_IIter>::value_type _IValueType; typedef typename std::iterator_traits<_FIterator>::value_type _FValueType; return __gnu_parallel::find_first_of(__begin1, __end1, __begin2, __end2, __gnu_parallel::_EqualTo<_IValueType, _FValueType>()); } // Sequential fallback template<typename _IIter, typename _OutputIterator> inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out); } // Sequential fallback template<typename _IIter, typename _OutputIterator, typename _Predicate> inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out, __pred); } // Sequential fallback for input iterator case template<typename _IIter, typename _OutputIterator, typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> inline _OutputIterator __unique_copy_switch(_IIter __begin, _IIter __last, _OutputIterator __out, _Predicate __pred, _IteratorTag1, _IteratorTag2) { return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); } // Parallel unique_copy for random access iterators template<typename _RAIter, typename RandomAccessOutputIterator, typename _Predicate> RandomAccessOutputIterator __unique_copy_switch(_RAIter __begin, _RAIter __last, RandomAccessOutputIterator __out, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin) > __gnu_parallel::_Settings::get().unique_copy_minimal_n)) return __gnu_parallel::__parallel_unique_copy( __begin, __last, __out, __pred); else return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); } // Public interface template<typename _IIter, typename _OutputIterator> inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter>::value_type _ValueType; return __unique_copy_switch( __begin1, __end1, __out, equal_to<_ValueType>(), std::__iterator_category(__begin1), std::__iterator_category(__out)); } // Public interface template<typename _IIter, typename _OutputIterator, typename _Predicate> inline _OutputIterator unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out, _Predicate __pred) { return __unique_copy_switch( __begin1, __end1, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__out)); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _OutputIterator> inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_union( __begin1, __end1, __begin2, __end2, __out); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Predicate> inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_union(__begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case template<typename _IIter1, typename _IIter2, typename _Predicate, typename _OutputIterator, typename _IteratorTag1, typename _IteratorTag2, typename _IteratorTag3> inline _OutputIterator __set_union_switch( _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_union(__begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_union for random access iterators template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, typename _Predicate> _Output_RAIter __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_union_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_union_minimal_n)) return __gnu_parallel::__parallel_set_union( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_union(__begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface template<typename _IIter1, typename _IIter2, typename _OutputIterator> inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_union_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Public interface template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Predicate> inline _OutputIterator set_union(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_union_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback. template<typename _IIter1, typename _IIter2, typename _OutputIterator> inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2, __end2, __out); } // Sequential fallback. template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Predicate> inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_intersection( __begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case template<typename _IIter1, typename _IIter2, typename _Predicate, typename _OutputIterator, typename _IteratorTag1, typename _IteratorTag2, typename _IteratorTag3> inline _OutputIterator __set_intersection_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_intersection for random access iterators template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, typename _Predicate> _Output_RAIter __set_intersection_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_union_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_union_minimal_n)) return __gnu_parallel::__parallel_set_intersection( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_intersection( __begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface template<typename _IIter1, typename _IIter2, typename _OutputIterator> inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_intersection_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Predicate> inline _OutputIterator set_intersection(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_intersection_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _OutputIterator> inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __out); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Predicate> inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case template<typename _IIter1, typename _IIter2, typename _Predicate, typename _OutputIterator, typename _IteratorTag1, typename _IteratorTag2, typename _IteratorTag3> inline _OutputIterator __set_symmetric_difference_switch( _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_symmetric_difference for random access iterators template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, typename _Predicate> _Output_RAIter __set_symmetric_difference_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n)) return __gnu_parallel::__parallel_set_symmetric_difference( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_symmetric_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface. template<typename _IIter1, typename _IIter2, typename _OutputIterator> inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_symmetric_difference_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Public interface. template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Predicate> inline _OutputIterator set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_symmetric_difference_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback. template<typename _IIter1, typename _IIter2, typename _OutputIterator> inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_difference( __begin1,__end1, __begin2, __end2, __out); } // Sequential fallback. template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Predicate> inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::set_difference(__begin1, __end1, __begin2, __end2, __out, __pred); } // Sequential fallback for input iterator case. template<typename _IIter1, typename _IIter2, typename _Predicate, typename _OutputIterator, typename _IteratorTag1, typename _IteratorTag2, typename _IteratorTag3> inline _OutputIterator __set_difference_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::set_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Parallel set_difference for random access iterators template<typename _RAIter1, typename _RAIter2, typename _Output_RAIter, typename _Predicate> _Output_RAIter __set_difference_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().set_difference_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().set_difference_minimal_n)) return __gnu_parallel::__parallel_set_difference( __begin1, __end1, __begin2, __end2, __result, __pred); else return _GLIBCXX_STD_A::set_difference( __begin1, __end1, __begin2, __end2, __result, __pred); } // Public interface template<typename _IIter1, typename _IIter2, typename _OutputIterator> inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __set_difference_switch( __begin1, __end1, __begin2, __end2, __out, __gnu_parallel::_Less<_ValueType1, _ValueType2>(), std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Public interface template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Predicate> inline _OutputIterator set_difference(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out, _Predicate __pred) { return __set_difference_switch( __begin1, __end1, __begin2, __end2, __out, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__out)); } // Sequential fallback template<typename _FIterator> inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_find(__begin, __end); } // Sequential fallback template<typename _FIterator, typename _BinaryPredicate> inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::adjacent_find(__begin, __end, __binary_pred); } // Parallel algorithm for random access iterators template<typename _RAIter> _RAIter __adjacent_find_switch(_RAIter __begin, _RAIter __end, random_access_iterator_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; if (_GLIBCXX_PARALLEL_CONDITION(true)) { _RAIter __spot = __gnu_parallel:: __find_template( __begin, __end - 1, __begin, equal_to<_ValueType>(), __gnu_parallel::__adjacent_find_selector()) .first; if (__spot == (__end - 1)) return __end; else return __spot; } else return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case template<typename _FIterator, typename _IteratorTag> inline _FIterator __adjacent_find_switch(_FIterator __begin, _FIterator __end, _IteratorTag) { return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); } // Public interface template<typename _FIterator> inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end) { return __adjacent_find_switch(__begin, __end, std::__iterator_category(__begin)); } // Sequential fallback for input iterator case template<typename _FIterator, typename _BinaryPredicate, typename _IteratorTag> inline _FIterator __adjacent_find_switch(_FIterator __begin, _FIterator __end, _BinaryPredicate __pred, _IteratorTag) { return adjacent_find(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template<typename _RAIter, typename _BinaryPredicate> _RAIter __adjacent_find_switch(_RAIter __begin, _RAIter __end, _BinaryPredicate __pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION(true)) return __gnu_parallel::__find_template(__begin, __end, __begin, __pred, __gnu_parallel:: __adjacent_find_selector()).first; else return adjacent_find(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Public interface template<typename _FIterator, typename _BinaryPredicate> inline _FIterator adjacent_find(_FIterator __begin, _FIterator __end, _BinaryPredicate __pred) { return __adjacent_find_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // Sequential fallback template<typename _IIter, typename _Tp> inline typename iterator_traits<_IIter>::difference_type count(_IIter __begin, _IIter __end, const _Tp& __value, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::count(__begin, __end, __value); } // Parallel code for random access iterators template<typename _RAIter, typename _Tp> typename iterator_traits<_RAIter>::difference_type __count_switch(_RAIter __begin, _RAIter __end, const _Tp& __value, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef __gnu_parallel::_SequenceIndex _SequenceIndex; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().count_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { __gnu_parallel::__count_selector<_RAIter, _DifferenceType> __functionality; _DifferenceType __res = 0; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __value, __functionality, std::plus<_SequenceIndex>(), __res, __res, -1, __parallelism_tag); return __res; } else return count(__begin, __end, __value, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template<typename _IIter, typename _Tp, typename _IteratorTag> inline typename iterator_traits<_IIter>::difference_type __count_switch(_IIter __begin, _IIter __end, const _Tp& __value, _IteratorTag) { return count(__begin, __end, __value, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _IIter, typename _Tp> inline typename iterator_traits<_IIter>::difference_type count(_IIter __begin, _IIter __end, const _Tp& __value, __gnu_parallel::_Parallelism __parallelism_tag) { return __count_switch(__begin, __end, __value, std::__iterator_category(__begin), __parallelism_tag); } template<typename _IIter, typename _Tp> inline typename iterator_traits<_IIter>::difference_type count(_IIter __begin, _IIter __end, const _Tp& __value) { return __count_switch(__begin, __end, __value, std::__iterator_category(__begin)); } // Sequential fallback. template<typename _IIter, typename _Predicate> inline typename iterator_traits<_IIter>::difference_type count_if(_IIter __begin, _IIter __end, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::count_if(__begin, __end, __pred); } // Parallel count_if for random access iterators template<typename _RAIter, typename _Predicate> typename iterator_traits<_RAIter>::difference_type __count_if_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; typedef typename _TraitsType::difference_type _DifferenceType; typedef __gnu_parallel::_SequenceIndex _SequenceIndex; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().count_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _DifferenceType __res = 0; __gnu_parallel:: __count_if_selector<_RAIter, _DifferenceType> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __pred, __functionality, std::plus<_SequenceIndex>(), __res, __res, -1, __parallelism_tag); return __res; } else return count_if(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template<typename _IIter, typename _Predicate, typename _IteratorTag> inline typename iterator_traits<_IIter>::difference_type __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred, _IteratorTag) { return count_if(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _IIter, typename _Predicate> inline typename iterator_traits<_IIter>::difference_type count_if(_IIter __begin, _IIter __end, _Predicate __pred, __gnu_parallel::_Parallelism __parallelism_tag) { return __count_if_switch(__begin, __end, __pred, std::__iterator_category(__begin), __parallelism_tag); } template<typename _IIter, typename _Predicate> inline typename iterator_traits<_IIter>::difference_type count_if(_IIter __begin, _IIter __end, _Predicate __pred) { return __count_if_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // Sequential fallback. template<typename _FIterator1, typename _FIterator2> inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search(__begin1, __end1, __begin2, __end2); } // Parallel algorithm for random access iterator template<typename _RAIter1, typename _RAIter2> _RAIter1 __search_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, random_access_iterator_tag, random_access_iterator_tag) { typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_RAIter2>::value_type _ValueType2; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().search_minimal_n)) return __gnu_parallel:: __search_template( __begin1, __end1, __begin2, __end2, __gnu_parallel::_EqualTo<_ValueType1, _ValueType2>()); else return search(__begin1, __end1, __begin2, __end2, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case template<typename _FIterator1, typename _FIterator2, typename _IteratorTag1, typename _IteratorTag2> inline _FIterator1 __search_switch(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _IteratorTag1, _IteratorTag2) { return search(__begin1, __end1, __begin2, __end2, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _FIterator1, typename _FIterator2> inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2) { return __search_switch(__begin1, __end1, __begin2, __end2, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Public interface. template<typename _FIterator1, typename _FIterator2, typename _BinaryPredicate> inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _BinaryPredicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search( __begin1, __end1, __begin2, __end2, __pred); } // Parallel algorithm for random access iterator. template<typename _RAIter1, typename _RAIter2, typename _BinaryPredicate> _RAIter1 __search_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().search_minimal_n)) return __gnu_parallel::__search_template(__begin1, __end1, __begin2, __end2, __pred); else return search(__begin1, __end1, __begin2, __end2, __pred, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case template<typename _FIterator1, typename _FIterator2, typename _BinaryPredicate, typename _IteratorTag1, typename _IteratorTag2> inline _FIterator1 __search_switch(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2) { return search(__begin1, __end1, __begin2, __end2, __pred, __gnu_parallel::sequential_tag()); } // Public interface template<typename _FIterator1, typename _FIterator2, typename _BinaryPredicate> inline _FIterator1 search(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2, _BinaryPredicate __pred) { return __search_switch(__begin1, __end1, __begin2, __end2, __pred, std::__iterator_category(__begin1), std::__iterator_category(__begin2)); } // Sequential fallback template<typename _FIterator, typename _Integer, typename _Tp> inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val); } // Sequential fallback template<typename _FIterator, typename _Integer, typename _Tp, typename _BinaryPredicate> inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::search_n( __begin, __end, __count, __val, __binary_pred); } // Public interface. template<typename _FIterator, typename _Integer, typename _Tp> inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return __gnu_parallel::search_n(__begin, __end, __count, __val, __gnu_parallel::_EqualTo<_ValueType, _Tp>()); } // Parallel algorithm for random access iterators. template<typename _RAIter, typename _Integer, typename _Tp, typename _BinaryPredicate> _RAIter __search_n_switch(_RAIter __begin, _RAIter __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().search_minimal_n)) { __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, __count); return __gnu_parallel::__search_template( __begin, __end, __ps.begin(), __ps.end(), __binary_pred); } else return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val, __binary_pred); } // Sequential fallback for input iterator case. template<typename _FIterator, typename _Integer, typename _Tp, typename _BinaryPredicate, typename _IteratorTag> inline _FIterator __search_n_switch(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred, _IteratorTag) { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val, __binary_pred); } // Public interface. template<typename _FIterator, typename _Integer, typename _Tp, typename _BinaryPredicate> inline _FIterator search_n(_FIterator __begin, _FIterator __end, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred) { return __search_n_switch(__begin, __end, __count, __val, __binary_pred, std::__iterator_category(__begin)); } // Sequential fallback. template<typename _IIter, typename _OutputIterator, typename _UnaryOperation> inline _OutputIterator transform(_IIter __begin, _IIter __end, _OutputIterator __result, _UnaryOperation __unary_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::transform(__begin, __end, __result, __unary_op); } // Parallel unary transform for random access iterators. template<typename _RAIter1, typename _RAIter2, typename _UnaryOperation> _RAIter2 __transform1_switch(_RAIter1 __begin, _RAIter1 __end, _RAIter2 __result, _UnaryOperation __unary_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().transform_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy = true; typedef __gnu_parallel::_IteratorPair<_RAIter1, _RAIter2, random_access_iterator_tag> _ItTrip; _ItTrip __begin_pair(__begin, __result), __end_pair(__end, __result + (__end - __begin)); __gnu_parallel::__transform1_selector<_ItTrip> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin_pair, __end_pair, __unary_op, __functionality, __gnu_parallel::_DummyReduct(), __dummy, __dummy, -1, __parallelism_tag); return __functionality._M_finish_iterator; } else return transform(__begin, __end, __result, __unary_op, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template<typename _RAIter1, typename _RAIter2, typename _UnaryOperation, typename _IteratorTag1, typename _IteratorTag2> inline _RAIter2 __transform1_switch(_RAIter1 __begin, _RAIter1 __end, _RAIter2 __result, _UnaryOperation __unary_op, _IteratorTag1, _IteratorTag2) { return transform(__begin, __end, __result, __unary_op, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _IIter, typename _OutputIterator, typename _UnaryOperation> inline _OutputIterator transform(_IIter __begin, _IIter __end, _OutputIterator __result, _UnaryOperation __unary_op, __gnu_parallel::_Parallelism __parallelism_tag) { return __transform1_switch(__begin, __end, __result, __unary_op, std::__iterator_category(__begin), std::__iterator_category(__result), __parallelism_tag); } template<typename _IIter, typename _OutputIterator, typename _UnaryOperation> inline _OutputIterator transform(_IIter __begin, _IIter __end, _OutputIterator __result, _UnaryOperation __unary_op) { return __transform1_switch(__begin, __end, __result, __unary_op, std::__iterator_category(__begin), std::__iterator_category(__result)); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _BinaryOperation> inline _OutputIterator transform(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::transform(__begin1, __end1, __begin2, __result, __binary_op); } // Parallel binary transform for random access iterators. template<typename _RAIter1, typename _RAIter2, typename _RAIter3, typename _BinaryOperation> _RAIter3 __transform2_switch(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter3 __result, _BinaryOperation __binary_op, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( (__end1 - __begin1) >= __gnu_parallel::_Settings::get().transform_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy = true; typedef __gnu_parallel::_IteratorTriple<_RAIter1, _RAIter2, _RAIter3, random_access_iterator_tag> _ItTrip; _ItTrip __begin_triple(__begin1, __begin2, __result), __end_triple(__end1, __begin2 + (__end1 - __begin1), __result + (__end1 - __begin1)); __gnu_parallel::__transform2_selector<_ItTrip> __functionality; __gnu_parallel:: __for_each_template_random_access(__begin_triple, __end_triple, __binary_op, __functionality, __gnu_parallel::_DummyReduct(), __dummy, __dummy, -1, __parallelism_tag); return __functionality._M_finish_iterator; } else return transform(__begin1, __end1, __begin2, __result, __binary_op, __gnu_parallel::sequential_tag()); } // Sequential fallback for input iterator case. template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _BinaryOperation, typename _Tag1, typename _Tag2, typename _Tag3> inline _OutputIterator __transform2_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3) { return transform(__begin1, __end1, __begin2, __result, __binary_op, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _BinaryOperation> inline _OutputIterator transform(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag) { return __transform2_switch( __begin1, __end1, __begin2, __result, __binary_op, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__result), __parallelism_tag); } template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _BinaryOperation> inline _OutputIterator transform(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op) { return __transform2_switch( __begin1, __end1, __begin2, __result, __binary_op, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__result)); } // Sequential fallback template<typename _FIterator, typename _Tp> inline void replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::replace(__begin, __end, __old_value, __new_value); } // Sequential fallback for input iterator case template<typename _FIterator, typename _Tp, typename _IteratorTag> inline void __replace_switch(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value, _IteratorTag) { replace(__begin, __end, __old_value, __new_value, __gnu_parallel::sequential_tag()); } // Parallel replace for random access iterators template<typename _RAIter, typename _Tp> inline void __replace_switch(_RAIter __begin, _RAIter __end, const _Tp& __old_value, const _Tp& __new_value, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { // XXX parallel version is where? replace(__begin, __end, __old_value, __new_value, __gnu_parallel::sequential_tag()); } // Public interface template<typename _FIterator, typename _Tp> inline void replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value, __gnu_parallel::_Parallelism __parallelism_tag) { __replace_switch(__begin, __end, __old_value, __new_value, std::__iterator_category(__begin), __parallelism_tag); } template<typename _FIterator, typename _Tp> inline void replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, const _Tp& __new_value) { __replace_switch(__begin, __end, __old_value, __new_value, std::__iterator_category(__begin)); } // Sequential fallback template<typename _FIterator, typename _Predicate, typename _Tp> inline void replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::replace_if(__begin, __end, __pred, __new_value); } // Sequential fallback for input iterator case template<typename _FIterator, typename _Predicate, typename _Tp, typename _IteratorTag> inline void __replace_if_switch(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value, _IteratorTag) { replace_if(__begin, __end, __pred, __new_value, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template<typename _RAIter, typename _Predicate, typename _Tp> void __replace_if_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, const _Tp& __new_value, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().replace_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy; __gnu_parallel:: __replace_if_selector<_RAIter, _Predicate, _Tp> __functionality(__new_value); __gnu_parallel:: __for_each_template_random_access( __begin, __end, __pred, __functionality, __gnu_parallel::_DummyReduct(), true, __dummy, -1, __parallelism_tag); } else replace_if(__begin, __end, __pred, __new_value, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _FIterator, typename _Predicate, typename _Tp> inline void replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value, __gnu_parallel::_Parallelism __parallelism_tag) { __replace_if_switch(__begin, __end, __pred, __new_value, std::__iterator_category(__begin), __parallelism_tag); } template<typename _FIterator, typename _Predicate, typename _Tp> inline void replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred, const _Tp& __new_value) { __replace_if_switch(__begin, __end, __pred, __new_value, std::__iterator_category(__begin)); } // Sequential fallback template<typename _FIterator, typename _Generator> inline void generate(_FIterator __begin, _FIterator __end, _Generator __gen, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::generate(__begin, __end, __gen); } // Sequential fallback for input iterator case. template<typename _FIterator, typename _Generator, typename _IteratorTag> inline void __generate_switch(_FIterator __begin, _FIterator __end, _Generator __gen, _IteratorTag) { generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template<typename _RAIter, typename _Generator> void __generate_switch(_RAIter __begin, _RAIter __end, _Generator __gen, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().generate_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { bool __dummy; __gnu_parallel::__generate_selector<_RAIter> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __gen, __functionality, __gnu_parallel::_DummyReduct(), true, __dummy, -1, __parallelism_tag); } else generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _FIterator, typename _Generator> inline void generate(_FIterator __begin, _FIterator __end, _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag) { __generate_switch(__begin, __end, __gen, std::__iterator_category(__begin), __parallelism_tag); } template<typename _FIterator, typename _Generator> inline void generate(_FIterator __begin, _FIterator __end, _Generator __gen) { __generate_switch(__begin, __end, __gen, std::__iterator_category(__begin)); } // Sequential fallback. template<typename _OutputIterator, typename _Size, typename _Generator> inline _OutputIterator generate_n(_OutputIterator __begin, _Size __n, _Generator __gen, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::generate_n(__begin, __n, __gen); } // Sequential fallback for input iterator case. template<typename _OutputIterator, typename _Size, typename _Generator, typename _IteratorTag> inline _OutputIterator __generate_n_switch(_OutputIterator __begin, _Size __n, _Generator __gen, _IteratorTag) { return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template<typename _RAIter, typename _Size, typename _Generator> inline _RAIter __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { // XXX parallel version is where? return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _OutputIterator, typename _Size, typename _Generator> inline _OutputIterator generate_n(_OutputIterator __begin, _Size __n, _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag) { return __generate_n_switch(__begin, __n, __gen, std::__iterator_category(__begin), __parallelism_tag); } template<typename _OutputIterator, typename _Size, typename _Generator> inline _OutputIterator generate_n(_OutputIterator __begin, _Size __n, _Generator __gen) { return __generate_n_switch(__begin, __n, __gen, std::__iterator_category(__begin)); } // Sequential fallback. template<typename _RAIter> inline void random_shuffle(_RAIter __begin, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::random_shuffle(__begin, __end); } // Sequential fallback. template<typename _RAIter, typename _RandomNumberGenerator> inline void random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator& __rand, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::random_shuffle(__begin, __end, __rand); } /** @brief Functor wrapper for std::rand(). */ template<typename _MustBeInt = int> struct _CRandNumber { int operator()(int __limit) { return rand() % __limit; } }; // Fill in random number generator. template<typename _RAIter> inline void random_shuffle(_RAIter __begin, _RAIter __end) { _CRandNumber<> __r; // Parallelization still possible. __gnu_parallel::random_shuffle(__begin, __end, __r); } // Parallel algorithm for random access iterators. template<typename _RAIter, typename _RandomNumberGenerator> void random_shuffle(_RAIter __begin, _RAIter __end, #if __cplusplus >= 201103L _RandomNumberGenerator&& __rand) #else _RandomNumberGenerator& __rand) #endif { if (__begin == __end) return; if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n)) __gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand); else __gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand); } // Sequential fallback. template<typename _FIterator, typename _Predicate> inline _FIterator partition(_FIterator __begin, _FIterator __end, _Predicate __pred, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::partition(__begin, __end, __pred); } // Sequential fallback for input iterator case. template<typename _FIterator, typename _Predicate, typename _IteratorTag> inline _FIterator __partition_switch(_FIterator __begin, _FIterator __end, _Predicate __pred, _IteratorTag) { return partition(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators. template<typename _RAIter, typename _Predicate> _RAIter __partition_switch(_RAIter __begin, _RAIter __end, _Predicate __pred, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().partition_minimal_n)) { typedef typename std::iterator_traits<_RAIter>:: difference_type _DifferenceType; _DifferenceType __middle = __gnu_parallel:: __parallel_partition(__begin, __end, __pred, __gnu_parallel::__get_max_threads()); return __begin + __middle; } else return partition(__begin, __end, __pred, __gnu_parallel::sequential_tag()); } // Public interface. template<typename _FIterator, typename _Predicate> inline _FIterator partition(_FIterator __begin, _FIterator __end, _Predicate __pred) { return __partition_switch(__begin, __end, __pred, std::__iterator_category(__begin)); } // sort interface // Sequential fallback template<typename _RAIter> inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::sort(__begin, __end); } // Sequential fallback template<typename _RAIter, typename _Compare> inline void sort(_RAIter __begin, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::sort<_RAIter, _Compare>(__begin, __end, __comp); } // Public interface template<typename _RAIter, typename _Compare, typename _Parallelism> void sort(_RAIter __begin, _RAIter __end, _Compare __comp, _Parallelism __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; if (__begin != __end) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().sort_minimal_n)) __gnu_parallel::__parallel_sort<false>( __begin, __end, __comp, __parallelism); else sort(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } } // Public interface, insert default comparator template<typename _RAIter> inline void sort(_RAIter __begin, _RAIter __end) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __gnu_parallel::default_parallel_tag()); } // Public interface, insert default comparator template<typename _RAIter> inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::default_parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template<typename _RAIter> inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template<typename _RAIter> inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template<typename _RAIter> inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_sampling_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template<typename _RAIter> inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_exact_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template<typename _RAIter> inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template<typename _RAIter> inline void sort(_RAIter __begin, _RAIter __end, __gnu_parallel::balanced_quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface template<typename _RAIter, typename _Compare> void sort(_RAIter __begin, _RAIter __end, _Compare __comp) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag()); } // stable_sort interface // Sequential fallback template<typename _RAIter> inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::stable_sort(__begin, __end); } // Sequential fallback template<typename _RAIter, typename _Compare> inline void stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::stable_sort<_RAIter, _Compare>(__begin, __end, __comp); } // Public interface template<typename _RAIter, typename _Compare, typename _Parallelism> void stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp, _Parallelism __parallelism) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; if (__begin != __end) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().sort_minimal_n)) __gnu_parallel::__parallel_sort<true>(__begin, __end, __comp, __parallelism); else stable_sort(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } } // Public interface, insert default comparator template<typename _RAIter> inline void stable_sort(_RAIter __begin, _RAIter __end) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __gnu_parallel::default_parallel_tag()); } // Public interface, insert default comparator template<typename _RAIter> inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::default_parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template<typename _RAIter> inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::parallel_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template<typename _RAIter> inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::multiway_mergesort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template<typename _RAIter> inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface, insert default comparator template<typename _RAIter> inline void stable_sort(_RAIter __begin, _RAIter __end, __gnu_parallel::balanced_quicksort_tag __parallelism) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism); } // Public interface template<typename _RAIter, typename _Compare> void stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp) { stable_sort( __begin, __end, __comp, __gnu_parallel::default_parallel_tag()); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _OutputIterator> inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::merge( __begin1, __end1, __begin2, __end2, __result); } // Sequential fallback template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Compare> inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::merge( __begin1, __end1, __begin2, __end2, __result, __comp); } // Sequential fallback for input iterator case template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Compare, typename _IteratorTag1, typename _IteratorTag2, typename _IteratorTag3> inline _OutputIterator __merge_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp, _IteratorTag1, _IteratorTag2, _IteratorTag3) { return _GLIBCXX_STD_A::merge(__begin1, __end1, __begin2, __end2, __result, __comp); } // Parallel algorithm for random access iterators template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Compare> _OutputIterator __merge_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag) { if (_GLIBCXX_PARALLEL_CONDITION( (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1) >= __gnu_parallel::_Settings::get().merge_minimal_n || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2) >= __gnu_parallel::_Settings::get().merge_minimal_n))) return __gnu_parallel::__parallel_merge_advance( __begin1, __end1, __begin2, __end2, __result, (__end1 - __begin1) + (__end2 - __begin2), __comp); else return __gnu_parallel::__merge_advance( __begin1, __end1, __begin2, __end2, __result, (__end1 - __begin1) + (__end2 - __begin2), __comp); } // Public interface template<typename _IIter1, typename _IIter2, typename _OutputIterator, typename _Compare> inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Compare __comp) { return __merge_switch( __begin1, __end1, __begin2, __end2, __result, __comp, std::__iterator_category(__begin1), std::__iterator_category(__begin2), std::__iterator_category(__result)); } // Public interface, insert default comparator template<typename _IIter1, typename _IIter2, typename _OutputIterator> inline _OutputIterator merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result) { typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2; return __gnu_parallel::merge(__begin1, __end1, __begin2, __end2, __result, __gnu_parallel::_Less<_ValueType1, _ValueType2>()); } // Sequential fallback template<typename _RAIter> inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end); } // Sequential fallback template<typename _RAIter, typename _Compare> inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end, __comp); } // Public interface template<typename _RAIter, typename _Compare> inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().nth_element_minimal_n)) __gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp); else nth_element(__begin, __nth, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template<typename _RAIter> inline void nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end) { typedef typename iterator_traits<_RAIter>::value_type _ValueType; __gnu_parallel::nth_element(__begin, __nth, __end, std::less<_ValueType>()); } // Sequential fallback template<typename _RAIter, typename _Compare> inline void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end, __comp); } // Sequential fallback template<typename _RAIter> inline void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, __gnu_parallel::sequential_tag) { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end); } // Public interface, parallel algorithm for random access iterators template<typename _RAIter, typename _Compare> void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().partial_sort_minimal_n)) __gnu_parallel:: __parallel_partial_sort(__begin, __middle, __end, __comp); else partial_sort(__begin, __middle, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template<typename _RAIter> inline void partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end) { typedef iterator_traits<_RAIter> _TraitsType; typedef typename _TraitsType::value_type _ValueType; __gnu_parallel::partial_sort(__begin, __middle, __end, std::less<_ValueType>()); } // Sequential fallback template<typename _FIterator> inline _FIterator max_element(_FIterator __begin, _FIterator __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::max_element(__begin, __end); } // Sequential fallback template<typename _FIterator, typename _Compare> inline _FIterator max_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::max_element(__begin, __end, __comp); } // Sequential fallback for input iterator case template<typename _FIterator, typename _Compare, typename _IteratorTag> inline _FIterator __max_element_switch(_FIterator __begin, _FIterator __end, _Compare __comp, _IteratorTag) { return max_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template<typename _RAIter, typename _Compare> _RAIter __max_element_switch(_RAIter __begin, _RAIter __end, _Compare __comp, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().max_element_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _RAIter __res(__begin); __gnu_parallel::__identity_selector<_RAIter> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __gnu_parallel::_Nothing(), __functionality, __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp), __res, __res, -1, __parallelism_tag); return __res; } else return max_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template<typename _FIterator> inline _FIterator max_element(_FIterator __begin, _FIterator __end, __gnu_parallel::_Parallelism __parallelism_tag) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return max_element(__begin, __end, std::less<_ValueType>(), __parallelism_tag); } template<typename _FIterator> inline _FIterator max_element(_FIterator __begin, _FIterator __end) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return __gnu_parallel::max_element(__begin, __end, std::less<_ValueType>()); } // Public interface template<typename _FIterator, typename _Compare> inline _FIterator max_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::_Parallelism __parallelism_tag) { return __max_element_switch(__begin, __end, __comp, std::__iterator_category(__begin), __parallelism_tag); } template<typename _FIterator, typename _Compare> inline _FIterator max_element(_FIterator __begin, _FIterator __end, _Compare __comp) { return __max_element_switch(__begin, __end, __comp, std::__iterator_category(__begin)); } // Sequential fallback template<typename _FIterator> inline _FIterator min_element(_FIterator __begin, _FIterator __end, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::min_element(__begin, __end); } // Sequential fallback template<typename _FIterator, typename _Compare> inline _FIterator min_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::sequential_tag) { return _GLIBCXX_STD_A::min_element(__begin, __end, __comp); } // Sequential fallback for input iterator case template<typename _FIterator, typename _Compare, typename _IteratorTag> inline _FIterator __min_element_switch(_FIterator __begin, _FIterator __end, _Compare __comp, _IteratorTag) { return min_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Parallel algorithm for random access iterators template<typename _RAIter, typename _Compare> _RAIter __min_element_switch(_RAIter __begin, _RAIter __end, _Compare __comp, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag) { if (_GLIBCXX_PARALLEL_CONDITION( static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >= __gnu_parallel::_Settings::get().min_element_minimal_n && __gnu_parallel::__is_parallel(__parallelism_tag))) { _RAIter __res(__begin); __gnu_parallel::__identity_selector<_RAIter> __functionality; __gnu_parallel:: __for_each_template_random_access( __begin, __end, __gnu_parallel::_Nothing(), __functionality, __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp), __res, __res, -1, __parallelism_tag); return __res; } else return min_element(__begin, __end, __comp, __gnu_parallel::sequential_tag()); } // Public interface, insert default comparator template<typename _FIterator> inline _FIterator min_element(_FIterator __begin, _FIterator __end, __gnu_parallel::_Parallelism __parallelism_tag) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return min_element(__begin, __end, std::less<_ValueType>(), __parallelism_tag); } template<typename _FIterator> inline _FIterator min_element(_FIterator __begin, _FIterator __end) { typedef typename iterator_traits<_FIterator>::value_type _ValueType; return __gnu_parallel::min_element(__begin, __end, std::less<_ValueType>()); } // Public interface template<typename _FIterator, typename _Compare> inline _FIterator min_element(_FIterator __begin, _FIterator __end, _Compare __comp, __gnu_parallel::_Parallelism __parallelism_tag) { return __min_element_switch(__begin, __end, __comp, std::__iterator_category(__begin), __parallelism_tag); } template<typename _FIterator, typename _Compare> inline _FIterator min_element(_FIterator __begin, _FIterator __end, _Compare __comp) { return __min_element_switch(__begin, __end, __comp, std::__iterator_category(__begin)); } } // end namespace } // end namespace #endif /* _GLIBCXX_PARALLEL_ALGO_H */ c++/8/parallel/merge.h 0000644 00000022552 15146341150 0010335 0 ustar 00 // -*- C++ -*- // Copyright (C) 2007-2018 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 parallel/merge.h * @brief Parallel implementation of std::merge(). * This file is a GNU parallel extension to the Standard C++ Library. */ // Written by Johannes Singler. #ifndef _GLIBCXX_PARALLEL_MERGE_H #define _GLIBCXX_PARALLEL_MERGE_H 1 #include <parallel/basic_iterator.h> #include <bits/stl_algo.h> namespace __gnu_parallel { /** @brief Merge routine being able to merge only the @c __max_length * smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template<typename _RAIter1, typename _RAIter2, typename _OutputIterator, typename _DifferenceTp, typename _Compare> _OutputIterator __merge_advance_usual(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) { typedef _DifferenceTp _DifferenceType; while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0) { // array1[__i1] < array0[i0] if (__comp(*__begin2, *__begin1)) *__target++ = *__begin2++; else *__target++ = *__begin1++; --__max_length; } if (__begin1 != __end1) { __target = std::copy(__begin1, __begin1 + __max_length, __target); __begin1 += __max_length; } else { __target = std::copy(__begin2, __begin2 + __max_length, __target); __begin2 += __max_length; } return __target; } /** @brief Merge routine being able to merge only the @c __max_length * smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * Specially designed code should allow the compiler to generate * conditional moves instead of branches. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template<typename _RAIter1, typename _RAIter2, typename _OutputIterator, typename _DifferenceTp, typename _Compare> _OutputIterator __merge_advance_movc(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) { typedef _DifferenceTp _DifferenceType; typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType1; typedef typename std::iterator_traits<_RAIter2>::value_type _ValueType2; #if _GLIBCXX_PARALLEL_ASSERTIONS _GLIBCXX_PARALLEL_ASSERT(__max_length >= 0); #endif while (__begin1 != __end1 && __begin2 != __end2 && __max_length > 0) { _RAIter1 __next1 = __begin1 + 1; _RAIter2 __next2 = __begin2 + 1; _ValueType1 __element1 = *__begin1; _ValueType2 __element2 = *__begin2; if (__comp(__element2, __element1)) { __element1 = __element2; __begin2 = __next2; } else __begin1 = __next1; *__target = __element1; ++__target; --__max_length; } if (__begin1 != __end1) { __target = std::copy(__begin1, __begin1 + __max_length, __target); __begin1 += __max_length; } else { __target = std::copy(__begin2, __begin2 + __max_length, __target); __begin2 += __max_length; } return __target; } /** @brief Merge routine being able to merge only the @c __max_length * smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * Static switch on whether to use the conditional-move variant. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template<typename _RAIter1, typename _RAIter2, typename _OutputIterator, typename _DifferenceTp, typename _Compare> inline _OutputIterator __merge_advance(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) { _GLIBCXX_CALL(__max_length) return __merge_advance_movc(__begin1, __end1, __begin2, __end2, __target, __max_length, __comp); } /** @brief Merge routine fallback to sequential in case the iterators of the two input sequences are of different type. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template<typename _RAIter1, typename _RAIter2, typename _RAIter3, typename _Compare> inline _RAIter3 __parallel_merge_advance(_RAIter1& __begin1, _RAIter1 __end1, _RAIter2& __begin2, // different iterators, parallel implementation // not available _RAIter2 __end2, _RAIter3 __target, typename std::iterator_traits<_RAIter1>:: difference_type __max_length, _Compare __comp) { return __merge_advance(__begin1, __end1, __begin2, __end2, __target, __max_length, __comp); } /** @brief Parallel merge routine being able to merge only the @c * __max_length smallest elements. * * The @c __begin iterators are advanced accordingly, they might not * reach @c __end, in contrast to the usual variant. * The functionality is projected onto parallel_multiway_merge. * @param __begin1 Begin iterator of first sequence. * @param __end1 End iterator of first sequence. * @param __begin2 Begin iterator of second sequence. * @param __end2 End iterator of second sequence. * @param __target Target begin iterator. * @param __max_length Maximum number of elements to merge. * @param __comp Comparator. * @return Output end iterator. */ template<typename _RAIter1, typename _RAIter3, typename _Compare> inline _RAIter3 __parallel_merge_advance(_RAIter1& __begin1, _RAIter1 __end1, _RAIter1& __begin2, _RAIter1 __end2, _RAIter3 __target, typename std::iterator_traits<_RAIter1>:: difference_type __max_length, _Compare __comp) { typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType; typedef typename std::iterator_traits<_RAIter1>:: difference_type _DifferenceType1 /* == difference_type2 */; typedef typename std::iterator_traits<_RAIter3>:: difference_type _DifferenceType3; typedef typename std::pair<_RAIter1, _RAIter1> _IteratorPair; _IteratorPair __seqs[2] = { std::make_pair(__begin1, __end1), std::make_pair(__begin2, __end2) }; _RAIter3 __target_end = parallel_multiway_merge < /* __stable = */ true, /* __sentinels = */ false> (__seqs, __seqs + 2, __target, multiway_merge_exact_splitting < /* __stable = */ true, _IteratorPair*, _Compare, _DifferenceType1>, __max_length, __comp, omp_get_max_threads()); return __target_end; } } //namespace __gnu_parallel #endif /* _GLIBCXX_PARALLEL_MERGE_H */ c++/8/cstddef 0000644 00000014450 15146341150 0006626 0 ustar 00 // -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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 cstddef * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c stddef.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 18.1 Types // #ifndef _GLIBCXX_CSTDDEF #define _GLIBCXX_CSTDDEF 1 #pragma GCC system_header #undef __need_wchar_t #undef __need_ptrdiff_t #undef __need_size_t #undef __need_NULL #undef __need_wint_t #include <bits/c++config.h> #include <stddef.h> #if __cplusplus >= 201103L namespace std { // We handle size_t, ptrdiff_t, and nullptr_t in c++config.h. using ::max_align_t; } #endif #if __cplusplus >= 201703L namespace std { #define __cpp_lib_byte 201603 /// std::byte enum class byte : unsigned char {}; template<typename _IntegerType> struct __byte_operand { }; template<> struct __byte_operand<bool> { using __type = byte; }; template<> struct __byte_operand<char> { using __type = byte; }; template<> struct __byte_operand<signed char> { using __type = byte; }; template<> struct __byte_operand<unsigned char> { using __type = byte; }; #ifdef _GLIBCXX_USE_WCHAR_T template<> struct __byte_operand<wchar_t> { using __type = byte; }; #endif template<> struct __byte_operand<char16_t> { using __type = byte; }; template<> struct __byte_operand<char32_t> { using __type = byte; }; template<> struct __byte_operand<short> { using __type = byte; }; template<> struct __byte_operand<unsigned short> { using __type = byte; }; template<> struct __byte_operand<int> { using __type = byte; }; template<> struct __byte_operand<unsigned int> { using __type = byte; }; template<> struct __byte_operand<long> { using __type = byte; }; template<> struct __byte_operand<unsigned long> { using __type = byte; }; template<> struct __byte_operand<long long> { using __type = byte; }; template<> struct __byte_operand<unsigned long long> { using __type = byte; }; #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __byte_operand<__GLIBCXX_TYPE_INT_N_0> { using __type = byte; }; template<> struct __byte_operand<unsigned __GLIBCXX_TYPE_INT_N_0> { using __type = byte; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) template<> struct __byte_operand<__GLIBCXX_TYPE_INT_N_1> { using __type = byte; }; template<> struct __byte_operand<unsigned __GLIBCXX_TYPE_INT_N_1> { using __type = byte; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) template<> struct __byte_operand<__GLIBCXX_TYPE_INT_N_2> { using __type = byte; }; template<> struct __byte_operand<unsigned __GLIBCXX_TYPE_INT_N_2> { using __type = byte; }; #endif template<typename _IntegerType> struct __byte_operand<const _IntegerType> : __byte_operand<_IntegerType> { }; template<typename _IntegerType> struct __byte_operand<volatile _IntegerType> : __byte_operand<_IntegerType> { }; template<typename _IntegerType> struct __byte_operand<const volatile _IntegerType> : __byte_operand<_IntegerType> { }; template<typename _IntegerType> using __byte_op_t = typename __byte_operand<_IntegerType>::__type; template<typename _IntegerType> constexpr __byte_op_t<_IntegerType>& operator<<=(byte& __b, _IntegerType __shift) noexcept { return __b = byte(static_cast<unsigned char>(__b) << __shift); } template<typename _IntegerType> constexpr __byte_op_t<_IntegerType> operator<<(byte __b, _IntegerType __shift) noexcept { return byte(static_cast<unsigned char>(__b) << __shift); } template<typename _IntegerType> constexpr __byte_op_t<_IntegerType>& operator>>=(byte& __b, _IntegerType __shift) noexcept { return __b = byte(static_cast<unsigned char>(__b) >> __shift); } template<typename _IntegerType> constexpr __byte_op_t<_IntegerType> operator>>(byte __b, _IntegerType __shift) noexcept { return byte(static_cast<unsigned char>(__b) >> __shift); } constexpr byte& operator|=(byte& __l, byte __r) noexcept { return __l = byte(static_cast<unsigned char>(__l) | static_cast<unsigned char>(__r)); } constexpr byte operator|(byte __l, byte __r) noexcept { return byte(static_cast<unsigned char>(__l) | static_cast<unsigned char>(__r)); } constexpr byte& operator&=(byte& __l, byte __r) noexcept { return __l = byte(static_cast<unsigned char>(__l) & static_cast<unsigned char>(__r)); } constexpr byte operator&(byte __l, byte __r) noexcept { return byte(static_cast<unsigned char>(__l) & static_cast<unsigned char>(__r)); } constexpr byte& operator^=(byte& __l, byte __r) noexcept { return __l = byte(static_cast<unsigned char>(__l) ^ static_cast<unsigned char>(__r)); } constexpr byte operator^(byte __l, byte __r) noexcept { return byte(static_cast<unsigned char>(__l) ^ static_cast<unsigned char>(__r)); } constexpr byte operator~(byte __b) noexcept { return byte(~static_cast<unsigned char>(__b)); } template<typename _IntegerType> constexpr _IntegerType to_integer(__byte_op_t<_IntegerType> __b) noexcept { return _IntegerType(__b); } } // namespace std #endif #endif // _GLIBCXX_CSTDDEF c++/8/cinttypes 0000644 00000004155 15146341150 0007235 0 ustar 00 // <cinttypes> -*- C++ -*- // Copyright (C) 2007-2018 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/cinttypes * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CINTTYPES #define _GLIBCXX_CINTTYPES 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <cstdint> // For 27.9.2/3 (see C99, Note 184) #if _GLIBCXX_HAVE_INTTYPES_H # ifndef __STDC_FORMAT_MACROS # define _UNDEF__STDC_FORMAT_MACROS # define __STDC_FORMAT_MACROS # endif # include <inttypes.h> # ifdef _UNDEF__STDC_FORMAT_MACROS # undef __STDC_FORMAT_MACROS # undef _UNDEF__STDC_FORMAT_MACROS # endif #endif #ifdef _GLIBCXX_USE_C99_INTTYPES_TR1 namespace std { // types using ::imaxdiv_t; // functions using ::imaxabs; using ::imaxdiv; // GCC does not support extended integer types // intmax_t abs(intmax_t) // imaxdiv_t div(intmax_t, intmax_t) using ::strtoimax; using ::strtoumax; #if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1 using ::wcstoimax; using ::wcstoumax; #endif } // namespace std #endif // _GLIBCXX_USE_C99_INTTYPES_TR1 #endif // C++11 #endif // _GLIBCXX_CINTTYPES c++/8/atomic 0000644 00000120141 15146341150 0006461 0 ustar 00 // -*- C++ -*- header. // Copyright (C) 2008-2018 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/atomic * This is a Standard C++ Library header. */ // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl. // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html #ifndef _GLIBCXX_ATOMIC #define _GLIBCXX_ATOMIC 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <bits/atomic_base.h> #include <bits/move.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup atomics * @{ */ #if __cplusplus > 201402L # define __cpp_lib_atomic_is_always_lock_free 201603 #endif template<typename _Tp> struct atomic; /// atomic<bool> // NB: No operators or fetch-operations for this type. template<> struct atomic<bool> { private: __atomic_base<bool> _M_base; public: atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(bool __i) noexcept : _M_base(__i) { } bool operator=(bool __i) noexcept { return _M_base.operator=(__i); } bool operator=(bool __i) volatile noexcept { return _M_base.operator=(__i); } operator bool() const noexcept { return _M_base.load(); } operator bool() const volatile noexcept { return _M_base.load(); } bool is_lock_free() const noexcept { return _M_base.is_lock_free(); } bool is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); } #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2; #endif void store(bool __i, memory_order __m = memory_order_seq_cst) noexcept { _M_base.store(__i, __m); } void store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept { _M_base.store(__i, __m); } bool load(memory_order __m = memory_order_seq_cst) const noexcept { return _M_base.load(__m); } bool load(memory_order __m = memory_order_seq_cst) const volatile noexcept { return _M_base.load(__m); } bool exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept { return _M_base.exchange(__i, __m); } bool exchange(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_base.exchange(__i, __m); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m); } bool compare_exchange_weak(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_base.compare_exchange_weak(__i1, __i2, __m); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m); } bool compare_exchange_strong(bool& __i1, bool __i2, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_base.compare_exchange_strong(__i1, __i2, __m); } }; /** * @brief Generic atomic type, primary class template. * * @tparam _Tp Type to be made atomic, must be trivally copyable. */ template<typename _Tp> struct atomic { private: // Align 1/2/4/8/16-byte types to at least their size. static constexpr int _S_min_alignment = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16 ? 0 : sizeof(_Tp); static constexpr int _S_alignment = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp); alignas(_S_alignment) _Tp _M_i; static_assert(__is_trivially_copyable(_Tp), "std::atomic requires a trivially copyable type"); static_assert(sizeof(_Tp) > 0, "Incomplete or zero-sized types are not supported"); public: atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } operator _Tp() const noexcept { return load(); } operator _Tp() const volatile noexcept { return load(); } _Tp operator=(_Tp __i) noexcept { store(__i); return __i; } _Tp operator=(_Tp __i) volatile noexcept { store(__i); return __i; } bool is_lock_free() const noexcept { // Produce a fake, minimally aligned pointer. return __atomic_is_lock_free(sizeof(_M_i), reinterpret_cast<void *>(-__alignof(_M_i))); } bool is_lock_free() const volatile noexcept { // Produce a fake, minimally aligned pointer. return __atomic_is_lock_free(sizeof(_M_i), reinterpret_cast<void *>(-__alignof(_M_i))); } #if __cplusplus > 201402L static constexpr bool is_always_lock_free = __atomic_always_lock_free(sizeof(_M_i), 0); #endif void store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), __m); } void store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), __m); } _Tp load(memory_order __m = memory_order_seq_cst) const noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_load(std::__addressof(_M_i), __ptr, __m); return *__ptr; } _Tp load(memory_order __m = memory_order_seq_cst) const volatile noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_load(std::__addressof(_M_i), __ptr, __m); return *__ptr; } _Tp exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), __ptr, __m); return *__ptr; } _Tp exchange(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), __ptr, __m); return *__ptr; } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), true, __s, __f); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), true, __s, __f); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_weak(__e, __i, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_weak(__e, __i, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), false, __s, __f); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { return __atomic_compare_exchange(std::__addressof(_M_i), std::__addressof(__e), std::__addressof(__i), false, __s, __f); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_strong(__e, __i, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_strong(__e, __i, __m, __cmpexch_failure_order(__m)); } }; /// Partial specialization for pointer types. template<typename _Tp> struct atomic<_Tp*> { typedef _Tp* __pointer_type; typedef __atomic_base<_Tp*> __base_type; __base_type _M_b; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } operator __pointer_type() const noexcept { return __pointer_type(_M_b); } operator __pointer_type() const volatile noexcept { return __pointer_type(_M_b); } __pointer_type operator=(__pointer_type __p) noexcept { return _M_b.operator=(__p); } __pointer_type operator=(__pointer_type __p) volatile noexcept { return _M_b.operator=(__p); } __pointer_type operator++(int) noexcept { return _M_b++; } __pointer_type operator++(int) volatile noexcept { return _M_b++; } __pointer_type operator--(int) noexcept { return _M_b--; } __pointer_type operator--(int) volatile noexcept { return _M_b--; } __pointer_type operator++() noexcept { return ++_M_b; } __pointer_type operator++() volatile noexcept { return ++_M_b; } __pointer_type operator--() noexcept { return --_M_b; } __pointer_type operator--() volatile noexcept { return --_M_b; } __pointer_type operator+=(ptrdiff_t __d) noexcept { return _M_b.operator+=(__d); } __pointer_type operator+=(ptrdiff_t __d) volatile noexcept { return _M_b.operator+=(__d); } __pointer_type operator-=(ptrdiff_t __d) noexcept { return _M_b.operator-=(__d); } __pointer_type operator-=(ptrdiff_t __d) volatile noexcept { return _M_b.operator-=(__d); } bool is_lock_free() const noexcept { return _M_b.is_lock_free(); } bool is_lock_free() const volatile noexcept { return _M_b.is_lock_free(); } #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_POINTER_LOCK_FREE == 2; #endif void store(__pointer_type __p, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.store(__p, __m); } void store(__pointer_type __p, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.store(__p, __m); } __pointer_type load(memory_order __m = memory_order_seq_cst) const noexcept { return _M_b.load(__m); } __pointer_type load(memory_order __m = memory_order_seq_cst) const volatile noexcept { return _M_b.load(__m); } __pointer_type exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.exchange(__p, __m); } __pointer_type exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.exchange(__p, __m); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_weak(__p1, __p2, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_weak(__p1, __p2, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) volatile noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m, __cmpexch_failure_order(__m)); } bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.compare_exchange_strong(__p1, __p2, __m, __cmpexch_failure_order(__m)); } __pointer_type fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.fetch_add(__d, __m); } __pointer_type fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.fetch_add(__d, __m); } __pointer_type fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) noexcept { return _M_b.fetch_sub(__d, __m); } __pointer_type fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) volatile noexcept { return _M_b.fetch_sub(__d, __m); } }; /// Explicit specialization for char. template<> struct atomic<char> : __atomic_base<char> { typedef char __integral_type; typedef __atomic_base<char> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; #endif }; /// Explicit specialization for signed char. template<> struct atomic<signed char> : __atomic_base<signed char> { typedef signed char __integral_type; typedef __atomic_base<signed char> __base_type; atomic() noexcept= default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned char. template<> struct atomic<unsigned char> : __atomic_base<unsigned char> { typedef unsigned char __integral_type; typedef __atomic_base<unsigned char> __base_type; atomic() noexcept= default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; #endif }; /// Explicit specialization for short. template<> struct atomic<short> : __atomic_base<short> { typedef short __integral_type; typedef __atomic_base<short> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned short. template<> struct atomic<unsigned short> : __atomic_base<unsigned short> { typedef unsigned short __integral_type; typedef __atomic_base<unsigned short> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2; #endif }; /// Explicit specialization for int. template<> struct atomic<int> : __atomic_base<int> { typedef int __integral_type; typedef __atomic_base<int> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned int. template<> struct atomic<unsigned int> : __atomic_base<unsigned int> { typedef unsigned int __integral_type; typedef __atomic_base<unsigned int> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2; #endif }; /// Explicit specialization for long. template<> struct atomic<long> : __atomic_base<long> { typedef long __integral_type; typedef __atomic_base<long> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned long. template<> struct atomic<unsigned long> : __atomic_base<unsigned long> { typedef unsigned long __integral_type; typedef __atomic_base<unsigned long> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for long long. template<> struct atomic<long long> : __atomic_base<long long> { typedef long long __integral_type; typedef __atomic_base<long long> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for unsigned long long. template<> struct atomic<unsigned long long> : __atomic_base<unsigned long long> { typedef unsigned long long __integral_type; typedef __atomic_base<unsigned long long> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2; #endif }; /// Explicit specialization for wchar_t. template<> struct atomic<wchar_t> : __atomic_base<wchar_t> { typedef wchar_t __integral_type; typedef __atomic_base<wchar_t> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2; #endif }; /// Explicit specialization for char16_t. template<> struct atomic<char16_t> : __atomic_base<char16_t> { typedef char16_t __integral_type; typedef __atomic_base<char16_t> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR16_T_LOCK_FREE == 2; #endif }; /// Explicit specialization for char32_t. template<> struct atomic<char32_t> : __atomic_base<char32_t> { typedef char32_t __integral_type; typedef __atomic_base<char32_t> __base_type; atomic() noexcept = default; ~atomic() noexcept = default; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } using __base_type::operator __integral_type; using __base_type::operator=; #if __cplusplus > 201402L static constexpr bool is_always_lock_free = ATOMIC_CHAR32_T_LOCK_FREE == 2; #endif }; /// atomic_bool typedef atomic<bool> atomic_bool; /// atomic_char typedef atomic<char> atomic_char; /// atomic_schar typedef atomic<signed char> atomic_schar; /// atomic_uchar typedef atomic<unsigned char> atomic_uchar; /// atomic_short typedef atomic<short> atomic_short; /// atomic_ushort typedef atomic<unsigned short> atomic_ushort; /// atomic_int typedef atomic<int> atomic_int; /// atomic_uint typedef atomic<unsigned int> atomic_uint; /// atomic_long typedef atomic<long> atomic_long; /// atomic_ulong typedef atomic<unsigned long> atomic_ulong; /// atomic_llong typedef atomic<long long> atomic_llong; /// atomic_ullong typedef atomic<unsigned long long> atomic_ullong; /// atomic_wchar_t typedef atomic<wchar_t> atomic_wchar_t; /// atomic_char16_t typedef atomic<char16_t> atomic_char16_t; /// atomic_char32_t typedef atomic<char32_t> atomic_char32_t; #ifdef _GLIBCXX_USE_C99_STDINT_TR1 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2441. Exact-width atomic typedefs should be provided /// atomic_int8_t typedef atomic<int8_t> atomic_int8_t; /// atomic_uint8_t typedef atomic<uint8_t> atomic_uint8_t; /// atomic_int16_t typedef atomic<int16_t> atomic_int16_t; /// atomic_uint16_t typedef atomic<uint16_t> atomic_uint16_t; /// atomic_int32_t typedef atomic<int32_t> atomic_int32_t; /// atomic_uint32_t typedef atomic<uint32_t> atomic_uint32_t; /// atomic_int64_t typedef atomic<int64_t> atomic_int64_t; /// atomic_uint64_t typedef atomic<uint64_t> atomic_uint64_t; /// atomic_int_least8_t typedef atomic<int_least8_t> atomic_int_least8_t; /// atomic_uint_least8_t typedef atomic<uint_least8_t> atomic_uint_least8_t; /// atomic_int_least16_t typedef atomic<int_least16_t> atomic_int_least16_t; /// atomic_uint_least16_t typedef atomic<uint_least16_t> atomic_uint_least16_t; /// atomic_int_least32_t typedef atomic<int_least32_t> atomic_int_least32_t; /// atomic_uint_least32_t typedef atomic<uint_least32_t> atomic_uint_least32_t; /// atomic_int_least64_t typedef atomic<int_least64_t> atomic_int_least64_t; /// atomic_uint_least64_t typedef atomic<uint_least64_t> atomic_uint_least64_t; /// atomic_int_fast8_t typedef atomic<int_fast8_t> atomic_int_fast8_t; /// atomic_uint_fast8_t typedef atomic<uint_fast8_t> atomic_uint_fast8_t; /// atomic_int_fast16_t typedef atomic<int_fast16_t> atomic_int_fast16_t; /// atomic_uint_fast16_t typedef atomic<uint_fast16_t> atomic_uint_fast16_t; /// atomic_int_fast32_t typedef atomic<int_fast32_t> atomic_int_fast32_t; /// atomic_uint_fast32_t typedef atomic<uint_fast32_t> atomic_uint_fast32_t; /// atomic_int_fast64_t typedef atomic<int_fast64_t> atomic_int_fast64_t; /// atomic_uint_fast64_t typedef atomic<uint_fast64_t> atomic_uint_fast64_t; #endif /// atomic_intptr_t typedef atomic<intptr_t> atomic_intptr_t; /// atomic_uintptr_t typedef atomic<uintptr_t> atomic_uintptr_t; /// atomic_size_t typedef atomic<size_t> atomic_size_t; /// atomic_ptrdiff_t typedef atomic<ptrdiff_t> atomic_ptrdiff_t; #ifdef _GLIBCXX_USE_C99_STDINT_TR1 /// atomic_intmax_t typedef atomic<intmax_t> atomic_intmax_t; /// atomic_uintmax_t typedef atomic<uintmax_t> atomic_uintmax_t; #endif // Function definitions, atomic_flag operations. inline bool atomic_flag_test_and_set_explicit(atomic_flag* __a, memory_order __m) noexcept { return __a->test_and_set(__m); } inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, memory_order __m) noexcept { return __a->test_and_set(__m); } inline void atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept { __a->clear(__m); } inline void atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m) noexcept { __a->clear(__m); } inline bool atomic_flag_test_and_set(atomic_flag* __a) noexcept { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } inline bool atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } inline void atomic_flag_clear(atomic_flag* __a) noexcept { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } inline void atomic_flag_clear(volatile atomic_flag* __a) noexcept { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } // Function templates generally applicable to atomic types. template<typename _ITp> inline bool atomic_is_lock_free(const atomic<_ITp>* __a) noexcept { return __a->is_lock_free(); } template<typename _ITp> inline bool atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept { return __a->is_lock_free(); } template<typename _ITp> inline void atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept { __a->store(__i, memory_order_relaxed); } template<typename _ITp> inline void atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept { __a->store(__i, memory_order_relaxed); } template<typename _ITp> inline void atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { __a->store(__i, __m); } template<typename _ITp> inline void atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { __a->store(__i, __m); } template<typename _ITp> inline _ITp atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept { return __a->load(__m); } template<typename _ITp> inline _ITp atomic_load_explicit(const volatile atomic<_ITp>* __a, memory_order __m) noexcept { return __a->load(__m); } template<typename _ITp> inline _ITp atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->exchange(__i, __m); } template<typename _ITp> inline _ITp atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->exchange(__i, __m); } template<typename _ITp> inline bool atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } template<typename _ITp> inline bool atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } template<typename _ITp> inline bool atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } template<typename _ITp> inline bool atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2, memory_order __m1, memory_order __m2) noexcept { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } template<typename _ITp> inline void atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept { atomic_store_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline void atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept { atomic_store_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_load(const atomic<_ITp>* __a) noexcept { return atomic_load_explicit(__a, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_load(const volatile atomic<_ITp>* __a) noexcept { return atomic_load_explicit(__a, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline bool atomic_compare_exchange_weak(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } template<typename _ITp> inline bool atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } template<typename _ITp> inline bool atomic_compare_exchange_strong(atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } template<typename _ITp> inline bool atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, _ITp* __i1, _ITp __i2) noexcept { return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, memory_order_seq_cst, memory_order_seq_cst); } // Function templates for atomic_integral operations only, using // __atomic_base. Template argument should be constricted to // intergral types as specified in the standard, excluding address // types. template<typename _ITp> inline _ITp atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_add(__i, __m); } template<typename _ITp> inline _ITp atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_add(__i, __m); } template<typename _ITp> inline _ITp atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_sub(__i, __m); } template<typename _ITp> inline _ITp atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_sub(__i, __m); } template<typename _ITp> inline _ITp atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_and(__i, __m); } template<typename _ITp> inline _ITp atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_and(__i, __m); } template<typename _ITp> inline _ITp atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_or(__i, __m); } template<typename _ITp> inline _ITp atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_or(__i, __m); } template<typename _ITp> inline _ITp atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_xor(__i, __m); } template<typename _ITp> inline _ITp atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, memory_order __m) noexcept { return __a->fetch_xor(__i, __m); } template<typename _ITp> inline _ITp atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } template<typename _ITp> inline _ITp atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } // Partial specializations for pointers. template<typename _ITp> inline _ITp* atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_add(__d, __m); } template<typename _ITp> inline _ITp* atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_add(__d, __m); } template<typename _ITp> inline _ITp* atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_add(__d); } template<typename _ITp> inline _ITp* atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_add(__d); } template<typename _ITp> inline _ITp* atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_sub(__d, __m); } template<typename _ITp> inline _ITp* atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, memory_order __m) noexcept { return __a->fetch_sub(__d, __m); } template<typename _ITp> inline _ITp* atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_sub(__d); } template<typename _ITp> inline _ITp* atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept { return __a->fetch_sub(__d); } // @} group atomics _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _GLIBCXX_ATOMIC c++/8/cctype 0000644 00000004551 15146341150 0006502 0 ustar 00 // -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cctype * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c ctype.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: <ccytpe> // #pragma GCC system_header #include <bits/c++config.h> #include <ctype.h> #ifndef _GLIBCXX_CCTYPE #define _GLIBCXX_CCTYPE 1 // Get rid of those macros defined in <ctype.h> in lieu of real functions. #undef isalnum #undef isalpha #undef iscntrl #undef isdigit #undef isgraph #undef islower #undef isprint #undef ispunct #undef isspace #undef isupper #undef isxdigit #undef tolower #undef toupper namespace std { using ::isalnum; using ::isalpha; using ::iscntrl; using ::isdigit; using ::isgraph; using ::islower; using ::isprint; using ::ispunct; using ::isspace; using ::isupper; using ::isxdigit; using ::tolower; using ::toupper; } // namespace std #if __cplusplus >= 201103L #ifdef _GLIBCXX_USE_C99_CTYPE_TR1 #undef isblank namespace std { using ::isblank; } // namespace std #endif // _GLIBCXX_USE_C99_CTYPE_TR1 #endif // C++11 #endif c++/8/codecvt 0000644 00000012335 15146341150 0006641 0 ustar 00 // <codecvt> -*- C++ -*- // Copyright (C) 2015-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. // ISO C++ 14882: 22.5 Standard code conversion facets /** @file include/codecvt * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CODECVT #define _GLIBCXX_CODECVT 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <bits/locale_classes.h> #include <bits/codecvt.h> #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION enum codecvt_mode { consume_header = 4, generate_header = 2, little_endian = 1 }; template<typename _Elem, unsigned long _Maxcode = 0x10ffff, codecvt_mode _Mode = (codecvt_mode)0> class codecvt_utf8 : public codecvt<_Elem, char, mbstate_t> { public: explicit codecvt_utf8(size_t __refs = 0); ~codecvt_utf8(); }; template<typename _Elem, unsigned long _Maxcode = 0x10ffff, codecvt_mode _Mode = (codecvt_mode)0> class codecvt_utf16 : public codecvt<_Elem, char, mbstate_t> { public: explicit codecvt_utf16(size_t __refs = 0); ~codecvt_utf16(); }; template<typename _Elem, unsigned long _Maxcode = 0x10ffff, codecvt_mode _Mode = (codecvt_mode)0> class codecvt_utf8_utf16 : public codecvt<_Elem, char, mbstate_t> { public: explicit codecvt_utf8_utf16(size_t __refs = 0); ~codecvt_utf8_utf16(); }; #define _GLIBCXX_CODECVT_SPECIALIZATION2(_NAME, _ELEM) \ template<> \ class _NAME<_ELEM> \ : public codecvt<_ELEM, char, mbstate_t> \ { \ public: \ typedef _ELEM intern_type; \ typedef char extern_type; \ typedef mbstate_t state_type; \ \ protected: \ _NAME(unsigned long __maxcode, codecvt_mode __mode, size_t __refs) \ : codecvt(__refs), _M_maxcode(__maxcode), _M_mode(__mode) { } \ \ virtual \ ~_NAME(); \ \ 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(); \ \ private: \ unsigned long _M_maxcode; \ codecvt_mode _M_mode; \ } #define _GLIBCXX_CODECVT_SPECIALIZATION(_NAME, _ELEM) \ _GLIBCXX_CODECVT_SPECIALIZATION2(__ ## _NAME ## _base, _ELEM); \ template<unsigned long _Maxcode, codecvt_mode _Mode> \ class _NAME<_ELEM, _Maxcode, _Mode> \ : public __ ## _NAME ## _base<_ELEM> \ { \ public: \ explicit \ _NAME(size_t __refs = 0) \ : __ ## _NAME ## _base<_ELEM>(std::min(_Maxcode, 0x10fffful), \ _Mode, __refs) \ { } \ } template<typename _Elem> class __codecvt_utf8_base; template<typename _Elem> class __codecvt_utf16_base; template<typename _Elem> class __codecvt_utf8_utf16_base; _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8, char16_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf16, char16_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8_utf16, char16_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8, char32_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf16, char32_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8_utf16, char32_t); #ifdef _GLIBCXX_USE_WCHAR_T _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8, wchar_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf16, wchar_t); _GLIBCXX_CODECVT_SPECIALIZATION(codecvt_utf8_utf16, wchar_t); #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif #endif /* _GLIBCXX_CODECVT */ c++/8/cmath 0000644 00000136016 15146341150 0006311 0 ustar 00 // -*- C++ -*- C forwarding header. // Copyright (C) 1997-2018 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/cmath * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c math.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 26.5 C library // #pragma GCC system_header #include <bits/c++config.h> #include <bits/cpp_type_traits.h> #include <ext/type_traits.h> #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include_next <math.h> #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include <bits/std_abs.h> #ifndef _GLIBCXX_CMATH #define _GLIBCXX_CMATH 1 // Get rid of those macros defined in <math.h> in lieu of real functions. #undef div #undef acos #undef asin #undef atan #undef atan2 #undef ceil #undef cos #undef cosh #undef exp #undef fabs #undef floor #undef fmod #undef frexp #undef ldexp #undef log #undef log10 #undef modf #undef pow #undef sin #undef sinh #undef sqrt #undef tan #undef tanh extern "C++" { namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::acos; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float acos(float __x) { return __builtin_acosf(__x); } inline _GLIBCXX_CONSTEXPR long double acos(long double __x) { return __builtin_acosl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type acos(_Tp __x) { return __builtin_acos(__x); } using ::asin; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float asin(float __x) { return __builtin_asinf(__x); } inline _GLIBCXX_CONSTEXPR long double asin(long double __x) { return __builtin_asinl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type asin(_Tp __x) { return __builtin_asin(__x); } using ::atan; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float atan(float __x) { return __builtin_atanf(__x); } inline _GLIBCXX_CONSTEXPR long double atan(long double __x) { return __builtin_atanl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type atan(_Tp __x) { return __builtin_atan(__x); } using ::atan2; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float atan2(float __y, float __x) { return __builtin_atan2f(__y, __x); } inline _GLIBCXX_CONSTEXPR long double atan2(long double __y, long double __x) { return __builtin_atan2l(__y, __x); } #endif template<typename _Tp, typename _Up> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__promote_2<_Tp, _Up>::__type atan2(_Tp __y, _Up __x) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return atan2(__type(__y), __type(__x)); } using ::ceil; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float ceil(float __x) { return __builtin_ceilf(__x); } inline _GLIBCXX_CONSTEXPR long double ceil(long double __x) { return __builtin_ceill(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type ceil(_Tp __x) { return __builtin_ceil(__x); } using ::cos; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float cos(float __x) { return __builtin_cosf(__x); } inline _GLIBCXX_CONSTEXPR long double cos(long double __x) { return __builtin_cosl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cos(_Tp __x) { return __builtin_cos(__x); } using ::cosh; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float cosh(float __x) { return __builtin_coshf(__x); } inline _GLIBCXX_CONSTEXPR long double cosh(long double __x) { return __builtin_coshl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cosh(_Tp __x) { return __builtin_cosh(__x); } using ::exp; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float exp(float __x) { return __builtin_expf(__x); } inline _GLIBCXX_CONSTEXPR long double exp(long double __x) { return __builtin_expl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type exp(_Tp __x) { return __builtin_exp(__x); } using ::fabs; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float fabs(float __x) { return __builtin_fabsf(__x); } inline _GLIBCXX_CONSTEXPR long double fabs(long double __x) { return __builtin_fabsl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type fabs(_Tp __x) { return __builtin_fabs(__x); } using ::floor; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float floor(float __x) { return __builtin_floorf(__x); } inline _GLIBCXX_CONSTEXPR long double floor(long double __x) { return __builtin_floorl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type floor(_Tp __x) { return __builtin_floor(__x); } using ::fmod; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float fmod(float __x, float __y) { return __builtin_fmodf(__x, __y); } inline _GLIBCXX_CONSTEXPR long double fmod(long double __x, long double __y) { return __builtin_fmodl(__x, __y); } #endif template<typename _Tp, typename _Up> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fmod(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fmod(__type(__x), __type(__y)); } using ::frexp; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline float frexp(float __x, int* __exp) { return __builtin_frexpf(__x, __exp); } inline long double frexp(long double __x, int* __exp) { return __builtin_frexpl(__x, __exp); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type frexp(_Tp __x, int* __exp) { return __builtin_frexp(__x, __exp); } using ::ldexp; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float ldexp(float __x, int __exp) { return __builtin_ldexpf(__x, __exp); } inline _GLIBCXX_CONSTEXPR long double ldexp(long double __x, int __exp) { return __builtin_ldexpl(__x, __exp); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type ldexp(_Tp __x, int __exp) { return __builtin_ldexp(__x, __exp); } using ::log; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float log(float __x) { return __builtin_logf(__x); } inline _GLIBCXX_CONSTEXPR long double log(long double __x) { return __builtin_logl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log(_Tp __x) { return __builtin_log(__x); } using ::log10; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float log10(float __x) { return __builtin_log10f(__x); } inline _GLIBCXX_CONSTEXPR long double log10(long double __x) { return __builtin_log10l(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log10(_Tp __x) { return __builtin_log10(__x); } using ::modf; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline float modf(float __x, float* __iptr) { return __builtin_modff(__x, __iptr); } inline long double modf(long double __x, long double* __iptr) { return __builtin_modfl(__x, __iptr); } #endif using ::pow; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float pow(float __x, float __y) { return __builtin_powf(__x, __y); } inline _GLIBCXX_CONSTEXPR long double pow(long double __x, long double __y) { return __builtin_powl(__x, __y); } #if __cplusplus < 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 550. What should the return type of pow(float,int) be? inline double pow(double __x, int __i) { return __builtin_powi(__x, __i); } inline float pow(float __x, int __n) { return __builtin_powif(__x, __n); } inline long double pow(long double __x, int __n) { return __builtin_powil(__x, __n); } #endif #endif template<typename _Tp, typename _Up> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__promote_2<_Tp, _Up>::__type pow(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return pow(__type(__x), __type(__y)); } using ::sin; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float sin(float __x) { return __builtin_sinf(__x); } inline _GLIBCXX_CONSTEXPR long double sin(long double __x) { return __builtin_sinl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sin(_Tp __x) { return __builtin_sin(__x); } using ::sinh; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float sinh(float __x) { return __builtin_sinhf(__x); } inline _GLIBCXX_CONSTEXPR long double sinh(long double __x) { return __builtin_sinhl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sinh(_Tp __x) { return __builtin_sinh(__x); } using ::sqrt; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float sqrt(float __x) { return __builtin_sqrtf(__x); } inline _GLIBCXX_CONSTEXPR long double sqrt(long double __x) { return __builtin_sqrtl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type sqrt(_Tp __x) { return __builtin_sqrt(__x); } using ::tan; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float tan(float __x) { return __builtin_tanf(__x); } inline _GLIBCXX_CONSTEXPR long double tan(long double __x) { return __builtin_tanl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tan(_Tp __x) { return __builtin_tan(__x); } using ::tanh; #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR float tanh(float __x) { return __builtin_tanhf(__x); } inline _GLIBCXX_CONSTEXPR long double tanh(long double __x) { return __builtin_tanhl(__x); } #endif template<typename _Tp> inline _GLIBCXX_CONSTEXPR typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tanh(_Tp __x) { return __builtin_tanh(__x); } #if _GLIBCXX_USE_C99_MATH #if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC // These are possible macros imported from C99-land. #undef fpclassify #undef isfinite #undef isinf #undef isnan #undef isnormal #undef signbit #undef isgreater #undef isgreaterequal #undef isless #undef islessequal #undef islessgreater #undef isunordered #if __cplusplus >= 201103L #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr int fpclassify(float __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } constexpr int fpclassify(double __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } constexpr int fpclassify(long double __x) { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, int>::__type fpclassify(_Tp __x) { return __x != 0 ? FP_NORMAL : FP_ZERO; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isfinite(float __x) { return __builtin_isfinite(__x); } constexpr bool isfinite(double __x) { return __builtin_isfinite(__x); } constexpr bool isfinite(long double __x) { return __builtin_isfinite(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isfinite(_Tp __x) { return true; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isinf(float __x) { return __builtin_isinf(__x); } #if _GLIBCXX_HAVE_OBSOLETE_ISINF \ && !_GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC using ::isinf; #else constexpr bool isinf(double __x) { return __builtin_isinf(__x); } #endif constexpr bool isinf(long double __x) { return __builtin_isinf(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isinf(_Tp __x) { return false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isnan(float __x) { return __builtin_isnan(__x); } #if _GLIBCXX_HAVE_OBSOLETE_ISNAN \ && !_GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC using ::isnan; #else constexpr bool isnan(double __x) { return __builtin_isnan(__x); } #endif constexpr bool isnan(long double __x) { return __builtin_isnan(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isnan(_Tp __x) { return false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isnormal(float __x) { return __builtin_isnormal(__x); } constexpr bool isnormal(double __x) { return __builtin_isnormal(__x); } constexpr bool isnormal(long double __x) { return __builtin_isnormal(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type isnormal(_Tp __x) { return __x != 0 ? true : false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP // Note: middle-end/36757 is fixed, __builtin_signbit is type-generic. constexpr bool signbit(float __x) { return __builtin_signbit(__x); } constexpr bool signbit(double __x) { return __builtin_signbit(__x); } constexpr bool signbit(long double __x) { return __builtin_signbit(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, bool>::__type signbit(_Tp __x) { return __x < 0 ? true : false; } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isgreater(float __x, float __y) { return __builtin_isgreater(__x, __y); } constexpr bool isgreater(double __x, double __y) { return __builtin_isgreater(__x, __y); } constexpr bool isgreater(long double __x, long double __y) { return __builtin_isgreater(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isgreater(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isgreater(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isgreaterequal(float __x, float __y) { return __builtin_isgreaterequal(__x, __y); } constexpr bool isgreaterequal(double __x, double __y) { return __builtin_isgreaterequal(__x, __y); } constexpr bool isgreaterequal(long double __x, long double __y) { return __builtin_isgreaterequal(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isgreaterequal(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isgreaterequal(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isless(float __x, float __y) { return __builtin_isless(__x, __y); } constexpr bool isless(double __x, double __y) { return __builtin_isless(__x, __y); } constexpr bool isless(long double __x, long double __y) { return __builtin_isless(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isless(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isless(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool islessequal(float __x, float __y) { return __builtin_islessequal(__x, __y); } constexpr bool islessequal(double __x, double __y) { return __builtin_islessequal(__x, __y); } constexpr bool islessequal(long double __x, long double __y) { return __builtin_islessequal(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type islessequal(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_islessequal(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool islessgreater(float __x, float __y) { return __builtin_islessgreater(__x, __y); } constexpr bool islessgreater(double __x, double __y) { return __builtin_islessgreater(__x, __y); } constexpr bool islessgreater(long double __x, long double __y) { return __builtin_islessgreater(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type islessgreater(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_islessgreater(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr bool isunordered(float __x, float __y) { return __builtin_isunordered(__x, __y); } constexpr bool isunordered(double __x, double __y) { return __builtin_isunordered(__x, __y); } constexpr bool isunordered(long double __x, long double __y) { return __builtin_isunordered(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__enable_if<(__is_arithmetic<_Tp>::__value && __is_arithmetic<_Up>::__value), bool>::__type isunordered(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return __builtin_isunordered(__type(__x), __type(__y)); } #endif #else template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type fpclassify(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __type(__f)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isfinite(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isfinite(__type(__f)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isinf(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isinf(__type(__f)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isnan(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isnan(__type(__f)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isnormal(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isnormal(__type(__f)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type signbit(_Tp __f) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_signbit(__type(__f)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isgreater(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isgreater(__type(__f1), __type(__f2)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isgreaterequal(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isgreaterequal(__type(__f1), __type(__f2)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isless(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isless(__type(__f1), __type(__f2)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type islessequal(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_islessequal(__type(__f1), __type(__f2)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type islessgreater(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_islessgreater(__type(__f1), __type(__f2)); } template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_arithmetic<_Tp>::__value, int>::__type isunordered(_Tp __f1, _Tp __f2) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __builtin_isunordered(__type(__f1), __type(__f2)); } #endif // C++11 #endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */ #endif /* _GLIBCXX_USE_C99_MATH */ #if __cplusplus >= 201103L #ifdef _GLIBCXX_USE_C99_MATH_TR1 #undef acosh #undef acoshf #undef acoshl #undef asinh #undef asinhf #undef asinhl #undef atanh #undef atanhf #undef atanhl #undef cbrt #undef cbrtf #undef cbrtl #undef copysign #undef copysignf #undef copysignl #undef erf #undef erff #undef erfl #undef erfc #undef erfcf #undef erfcl #undef exp2 #undef exp2f #undef exp2l #undef expm1 #undef expm1f #undef expm1l #undef fdim #undef fdimf #undef fdiml #undef fma #undef fmaf #undef fmal #undef fmax #undef fmaxf #undef fmaxl #undef fmin #undef fminf #undef fminl #undef hypot #undef hypotf #undef hypotl #undef ilogb #undef ilogbf #undef ilogbl #undef lgamma #undef lgammaf #undef lgammal #ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS #undef llrint #undef llrintf #undef llrintl #undef llround #undef llroundf #undef llroundl #endif #undef log1p #undef log1pf #undef log1pl #undef log2 #undef log2f #undef log2l #undef logb #undef logbf #undef logbl #undef lrint #undef lrintf #undef lrintl #undef lround #undef lroundf #undef lroundl #undef nan #undef nanf #undef nanl #undef nearbyint #undef nearbyintf #undef nearbyintl #undef nextafter #undef nextafterf #undef nextafterl #undef nexttoward #undef nexttowardf #undef nexttowardl #undef remainder #undef remainderf #undef remainderl #undef remquo #undef remquof #undef remquol #undef rint #undef rintf #undef rintl #undef round #undef roundf #undef roundl #undef scalbln #undef scalblnf #undef scalblnl #undef scalbn #undef scalbnf #undef scalbnl #undef tgamma #undef tgammaf #undef tgammal #undef trunc #undef truncf #undef truncl // types using ::double_t; using ::float_t; // functions using ::acosh; using ::acoshf; using ::acoshl; using ::asinh; using ::asinhf; using ::asinhl; using ::atanh; using ::atanhf; using ::atanhl; using ::cbrt; using ::cbrtf; using ::cbrtl; using ::copysign; using ::copysignf; using ::copysignl; using ::erf; using ::erff; using ::erfl; using ::erfc; using ::erfcf; using ::erfcl; using ::exp2; using ::exp2f; using ::exp2l; using ::expm1; using ::expm1f; using ::expm1l; using ::fdim; using ::fdimf; using ::fdiml; using ::fma; using ::fmaf; using ::fmal; using ::fmax; using ::fmaxf; using ::fmaxl; using ::fmin; using ::fminf; using ::fminl; using ::hypot; using ::hypotf; using ::hypotl; using ::ilogb; using ::ilogbf; using ::ilogbl; using ::lgamma; using ::lgammaf; using ::lgammal; #ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS using ::llrint; using ::llrintf; using ::llrintl; using ::llround; using ::llroundf; using ::llroundl; #endif using ::log1p; using ::log1pf; using ::log1pl; using ::log2; using ::log2f; using ::log2l; using ::logb; using ::logbf; using ::logbl; using ::lrint; using ::lrintf; using ::lrintl; using ::lround; using ::lroundf; using ::lroundl; using ::nan; using ::nanf; using ::nanl; using ::nearbyint; using ::nearbyintf; using ::nearbyintl; using ::nextafter; using ::nextafterf; using ::nextafterl; using ::nexttoward; using ::nexttowardf; using ::nexttowardl; using ::remainder; using ::remainderf; using ::remainderl; using ::remquo; using ::remquof; using ::remquol; using ::rint; using ::rintf; using ::rintl; using ::round; using ::roundf; using ::roundl; using ::scalbln; using ::scalblnf; using ::scalblnl; using ::scalbn; using ::scalbnf; using ::scalbnl; using ::tgamma; using ::tgammaf; using ::tgammal; using ::trunc; using ::truncf; using ::truncl; /// Additional overloads. #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float acosh(float __x) { return __builtin_acoshf(__x); } constexpr long double acosh(long double __x) { return __builtin_acoshl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type acosh(_Tp __x) { return __builtin_acosh(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float asinh(float __x) { return __builtin_asinhf(__x); } constexpr long double asinh(long double __x) { return __builtin_asinhl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type asinh(_Tp __x) { return __builtin_asinh(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float atanh(float __x) { return __builtin_atanhf(__x); } constexpr long double atanh(long double __x) { return __builtin_atanhl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type atanh(_Tp __x) { return __builtin_atanh(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float cbrt(float __x) { return __builtin_cbrtf(__x); } constexpr long double cbrt(long double __x) { return __builtin_cbrtl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type cbrt(_Tp __x) { return __builtin_cbrt(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float copysign(float __x, float __y) { return __builtin_copysignf(__x, __y); } constexpr long double copysign(long double __x, long double __y) { return __builtin_copysignl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type copysign(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return copysign(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float erf(float __x) { return __builtin_erff(__x); } constexpr long double erf(long double __x) { return __builtin_erfl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type erf(_Tp __x) { return __builtin_erf(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float erfc(float __x) { return __builtin_erfcf(__x); } constexpr long double erfc(long double __x) { return __builtin_erfcl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type erfc(_Tp __x) { return __builtin_erfc(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float exp2(float __x) { return __builtin_exp2f(__x); } constexpr long double exp2(long double __x) { return __builtin_exp2l(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type exp2(_Tp __x) { return __builtin_exp2(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float expm1(float __x) { return __builtin_expm1f(__x); } constexpr long double expm1(long double __x) { return __builtin_expm1l(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type expm1(_Tp __x) { return __builtin_expm1(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fdim(float __x, float __y) { return __builtin_fdimf(__x, __y); } constexpr long double fdim(long double __x, long double __y) { return __builtin_fdiml(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fdim(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fdim(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fma(float __x, float __y, float __z) { return __builtin_fmaf(__x, __y, __z); } constexpr long double fma(long double __x, long double __y, long double __z) { return __builtin_fmal(__x, __y, __z); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up, typename _Vp> constexpr typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type fma(_Tp __x, _Up __y, _Vp __z) { typedef typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type __type; return fma(__type(__x), __type(__y), __type(__z)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fmax(float __x, float __y) { return __builtin_fmaxf(__x, __y); } constexpr long double fmax(long double __x, long double __y) { return __builtin_fmaxl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fmax(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fmax(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float fmin(float __x, float __y) { return __builtin_fminf(__x, __y); } constexpr long double fmin(long double __x, long double __y) { return __builtin_fminl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type fmin(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return fmin(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float hypot(float __x, float __y) { return __builtin_hypotf(__x, __y); } constexpr long double hypot(long double __x, long double __y) { return __builtin_hypotl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type hypot(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return hypot(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr int ilogb(float __x) { return __builtin_ilogbf(__x); } constexpr int ilogb(long double __x) { return __builtin_ilogbl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, int>::__type ilogb(_Tp __x) { return __builtin_ilogb(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float lgamma(float __x) { return __builtin_lgammaf(__x); } constexpr long double lgamma(long double __x) { return __builtin_lgammal(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type lgamma(_Tp __x) { return __builtin_lgamma(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long long llrint(float __x) { return __builtin_llrintf(__x); } constexpr long long llrint(long double __x) { return __builtin_llrintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long long>::__type llrint(_Tp __x) { return __builtin_llrint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long long llround(float __x) { return __builtin_llroundf(__x); } constexpr long long llround(long double __x) { return __builtin_llroundl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long long>::__type llround(_Tp __x) { return __builtin_llround(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float log1p(float __x) { return __builtin_log1pf(__x); } constexpr long double log1p(long double __x) { return __builtin_log1pl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log1p(_Tp __x) { return __builtin_log1p(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP // DR 568. constexpr float log2(float __x) { return __builtin_log2f(__x); } constexpr long double log2(long double __x) { return __builtin_log2l(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type log2(_Tp __x) { return __builtin_log2(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float logb(float __x) { return __builtin_logbf(__x); } constexpr long double logb(long double __x) { return __builtin_logbl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type logb(_Tp __x) { return __builtin_logb(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long lrint(float __x) { return __builtin_lrintf(__x); } constexpr long lrint(long double __x) { return __builtin_lrintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long>::__type lrint(_Tp __x) { return __builtin_lrint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr long lround(float __x) { return __builtin_lroundf(__x); } constexpr long lround(long double __x) { return __builtin_lroundl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, long>::__type lround(_Tp __x) { return __builtin_lround(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float nearbyint(float __x) { return __builtin_nearbyintf(__x); } constexpr long double nearbyint(long double __x) { return __builtin_nearbyintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type nearbyint(_Tp __x) { return __builtin_nearbyint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float nextafter(float __x, float __y) { return __builtin_nextafterf(__x, __y); } constexpr long double nextafter(long double __x, long double __y) { return __builtin_nextafterl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type nextafter(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return nextafter(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float nexttoward(float __x, long double __y) { return __builtin_nexttowardf(__x, __y); } constexpr long double nexttoward(long double __x, long double __y) { return __builtin_nexttowardl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type nexttoward(_Tp __x, long double __y) { return __builtin_nexttoward(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float remainder(float __x, float __y) { return __builtin_remainderf(__x, __y); } constexpr long double remainder(long double __x, long double __y) { return __builtin_remainderl(__x, __y); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> constexpr typename __gnu_cxx::__promote_2<_Tp, _Up>::__type remainder(_Tp __x, _Up __y) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return remainder(__type(__x), __type(__y)); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP inline float remquo(float __x, float __y, int* __pquo) { return __builtin_remquof(__x, __y, __pquo); } inline long double remquo(long double __x, long double __y, int* __pquo) { return __builtin_remquol(__x, __y, __pquo); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp, typename _Up> inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type remquo(_Tp __x, _Up __y, int* __pquo) { typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type; return remquo(__type(__x), __type(__y), __pquo); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float rint(float __x) { return __builtin_rintf(__x); } constexpr long double rint(long double __x) { return __builtin_rintl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type rint(_Tp __x) { return __builtin_rint(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float round(float __x) { return __builtin_roundf(__x); } constexpr long double round(long double __x) { return __builtin_roundl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type round(_Tp __x) { return __builtin_round(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float scalbln(float __x, long __ex) { return __builtin_scalblnf(__x, __ex); } constexpr long double scalbln(long double __x, long __ex) { return __builtin_scalblnl(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type scalbln(_Tp __x, long __ex) { return __builtin_scalbln(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float scalbn(float __x, int __ex) { return __builtin_scalbnf(__x, __ex); } constexpr long double scalbn(long double __x, int __ex) { return __builtin_scalbnl(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type scalbn(_Tp __x, int __ex) { return __builtin_scalbn(__x, __ex); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float tgamma(float __x) { return __builtin_tgammaf(__x); } constexpr long double tgamma(long double __x) { return __builtin_tgammal(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type tgamma(_Tp __x) { return __builtin_tgamma(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP constexpr float trunc(float __x) { return __builtin_truncf(__x); } constexpr long double trunc(long double __x) { return __builtin_truncl(__x); } #endif #ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT template<typename _Tp> constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type trunc(_Tp __x) { return __builtin_trunc(__x); } #endif #endif // _GLIBCXX_USE_C99_MATH_TR1 #endif // C++11 #if __cplusplus > 201402L // [c.math.hypot3], three-dimensional hypotenuse #define __cpp_lib_hypot 201603 template<typename _Tp> inline _Tp __hypot3(_Tp __x, _Tp __y, _Tp __z) { __x = std::abs(__x); __y = std::abs(__y); __z = std::abs(__z); if (_Tp __a = __x < __y ? __y < __z ? __z : __y : __x < __z ? __z : __x) return __a * std::sqrt((__x / __a) * (__x / __a) + (__y / __a) * (__y / __a) + (__z / __a) * (__z / __a)); else return {}; } inline float hypot(float __x, float __y, float __z) { return std::__hypot3<float>(__x, __y, __z); } inline double hypot(double __x, double __y, double __z) { return std::__hypot3<double>(__x, __y, __z); } inline long double hypot(long double __x, long double __y, long double __z) { return std::__hypot3<long double>(__x, __y, __z); } template<typename _Tp, typename _Up, typename _Vp> typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type hypot(_Tp __x, _Up __y, _Vp __z) { using __type = typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type; return std::__hypot3<__type>(__x, __y, __z); } #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if _GLIBCXX_USE_STD_SPEC_FUNCS # include <bits/specfun.h> #endif } // extern "C++" #endif c++/8/fenv.h 0000644 00000003744 15146341150 0006402 0 ustar 00 // -*- C++ -*- compatibility header. // Copyright (C) 2007-2018 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 fenv.h * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_FENV_H #define _GLIBCXX_FENV_H 1 #pragma GCC system_header #include <bits/c++config.h> #if _GLIBCXX_HAVE_FENV_H # include_next <fenv.h> #endif #if __cplusplus >= 201103L #if _GLIBCXX_USE_C99_FENV_TR1 #undef feclearexcept #undef fegetexceptflag #undef feraiseexcept #undef fesetexceptflag #undef fetestexcept #undef fegetround #undef fesetround #undef fegetenv #undef feholdexcept #undef fesetenv #undef feupdateenv namespace std { // types using ::fenv_t; using ::fexcept_t; // functions using ::feclearexcept; using ::fegetexceptflag; using ::feraiseexcept; using ::fesetexceptflag; using ::fetestexcept; using ::fegetround; using ::fesetround; using ::fegetenv; using ::feholdexcept; using ::fesetenv; using ::feupdateenv; } // namespace #endif // _GLIBCXX_USE_C99_FENV_TR1 #endif // C++11 #endif // _GLIBCXX_FENV_H c++/8/cwchar 0000644 00000014555 15146341150 0006467 0 ustar 00 // -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/cwchar * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c wchar.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 21.4 // #pragma GCC system_header #include <bits/c++config.h> #if _GLIBCXX_HAVE_WCHAR_H #include <wchar.h> #endif #ifndef _GLIBCXX_CWCHAR #define _GLIBCXX_CWCHAR 1 // Need to do a bit of trickery here with mbstate_t as char_traits // assumes it is in wchar.h, regardless of wchar_t specializations. #ifndef _GLIBCXX_HAVE_MBSTATE_T extern "C" { typedef struct { int __fill[6]; } mbstate_t; } #endif namespace std { using ::mbstate_t; } // namespace std // Get rid of those macros defined in <wchar.h> in lieu of real functions. #undef btowc #undef fgetwc #undef fgetws #undef fputwc #undef fputws #undef fwide #undef fwprintf #undef fwscanf #undef getwc #undef getwchar #undef mbrlen #undef mbrtowc #undef mbsinit #undef mbsrtowcs #undef putwc #undef putwchar #undef swprintf #undef swscanf #undef ungetwc #undef vfwprintf #if _GLIBCXX_HAVE_VFWSCANF # undef vfwscanf #endif #undef vswprintf #if _GLIBCXX_HAVE_VSWSCANF # undef vswscanf #endif #undef vwprintf #if _GLIBCXX_HAVE_VWSCANF # undef vwscanf #endif #undef wcrtomb #undef wcscat #undef wcschr #undef wcscmp #undef wcscoll #undef wcscpy #undef wcscspn #undef wcsftime #undef wcslen #undef wcsncat #undef wcsncmp #undef wcsncpy #undef wcspbrk #undef wcsrchr #undef wcsrtombs #undef wcsspn #undef wcsstr #undef wcstod #if _GLIBCXX_HAVE_WCSTOF # undef wcstof #endif #undef wcstok #undef wcstol #undef wcstoul #undef wcsxfrm #undef wctob #undef wmemchr #undef wmemcmp #undef wmemcpy #undef wmemmove #undef wmemset #undef wprintf #undef wscanf #if _GLIBCXX_USE_WCHAR_T namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::wint_t; using ::btowc; using ::fgetwc; using ::fgetws; using ::fputwc; using ::fputws; using ::fwide; using ::fwprintf; using ::fwscanf; using ::getwc; using ::getwchar; using ::mbrlen; using ::mbrtowc; using ::mbsinit; using ::mbsrtowcs; using ::putwc; using ::putwchar; #ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF using ::swprintf; #endif using ::swscanf; using ::ungetwc; using ::vfwprintf; #if _GLIBCXX_HAVE_VFWSCANF using ::vfwscanf; #endif #ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF using ::vswprintf; #endif #if _GLIBCXX_HAVE_VSWSCANF using ::vswscanf; #endif using ::vwprintf; #if _GLIBCXX_HAVE_VWSCANF using ::vwscanf; #endif using ::wcrtomb; using ::wcscat; using ::wcscmp; using ::wcscoll; using ::wcscpy; using ::wcscspn; using ::wcsftime; using ::wcslen; using ::wcsncat; using ::wcsncmp; using ::wcsncpy; using ::wcsrtombs; using ::wcsspn; using ::wcstod; #if _GLIBCXX_HAVE_WCSTOF using ::wcstof; #endif using ::wcstok; using ::wcstol; using ::wcstoul; using ::wcsxfrm; using ::wctob; using ::wmemcmp; using ::wmemcpy; using ::wmemmove; using ::wmemset; using ::wprintf; using ::wscanf; using ::wcschr; using ::wcspbrk; using ::wcsrchr; using ::wcsstr; using ::wmemchr; #ifndef __CORRECT_ISO_CPP_WCHAR_H_PROTO inline wchar_t* wcschr(wchar_t* __p, wchar_t __c) { return wcschr(const_cast<const wchar_t*>(__p), __c); } inline wchar_t* wcspbrk(wchar_t* __s1, const wchar_t* __s2) { return wcspbrk(const_cast<const wchar_t*>(__s1), __s2); } inline wchar_t* wcsrchr(wchar_t* __p, wchar_t __c) { return wcsrchr(const_cast<const wchar_t*>(__p), __c); } inline wchar_t* wcsstr(wchar_t* __s1, const wchar_t* __s2) { return wcsstr(const_cast<const wchar_t*>(__s1), __s2); } inline wchar_t* wmemchr(wchar_t* __p, wchar_t __c, size_t __n) { return wmemchr(const_cast<const wchar_t*>(__p), __c, __n); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if _GLIBCXX_USE_C99_WCHAR #undef wcstold #undef wcstoll #undef wcstoull namespace __gnu_cxx { #if _GLIBCXX_USE_C99_CHECK || _GLIBCXX_USE_C99_DYNAMIC extern "C" long double (wcstold)(const wchar_t * __restrict, wchar_t ** __restrict) throw (); #endif #if !_GLIBCXX_USE_C99_DYNAMIC using ::wcstold; #endif #if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC extern "C" long long int (wcstoll)(const wchar_t * __restrict, wchar_t ** __restrict, int) throw (); extern "C" unsigned long long int (wcstoull)(const wchar_t * __restrict, wchar_t ** __restrict, int) throw (); #endif #if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC using ::wcstoll; using ::wcstoull; #endif } // namespace __gnu_cxx namespace std { using ::__gnu_cxx::wcstold; using ::__gnu_cxx::wcstoll; using ::__gnu_cxx::wcstoull; } // namespace #endif #endif //_GLIBCXX_USE_WCHAR_T #if __cplusplus >= 201103L #ifdef _GLIBCXX_USE_WCHAR_T namespace std { #if _GLIBCXX_HAVE_WCSTOF using std::wcstof; #endif #if _GLIBCXX_HAVE_VFWSCANF using std::vfwscanf; #endif #if _GLIBCXX_HAVE_VSWSCANF using std::vswscanf; #endif #if _GLIBCXX_HAVE_VWSCANF using std::vwscanf; #endif #if _GLIBCXX_USE_C99_WCHAR using std::wcstold; using std::wcstoll; using std::wcstoull; #endif } // namespace #endif // _GLIBCXX_USE_WCHAR_T #endif // C++11 #endif c++/8/array 0000644 00000026611 15146341150 0006332 0 ustar 00 // <array> -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file include/array * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_ARRAY #define _GLIBCXX_ARRAY 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <utility> #include <stdexcept> #include <bits/stl_algobase.h> #include <bits/range_access.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, std::size_t _Nm> struct __array_traits { typedef _Tp _Type[_Nm]; typedef __is_swappable<_Tp> _Is_swappable; typedef __is_nothrow_swappable<_Tp> _Is_nothrow_swappable; static constexpr _Tp& _S_ref(const _Type& __t, std::size_t __n) noexcept { return const_cast<_Tp&>(__t[__n]); } static constexpr _Tp* _S_ptr(const _Type& __t) noexcept { return const_cast<_Tp*>(__t); } }; template<typename _Tp> struct __array_traits<_Tp, 0> { struct _Type { }; typedef true_type _Is_swappable; typedef true_type _Is_nothrow_swappable; static constexpr _Tp& _S_ref(const _Type&, std::size_t) noexcept { return *static_cast<_Tp*>(nullptr); } static constexpr _Tp* _S_ptr(const _Type&) noexcept { return nullptr; } }; /** * @brief A standard container for storing a fixed size sequence of elements. * * @ingroup sequences * * Meets the requirements of a <a href="tables.html#65">container</a>, a * <a href="tables.html#66">reversible container</a>, and a * <a href="tables.html#67">sequence</a>. * * Sets support random access iterators. * * @tparam Tp Type of element. Required to be a complete type. * @tparam N Number of elements. */ template<typename _Tp, std::size_t _Nm> struct array { typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef value_type* iterator; typedef const value_type* const_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; // Support for zero-sized arrays mandatory. typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type; typename _AT_Type::_Type _M_elems; // No explicit construct/copy/destroy for aggregate type. // DR 776. void fill(const value_type& __u) { std::fill_n(begin(), size(), __u); } void swap(array& __other) noexcept(_AT_Type::_Is_nothrow_swappable::value) { std::swap_ranges(begin(), end(), __other.begin()); } // Iterators. _GLIBCXX17_CONSTEXPR iterator begin() noexcept { return iterator(data()); } _GLIBCXX17_CONSTEXPR const_iterator begin() const noexcept { return const_iterator(data()); } _GLIBCXX17_CONSTEXPR iterator end() noexcept { return iterator(data() + _Nm); } _GLIBCXX17_CONSTEXPR const_iterator end() const noexcept { return const_iterator(data() + _Nm); } _GLIBCXX17_CONSTEXPR reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } _GLIBCXX17_CONSTEXPR const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } _GLIBCXX17_CONSTEXPR reverse_iterator rend() noexcept { return reverse_iterator(begin()); } _GLIBCXX17_CONSTEXPR const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } _GLIBCXX17_CONSTEXPR const_iterator cbegin() const noexcept { return const_iterator(data()); } _GLIBCXX17_CONSTEXPR const_iterator cend() const noexcept { return const_iterator(data() + _Nm); } _GLIBCXX17_CONSTEXPR const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } _GLIBCXX17_CONSTEXPR const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } // Capacity. constexpr size_type size() const noexcept { return _Nm; } constexpr size_type max_size() const noexcept { return _Nm; } constexpr bool empty() const noexcept { return size() == 0; } // Element access. _GLIBCXX17_CONSTEXPR reference operator[](size_type __n) noexcept { return _AT_Type::_S_ref(_M_elems, __n); } constexpr const_reference operator[](size_type __n) const noexcept { return _AT_Type::_S_ref(_M_elems, __n); } _GLIBCXX17_CONSTEXPR reference at(size_type __n) { if (__n >= _Nm) std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " ">= _Nm (which is %zu)"), __n, _Nm); return _AT_Type::_S_ref(_M_elems, __n); } constexpr const_reference at(size_type __n) const { // Result of conditional expression must be an lvalue so use // boolean ? lvalue : (throw-expr, lvalue) return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " ">= _Nm (which is %zu)"), __n, _Nm), _AT_Type::_S_ref(_M_elems, 0)); } _GLIBCXX17_CONSTEXPR reference front() noexcept { return *begin(); } constexpr const_reference front() const noexcept { return _AT_Type::_S_ref(_M_elems, 0); } _GLIBCXX17_CONSTEXPR reference back() noexcept { return _Nm ? *(end() - 1) : *end(); } constexpr const_reference back() const noexcept { return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) : _AT_Type::_S_ref(_M_elems, 0); } _GLIBCXX17_CONSTEXPR pointer data() noexcept { return _AT_Type::_S_ptr(_M_elems); } _GLIBCXX17_CONSTEXPR const_pointer data() const noexcept { return _AT_Type::_S_ptr(_M_elems); } }; #if __cpp_deduction_guides >= 201606 template<typename _Tp, typename... _Up> array(_Tp, _Up...) -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>, 1 + sizeof...(_Up)>; #endif // Array comparisons. template<typename _Tp, std::size_t _Nm> inline bool operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return std::equal(__one.begin(), __one.end(), __two.begin()); } template<typename _Tp, std::size_t _Nm> inline bool operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return !(__one == __two); } template<typename _Tp, std::size_t _Nm> 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> inline bool operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return __two < __one; } template<typename _Tp, std::size_t _Nm> inline bool operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return !(__one > __two); } template<typename _Tp, std::size_t _Nm> inline bool operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) { return !(__one < __two); } // Specialized algorithms. template<typename _Tp, std::size_t _Nm> inline #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 // Constrained free swap overload, see p0185r1 typename enable_if< _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value >::type #else void #endif swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) noexcept(noexcept(__one.swap(__two))) { __one.swap(__two); } #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 template<typename _Tp, std::size_t _Nm> typename enable_if< !_GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value>::type swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete; #endif template<std::size_t _Int, typename _Tp, std::size_t _Nm> constexpr _Tp& get(array<_Tp, _Nm>& __arr) noexcept { static_assert(_Int < _Nm, "array index is within bounds"); return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: _S_ref(__arr._M_elems, _Int); } template<std::size_t _Int, typename _Tp, std::size_t _Nm> constexpr _Tp&& get(array<_Tp, _Nm>&& __arr) noexcept { static_assert(_Int < _Nm, "array index is within bounds"); return std::move(_GLIBCXX_STD_C::get<_Int>(__arr)); } template<std::size_t _Int, typename _Tp, std::size_t _Nm> constexpr const _Tp& get(const array<_Tp, _Nm>& __arr) noexcept { static_assert(_Int < _Nm, "array index is within bounds"); return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>:: _S_ref(__arr._M_elems, _Int); } template<std::size_t _Int, typename _Tp, std::size_t _Nm> constexpr const _Tp&& get(const array<_Tp, _Nm>&& __arr) noexcept { static_assert(_Int < _Nm, "array index is within bounds"); return std::move(_GLIBCXX_STD_C::get<_Int>(__arr)); } _GLIBCXX_END_NAMESPACE_CONTAINER } // namespace std namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Tuple interface to class template array. /// tuple_size template<typename _Tp> struct tuple_size; /// Partial specialization for std::array template<typename _Tp, std::size_t _Nm> struct tuple_size<_GLIBCXX_STD_C::array<_Tp, _Nm>> : public integral_constant<std::size_t, _Nm> { }; /// tuple_element template<std::size_t _Int, typename _Tp> struct tuple_element; /// Partial specialization for std::array template<std::size_t _Int, typename _Tp, std::size_t _Nm> struct tuple_element<_Int, _GLIBCXX_STD_C::array<_Tp, _Nm>> { static_assert(_Int < _Nm, "index is out of bounds"); typedef _Tp type; }; template<typename _Tp, std::size_t _Nm> struct __is_tuple_like_impl<_GLIBCXX_STD_C::array<_Tp, _Nm>> : true_type { }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #ifdef _GLIBCXX_DEBUG # include <debug/array> #endif #ifdef _GLIBCXX_PROFILE # include <profile/array> #endif #endif // C++11 #endif // _GLIBCXX_ARRAY c++/8/bits/shared_ptr_atomic.h 0000644 00000023051 15146341150 0012065 0 ustar 00 // shared_ptr atomic access -*- C++ -*- // Copyright (C) 2014-2018 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/shared_ptr_atomic.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _SHARED_PTR_ATOMIC_H #define _SHARED_PTR_ATOMIC_H 1 #include <bits/atomic_base.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup pointer_abstractions * @{ */ struct _Sp_locker { _Sp_locker(const _Sp_locker&) = delete; _Sp_locker& operator=(const _Sp_locker&) = delete; #ifdef __GTHREADS explicit _Sp_locker(const void*) noexcept; _Sp_locker(const void*, const void*) noexcept; ~_Sp_locker(); private: unsigned char _M_key1; unsigned char _M_key2; #else explicit _Sp_locker(const void*, const void* = nullptr) { } #endif }; /** * @brief Report whether shared_ptr atomic operations are lock-free. * @param __p A non-null pointer to a shared_ptr object. * @return True if atomic access to @c *__p is lock-free, false otherwise. * @{ */ template<typename _Tp, _Lock_policy _Lp> inline bool atomic_is_lock_free(const __shared_ptr<_Tp, _Lp>* __p) { #ifdef __GTHREADS return __gthread_active_p() == 0; #else return true; #endif } template<typename _Tp> inline bool atomic_is_lock_free(const shared_ptr<_Tp>* __p) { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); } // @} /** * @brief Atomic load for shared_ptr objects. * @param __p A non-null pointer to a shared_ptr object. * @return @c *__p * * The memory order shall not be @c memory_order_release or * @c memory_order_acq_rel. * @{ */ template<typename _Tp> inline shared_ptr<_Tp> atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order) { _Sp_locker __lock{__p}; return *__p; } template<typename _Tp> inline shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p) { return std::atomic_load_explicit(__p, memory_order_seq_cst); } template<typename _Tp, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> atomic_load_explicit(const __shared_ptr<_Tp, _Lp>* __p, memory_order) { _Sp_locker __lock{__p}; return *__p; } template<typename _Tp, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> atomic_load(const __shared_ptr<_Tp, _Lp>* __p) { return std::atomic_load_explicit(__p, memory_order_seq_cst); } // @} /** * @brief Atomic store for shared_ptr objects. * @param __p A non-null pointer to a shared_ptr object. * @param __r The value to store. * * The memory order shall not be @c memory_order_acquire or * @c memory_order_acq_rel. * @{ */ template<typename _Tp> inline void atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) { _Sp_locker __lock{__p}; __p->swap(__r); // use swap so that **__p not destroyed while lock held } template<typename _Tp> inline void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) { std::atomic_store_explicit(__p, std::move(__r), memory_order_seq_cst); } template<typename _Tp, _Lock_policy _Lp> inline void atomic_store_explicit(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp> __r, memory_order) { _Sp_locker __lock{__p}; __p->swap(__r); // use swap so that **__p not destroyed while lock held } template<typename _Tp, _Lock_policy _Lp> inline void atomic_store(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp> __r) { std::atomic_store_explicit(__p, std::move(__r), memory_order_seq_cst); } // @} /** * @brief Atomic exchange for shared_ptr objects. * @param __p A non-null pointer to a shared_ptr object. * @param __r New value to store in @c *__p. * @return The original value of @c *__p * @{ */ template<typename _Tp> inline shared_ptr<_Tp> atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) { _Sp_locker __lock{__p}; __p->swap(__r); return __r; } template<typename _Tp> inline shared_ptr<_Tp> atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r) { return std::atomic_exchange_explicit(__p, std::move(__r), memory_order_seq_cst); } template<typename _Tp, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> atomic_exchange_explicit(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp> __r, memory_order) { _Sp_locker __lock{__p}; __p->swap(__r); return __r; } template<typename _Tp, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> atomic_exchange(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp> __r) { return std::atomic_exchange_explicit(__p, std::move(__r), memory_order_seq_cst); } // @} /** * @brief Atomic compare-and-swap for shared_ptr objects. * @param __p A non-null pointer to a shared_ptr object. * @param __v A non-null pointer to a shared_ptr object. * @param __w A non-null pointer to a shared_ptr object. * @return True if @c *__p was equivalent to @c *__v, false otherwise. * * The memory order for failure shall not be @c memory_order_release or * @c memory_order_acq_rel, or stronger than the memory order for success. * @{ */ template<typename _Tp> bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w, memory_order, memory_order) { shared_ptr<_Tp> __x; // goes out of scope after __lock _Sp_locker __lock{__p, __v}; owner_less<shared_ptr<_Tp>> __less; if (*__p == *__v && !__less(*__p, *__v) && !__less(*__v, *__p)) { __x = std::move(*__p); *__p = std::move(__w); return true; } __x = std::move(*__v); *__v = *__p; return false; } template<typename _Tp> inline bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) { return std::atomic_compare_exchange_strong_explicit(__p, __v, std::move(__w), memory_order_seq_cst, memory_order_seq_cst); } template<typename _Tp> inline bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w, memory_order __success, memory_order __failure) { return std::atomic_compare_exchange_strong_explicit(__p, __v, std::move(__w), __success, __failure); } template<typename _Tp> inline bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) { return std::atomic_compare_exchange_weak_explicit(__p, __v, std::move(__w), memory_order_seq_cst, memory_order_seq_cst); } template<typename _Tp, _Lock_policy _Lp> bool atomic_compare_exchange_strong_explicit(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp>* __v, __shared_ptr<_Tp, _Lp> __w, memory_order, memory_order) { __shared_ptr<_Tp, _Lp> __x; // goes out of scope after __lock _Sp_locker __lock{__p, __v}; owner_less<__shared_ptr<_Tp, _Lp>> __less; if (*__p == *__v && !__less(*__p, *__v) && !__less(*__v, *__p)) { __x = std::move(*__p); *__p = std::move(__w); return true; } __x = std::move(*__v); *__v = *__p; return false; } template<typename _Tp, _Lock_policy _Lp> inline bool atomic_compare_exchange_strong(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp>* __v, __shared_ptr<_Tp, _Lp> __w) { return std::atomic_compare_exchange_strong_explicit(__p, __v, std::move(__w), memory_order_seq_cst, memory_order_seq_cst); } template<typename _Tp, _Lock_policy _Lp> inline bool atomic_compare_exchange_weak_explicit(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp>* __v, __shared_ptr<_Tp, _Lp> __w, memory_order __success, memory_order __failure) { return std::atomic_compare_exchange_strong_explicit(__p, __v, std::move(__w), __success, __failure); } template<typename _Tp, _Lock_policy _Lp> inline bool atomic_compare_exchange_weak(__shared_ptr<_Tp, _Lp>* __p, __shared_ptr<_Tp, _Lp>* __v, __shared_ptr<_Tp, _Lp> __w) { return std::atomic_compare_exchange_weak_explicit(__p, __v, std::move(__w), memory_order_seq_cst, memory_order_seq_cst); } // @} // @} group pointer_abstractions _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _SHARED_PTR_ATOMIC_H c++/8/bits/valarray_after.h 0000644 00000054177 15146341150 0011415 0 ustar 00 // The template and inlines for the -*- C++ -*- internal _Meta class. // Copyright (C) 1997-2018 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/valarray_after.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{valarray} */ // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> #ifndef _VALARRAY_AFTER_H #define _VALARRAY_AFTER_H 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // // gslice_array closure. // template<class _Dom> class _GBase { public: typedef typename _Dom::value_type value_type; _GBase (const _Dom& __e, const valarray<size_t>& __i) : _M_expr (__e), _M_index(__i) {} value_type operator[] (size_t __i) const { return _M_expr[_M_index[__i]]; } size_t size () const { return _M_index.size(); } private: const _Dom& _M_expr; const valarray<size_t>& _M_index; }; template<typename _Tp> class _GBase<_Array<_Tp> > { public: typedef _Tp value_type; _GBase (_Array<_Tp> __a, const valarray<size_t>& __i) : _M_array (__a), _M_index(__i) {} value_type operator[] (size_t __i) const { return _M_array._M_data[_M_index[__i]]; } size_t size () const { return _M_index.size(); } private: const _Array<_Tp> _M_array; const valarray<size_t>& _M_index; }; template<class _Dom> struct _GClos<_Expr, _Dom> : _GBase<_Dom> { typedef _GBase<_Dom> _Base; typedef typename _Base::value_type value_type; _GClos (const _Dom& __e, const valarray<size_t>& __i) : _Base (__e, __i) {} }; template<typename _Tp> struct _GClos<_ValArray, _Tp> : _GBase<_Array<_Tp> > { typedef _GBase<_Array<_Tp> > _Base; typedef typename _Base::value_type value_type; _GClos (_Array<_Tp> __a, const valarray<size_t>& __i) : _Base (__a, __i) {} }; // // indirect_array closure // template<class _Dom> class _IBase { public: typedef typename _Dom::value_type value_type; _IBase (const _Dom& __e, const valarray<size_t>& __i) : _M_expr (__e), _M_index (__i) {} value_type operator[] (size_t __i) const { return _M_expr[_M_index[__i]]; } size_t size() const { return _M_index.size(); } private: const _Dom& _M_expr; const valarray<size_t>& _M_index; }; template<class _Dom> struct _IClos<_Expr, _Dom> : _IBase<_Dom> { typedef _IBase<_Dom> _Base; typedef typename _Base::value_type value_type; _IClos (const _Dom& __e, const valarray<size_t>& __i) : _Base (__e, __i) {} }; template<typename _Tp> struct _IClos<_ValArray, _Tp> : _IBase<valarray<_Tp> > { typedef _IBase<valarray<_Tp> > _Base; typedef _Tp value_type; _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i) : _Base (__a, __i) {} }; // // class _Expr // template<class _Clos, typename _Tp> class _Expr { public: typedef _Tp value_type; _Expr(const _Clos&); const _Clos& operator()() const; value_type operator[](size_t) const; valarray<value_type> operator[](slice) const; valarray<value_type> operator[](const gslice&) const; valarray<value_type> operator[](const valarray<bool>&) const; valarray<value_type> operator[](const valarray<size_t>&) const; _Expr<_UnClos<__unary_plus, std::_Expr, _Clos>, value_type> operator+() const; _Expr<_UnClos<__negate, std::_Expr, _Clos>, value_type> operator-() const; _Expr<_UnClos<__bitwise_not, std::_Expr, _Clos>, value_type> operator~() const; _Expr<_UnClos<__logical_not, std::_Expr, _Clos>, bool> operator!() const; size_t size() const; value_type sum() const; valarray<value_type> shift(int) const; valarray<value_type> cshift(int) const; value_type min() const; value_type max() const; valarray<value_type> apply(value_type (*)(const value_type&)) const; valarray<value_type> apply(value_type (*)(value_type)) const; private: const _Clos _M_closure; }; template<class _Clos, typename _Tp> inline _Expr<_Clos, _Tp>::_Expr(const _Clos& __c) : _M_closure(__c) {} template<class _Clos, typename _Tp> inline const _Clos& _Expr<_Clos, _Tp>::operator()() const { return _M_closure; } template<class _Clos, typename _Tp> inline _Tp _Expr<_Clos, _Tp>::operator[](size_t __i) const { return _M_closure[__i]; } template<class _Clos, typename _Tp> inline valarray<_Tp> _Expr<_Clos, _Tp>::operator[](slice __s) const { valarray<_Tp> __v = valarray<_Tp>(*this)[__s]; return __v; } template<class _Clos, typename _Tp> inline valarray<_Tp> _Expr<_Clos, _Tp>::operator[](const gslice& __gs) const { valarray<_Tp> __v = valarray<_Tp>(*this)[__gs]; return __v; } template<class _Clos, typename _Tp> inline valarray<_Tp> _Expr<_Clos, _Tp>::operator[](const valarray<bool>& __m) const { valarray<_Tp> __v = valarray<_Tp>(*this)[__m]; return __v; } template<class _Clos, typename _Tp> inline valarray<_Tp> _Expr<_Clos, _Tp>::operator[](const valarray<size_t>& __i) const { valarray<_Tp> __v = valarray<_Tp>(*this)[__i]; return __v; } template<class _Clos, typename _Tp> inline size_t _Expr<_Clos, _Tp>::size() const { return _M_closure.size(); } template<class _Clos, typename _Tp> inline valarray<_Tp> _Expr<_Clos, _Tp>::shift(int __n) const { valarray<_Tp> __v = valarray<_Tp>(*this).shift(__n); return __v; } template<class _Clos, typename _Tp> inline valarray<_Tp> _Expr<_Clos, _Tp>::cshift(int __n) const { valarray<_Tp> __v = valarray<_Tp>(*this).cshift(__n); return __v; } template<class _Clos, typename _Tp> inline valarray<_Tp> _Expr<_Clos, _Tp>::apply(_Tp __f(const _Tp&)) const { valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f); return __v; } template<class _Clos, typename _Tp> inline valarray<_Tp> _Expr<_Clos, _Tp>::apply(_Tp __f(_Tp)) const { valarray<_Tp> __v = valarray<_Tp>(*this).apply(__f); return __v; } // XXX: replace this with a more robust summation algorithm. template<class _Clos, typename _Tp> inline _Tp _Expr<_Clos, _Tp>::sum() const { size_t __n = _M_closure.size(); if (__n == 0) return _Tp(); else { _Tp __s = _M_closure[--__n]; while (__n != 0) __s += _M_closure[--__n]; return __s; } } template<class _Clos, typename _Tp> inline _Tp _Expr<_Clos, _Tp>::min() const { return __valarray_min(_M_closure); } template<class _Clos, typename _Tp> inline _Tp _Expr<_Clos, _Tp>::max() const { return __valarray_max(_M_closure); } template<class _Dom, typename _Tp> inline _Expr<_UnClos<__logical_not, _Expr, _Dom>, bool> _Expr<_Dom, _Tp>::operator!() const { typedef _UnClos<__logical_not, std::_Expr, _Dom> _Closure; return _Expr<_Closure, bool>(_Closure(this->_M_closure)); } #define _DEFINE_EXPR_UNARY_OPERATOR(_Op, _Name) \ template<class _Dom, typename _Tp> \ inline _Expr<_UnClos<_Name, std::_Expr, _Dom>, _Tp> \ _Expr<_Dom, _Tp>::operator _Op() const \ { \ typedef _UnClos<_Name, std::_Expr, _Dom> _Closure; \ return _Expr<_Closure, _Tp>(_Closure(this->_M_closure)); \ } _DEFINE_EXPR_UNARY_OPERATOR(+, __unary_plus) _DEFINE_EXPR_UNARY_OPERATOR(-, __negate) _DEFINE_EXPR_UNARY_OPERATOR(~, __bitwise_not) #undef _DEFINE_EXPR_UNARY_OPERATOR #define _DEFINE_EXPR_BINARY_OPERATOR(_Op, _Name) \ template<class _Dom1, class _Dom2> \ inline _Expr<_BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2>, \ typename __fun<_Name, typename _Dom1::value_type>::result_type> \ operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v, \ const _Expr<_Dom2, typename _Dom2::value_type>& __w) \ { \ typedef typename _Dom1::value_type _Arg; \ typedef typename __fun<_Name, _Arg>::result_type _Value; \ typedef _BinClos<_Name, _Expr, _Expr, _Dom1, _Dom2> _Closure; \ return _Expr<_Closure, _Value>(_Closure(__v(), __w())); \ } \ \ template<class _Dom> \ inline _Expr<_BinClos<_Name, _Expr, _Constant, _Dom, \ typename _Dom::value_type>, \ typename __fun<_Name, typename _Dom::value_type>::result_type> \ operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v, \ const typename _Dom::value_type& __t) \ { \ typedef typename _Dom::value_type _Arg; \ typedef typename __fun<_Name, _Arg>::result_type _Value; \ typedef _BinClos<_Name, _Expr, _Constant, _Dom, _Arg> _Closure; \ return _Expr<_Closure, _Value>(_Closure(__v(), __t)); \ } \ \ template<class _Dom> \ inline _Expr<_BinClos<_Name, _Constant, _Expr, \ typename _Dom::value_type, _Dom>, \ typename __fun<_Name, typename _Dom::value_type>::result_type> \ operator _Op(const typename _Dom::value_type& __t, \ const _Expr<_Dom, typename _Dom::value_type>& __v) \ { \ typedef typename _Dom::value_type _Arg; \ typedef typename __fun<_Name, _Arg>::result_type _Value; \ typedef _BinClos<_Name, _Constant, _Expr, _Arg, _Dom> _Closure; \ return _Expr<_Closure, _Value>(_Closure(__t, __v())); \ } \ \ template<class _Dom> \ inline _Expr<_BinClos<_Name, _Expr, _ValArray, \ _Dom, typename _Dom::value_type>, \ typename __fun<_Name, typename _Dom::value_type>::result_type> \ operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e, \ const valarray<typename _Dom::value_type>& __v) \ { \ typedef typename _Dom::value_type _Arg; \ typedef typename __fun<_Name, _Arg>::result_type _Value; \ typedef _BinClos<_Name, _Expr, _ValArray, _Dom, _Arg> _Closure; \ return _Expr<_Closure, _Value>(_Closure(__e(), __v)); \ } \ \ template<class _Dom> \ inline _Expr<_BinClos<_Name, _ValArray, _Expr, \ typename _Dom::value_type, _Dom>, \ typename __fun<_Name, typename _Dom::value_type>::result_type> \ operator _Op(const valarray<typename _Dom::value_type>& __v, \ const _Expr<_Dom, typename _Dom::value_type>& __e) \ { \ typedef typename _Dom::value_type _Tp; \ typedef typename __fun<_Name, _Tp>::result_type _Value; \ typedef _BinClos<_Name, _ValArray, _Expr, _Tp, _Dom> _Closure; \ return _Expr<_Closure, _Value>(_Closure(__v, __e ())); \ } _DEFINE_EXPR_BINARY_OPERATOR(+, __plus) _DEFINE_EXPR_BINARY_OPERATOR(-, __minus) _DEFINE_EXPR_BINARY_OPERATOR(*, __multiplies) _DEFINE_EXPR_BINARY_OPERATOR(/, __divides) _DEFINE_EXPR_BINARY_OPERATOR(%, __modulus) _DEFINE_EXPR_BINARY_OPERATOR(^, __bitwise_xor) _DEFINE_EXPR_BINARY_OPERATOR(&, __bitwise_and) _DEFINE_EXPR_BINARY_OPERATOR(|, __bitwise_or) _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left) _DEFINE_EXPR_BINARY_OPERATOR(>>, __shift_right) _DEFINE_EXPR_BINARY_OPERATOR(&&, __logical_and) _DEFINE_EXPR_BINARY_OPERATOR(||, __logical_or) _DEFINE_EXPR_BINARY_OPERATOR(==, __equal_to) _DEFINE_EXPR_BINARY_OPERATOR(!=, __not_equal_to) _DEFINE_EXPR_BINARY_OPERATOR(<, __less) _DEFINE_EXPR_BINARY_OPERATOR(>, __greater) _DEFINE_EXPR_BINARY_OPERATOR(<=, __less_equal) _DEFINE_EXPR_BINARY_OPERATOR(>=, __greater_equal) #undef _DEFINE_EXPR_BINARY_OPERATOR #define _DEFINE_EXPR_UNARY_FUNCTION(_Name, _UName) \ template<class _Dom> \ inline _Expr<_UnClos<_UName, _Expr, _Dom>, \ typename _Dom::value_type> \ _Name(const _Expr<_Dom, typename _Dom::value_type>& __e) \ { \ typedef typename _Dom::value_type _Tp; \ typedef _UnClos<_UName, _Expr, _Dom> _Closure; \ return _Expr<_Closure, _Tp>(_Closure(__e())); \ } \ \ template<typename _Tp> \ inline _Expr<_UnClos<_UName, _ValArray, _Tp>, _Tp> \ _Name(const valarray<_Tp>& __v) \ { \ typedef _UnClos<_UName, _ValArray, _Tp> _Closure; \ return _Expr<_Closure, _Tp>(_Closure(__v)); \ } _DEFINE_EXPR_UNARY_FUNCTION(abs, _Abs) _DEFINE_EXPR_UNARY_FUNCTION(cos, _Cos) _DEFINE_EXPR_UNARY_FUNCTION(acos, _Acos) _DEFINE_EXPR_UNARY_FUNCTION(cosh, _Cosh) _DEFINE_EXPR_UNARY_FUNCTION(sin, _Sin) _DEFINE_EXPR_UNARY_FUNCTION(asin, _Asin) _DEFINE_EXPR_UNARY_FUNCTION(sinh, _Sinh) _DEFINE_EXPR_UNARY_FUNCTION(tan, _Tan) _DEFINE_EXPR_UNARY_FUNCTION(tanh, _Tanh) _DEFINE_EXPR_UNARY_FUNCTION(atan, _Atan) _DEFINE_EXPR_UNARY_FUNCTION(exp, _Exp) _DEFINE_EXPR_UNARY_FUNCTION(log, _Log) _DEFINE_EXPR_UNARY_FUNCTION(log10, _Log10) _DEFINE_EXPR_UNARY_FUNCTION(sqrt, _Sqrt) #undef _DEFINE_EXPR_UNARY_FUNCTION #define _DEFINE_EXPR_BINARY_FUNCTION(_Fun, _UFun) \ template<class _Dom1, class _Dom2> \ inline _Expr<_BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2>, \ typename _Dom1::value_type> \ _Fun(const _Expr<_Dom1, typename _Dom1::value_type>& __e1, \ const _Expr<_Dom2, typename _Dom2::value_type>& __e2) \ { \ typedef typename _Dom1::value_type _Tp; \ typedef _BinClos<_UFun, _Expr, _Expr, _Dom1, _Dom2> _Closure; \ return _Expr<_Closure, _Tp>(_Closure(__e1(), __e2())); \ } \ \ template<class _Dom> \ inline _Expr<_BinClos<_UFun, _Expr, _ValArray, _Dom, \ typename _Dom::value_type>, \ typename _Dom::value_type> \ _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ const valarray<typename _Dom::value_type>& __v) \ { \ typedef typename _Dom::value_type _Tp; \ typedef _BinClos<_UFun, _Expr, _ValArray, _Dom, _Tp> _Closure; \ return _Expr<_Closure, _Tp>(_Closure(__e(), __v)); \ } \ \ template<class _Dom> \ inline _Expr<_BinClos<_UFun, _ValArray, _Expr, \ typename _Dom::value_type, _Dom>, \ typename _Dom::value_type> \ _Fun(const valarray<typename _Dom::valarray>& __v, \ const _Expr<_Dom, typename _Dom::value_type>& __e) \ { \ typedef typename _Dom::value_type _Tp; \ typedef _BinClos<_UFun, _ValArray, _Expr, _Tp, _Dom> _Closure; \ return _Expr<_Closure, _Tp>(_Closure(__v, __e())); \ } \ \ template<class _Dom> \ inline _Expr<_BinClos<_UFun, _Expr, _Constant, _Dom, \ typename _Dom::value_type>, \ typename _Dom::value_type> \ _Fun(const _Expr<_Dom, typename _Dom::value_type>& __e, \ const typename _Dom::value_type& __t) \ { \ typedef typename _Dom::value_type _Tp; \ typedef _BinClos<_UFun, _Expr, _Constant, _Dom, _Tp> _Closure; \ return _Expr<_Closure, _Tp>(_Closure(__e(), __t)); \ } \ \ template<class _Dom> \ inline _Expr<_BinClos<_UFun, _Constant, _Expr, \ typename _Dom::value_type, _Dom>, \ typename _Dom::value_type> \ _Fun(const typename _Dom::value_type& __t, \ const _Expr<_Dom, typename _Dom::value_type>& __e) \ { \ typedef typename _Dom::value_type _Tp; \ typedef _BinClos<_UFun, _Constant, _Expr, _Tp, _Dom> _Closure; \ return _Expr<_Closure, _Tp>(_Closure(__t, __e())); \ } \ \ template<typename _Tp> \ inline _Expr<_BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp>, _Tp> \ _Fun(const valarray<_Tp>& __v, const valarray<_Tp>& __w) \ { \ typedef _BinClos<_UFun, _ValArray, _ValArray, _Tp, _Tp> _Closure;\ return _Expr<_Closure, _Tp>(_Closure(__v, __w)); \ } \ \ template<typename _Tp> \ inline _Expr<_BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp>, _Tp> \ _Fun(const valarray<_Tp>& __v, const _Tp& __t) \ { \ typedef _BinClos<_UFun, _ValArray, _Constant, _Tp, _Tp> _Closure;\ return _Expr<_Closure, _Tp>(_Closure(__v, __t)); \ } \ \ template<typename _Tp> \ inline _Expr<_BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp>, _Tp> \ _Fun(const _Tp& __t, const valarray<_Tp>& __v) \ { \ typedef _BinClos<_UFun, _Constant, _ValArray, _Tp, _Tp> _Closure;\ return _Expr<_Closure, _Tp>(_Closure(__t, __v)); \ } _DEFINE_EXPR_BINARY_FUNCTION(atan2, _Atan2) _DEFINE_EXPR_BINARY_FUNCTION(pow, _Pow) #undef _DEFINE_EXPR_BINARY_FUNCTION _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _CPP_VALARRAY_AFTER_H */ c++/8/bits/shared_ptr_base.h 0000644 00000152016 15146341150 0011527 0 ustar 00 // shared_ptr and weak_ptr implementation details -*- C++ -*- // Copyright (C) 2007-2018 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/>. // GCC Note: Based on files from version 1.32.0 of the Boost library. // shared_count.hpp // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. // shared_ptr.hpp // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. // Copyright (C) 2001, 2002, 2003 Peter Dimov // weak_ptr.hpp // Copyright (C) 2001, 2002, 2003 Peter Dimov // enable_shared_from_this.hpp // Copyright (C) 2002 Peter Dimov // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) /** @file bits/shared_ptr_base.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _SHARED_PTR_BASE_H #define _SHARED_PTR_BASE_H 1 #include <typeinfo> #include <bits/allocated_ptr.h> #include <bits/refwrap.h> #include <bits/stl_function.h> #include <ext/aligned_buffer.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if _GLIBCXX_USE_DEPRECATED #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" template<typename> class auto_ptr; #pragma GCC diagnostic pop #endif /** * @brief Exception possibly thrown by @c shared_ptr. * @ingroup exceptions */ class bad_weak_ptr : public std::exception { public: virtual char const* what() const noexcept; virtual ~bad_weak_ptr() noexcept; }; // Substitute for bad_weak_ptr object in the case of -fno-exceptions. inline void __throw_bad_weak_ptr() { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); } using __gnu_cxx::_Lock_policy; using __gnu_cxx::__default_lock_policy; using __gnu_cxx::_S_single; using __gnu_cxx::_S_mutex; using __gnu_cxx::_S_atomic; // Empty helper class except when the template argument is _S_mutex. template<_Lock_policy _Lp> class _Mutex_base { protected: // The atomic policy uses fully-fenced builtins, single doesn't care. enum { _S_need_barriers = 0 }; }; template<> class _Mutex_base<_S_mutex> : public __gnu_cxx::__mutex { protected: // This policy is used when atomic builtins are not available. // The replacement atomic operations might not have the necessary // memory barriers. enum { _S_need_barriers = 1 }; }; template<_Lock_policy _Lp = __default_lock_policy> class _Sp_counted_base : public _Mutex_base<_Lp> { public: _Sp_counted_base() noexcept : _M_use_count(1), _M_weak_count(1) { } virtual ~_Sp_counted_base() noexcept { } // Called when _M_use_count drops to zero, to release the resources // managed by *this. virtual void _M_dispose() noexcept = 0; // Called when _M_weak_count drops to zero. virtual void _M_destroy() noexcept { delete this; } virtual void* _M_get_deleter(const std::type_info&) noexcept = 0; void _M_add_ref_copy() { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } void _M_add_ref_lock(); bool _M_add_ref_lock_nothrow(); void _M_release() noexcept { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); _M_dispose(); // There must be a memory barrier between dispose() and destroy() // to ensure that the effects of dispose() are observed in the // thread that runs destroy(). // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html if (_Mutex_base<_Lp>::_S_need_barriers) { __atomic_thread_fence (__ATOMIC_ACQ_REL); } // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); _M_destroy(); } } } void _M_weak_add_ref() noexcept { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } void _M_weak_release() noexcept { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); if (_Mutex_base<_Lp>::_S_need_barriers) { // See _M_release(), // destroy() must observe results of dispose() __atomic_thread_fence (__ATOMIC_ACQ_REL); } _M_destroy(); } } long _M_get_use_count() const noexcept { // No memory barrier is used here so there is no synchronization // with other threads. return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED); } private: _Sp_counted_base(_Sp_counted_base const&) = delete; _Sp_counted_base& operator=(_Sp_counted_base const&) = delete; _Atomic_word _M_use_count; // #shared _Atomic_word _M_weak_count; // #weak + (#shared != 0) }; template<> inline void _Sp_counted_base<_S_single>:: _M_add_ref_lock() { if (_M_use_count == 0) __throw_bad_weak_ptr(); ++_M_use_count; } template<> inline void _Sp_counted_base<_S_mutex>:: _M_add_ref_lock() { __gnu_cxx::__scoped_lock sentry(*this); if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) { _M_use_count = 0; __throw_bad_weak_ptr(); } } template<> inline void _Sp_counted_base<_S_atomic>:: _M_add_ref_lock() { // Perform lock-free add-if-not-zero operation. _Atomic_word __count = _M_get_use_count(); do { if (__count == 0) __throw_bad_weak_ptr(); // Replace the current counter value with the old value + 1, as // long as it's not changed meanwhile. } while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)); } template<> inline bool _Sp_counted_base<_S_single>:: _M_add_ref_lock_nothrow() { if (_M_use_count == 0) return false; ++_M_use_count; return true; } template<> inline bool _Sp_counted_base<_S_mutex>:: _M_add_ref_lock_nothrow() { __gnu_cxx::__scoped_lock sentry(*this); if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) { _M_use_count = 0; return false; } return true; } template<> inline bool _Sp_counted_base<_S_atomic>:: _M_add_ref_lock_nothrow() { // Perform lock-free add-if-not-zero operation. _Atomic_word __count = _M_get_use_count(); do { if (__count == 0) return false; // Replace the current counter value with the old value + 1, as // long as it's not changed meanwhile. } while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)); return true; } template<> inline void _Sp_counted_base<_S_single>::_M_add_ref_copy() { ++_M_use_count; } template<> inline void _Sp_counted_base<_S_single>::_M_release() noexcept { if (--_M_use_count == 0) { _M_dispose(); if (--_M_weak_count == 0) _M_destroy(); } } template<> inline void _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept { ++_M_weak_count; } template<> inline void _Sp_counted_base<_S_single>::_M_weak_release() noexcept { if (--_M_weak_count == 0) _M_destroy(); } template<> inline long _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept { return _M_use_count; } // Forward declarations. template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> class __shared_ptr; template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> class __weak_ptr; template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> class __enable_shared_from_this; template<typename _Tp> class shared_ptr; template<typename _Tp> class weak_ptr; template<typename _Tp> struct owner_less; template<typename _Tp> class enable_shared_from_this; template<_Lock_policy _Lp = __default_lock_policy> class __weak_count; template<_Lock_policy _Lp = __default_lock_policy> class __shared_count; // Counted ptr with no deleter or allocator support template<typename _Ptr, _Lock_policy _Lp> class _Sp_counted_ptr final : public _Sp_counted_base<_Lp> { public: explicit _Sp_counted_ptr(_Ptr __p) noexcept : _M_ptr(__p) { } virtual void _M_dispose() noexcept { delete _M_ptr; } virtual void _M_destroy() noexcept { delete this; } virtual void* _M_get_deleter(const std::type_info&) noexcept { return nullptr; } _Sp_counted_ptr(const _Sp_counted_ptr&) = delete; _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete; private: _Ptr _M_ptr; }; template<> inline void _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { } template<> inline void _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { } template<> inline void _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { } template<int _Nm, typename _Tp, bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)> struct _Sp_ebo_helper; /// Specialization using EBO. template<int _Nm, typename _Tp> struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp { explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { } explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { } static _Tp& _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); } }; /// Specialization not using EBO. template<int _Nm, typename _Tp> struct _Sp_ebo_helper<_Nm, _Tp, false> { explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { } explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { } static _Tp& _S_get(_Sp_ebo_helper& __eboh) { return __eboh._M_tp; } private: _Tp _M_tp; }; // Support for custom deleter and/or allocator template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp> class _Sp_counted_deleter final : public _Sp_counted_base<_Lp> { class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc> { typedef _Sp_ebo_helper<0, _Deleter> _Del_base; typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base; public: _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept : _M_ptr(__p), _Del_base(std::move(__d)), _Alloc_base(__a) { } _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); } _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); } _Ptr _M_ptr; }; public: using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>; // __d(__p) must not throw. _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept : _M_impl(__p, std::move(__d), _Alloc()) { } // __d(__p) must not throw. _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept : _M_impl(__p, std::move(__d), __a) { } ~_Sp_counted_deleter() noexcept { } virtual void _M_dispose() noexcept { _M_impl._M_del()(_M_impl._M_ptr); } virtual void _M_destroy() noexcept { __allocator_type __a(_M_impl._M_alloc()); __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; this->~_Sp_counted_deleter(); } virtual void* _M_get_deleter(const std::type_info& __ti) noexcept { #if __cpp_rtti // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2400. shared_ptr's get_deleter() should use addressof() return __ti == typeid(_Deleter) ? std::__addressof(_M_impl._M_del()) : nullptr; #else return nullptr; #endif } private: _Impl _M_impl; }; // helpers for make_shared / allocate_shared struct _Sp_make_shared_tag { private: template<typename _Tp, typename _Alloc, _Lock_policy _Lp> friend class _Sp_counted_ptr_inplace; static const type_info& _S_ti() noexcept _GLIBCXX_VISIBILITY(default) { alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { }; return reinterpret_cast<const type_info&>(__tag); } }; template<typename _Alloc> struct _Sp_alloc_shared_tag { const _Alloc& _M_a; }; template<typename _Tp, typename _Alloc, _Lock_policy _Lp> class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> { class _Impl : _Sp_ebo_helper<0, _Alloc> { typedef _Sp_ebo_helper<0, _Alloc> _A_base; public: explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { } _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); } __gnu_cxx::__aligned_buffer<_Tp> _M_storage; }; public: using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>; template<typename... _Args> _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) : _M_impl(__a) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2070. allocate_shared should use allocator_traits<A>::construct allocator_traits<_Alloc>::construct(__a, _M_ptr(), std::forward<_Args>(__args)...); // might throw } ~_Sp_counted_ptr_inplace() noexcept { } virtual void _M_dispose() noexcept { allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr()); } // Override because the allocator needs to know the dynamic type virtual void _M_destroy() noexcept { __allocator_type __a(_M_impl._M_alloc()); __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; this->~_Sp_counted_ptr_inplace(); } private: friend class __shared_count<_Lp>; // To be able to call _M_ptr(). // No longer used, but code compiled against old libstdc++ headers // might still call it from __shared_ptr ctor to get the pointer out. virtual void* _M_get_deleter(const std::type_info& __ti) noexcept override { // Check for the fake type_info first, so we don't try to access it // as a real type_info object. if (&__ti == &_Sp_make_shared_tag::_S_ti()) return const_cast<typename remove_cv<_Tp>::type*>(_M_ptr()); #if __cpp_rtti // Callers compiled with old libstdc++ headers and RTTI enabled // might pass this instead: else if (__ti == typeid(_Sp_make_shared_tag)) return const_cast<typename remove_cv<_Tp>::type*>(_M_ptr()); #else // Cannot detect a real type_info object. If the linker keeps a // definition of this function compiled with -fno-rtti then callers // that have RTTI enabled and pass a real type_info object will get // a null pointer returned. #endif return nullptr; } _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); } _Impl _M_impl; }; // The default deleter for shared_ptr<T[]> and shared_ptr<T[N]>. struct __sp_array_delete { template<typename _Yp> void operator()(_Yp* __p) const { delete[] __p; } }; template<_Lock_policy _Lp> class __shared_count { template<typename _Tp> struct __not_alloc_shared_tag { using type = void; }; template<typename _Tp> struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { }; public: constexpr __shared_count() noexcept : _M_pi(0) { } template<typename _Ptr> explicit __shared_count(_Ptr __p) : _M_pi(0) { __try { _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); } __catch(...) { delete __p; __throw_exception_again; } } template<typename _Ptr> __shared_count(_Ptr __p, /* is_array = */ false_type) : __shared_count(__p) { } template<typename _Ptr> __shared_count(_Ptr __p, /* is_array = */ true_type) : __shared_count(__p, __sp_array_delete{}, allocator<void>()) { } template<typename _Ptr, typename _Deleter, typename = typename __not_alloc_shared_tag<_Deleter>::type> __shared_count(_Ptr __p, _Deleter __d) : __shared_count(__p, std::move(__d), allocator<void>()) { } template<typename _Ptr, typename _Deleter, typename _Alloc, typename = typename __not_alloc_shared_tag<_Deleter>::type> __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) { typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; __try { typename _Sp_cd_type::__allocator_type __a2(__a); auto __guard = std::__allocate_guarded(__a2); _Sp_cd_type* __mem = __guard.get(); ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a)); _M_pi = __mem; __guard = nullptr; } __catch(...) { __d(__p); // Call _Deleter on __p. __throw_exception_again; } } template<typename _Tp, typename _Alloc, typename... _Args> __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a, _Args&&... __args) { typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; typename _Sp_cp_type::__allocator_type __a2(__a._M_a); auto __guard = std::__allocate_guarded(__a2); _Sp_cp_type* __mem = __guard.get(); auto __pi = ::new (__mem) _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...); __guard = nullptr; _M_pi = __pi; __p = __pi->_M_ptr(); } #if _GLIBCXX_USE_DEPRECATED #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" // Special case for auto_ptr<_Tp> to provide the strong guarantee. template<typename _Tp> explicit __shared_count(std::auto_ptr<_Tp>&& __r); #pragma GCC diagnostic pop #endif // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee. template<typename _Tp, typename _Del> explicit __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2415. Inconsistency between unique_ptr and shared_ptr if (__r.get() == nullptr) return; using _Ptr = typename unique_ptr<_Tp, _Del>::pointer; using _Del2 = typename conditional<is_reference<_Del>::value, reference_wrapper<typename remove_reference<_Del>::type>, _Del>::type; using _Sp_cd_type = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>; using _Alloc = allocator<_Sp_cd_type>; using _Alloc_traits = allocator_traits<_Alloc>; _Alloc __a; _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1); _Alloc_traits::construct(__a, __mem, __r.release(), __r.get_deleter()); // non-throwing _M_pi = __mem; } // Throw bad_weak_ptr when __r._M_get_use_count() == 0. explicit __shared_count(const __weak_count<_Lp>& __r); // Does not throw if __r._M_get_use_count() == 0, caller must check. explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t); ~__shared_count() noexcept { if (_M_pi != nullptr) _M_pi->_M_release(); } __shared_count(const __shared_count& __r) noexcept : _M_pi(__r._M_pi) { if (_M_pi != 0) _M_pi->_M_add_ref_copy(); } __shared_count& operator=(const __shared_count& __r) noexcept { _Sp_counted_base<_Lp>* __tmp = __r._M_pi; if (__tmp != _M_pi) { if (__tmp != 0) __tmp->_M_add_ref_copy(); if (_M_pi != 0) _M_pi->_M_release(); _M_pi = __tmp; } return *this; } void _M_swap(__shared_count& __r) noexcept { _Sp_counted_base<_Lp>* __tmp = __r._M_pi; __r._M_pi = _M_pi; _M_pi = __tmp; } long _M_get_use_count() const noexcept { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } bool _M_unique() const noexcept { return this->_M_get_use_count() == 1; } void* _M_get_deleter(const std::type_info& __ti) const noexcept { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; } bool _M_less(const __shared_count& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } bool _M_less(const __weak_count<_Lp>& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } // Friend function injected into enclosing namespace and found by ADL friend inline bool operator==(const __shared_count& __a, const __shared_count& __b) noexcept { return __a._M_pi == __b._M_pi; } private: friend class __weak_count<_Lp>; _Sp_counted_base<_Lp>* _M_pi; }; template<_Lock_policy _Lp> class __weak_count { public: constexpr __weak_count() noexcept : _M_pi(nullptr) { } __weak_count(const __shared_count<_Lp>& __r) noexcept : _M_pi(__r._M_pi) { if (_M_pi != nullptr) _M_pi->_M_weak_add_ref(); } __weak_count(const __weak_count& __r) noexcept : _M_pi(__r._M_pi) { if (_M_pi != nullptr) _M_pi->_M_weak_add_ref(); } __weak_count(__weak_count&& __r) noexcept : _M_pi(__r._M_pi) { __r._M_pi = nullptr; } ~__weak_count() noexcept { if (_M_pi != nullptr) _M_pi->_M_weak_release(); } __weak_count& operator=(const __shared_count<_Lp>& __r) noexcept { _Sp_counted_base<_Lp>* __tmp = __r._M_pi; if (__tmp != nullptr) __tmp->_M_weak_add_ref(); if (_M_pi != nullptr) _M_pi->_M_weak_release(); _M_pi = __tmp; return *this; } __weak_count& operator=(const __weak_count& __r) noexcept { _Sp_counted_base<_Lp>* __tmp = __r._M_pi; if (__tmp != nullptr) __tmp->_M_weak_add_ref(); if (_M_pi != nullptr) _M_pi->_M_weak_release(); _M_pi = __tmp; return *this; } __weak_count& operator=(__weak_count&& __r) noexcept { if (_M_pi != nullptr) _M_pi->_M_weak_release(); _M_pi = __r._M_pi; __r._M_pi = nullptr; return *this; } void _M_swap(__weak_count& __r) noexcept { _Sp_counted_base<_Lp>* __tmp = __r._M_pi; __r._M_pi = _M_pi; _M_pi = __tmp; } long _M_get_use_count() const noexcept { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; } bool _M_less(const __weak_count& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } bool _M_less(const __shared_count<_Lp>& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } // Friend function injected into enclosing namespace and found by ADL friend inline bool operator==(const __weak_count& __a, const __weak_count& __b) noexcept { return __a._M_pi == __b._M_pi; } private: friend class __shared_count<_Lp>; _Sp_counted_base<_Lp>* _M_pi; }; // Now that __weak_count is defined we can define this constructor: template<_Lock_policy _Lp> inline __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r) : _M_pi(__r._M_pi) { if (_M_pi != nullptr) _M_pi->_M_add_ref_lock(); else __throw_bad_weak_ptr(); } // Now that __weak_count is defined we can define this constructor: template<_Lock_policy _Lp> inline __shared_count<_Lp>:: __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) : _M_pi(__r._M_pi) { if (_M_pi != nullptr) if (!_M_pi->_M_add_ref_lock_nothrow()) _M_pi = nullptr; } #define __cpp_lib_shared_ptr_arrays 201603 // Helper traits for shared_ptr of array: // A pointer type Y* is said to be compatible with a pointer type T* when // either Y* is convertible to T* or Y is U[N] and T is U cv []. template<typename _Yp_ptr, typename _Tp_ptr> struct __sp_compatible_with : false_type { }; template<typename _Yp, typename _Tp> struct __sp_compatible_with<_Yp*, _Tp*> : is_convertible<_Yp*, _Tp*>::type { }; template<typename _Up, size_t _Nm> struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]> : true_type { }; template<typename _Up, size_t _Nm> struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]> : true_type { }; template<typename _Up, size_t _Nm> struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]> : true_type { }; template<typename _Up, size_t _Nm> struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]> : true_type { }; // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N]. template<typename _Up, size_t _Nm, typename _Yp, typename = void> struct __sp_is_constructible_arrN : false_type { }; template<typename _Up, size_t _Nm, typename _Yp> struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>> : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type { }; // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[]. template<typename _Up, typename _Yp, typename = void> struct __sp_is_constructible_arr : false_type { }; template<typename _Up, typename _Yp> struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>> : is_convertible<_Yp(*)[], _Up(*)[]>::type { }; // Trait to check if shared_ptr<T> can be constructed from Y*. template<typename _Tp, typename _Yp> struct __sp_is_constructible; // When T is U[N], Y(*)[N] shall be convertible to T*; template<typename _Up, size_t _Nm, typename _Yp> struct __sp_is_constructible<_Up[_Nm], _Yp> : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type { }; // when T is U[], Y(*)[] shall be convertible to T*; template<typename _Up, typename _Yp> struct __sp_is_constructible<_Up[], _Yp> : __sp_is_constructible_arr<_Up, _Yp>::type { }; // otherwise, Y* shall be convertible to T*. template<typename _Tp, typename _Yp> struct __sp_is_constructible : is_convertible<_Yp*, _Tp*>::type { }; // Define operator* and operator-> for shared_ptr<T>. template<typename _Tp, _Lock_policy _Lp, bool = is_array<_Tp>::value, bool = is_void<_Tp>::value> class __shared_ptr_access { public: using element_type = _Tp; element_type& operator*() const noexcept { __glibcxx_assert(_M_get() != nullptr); return *_M_get(); } element_type* operator->() const noexcept { _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); return _M_get(); } private: element_type* _M_get() const noexcept { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); } }; // Define operator-> for shared_ptr<cv void>. template<typename _Tp, _Lock_policy _Lp> class __shared_ptr_access<_Tp, _Lp, false, true> { public: using element_type = _Tp; element_type* operator->() const noexcept { auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr); return __ptr; } }; // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>. template<typename _Tp, _Lock_policy _Lp> class __shared_ptr_access<_Tp, _Lp, true, false> { public: using element_type = typename remove_extent<_Tp>::type; #if __cplusplus <= 201402L [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]] element_type& operator*() const noexcept { __glibcxx_assert(_M_get() != nullptr); return *_M_get(); } [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]] element_type* operator->() const noexcept { _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); return _M_get(); } #endif element_type& operator[](ptrdiff_t __i) const { __glibcxx_assert(_M_get() != nullptr); __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value); return _M_get()[__i]; } private: element_type* _M_get() const noexcept { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); } }; template<typename _Tp, _Lock_policy _Lp> class __shared_ptr : public __shared_ptr_access<_Tp, _Lp> { public: using element_type = typename remove_extent<_Tp>::type; private: // Constraint for taking ownership of a pointer of type _Yp*: template<typename _Yp> using _SafeConv = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type; // Constraint for construction from shared_ptr and weak_ptr: template<typename _Yp, typename _Res = void> using _Compatible = typename enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type; // Constraint for assignment from shared_ptr and weak_ptr: template<typename _Yp> using _Assignable = _Compatible<_Yp, __shared_ptr&>; // Constraint for construction from unique_ptr: template<typename _Yp, typename _Del, typename _Res = void, typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer> using _UniqCompatible = typename enable_if<__and_< __sp_compatible_with<_Yp*, _Tp*>, is_convertible<_Ptr, element_type*> >::value, _Res>::type; // Constraint for assignment from unique_ptr: template<typename _Yp, typename _Del> using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>; public: #if __cplusplus > 201402L using weak_type = __weak_ptr<_Tp, _Lp>; #endif constexpr __shared_ptr() noexcept : _M_ptr(0), _M_refcount() { } template<typename _Yp, typename = _SafeConv<_Yp>> explicit __shared_ptr(_Yp* __p) : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type()) { static_assert( !is_void<_Yp>::value, "incomplete type" ); static_assert( sizeof(_Yp) > 0, "incomplete type" ); _M_enable_shared_from_this_with(__p); } template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>> __shared_ptr(_Yp* __p, _Deleter __d) : _M_ptr(__p), _M_refcount(__p, std::move(__d)) { static_assert(__is_invocable<_Deleter&, _Yp*&>::value, "deleter expression d(p) is well-formed"); _M_enable_shared_from_this_with(__p); } template<typename _Yp, typename _Deleter, typename _Alloc, typename = _SafeConv<_Yp>> __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) : _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a)) { static_assert(__is_invocable<_Deleter&, _Yp*&>::value, "deleter expression d(p) is well-formed"); _M_enable_shared_from_this_with(__p); } template<typename _Deleter> __shared_ptr(nullptr_t __p, _Deleter __d) : _M_ptr(0), _M_refcount(__p, std::move(__d)) { } template<typename _Deleter, typename _Alloc> __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) : _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a)) { } template<typename _Yp> __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r, element_type* __p) noexcept : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws { } __shared_ptr(const __shared_ptr&) noexcept = default; __shared_ptr& operator=(const __shared_ptr&) noexcept = default; ~__shared_ptr() = default; template<typename _Yp, typename = _Compatible<_Yp>> __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) { } __shared_ptr(__shared_ptr&& __r) noexcept : _M_ptr(__r._M_ptr), _M_refcount() { _M_refcount._M_swap(__r._M_refcount); __r._M_ptr = 0; } template<typename _Yp, typename = _Compatible<_Yp>> __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept : _M_ptr(__r._M_ptr), _M_refcount() { _M_refcount._M_swap(__r._M_refcount); __r._M_ptr = 0; } template<typename _Yp, typename = _Compatible<_Yp>> explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r) : _M_refcount(__r._M_refcount) // may throw { // It is now safe to copy __r._M_ptr, as // _M_refcount(__r._M_refcount) did not throw. _M_ptr = __r._M_ptr; } // If an exception is thrown this constructor has no effect. template<typename _Yp, typename _Del, typename = _UniqCompatible<_Yp, _Del>> __shared_ptr(unique_ptr<_Yp, _Del>&& __r) : _M_ptr(__r.get()), _M_refcount() { auto __raw = __to_address(__r.get()); _M_refcount = __shared_count<_Lp>(std::move(__r)); _M_enable_shared_from_this_with(__raw); } #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED protected: // If an exception is thrown this constructor has no effect. template<typename _Tp1, typename _Del, typename enable_if<__and_< __not_<is_array<_Tp>>, is_array<_Tp1>, is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*> >::value, bool>::type = true> __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete) : _M_ptr(__r.get()), _M_refcount() { auto __raw = __to_address(__r.get()); _M_refcount = __shared_count<_Lp>(std::move(__r)); _M_enable_shared_from_this_with(__raw); } public: #endif #if _GLIBCXX_USE_DEPRECATED #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" // Postcondition: use_count() == 1 and __r.get() == 0 template<typename _Yp, typename = _Compatible<_Yp>> __shared_ptr(auto_ptr<_Yp>&& __r); #pragma GCC diagnostic pop #endif constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { } template<typename _Yp> _Assignable<_Yp> operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept { _M_ptr = __r._M_ptr; _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw return *this; } #if _GLIBCXX_USE_DEPRECATED #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" template<typename _Yp> _Assignable<_Yp> operator=(auto_ptr<_Yp>&& __r) { __shared_ptr(std::move(__r)).swap(*this); return *this; } #pragma GCC diagnostic pop #endif __shared_ptr& operator=(__shared_ptr&& __r) noexcept { __shared_ptr(std::move(__r)).swap(*this); return *this; } template<class _Yp> _Assignable<_Yp> operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept { __shared_ptr(std::move(__r)).swap(*this); return *this; } template<typename _Yp, typename _Del> _UniqAssignable<_Yp, _Del> operator=(unique_ptr<_Yp, _Del>&& __r) { __shared_ptr(std::move(__r)).swap(*this); return *this; } void reset() noexcept { __shared_ptr().swap(*this); } template<typename _Yp> _SafeConv<_Yp> reset(_Yp* __p) // _Yp must be complete. { // Catch self-reset errors. __glibcxx_assert(__p == 0 || __p != _M_ptr); __shared_ptr(__p).swap(*this); } template<typename _Yp, typename _Deleter> _SafeConv<_Yp> reset(_Yp* __p, _Deleter __d) { __shared_ptr(__p, std::move(__d)).swap(*this); } template<typename _Yp, typename _Deleter, typename _Alloc> _SafeConv<_Yp> reset(_Yp* __p, _Deleter __d, _Alloc __a) { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); } element_type* get() const noexcept { return _M_ptr; } explicit operator bool() const // never throws { return _M_ptr == 0 ? false : true; } bool unique() const noexcept { return _M_refcount._M_unique(); } long use_count() const noexcept { return _M_refcount._M_get_use_count(); } void swap(__shared_ptr<_Tp, _Lp>& __other) noexcept { std::swap(_M_ptr, __other._M_ptr); _M_refcount._M_swap(__other._M_refcount); } template<typename _Tp1> bool owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept { return _M_refcount._M_less(__rhs._M_refcount); } template<typename _Tp1> bool owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept { return _M_refcount._M_less(__rhs._M_refcount); } protected: // This constructor is non-standard, it is used by allocate_shared. template<typename _Alloc, typename... _Args> __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...) { _M_enable_shared_from_this_with(_M_ptr); } template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc, typename... _Args> friend __shared_ptr<_Tp1, _Lp1> __allocate_shared(const _Alloc& __a, _Args&&... __args); // This constructor is used by __weak_ptr::lock() and // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t). __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) : _M_refcount(__r._M_refcount, std::nothrow) { _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr; } friend class __weak_ptr<_Tp, _Lp>; private: template<typename _Yp> using __esft_base_t = decltype(__enable_shared_from_this_base( std::declval<const __shared_count<_Lp>&>(), std::declval<_Yp*>())); // Detect an accessible and unambiguous enable_shared_from_this base. template<typename _Yp, typename = void> struct __has_esft_base : false_type { }; template<typename _Yp> struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>> : __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type> typename enable_if<__has_esft_base<_Yp2>::value>::type _M_enable_shared_from_this_with(_Yp* __p) noexcept { if (auto __base = __enable_shared_from_this_base(_M_refcount, __p)) __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount); } template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type> typename enable_if<!__has_esft_base<_Yp2>::value>::type _M_enable_shared_from_this_with(_Yp*) noexcept { } void* _M_get_deleter(const std::type_info& __ti) const noexcept { return _M_refcount._M_get_deleter(__ti); } template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; template<typename _Del, typename _Tp1, _Lock_policy _Lp1> friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; template<typename _Del, typename _Tp1> friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept; element_type* _M_ptr; // Contained pointer. __shared_count<_Lp> _M_refcount; // Reference counter. }; // 20.7.2.2.7 shared_ptr comparisons template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> inline bool operator==(const __shared_ptr<_Tp1, _Lp>& __a, const __shared_ptr<_Tp2, _Lp>& __b) noexcept { return __a.get() == __b.get(); } template<typename _Tp, _Lock_policy _Lp> inline bool operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept { return !__a; } template<typename _Tp, _Lock_policy _Lp> inline bool operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept { return !__a; } template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> inline bool operator!=(const __shared_ptr<_Tp1, _Lp>& __a, const __shared_ptr<_Tp2, _Lp>& __b) noexcept { return __a.get() != __b.get(); } template<typename _Tp, _Lock_policy _Lp> inline bool operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept { return (bool)__a; } template<typename _Tp, _Lock_policy _Lp> inline bool operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept { return (bool)__a; } template<typename _Tp, typename _Up, _Lock_policy _Lp> inline bool operator<(const __shared_ptr<_Tp, _Lp>& __a, const __shared_ptr<_Up, _Lp>& __b) noexcept { using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type; using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; return less<_Vp>()(__a.get(), __b.get()); } template<typename _Tp, _Lock_policy _Lp> inline bool operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept { using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; return less<_Tp_elt*>()(__a.get(), nullptr); } template<typename _Tp, _Lock_policy _Lp> inline bool operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept { using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; return less<_Tp_elt*>()(nullptr, __a.get()); } template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> inline bool operator<=(const __shared_ptr<_Tp1, _Lp>& __a, const __shared_ptr<_Tp2, _Lp>& __b) noexcept { return !(__b < __a); } template<typename _Tp, _Lock_policy _Lp> inline bool operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept { return !(nullptr < __a); } template<typename _Tp, _Lock_policy _Lp> inline bool operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept { return !(__a < nullptr); } template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> inline bool operator>(const __shared_ptr<_Tp1, _Lp>& __a, const __shared_ptr<_Tp2, _Lp>& __b) noexcept { return (__b < __a); } template<typename _Tp, _Lock_policy _Lp> inline bool operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept { return nullptr < __a; } template<typename _Tp, _Lock_policy _Lp> inline bool operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept { return __a < nullptr; } template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> inline bool operator>=(const __shared_ptr<_Tp1, _Lp>& __a, const __shared_ptr<_Tp2, _Lp>& __b) noexcept { return !(__a < __b); } template<typename _Tp, _Lock_policy _Lp> inline bool operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept { return !(__a < nullptr); } template<typename _Tp, _Lock_policy _Lp> inline bool operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept { return !(nullptr < __a); } template<typename _Sp> struct _Sp_less : public binary_function<_Sp, _Sp, bool> { bool operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept { typedef typename _Sp::element_type element_type; return std::less<element_type*>()(__lhs.get(), __rhs.get()); } }; template<typename _Tp, _Lock_policy _Lp> struct less<__shared_ptr<_Tp, _Lp>> : public _Sp_less<__shared_ptr<_Tp, _Lp>> { }; // 20.7.2.2.8 shared_ptr specialized algorithms. template<typename _Tp, _Lock_policy _Lp> inline void swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept { __a.swap(__b); } // 20.7.2.2.9 shared_ptr casts // The seemingly equivalent code: // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) // will eventually result in undefined behaviour, attempting to // delete the same object twice. /// static_pointer_cast template<typename _Tp, typename _Tp1, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept { using _Sp = __shared_ptr<_Tp, _Lp>; return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get())); } // The seemingly equivalent code: // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) // will eventually result in undefined behaviour, attempting to // delete the same object twice. /// const_pointer_cast template<typename _Tp, typename _Tp1, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept { using _Sp = __shared_ptr<_Tp, _Lp>; return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get())); } // The seemingly equivalent code: // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) // will eventually result in undefined behaviour, attempting to // delete the same object twice. /// dynamic_pointer_cast template<typename _Tp, typename _Tp1, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept { using _Sp = __shared_ptr<_Tp, _Lp>; if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get())) return _Sp(__r, __p); return _Sp(); } #if __cplusplus > 201402L template<typename _Tp, typename _Tp1, _Lock_policy _Lp> inline __shared_ptr<_Tp, _Lp> reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept { using _Sp = __shared_ptr<_Tp, _Lp>; return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get())); } #endif template<typename _Tp, _Lock_policy _Lp> class __weak_ptr { template<typename _Yp, typename _Res = void> using _Compatible = typename enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type; // Constraint for assignment from shared_ptr and weak_ptr: template<typename _Yp> using _Assignable = _Compatible<_Yp, __weak_ptr&>; public: using element_type = typename remove_extent<_Tp>::type; constexpr __weak_ptr() noexcept : _M_ptr(nullptr), _M_refcount() { } __weak_ptr(const __weak_ptr&) noexcept = default; ~__weak_ptr() = default; // The "obvious" converting constructor implementation: // // template<typename _Tp1> // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws // { } // // has a serious problem. // // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) // conversion may require access to *__r._M_ptr (virtual inheritance). // // It is not possible to avoid spurious access violations since // in multithreaded programs __r._M_ptr may be invalidated at any point. template<typename _Yp, typename = _Compatible<_Yp>> __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept : _M_refcount(__r._M_refcount) { _M_ptr = __r.lock().get(); } template<typename _Yp, typename = _Compatible<_Yp>> __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) { } __weak_ptr(__weak_ptr&& __r) noexcept : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount)) { __r._M_ptr = nullptr; } template<typename _Yp, typename = _Compatible<_Yp>> __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount)) { __r._M_ptr = nullptr; } __weak_ptr& operator=(const __weak_ptr& __r) noexcept = default; template<typename _Yp> _Assignable<_Yp> operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept { _M_ptr = __r.lock().get(); _M_refcount = __r._M_refcount; return *this; } template<typename _Yp> _Assignable<_Yp> operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept { _M_ptr = __r._M_ptr; _M_refcount = __r._M_refcount; return *this; } __weak_ptr& operator=(__weak_ptr&& __r) noexcept { _M_ptr = __r._M_ptr; _M_refcount = std::move(__r._M_refcount); __r._M_ptr = nullptr; return *this; } template<typename _Yp> _Assignable<_Yp> operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept { _M_ptr = __r.lock().get(); _M_refcount = std::move(__r._M_refcount); __r._M_ptr = nullptr; return *this; } __shared_ptr<_Tp, _Lp> lock() const noexcept { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); } long use_count() const noexcept { return _M_refcount._M_get_use_count(); } bool expired() const noexcept { return _M_refcount._M_get_use_count() == 0; } template<typename _Tp1> bool owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept { return _M_refcount._M_less(__rhs._M_refcount); } template<typename _Tp1> bool owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept { return _M_refcount._M_less(__rhs._M_refcount); } void reset() noexcept { __weak_ptr().swap(*this); } void swap(__weak_ptr& __s) noexcept { std::swap(_M_ptr, __s._M_ptr); _M_refcount._M_swap(__s._M_refcount); } private: // Used by __enable_shared_from_this. void _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept { if (use_count() == 0) { _M_ptr = __ptr; _M_refcount = __refcount; } } template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; friend class __enable_shared_from_this<_Tp, _Lp>; friend class enable_shared_from_this<_Tp>; element_type* _M_ptr; // Contained pointer. __weak_count<_Lp> _M_refcount; // Reference counter. }; // 20.7.2.3.6 weak_ptr specialized algorithms. template<typename _Tp, _Lock_policy _Lp> inline void swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept { __a.swap(__b); } template<typename _Tp, typename _Tp1> struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept { return __lhs.owner_before(__rhs); } bool operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept { return __lhs.owner_before(__rhs); } bool operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept { return __lhs.owner_before(__rhs); } }; template<> struct _Sp_owner_less<void, void> { template<typename _Tp, typename _Up> auto operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept -> decltype(__lhs.owner_before(__rhs)) { return __lhs.owner_before(__rhs); } using is_transparent = void; }; template<typename _Tp, _Lock_policy _Lp> struct owner_less<__shared_ptr<_Tp, _Lp>> : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>> { }; template<typename _Tp, _Lock_policy _Lp> struct owner_less<__weak_ptr<_Tp, _Lp>> : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>> { }; template<typename _Tp, _Lock_policy _Lp> class __enable_shared_from_this { protected: constexpr __enable_shared_from_this() noexcept { } __enable_shared_from_this(const __enable_shared_from_this&) noexcept { } __enable_shared_from_this& operator=(const __enable_shared_from_this&) noexcept { return *this; } ~__enable_shared_from_this() { } public: __shared_ptr<_Tp, _Lp> shared_from_this() { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } __shared_ptr<const _Tp, _Lp> shared_from_this() const { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 __weak_ptr<_Tp, _Lp> weak_from_this() noexcept { return this->_M_weak_this; } __weak_ptr<const _Tp, _Lp> weak_from_this() const noexcept { return this->_M_weak_this; } #endif private: template<typename _Tp1> void _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept { _M_weak_this._M_assign(__p, __n); } friend const __enable_shared_from_this* __enable_shared_from_this_base(const __shared_count<_Lp>&, const __enable_shared_from_this* __p) { return __p; } template<typename, _Lock_policy> friend class __shared_ptr; mutable __weak_ptr<_Tp, _Lp> _M_weak_this; }; template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args> inline __shared_ptr<_Tp, _Lp> __allocate_shared(const _Alloc& __a, _Args&&... __args) { static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported"); return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a}, std::forward<_Args>(__args)...); } template<typename _Tp, _Lock_policy _Lp, typename... _Args> inline __shared_ptr<_Tp, _Lp> __make_shared(_Args&&... __args) { typedef typename std::remove_const<_Tp>::type _Tp_nc; return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(), std::forward<_Args>(__args)...); } /// std::hash specialization for __shared_ptr. template<typename _Tp, _Lock_policy _Lp> struct hash<__shared_ptr<_Tp, _Lp>> : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>> { size_t operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept { return hash<typename __shared_ptr<_Tp, _Lp>::element_type*>()( __s.get()); } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _SHARED_PTR_BASE_H c++/8/bits/deque.tcc 0000644 00000102512 15146341150 0010023 0 ustar 00 // Deque implementation (out of line) -*- C++ -*- // Copyright (C) 2001-2018 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) 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/deque.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{deque} */ #ifndef _DEQUE_TCC #define _DEQUE_TCC 1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #if __cplusplus >= 201103L template <typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_default_initialize() { _Map_pointer __cur; __try { for (__cur = this->_M_impl._M_start._M_node; __cur < this->_M_impl._M_finish._M_node; ++__cur) std::__uninitialized_default_a(*__cur, *__cur + _S_buffer_size(), _M_get_Tp_allocator()); std::__uninitialized_default_a(this->_M_impl._M_finish._M_first, this->_M_impl._M_finish._M_cur, _M_get_Tp_allocator()); } __catch(...) { std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur), _M_get_Tp_allocator()); __throw_exception_again; } } #endif template <typename _Tp, typename _Alloc> deque<_Tp, _Alloc>& deque<_Tp, _Alloc>:: operator=(const deque& __x) { if (&__x != this) { #if __cplusplus >= 201103L if (_Alloc_traits::_S_propagate_on_copy_assign()) { if (!_Alloc_traits::_S_always_equal() && _M_get_Tp_allocator() != __x._M_get_Tp_allocator()) { // Replacement allocator cannot free existing storage, // so deallocate everything and take copy of __x's data. _M_replace_map(__x, __x.get_allocator()); std::__alloc_on_copy(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); return *this; } std::__alloc_on_copy(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); } #endif const size_type __len = size(); if (__len >= __x.size()) _M_erase_at_end(std::copy(__x.begin(), __x.end(), this->_M_impl._M_start)); else { const_iterator __mid = __x.begin() + difference_type(__len); std::copy(__x.begin(), __mid, this->_M_impl._M_start); _M_range_insert_aux(this->_M_impl._M_finish, __mid, __x.end(), std::random_access_iterator_tag()); } } return *this; } #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> template<typename... _Args> #if __cplusplus > 201402L typename deque<_Tp, _Alloc>::reference #else void #endif deque<_Tp, _Alloc>:: emplace_front(_Args&&... __args) { if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) { _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_start._M_cur - 1, std::forward<_Args>(__args)...); --this->_M_impl._M_start._M_cur; } else _M_push_front_aux(std::forward<_Args>(__args)...); #if __cplusplus > 201402L return front(); #endif } template<typename _Tp, typename _Alloc> template<typename... _Args> #if __cplusplus > 201402L typename deque<_Tp, _Alloc>::reference #else void #endif deque<_Tp, _Alloc>:: emplace_back(_Args&&... __args) { if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_last - 1) { _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish._M_cur, std::forward<_Args>(__args)...); ++this->_M_impl._M_finish._M_cur; } else _M_push_back_aux(std::forward<_Args>(__args)...); #if __cplusplus > 201402L return back(); #endif } #endif #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> template<typename... _Args> typename deque<_Tp, _Alloc>::iterator deque<_Tp, _Alloc>:: emplace(const_iterator __position, _Args&&... __args) { if (__position._M_cur == this->_M_impl._M_start._M_cur) { emplace_front(std::forward<_Args>(__args)...); return this->_M_impl._M_start; } else if (__position._M_cur == this->_M_impl._M_finish._M_cur) { emplace_back(std::forward<_Args>(__args)...); iterator __tmp = this->_M_impl._M_finish; --__tmp; return __tmp; } else return _M_insert_aux(__position._M_const_cast(), std::forward<_Args>(__args)...); } #endif template <typename _Tp, typename _Alloc> typename deque<_Tp, _Alloc>::iterator deque<_Tp, _Alloc>:: #if __cplusplus >= 201103L insert(const_iterator __position, const value_type& __x) #else insert(iterator __position, const value_type& __x) #endif { if (__position._M_cur == this->_M_impl._M_start._M_cur) { push_front(__x); return this->_M_impl._M_start; } else if (__position._M_cur == this->_M_impl._M_finish._M_cur) { push_back(__x); iterator __tmp = this->_M_impl._M_finish; --__tmp; return __tmp; } else return _M_insert_aux(__position._M_const_cast(), __x); } template <typename _Tp, typename _Alloc> typename deque<_Tp, _Alloc>::iterator deque<_Tp, _Alloc>:: _M_erase(iterator __position) { iterator __next = __position; ++__next; const difference_type __index = __position - begin(); if (static_cast<size_type>(__index) < (size() >> 1)) { if (__position != begin()) _GLIBCXX_MOVE_BACKWARD3(begin(), __position, __next); pop_front(); } else { if (__next != end()) _GLIBCXX_MOVE3(__next, end(), __position); pop_back(); } return begin() + __index; } template <typename _Tp, typename _Alloc> typename deque<_Tp, _Alloc>::iterator deque<_Tp, _Alloc>:: _M_erase(iterator __first, iterator __last) { if (__first == __last) return __first; else if (__first == begin() && __last == end()) { clear(); return end(); } else { const difference_type __n = __last - __first; const difference_type __elems_before = __first - begin(); if (static_cast<size_type>(__elems_before) <= (size() - __n) / 2) { if (__first != begin()) _GLIBCXX_MOVE_BACKWARD3(begin(), __first, __last); _M_erase_at_begin(begin() + __n); } else { if (__last != end()) _GLIBCXX_MOVE3(__last, end(), __first); _M_erase_at_end(end() - __n); } return begin() + __elems_before; } } template <typename _Tp, class _Alloc> template <typename _InputIterator> void deque<_Tp, _Alloc>:: _M_assign_aux(_InputIterator __first, _InputIterator __last, std::input_iterator_tag) { iterator __cur = begin(); for (; __first != __last && __cur != end(); ++__cur, ++__first) *__cur = *__first; if (__first == __last) _M_erase_at_end(__cur); else _M_range_insert_aux(end(), __first, __last, std::__iterator_category(__first)); } template <typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) { if (__pos._M_cur == this->_M_impl._M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); __try { std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start, __x, _M_get_Tp_allocator()); this->_M_impl._M_start = __new_start; } __catch(...) { _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); __throw_exception_again; } } else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) { iterator __new_finish = _M_reserve_elements_at_back(__n); __try { std::__uninitialized_fill_a(this->_M_impl._M_finish, __new_finish, __x, _M_get_Tp_allocator()); this->_M_impl._M_finish = __new_finish; } __catch(...) { _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, __new_finish._M_node + 1); __throw_exception_again; } } else _M_insert_aux(__pos, __n, __x); } #if __cplusplus >= 201103L template <typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_default_append(size_type __n) { if (__n) { iterator __new_finish = _M_reserve_elements_at_back(__n); __try { std::__uninitialized_default_a(this->_M_impl._M_finish, __new_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __new_finish; } __catch(...) { _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, __new_finish._M_node + 1); __throw_exception_again; } } } template <typename _Tp, typename _Alloc> bool deque<_Tp, _Alloc>:: _M_shrink_to_fit() { const difference_type __front_capacity = (this->_M_impl._M_start._M_cur - this->_M_impl._M_start._M_first); if (__front_capacity == 0) return false; const difference_type __back_capacity = (this->_M_impl._M_finish._M_last - this->_M_impl._M_finish._M_cur); if (__front_capacity + __back_capacity < _S_buffer_size()) return false; return std::__shrink_to_fit_aux<deque>::_S_do_it(*this); } #endif template <typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_fill_initialize(const value_type& __value) { _Map_pointer __cur; __try { for (__cur = this->_M_impl._M_start._M_node; __cur < this->_M_impl._M_finish._M_node; ++__cur) std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(), __value, _M_get_Tp_allocator()); std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first, this->_M_impl._M_finish._M_cur, __value, _M_get_Tp_allocator()); } __catch(...) { std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur), _M_get_Tp_allocator()); __throw_exception_again; } } template <typename _Tp, typename _Alloc> template <typename _InputIterator> void deque<_Tp, _Alloc>:: _M_range_initialize(_InputIterator __first, _InputIterator __last, std::input_iterator_tag) { this->_M_initialize_map(0); __try { for (; __first != __last; ++__first) #if __cplusplus >= 201103L emplace_back(*__first); #else push_back(*__first); #endif } __catch(...) { clear(); __throw_exception_again; } } template <typename _Tp, typename _Alloc> template <typename _ForwardIterator> void deque<_Tp, _Alloc>:: _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { const size_type __n = std::distance(__first, __last); this->_M_initialize_map(__n); _Map_pointer __cur_node; __try { for (__cur_node = this->_M_impl._M_start._M_node; __cur_node < this->_M_impl._M_finish._M_node; ++__cur_node) { _ForwardIterator __mid = __first; std::advance(__mid, _S_buffer_size()); std::__uninitialized_copy_a(__first, __mid, *__cur_node, _M_get_Tp_allocator()); __first = __mid; } std::__uninitialized_copy_a(__first, __last, this->_M_impl._M_finish._M_first, _M_get_Tp_allocator()); } __catch(...) { std::_Destroy(this->_M_impl._M_start, iterator(*__cur_node, __cur_node), _M_get_Tp_allocator()); __throw_exception_again; } } // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_last - 1. template<typename _Tp, typename _Alloc> #if __cplusplus >= 201103L template<typename... _Args> void deque<_Tp, _Alloc>:: _M_push_back_aux(_Args&&... __args) #else void deque<_Tp, _Alloc>:: _M_push_back_aux(const value_type& __t) #endif { _M_reserve_map_at_back(); *(this->_M_impl._M_finish._M_node + 1) = this->_M_allocate_node(); __try { #if __cplusplus >= 201103L _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish._M_cur, std::forward<_Args>(__args)...); #else this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __t); #endif this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node + 1); this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_first; } __catch(...) { _M_deallocate_node(*(this->_M_impl._M_finish._M_node + 1)); __throw_exception_again; } } // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_first. template<typename _Tp, typename _Alloc> #if __cplusplus >= 201103L template<typename... _Args> void deque<_Tp, _Alloc>:: _M_push_front_aux(_Args&&... __args) #else void deque<_Tp, _Alloc>:: _M_push_front_aux(const value_type& __t) #endif { _M_reserve_map_at_front(); *(this->_M_impl._M_start._M_node - 1) = this->_M_allocate_node(); __try { this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node - 1); this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_last - 1; #if __cplusplus >= 201103L _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_start._M_cur, std::forward<_Args>(__args)...); #else this->_M_impl.construct(this->_M_impl._M_start._M_cur, __t); #endif } __catch(...) { ++this->_M_impl._M_start; _M_deallocate_node(*(this->_M_impl._M_start._M_node - 1)); __throw_exception_again; } } // Called only if _M_impl._M_finish._M_cur == _M_impl._M_finish._M_first. template <typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_pop_back_aux() { _M_deallocate_node(this->_M_impl._M_finish._M_first); this->_M_impl._M_finish._M_set_node(this->_M_impl._M_finish._M_node - 1); this->_M_impl._M_finish._M_cur = this->_M_impl._M_finish._M_last - 1; _Alloc_traits::destroy(_M_get_Tp_allocator(), this->_M_impl._M_finish._M_cur); } // Called only if _M_impl._M_start._M_cur == _M_impl._M_start._M_last - 1. // Note that if the deque has at least one element (a precondition for this // member function), and if // _M_impl._M_start._M_cur == _M_impl._M_start._M_last, // then the deque must have at least two nodes. template <typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_pop_front_aux() { _Alloc_traits::destroy(_M_get_Tp_allocator(), this->_M_impl._M_start._M_cur); _M_deallocate_node(this->_M_impl._M_start._M_first); this->_M_impl._M_start._M_set_node(this->_M_impl._M_start._M_node + 1); this->_M_impl._M_start._M_cur = this->_M_impl._M_start._M_first; } template <typename _Tp, typename _Alloc> template <typename _InputIterator> void deque<_Tp, _Alloc>:: _M_range_insert_aux(iterator __pos, _InputIterator __first, _InputIterator __last, std::input_iterator_tag) { std::copy(__first, __last, std::inserter(*this, __pos)); } template <typename _Tp, typename _Alloc> template <typename _ForwardIterator> void deque<_Tp, _Alloc>:: _M_range_insert_aux(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { const size_type __n = std::distance(__first, __last); if (__pos._M_cur == this->_M_impl._M_start._M_cur) { iterator __new_start = _M_reserve_elements_at_front(__n); __try { std::__uninitialized_copy_a(__first, __last, __new_start, _M_get_Tp_allocator()); this->_M_impl._M_start = __new_start; } __catch(...) { _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); __throw_exception_again; } } else if (__pos._M_cur == this->_M_impl._M_finish._M_cur) { iterator __new_finish = _M_reserve_elements_at_back(__n); __try { std::__uninitialized_copy_a(__first, __last, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __new_finish; } __catch(...) { _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, __new_finish._M_node + 1); __throw_exception_again; } } else _M_insert_aux(__pos, __first, __last, __n); } template<typename _Tp, typename _Alloc> #if __cplusplus >= 201103L template<typename... _Args> typename deque<_Tp, _Alloc>::iterator deque<_Tp, _Alloc>:: _M_insert_aux(iterator __pos, _Args&&... __args) { value_type __x_copy(std::forward<_Args>(__args)...); // XXX copy #else typename deque<_Tp, _Alloc>::iterator deque<_Tp, _Alloc>:: _M_insert_aux(iterator __pos, const value_type& __x) { value_type __x_copy = __x; // XXX copy #endif difference_type __index = __pos - this->_M_impl._M_start; if (static_cast<size_type>(__index) < size() / 2) { push_front(_GLIBCXX_MOVE(front())); iterator __front1 = this->_M_impl._M_start; ++__front1; iterator __front2 = __front1; ++__front2; __pos = this->_M_impl._M_start + __index; iterator __pos1 = __pos; ++__pos1; _GLIBCXX_MOVE3(__front2, __pos1, __front1); } else { push_back(_GLIBCXX_MOVE(back())); iterator __back1 = this->_M_impl._M_finish; --__back1; iterator __back2 = __back1; --__back2; __pos = this->_M_impl._M_start + __index; _GLIBCXX_MOVE_BACKWARD3(__pos, __back2, __back1); } *__pos = _GLIBCXX_MOVE(__x_copy); return __pos; } template <typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_insert_aux(iterator __pos, size_type __n, const value_type& __x) { const difference_type __elems_before = __pos - this->_M_impl._M_start; const size_type __length = this->size(); value_type __x_copy = __x; if (__elems_before < difference_type(__length / 2)) { iterator __new_start = _M_reserve_elements_at_front(__n); iterator __old_start = this->_M_impl._M_start; __pos = this->_M_impl._M_start + __elems_before; __try { if (__elems_before >= difference_type(__n)) { iterator __start_n = (this->_M_impl._M_start + difference_type(__n)); std::__uninitialized_move_a(this->_M_impl._M_start, __start_n, __new_start, _M_get_Tp_allocator()); this->_M_impl._M_start = __new_start; _GLIBCXX_MOVE3(__start_n, __pos, __old_start); std::fill(__pos - difference_type(__n), __pos, __x_copy); } else { std::__uninitialized_move_fill(this->_M_impl._M_start, __pos, __new_start, this->_M_impl._M_start, __x_copy, _M_get_Tp_allocator()); this->_M_impl._M_start = __new_start; std::fill(__old_start, __pos, __x_copy); } } __catch(...) { _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); __throw_exception_again; } } else { iterator __new_finish = _M_reserve_elements_at_back(__n); iterator __old_finish = this->_M_impl._M_finish; const difference_type __elems_after = difference_type(__length) - __elems_before; __pos = this->_M_impl._M_finish - __elems_after; __try { if (__elems_after > difference_type(__n)) { iterator __finish_n = (this->_M_impl._M_finish - difference_type(__n)); std::__uninitialized_move_a(__finish_n, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __new_finish; _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); std::fill(__pos, __pos + difference_type(__n), __x_copy); } else { std::__uninitialized_fill_move(this->_M_impl._M_finish, __pos + difference_type(__n), __x_copy, __pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __new_finish; std::fill(__pos, __old_finish, __x_copy); } } __catch(...) { _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, __new_finish._M_node + 1); __throw_exception_again; } } } template <typename _Tp, typename _Alloc> template <typename _ForwardIterator> void deque<_Tp, _Alloc>:: _M_insert_aux(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, size_type __n) { const difference_type __elemsbefore = __pos - this->_M_impl._M_start; const size_type __length = size(); if (static_cast<size_type>(__elemsbefore) < __length / 2) { iterator __new_start = _M_reserve_elements_at_front(__n); iterator __old_start = this->_M_impl._M_start; __pos = this->_M_impl._M_start + __elemsbefore; __try { if (__elemsbefore >= difference_type(__n)) { iterator __start_n = (this->_M_impl._M_start + difference_type(__n)); std::__uninitialized_move_a(this->_M_impl._M_start, __start_n, __new_start, _M_get_Tp_allocator()); this->_M_impl._M_start = __new_start; _GLIBCXX_MOVE3(__start_n, __pos, __old_start); std::copy(__first, __last, __pos - difference_type(__n)); } else { _ForwardIterator __mid = __first; std::advance(__mid, difference_type(__n) - __elemsbefore); std::__uninitialized_move_copy(this->_M_impl._M_start, __pos, __first, __mid, __new_start, _M_get_Tp_allocator()); this->_M_impl._M_start = __new_start; std::copy(__mid, __last, __old_start); } } __catch(...) { _M_destroy_nodes(__new_start._M_node, this->_M_impl._M_start._M_node); __throw_exception_again; } } else { iterator __new_finish = _M_reserve_elements_at_back(__n); iterator __old_finish = this->_M_impl._M_finish; const difference_type __elemsafter = difference_type(__length) - __elemsbefore; __pos = this->_M_impl._M_finish - __elemsafter; __try { if (__elemsafter > difference_type(__n)) { iterator __finish_n = (this->_M_impl._M_finish - difference_type(__n)); std::__uninitialized_move_a(__finish_n, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __new_finish; _GLIBCXX_MOVE_BACKWARD3(__pos, __finish_n, __old_finish); std::copy(__first, __last, __pos); } else { _ForwardIterator __mid = __first; std::advance(__mid, __elemsafter); std::__uninitialized_copy_move(__mid, __last, __pos, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __new_finish; std::copy(__first, __mid, __pos); } } __catch(...) { _M_destroy_nodes(this->_M_impl._M_finish._M_node + 1, __new_finish._M_node + 1); __throw_exception_again; } } } template<typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_destroy_data_aux(iterator __first, iterator __last) { for (_Map_pointer __node = __first._M_node + 1; __node < __last._M_node; ++__node) std::_Destroy(*__node, *__node + _S_buffer_size(), _M_get_Tp_allocator()); if (__first._M_node != __last._M_node) { std::_Destroy(__first._M_cur, __first._M_last, _M_get_Tp_allocator()); std::_Destroy(__last._M_first, __last._M_cur, _M_get_Tp_allocator()); } else std::_Destroy(__first._M_cur, __last._M_cur, _M_get_Tp_allocator()); } template <typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_new_elements_at_front(size_type __new_elems) { if (this->max_size() - this->size() < __new_elems) __throw_length_error(__N("deque::_M_new_elements_at_front")); const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) / _S_buffer_size()); _M_reserve_map_at_front(__new_nodes); size_type __i; __try { for (__i = 1; __i <= __new_nodes; ++__i) *(this->_M_impl._M_start._M_node - __i) = this->_M_allocate_node(); } __catch(...) { for (size_type __j = 1; __j < __i; ++__j) _M_deallocate_node(*(this->_M_impl._M_start._M_node - __j)); __throw_exception_again; } } template <typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_new_elements_at_back(size_type __new_elems) { if (this->max_size() - this->size() < __new_elems) __throw_length_error(__N("deque::_M_new_elements_at_back")); const size_type __new_nodes = ((__new_elems + _S_buffer_size() - 1) / _S_buffer_size()); _M_reserve_map_at_back(__new_nodes); size_type __i; __try { for (__i = 1; __i <= __new_nodes; ++__i) *(this->_M_impl._M_finish._M_node + __i) = this->_M_allocate_node(); } __catch(...) { for (size_type __j = 1; __j < __i; ++__j) _M_deallocate_node(*(this->_M_impl._M_finish._M_node + __j)); __throw_exception_again; } } template <typename _Tp, typename _Alloc> void deque<_Tp, _Alloc>:: _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front) { const size_type __old_num_nodes = this->_M_impl._M_finish._M_node - this->_M_impl._M_start._M_node + 1; const size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; _Map_pointer __new_nstart; if (this->_M_impl._M_map_size > 2 * __new_num_nodes) { __new_nstart = this->_M_impl._M_map + (this->_M_impl._M_map_size - __new_num_nodes) / 2 + (__add_at_front ? __nodes_to_add : 0); if (__new_nstart < this->_M_impl._M_start._M_node) std::copy(this->_M_impl._M_start._M_node, this->_M_impl._M_finish._M_node + 1, __new_nstart); else std::copy_backward(this->_M_impl._M_start._M_node, this->_M_impl._M_finish._M_node + 1, __new_nstart + __old_num_nodes); } else { size_type __new_map_size = this->_M_impl._M_map_size + std::max(this->_M_impl._M_map_size, __nodes_to_add) + 2; _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + (__add_at_front ? __nodes_to_add : 0); std::copy(this->_M_impl._M_start._M_node, this->_M_impl._M_finish._M_node + 1, __new_nstart); _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); this->_M_impl._M_map = __new_map; this->_M_impl._M_map_size = __new_map_size; } this->_M_impl._M_start._M_set_node(__new_nstart); this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); } // Overload for deque::iterators, exploiting the "segmented-iterator // optimization". template<typename _Tp> void fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first, const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value) { typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; for (typename _Self::_Map_pointer __node = __first._M_node + 1; __node < __last._M_node; ++__node) std::fill(*__node, *__node + _Self::_S_buffer_size(), __value); if (__first._M_node != __last._M_node) { std::fill(__first._M_cur, __first._M_last, __value); std::fill(__last._M_first, __last._M_cur, __value); } else std::fill(__first._M_cur, __last._M_cur, __value); } template<typename _Tp> _Deque_iterator<_Tp, _Tp&, _Tp*> copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, _Deque_iterator<_Tp, _Tp&, _Tp*> __result) { typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; typedef typename _Self::difference_type difference_type; difference_type __len = __last - __first; while (__len > 0) { const difference_type __clen = std::min(__len, std::min(__first._M_last - __first._M_cur, __result._M_last - __result._M_cur)); std::copy(__first._M_cur, __first._M_cur + __clen, __result._M_cur); __first += __clen; __result += __clen; __len -= __clen; } return __result; } template<typename _Tp> _Deque_iterator<_Tp, _Tp&, _Tp*> copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, _Deque_iterator<_Tp, _Tp&, _Tp*> __result) { typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; typedef typename _Self::difference_type difference_type; difference_type __len = __last - __first; while (__len > 0) { difference_type __llen = __last._M_cur - __last._M_first; _Tp* __lend = __last._M_cur; difference_type __rlen = __result._M_cur - __result._M_first; _Tp* __rend = __result._M_cur; if (!__llen) { __llen = _Self::_S_buffer_size(); __lend = *(__last._M_node - 1) + __llen; } if (!__rlen) { __rlen = _Self::_S_buffer_size(); __rend = *(__result._M_node - 1) + __rlen; } const difference_type __clen = std::min(__len, std::min(__llen, __rlen)); std::copy_backward(__lend - __clen, __lend, __rend); __last -= __clen; __result -= __clen; __len -= __clen; } return __result; } #if __cplusplus >= 201103L template<typename _Tp> _Deque_iterator<_Tp, _Tp&, _Tp*> move(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, _Deque_iterator<_Tp, _Tp&, _Tp*> __result) { typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; typedef typename _Self::difference_type difference_type; difference_type __len = __last - __first; while (__len > 0) { const difference_type __clen = std::min(__len, std::min(__first._M_last - __first._M_cur, __result._M_last - __result._M_cur)); std::move(__first._M_cur, __first._M_cur + __clen, __result._M_cur); __first += __clen; __result += __clen; __len -= __clen; } return __result; } template<typename _Tp> _Deque_iterator<_Tp, _Tp&, _Tp*> move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, _Deque_iterator<_Tp, _Tp&, _Tp*> __result) { typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; typedef typename _Self::difference_type difference_type; difference_type __len = __last - __first; while (__len > 0) { difference_type __llen = __last._M_cur - __last._M_first; _Tp* __lend = __last._M_cur; difference_type __rlen = __result._M_cur - __result._M_first; _Tp* __rend = __result._M_cur; if (!__llen) { __llen = _Self::_S_buffer_size(); __lend = *(__last._M_node - 1) + __llen; } if (!__rlen) { __rlen = _Self::_S_buffer_size(); __rend = *(__result._M_node - 1) + __rlen; } const difference_type __clen = std::min(__len, std::min(__llen, __rlen)); std::move_backward(__lend - __clen, __lend, __rend); __last -= __clen; __result -= __clen; __len -= __clen; } return __result; } #endif _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/stl_set.h 0000644 00000106435 15146341150 0010063 0 ustar 00 // Set implementation -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_set.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{set} */ #ifndef _STL_SET_H #define _STL_SET_H 1 #include <bits/concept_check.h> #if __cplusplus >= 201103L #include <initializer_list> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Key, typename _Compare, typename _Alloc> class multiset; /** * @brief A standard container made up of unique keys, which can be * retrieved in logarithmic time. * * @ingroup associative_containers * * @tparam _Key Type of key objects. * @tparam _Compare Comparison function object type, defaults to less<_Key>. * @tparam _Alloc Allocator type, defaults to allocator<_Key>. * * Meets the requirements of a <a href="tables.html#65">container</a>, a * <a href="tables.html#66">reversible container</a>, and an * <a href="tables.html#69">associative container</a> (using unique keys). * * Sets support bidirectional iterators. * * The private tree data is declared exactly the same way for set and * multiset; the distinction is made entirely in how the tree functions are * called (*_unique versus *_equal, same as the standard). */ template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key> > class set { #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename _Alloc::value_type _Alloc_value_type; # if __cplusplus < 201103L __glibcxx_class_requires(_Key, _SGIAssignableConcept) # endif __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept) #endif #if __cplusplus >= 201103L static_assert(is_same<typename remove_cv<_Key>::type, _Key>::value, "std::set must have a non-const, non-volatile value_type"); # ifdef __STRICT_ANSI__ static_assert(is_same<typename _Alloc::value_type, _Key>::value, "std::set must have the same value_type as its allocator"); # endif #endif public: // typedefs: //@{ /// Public typedefs. typedef _Key key_type; typedef _Key value_type; typedef _Compare key_compare; typedef _Compare value_compare; typedef _Alloc allocator_type; //@} private: typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Key>::other _Key_alloc_type; typedef _Rb_tree<key_type, value_type, _Identity<value_type>, key_compare, _Key_alloc_type> _Rep_type; _Rep_type _M_t; // Red-black tree representing set. typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits; public: //@{ /// Iterator-related typedefs. 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; // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 103. set::iterator is required to be modifiable, // but this allows modification of keys. typedef typename _Rep_type::const_iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; typedef typename _Rep_type::const_reverse_iterator reverse_iterator; typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; typedef typename _Rep_type::size_type size_type; typedef typename _Rep_type::difference_type difference_type; //@} #if __cplusplus > 201402L using node_type = typename _Rep_type::node_type; using insert_return_type = typename _Rep_type::insert_return_type; #endif // allocation/deallocation /** * @brief Default constructor creates no elements. */ #if __cplusplus < 201103L set() : _M_t() { } #else set() = default; #endif /** * @brief Creates a %set with no elements. * @param __comp Comparator to use. * @param __a An allocator object. */ explicit set(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Key_alloc_type(__a)) { } /** * @brief Builds a %set from a range. * @param __first An input iterator. * @param __last An input iterator. * * Create a %set consisting of copies of the elements from * [__first,__last). This is linear in N if the range is * already sorted, and NlogN otherwise (where N is * distance(__first,__last)). */ template<typename _InputIterator> set(_InputIterator __first, _InputIterator __last) : _M_t() { _M_t._M_insert_unique(__first, __last); } /** * @brief Builds a %set from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __comp A comparison functor. * @param __a An allocator object. * * Create a %set consisting of copies of the elements from * [__first,__last). This is linear in N if the range is * already sorted, and NlogN otherwise (where N is * distance(__first,__last)). */ template<typename _InputIterator> set(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Key_alloc_type(__a)) { _M_t._M_insert_unique(__first, __last); } /** * @brief %Set copy constructor. * * Whether the allocator is copied depends on the allocator traits. */ #if __cplusplus < 201103L set(const set& __x) : _M_t(__x._M_t) { } #else set(const set&) = default; /** * @brief %Set move constructor * * The newly-created %set contains the exact contents of the moved * instance. The moved instance is a valid, but unspecified, %set. */ set(set&&) = default; /** * @brief Builds a %set from an initializer_list. * @param __l An initializer_list. * @param __comp A comparison functor. * @param __a An allocator object. * * Create a %set consisting of copies of the elements in the list. * This is linear in N if the list is already sorted, and NlogN * otherwise (where N is @a __l.size()). */ set(initializer_list<value_type> __l, const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _M_t(__comp, _Key_alloc_type(__a)) { _M_t._M_insert_unique(__l.begin(), __l.end()); } /// Allocator-extended default constructor. explicit set(const allocator_type& __a) : _M_t(_Compare(), _Key_alloc_type(__a)) { } /// Allocator-extended copy constructor. set(const set& __x, const allocator_type& __a) : _M_t(__x._M_t, _Key_alloc_type(__a)) { } /// Allocator-extended move constructor. set(set&& __x, const allocator_type& __a) noexcept(is_nothrow_copy_constructible<_Compare>::value && _Alloc_traits::_S_always_equal()) : _M_t(std::move(__x._M_t), _Key_alloc_type(__a)) { } /// Allocator-extended initialier-list constructor. set(initializer_list<value_type> __l, const allocator_type& __a) : _M_t(_Compare(), _Key_alloc_type(__a)) { _M_t._M_insert_unique(__l.begin(), __l.end()); } /// Allocator-extended range constructor. template<typename _InputIterator> set(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : _M_t(_Compare(), _Key_alloc_type(__a)) { _M_t._M_insert_unique(__first, __last); } /** * The dtor only erases the elements, and note that if the elements * themselves are pointers, the pointed-to memory is not touched in any * way. Managing the pointer is the user's responsibility. */ ~set() = default; #endif /** * @brief %Set assignment operator. * * Whether the allocator is copied depends on the allocator traits. */ #if __cplusplus < 201103L set& operator=(const set& __x) { _M_t = __x._M_t; return *this; } #else set& operator=(const set&) = default; /// Move assignment operator. set& operator=(set&&) = default; /** * @brief %Set list assignment operator. * @param __l An initializer_list. * * This function fills a %set with copies of the elements in the * initializer list @a __l. * * Note that the assignment completely changes the %set and * that the resulting %set's size is the same as the number * of elements assigned. */ set& operator=(initializer_list<value_type> __l) { _M_t._M_assign_unique(__l.begin(), __l.end()); return *this; } #endif // accessors: /// Returns the comparison object with which the %set was constructed. key_compare key_comp() const { return _M_t.key_comp(); } /// Returns the comparison object with which the %set was constructed. value_compare value_comp() const { return _M_t.key_comp(); } /// Returns the allocator object with which the %set was constructed. allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_t.get_allocator()); } /** * Returns a read-only (constant) iterator that points to the first * element in the %set. Iteration is done in ascending order according * to the keys. */ iterator begin() const _GLIBCXX_NOEXCEPT { return _M_t.begin(); } /** * Returns a read-only (constant) iterator that points one past the last * element in the %set. Iteration is done in ascending order according * to the keys. */ iterator end() const _GLIBCXX_NOEXCEPT { return _M_t.end(); } /** * Returns a read-only (constant) iterator that points to the last * element in the %set. Iteration is done in descending order according * to the keys. */ reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return _M_t.rbegin(); } /** * Returns a read-only (constant) reverse iterator that points to the * last pair in the %set. Iteration is done in descending order * according to the keys. */ reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return _M_t.rend(); } #if __cplusplus >= 201103L /** * Returns a read-only (constant) iterator that points to the first * element in the %set. Iteration is done in ascending order according * to the keys. */ iterator cbegin() const noexcept { return _M_t.begin(); } /** * Returns a read-only (constant) iterator that points one past the last * element in the %set. Iteration is done in ascending order according * to the keys. */ iterator cend() const noexcept { return _M_t.end(); } /** * Returns a read-only (constant) iterator that points to the last * element in the %set. Iteration is done in descending order according * to the keys. */ reverse_iterator crbegin() const noexcept { return _M_t.rbegin(); } /** * Returns a read-only (constant) reverse iterator that points to the * last pair in the %set. Iteration is done in descending order * according to the keys. */ reverse_iterator crend() const noexcept { return _M_t.rend(); } #endif /// Returns true if the %set is empty. bool empty() const _GLIBCXX_NOEXCEPT { return _M_t.empty(); } /// Returns the size of the %set. size_type size() const _GLIBCXX_NOEXCEPT { return _M_t.size(); } /// Returns the maximum size of the %set. size_type max_size() const _GLIBCXX_NOEXCEPT { return _M_t.max_size(); } /** * @brief Swaps data with another %set. * @param __x A %set of the same element and allocator types. * * This exchanges the elements between two sets in constant * time. (It is only swapping a pointer, an integer, and an * instance of the @c Compare type (which itself is often * stateless and empty), so it should be quite fast.) Note * that the global std::swap() function is specialized such * that std::swap(s1,s2) will feed to this function. * * Whether the allocators are swapped depends on the allocator traits. */ void swap(set& __x) _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value) { _M_t.swap(__x._M_t); } // insert/erase #if __cplusplus >= 201103L /** * @brief Attempts to build and insert an element into the %set. * @param __args Arguments used to generate an element. * @return A pair, of which the first element is an iterator that points * to the possibly inserted element, and the second is a bool * that is true if the element was actually inserted. * * This function attempts to build and insert an element into the %set. * A %set relies on unique keys and thus an element is only inserted if * it is not already present in the %set. * * Insertion requires logarithmic time. */ template<typename... _Args> std::pair<iterator, bool> emplace(_Args&&... __args) { return _M_t._M_emplace_unique(std::forward<_Args>(__args)...); } /** * @brief Attempts to insert an element into the %set. * @param __pos An iterator that serves as a hint as to where the * element should be inserted. * @param __args Arguments used to generate the element to be * inserted. * @return An iterator that points to the element with key equivalent to * the one generated from @a __args (may or may not be the * element itself). * * This function is not concerned about whether the insertion took place, * and thus does not return a boolean like the single-argument emplace() * does. Note that the first parameter is only a hint and can * potentially improve the performance of the insertion process. A bad * hint would cause no gains in efficiency. * * For more on @a hinting, see: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * * Insertion requires logarithmic time (if the hint is not taken). */ template<typename... _Args> iterator emplace_hint(const_iterator __pos, _Args&&... __args) { return _M_t._M_emplace_hint_unique(__pos, std::forward<_Args>(__args)...); } #endif /** * @brief Attempts to insert an element into the %set. * @param __x Element to be inserted. * @return A pair, of which the first element is an iterator that points * to the possibly inserted element, and the second is a bool * that is true if the element was actually inserted. * * This function attempts to insert an element into the %set. A %set * relies on unique keys and thus an element is only inserted if it is * not already present in the %set. * * Insertion requires logarithmic time. */ std::pair<iterator, bool> insert(const value_type& __x) { std::pair<typename _Rep_type::iterator, bool> __p = _M_t._M_insert_unique(__x); return std::pair<iterator, bool>(__p.first, __p.second); } #if __cplusplus >= 201103L std::pair<iterator, bool> insert(value_type&& __x) { std::pair<typename _Rep_type::iterator, bool> __p = _M_t._M_insert_unique(std::move(__x)); return std::pair<iterator, bool>(__p.first, __p.second); } #endif /** * @brief Attempts to insert an element into the %set. * @param __position An iterator that serves as a hint as to where the * element should be inserted. * @param __x Element to be inserted. * @return An iterator that points to the element with key of * @a __x (may or may not be the element passed in). * * This function is not concerned about whether the insertion took place, * and thus does not return a boolean like the single-argument insert() * does. Note that the first parameter is only a hint and can * potentially improve the performance of the insertion process. A bad * hint would cause no gains in efficiency. * * For more on @a hinting, see: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * * Insertion requires logarithmic time (if the hint is not taken). */ iterator insert(const_iterator __position, const value_type& __x) { return _M_t._M_insert_unique_(__position, __x); } #if __cplusplus >= 201103L iterator insert(const_iterator __position, value_type&& __x) { return _M_t._M_insert_unique_(__position, std::move(__x)); } #endif /** * @brief A template function that attempts to insert a range * of elements. * @param __first Iterator pointing to the start of the range to be * inserted. * @param __last Iterator pointing to the end of the range. * * Complexity similar to that of the range constructor. */ template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_t._M_insert_unique(__first, __last); } #if __cplusplus >= 201103L /** * @brief Attempts to insert a list of elements into the %set. * @param __l A std::initializer_list<value_type> of elements * to be inserted. * * Complexity similar to that of the range constructor. */ void insert(initializer_list<value_type> __l) { this->insert(__l.begin(), __l.end()); } #endif #if __cplusplus > 201402L /// Extract a node. node_type extract(const_iterator __pos) { __glibcxx_assert(__pos != end()); return _M_t.extract(__pos); } /// Extract a node. node_type extract(const key_type& __x) { return _M_t.extract(__x); } /// Re-insert an extracted node. insert_return_type insert(node_type&& __nh) { return _M_t._M_reinsert_node_unique(std::move(__nh)); } /// Re-insert an extracted node. iterator insert(const_iterator __hint, node_type&& __nh) { return _M_t._M_reinsert_node_hint_unique(__hint, std::move(__nh)); } template<typename, typename> friend class std::_Rb_tree_merge_helper; template<typename _Compare1> void merge(set<_Key, _Compare1, _Alloc>& __source) { using _Merge_helper = _Rb_tree_merge_helper<set, _Compare1>; _M_t._M_merge_unique(_Merge_helper::_S_get_tree(__source)); } template<typename _Compare1> void merge(set<_Key, _Compare1, _Alloc>&& __source) { merge(__source); } template<typename _Compare1> void merge(multiset<_Key, _Compare1, _Alloc>& __source) { using _Merge_helper = _Rb_tree_merge_helper<set, _Compare1>; _M_t._M_merge_unique(_Merge_helper::_S_get_tree(__source)); } template<typename _Compare1> void merge(multiset<_Key, _Compare1, _Alloc>&& __source) { merge(__source); } #endif // C++17 #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. /** * @brief Erases an element from a %set. * @param __position An iterator pointing to the element to be erased. * @return An iterator pointing to the element immediately following * @a __position prior to the element being erased. If no such * element exists, end() is returned. * * This function erases an element, pointed to by the given iterator, * from a %set. Note that this function only erases the element, and * that if the element is itself a pointer, the pointed-to memory is not * touched in any way. Managing the pointer is the user's * responsibility. */ _GLIBCXX_ABI_TAG_CXX11 iterator erase(const_iterator __position) { return _M_t.erase(__position); } #else /** * @brief Erases an element from a %set. * @param position An iterator pointing to the element to be erased. * * This function erases an element, pointed to by the given iterator, * from a %set. Note that this function only erases the element, and * that if the element is itself a pointer, the pointed-to memory is not * touched in any way. Managing the pointer is the user's * responsibility. */ void erase(iterator __position) { _M_t.erase(__position); } #endif /** * @brief Erases elements according to the provided key. * @param __x Key of element to be erased. * @return The number of elements erased. * * This function erases all the elements located by the given key from * a %set. * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ size_type erase(const key_type& __x) { return _M_t.erase(__x); } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. /** * @brief Erases a [__first,__last) range of elements from a %set. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to * be erased. * @return The iterator @a __last. * * This function erases a sequence of elements from a %set. * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ _GLIBCXX_ABI_TAG_CXX11 iterator erase(const_iterator __first, const_iterator __last) { return _M_t.erase(__first, __last); } #else /** * @brief Erases a [first,last) range of elements from a %set. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to * be erased. * * This function erases a sequence of elements from a %set. * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ void erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } #endif /** * Erases all elements in a %set. Note that this function only erases * the elements, and that if the elements themselves are pointers, the * pointed-to memory is not touched in any way. Managing the pointer is * the user's responsibility. */ void clear() _GLIBCXX_NOEXCEPT { _M_t.clear(); } // set operations: //@{ /** * @brief Finds the number of elements. * @param __x Element to located. * @return Number of elements with specified key. * * This function only makes sense for multisets; for set the result will * either be 0 (not present) or 1 (present). */ size_type count(const key_type& __x) const { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } #if __cplusplus > 201103L template<typename _Kt> auto count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x)) { return _M_t._M_count_tr(__x); } #endif //@} // _GLIBCXX_RESOLVE_LIB_DEFECTS // 214. set::find() missing const overload //@{ /** * @brief Tries to locate an element in a %set. * @param __x Element to be located. * @return Iterator pointing to sought-after element, or end() if not * found. * * This function takes a key and tries to locate the element with which * the key matches. If successful the function returns an iterator * pointing to the sought after element. If unsuccessful it returns the * past-the-end ( @c end() ) iterator. */ iterator find(const key_type& __x) { return _M_t.find(__x); } const_iterator find(const key_type& __x) const { return _M_t.find(__x); } #if __cplusplus > 201103L template<typename _Kt> auto find(const _Kt& __x) -> decltype(iterator{_M_t._M_find_tr(__x)}) { return iterator{_M_t._M_find_tr(__x)}; } template<typename _Kt> auto find(const _Kt& __x) const -> decltype(const_iterator{_M_t._M_find_tr(__x)}) { return const_iterator{_M_t._M_find_tr(__x)}; } #endif //@} //@{ /** * @brief Finds the beginning of a subsequence matching given key. * @param __x Key to be located. * @return Iterator pointing to first element equal to or greater * than key, or end(). * * This function returns the first element of a subsequence of elements * that matches the given key. If unsuccessful it returns an iterator * pointing to the first element that has a greater value than given key * or end() if no such element exists. */ iterator lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); } const_iterator lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto lower_bound(const _Kt& __x) -> decltype(iterator(_M_t._M_lower_bound_tr(__x))) { return iterator(_M_t._M_lower_bound_tr(__x)); } template<typename _Kt> auto lower_bound(const _Kt& __x) const -> decltype(const_iterator(_M_t._M_lower_bound_tr(__x))) { return const_iterator(_M_t._M_lower_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds the end of a subsequence matching given key. * @param __x Key to be located. * @return Iterator pointing to the first element * greater than key, or end(). */ iterator upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); } const_iterator upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto upper_bound(const _Kt& __x) -> decltype(iterator(_M_t._M_upper_bound_tr(__x))) { return iterator(_M_t._M_upper_bound_tr(__x)); } template<typename _Kt> auto upper_bound(const _Kt& __x) const -> decltype(iterator(_M_t._M_upper_bound_tr(__x))) { return const_iterator(_M_t._M_upper_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds a subsequence matching given key. * @param __x Key to be located. * @return Pair of iterators that possibly points to the subsequence * matching given key. * * This function is equivalent to * @code * std::make_pair(c.lower_bound(val), * c.upper_bound(val)) * @endcode * (but is faster than making the calls separately). * * This function probably only makes sense for multisets. */ std::pair<iterator, iterator> equal_range(const key_type& __x) { return _M_t.equal_range(__x); } std::pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } #if __cplusplus > 201103L template<typename _Kt> auto equal_range(const _Kt& __x) -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x))) { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); } template<typename _Kt> auto equal_range(const _Kt& __x) const -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x))) { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); } #endif //@} template<typename _K1, typename _C1, typename _A1> friend bool operator==(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); template<typename _K1, typename _C1, typename _A1> friend bool operator<(const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&); }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _Compare = less<typename iterator_traits<_InputIterator>::value_type>, typename _Allocator = allocator<typename iterator_traits<_InputIterator>::value_type>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) -> set<typename iterator_traits<_InputIterator>::value_type, _Compare, _Allocator>; template<typename _Key, typename _Compare = less<_Key>, typename _Allocator = allocator<_Key>, typename = _RequireAllocator<_Allocator>> set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) -> set<_Key, _Compare, _Allocator>; template<typename _InputIterator, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> set(_InputIterator, _InputIterator, _Allocator) -> set<typename iterator_traits<_InputIterator>::value_type, less<typename iterator_traits<_InputIterator>::value_type>, _Allocator>; template<typename _Key, typename _Allocator, typename = _RequireAllocator<_Allocator>> set(initializer_list<_Key>, _Allocator) -> set<_Key, less<_Key>, _Allocator>; #endif /** * @brief Set equality comparison. * @param __x A %set. * @param __y A %set of the same type as @a x. * @return True iff the size and elements of the sets are equal. * * This is an equivalence relation. It is linear in the size of the sets. * Sets are considered equivalent if their sizes are equal, and if * corresponding elements compare equal. */ template<typename _Key, typename _Compare, typename _Alloc> inline bool operator==(const set<_Key, _Compare, _Alloc>& __x, const set<_Key, _Compare, _Alloc>& __y) { return __x._M_t == __y._M_t; } /** * @brief Set ordering relation. * @param __x A %set. * @param __y A %set of the same type as @a x. * @return True iff @a __x is lexicographically less than @a __y. * * This is a total ordering relation. It is linear in the size of the * sets. The elements must be comparable with @c <. * * See std::lexicographical_compare() for how the determination is made. */ template<typename _Key, typename _Compare, typename _Alloc> inline bool operator<(const set<_Key, _Compare, _Alloc>& __x, const set<_Key, _Compare, _Alloc>& __y) { return __x._M_t < __y._M_t; } /// Returns !(x == y). template<typename _Key, typename _Compare, typename _Alloc> inline bool operator!=(const set<_Key, _Compare, _Alloc>& __x, const set<_Key, _Compare, _Alloc>& __y) { return !(__x == __y); } /// Returns y < x. template<typename _Key, typename _Compare, typename _Alloc> inline bool operator>(const set<_Key, _Compare, _Alloc>& __x, const set<_Key, _Compare, _Alloc>& __y) { return __y < __x; } /// Returns !(y < x) template<typename _Key, typename _Compare, typename _Alloc> inline bool operator<=(const set<_Key, _Compare, _Alloc>& __x, const set<_Key, _Compare, _Alloc>& __y) { return !(__y < __x); } /// Returns !(x < y) template<typename _Key, typename _Compare, typename _Alloc> inline bool operator>=(const set<_Key, _Compare, _Alloc>& __x, const set<_Key, _Compare, _Alloc>& __y) { return !(__x < __y); } /// See std::set::swap(). template<typename _Key, typename _Compare, typename _Alloc> inline void swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER #if __cplusplus > 201402L // Allow std::set access to internals of compatible sets. template<typename _Val, typename _Cmp1, typename _Alloc, typename _Cmp2> struct _Rb_tree_merge_helper<_GLIBCXX_STD_C::set<_Val, _Cmp1, _Alloc>, _Cmp2> { private: friend class _GLIBCXX_STD_C::set<_Val, _Cmp1, _Alloc>; static auto& _S_get_tree(_GLIBCXX_STD_C::set<_Val, _Cmp2, _Alloc>& __set) { return __set._M_t; } static auto& _S_get_tree(_GLIBCXX_STD_C::multiset<_Val, _Cmp2, _Alloc>& __set) { return __set._M_t; } }; #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } //namespace std #endif /* _STL_SET_H */ c++/8/bits/fs_fwd.h 0000644 00000024047 15146341150 0007654 0 ustar 00 // Filesystem declarations -*- C++ -*- // Copyright (C) 2014-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file include/bits/fs_fwd.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{filesystem} */ #ifndef _GLIBCXX_FS_FWD_H #define _GLIBCXX_FS_FWD_H 1 #if __cplusplus >= 201703L #include <system_error> #include <cstdint> #include <chrono> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace filesystem { #if _GLIBCXX_USE_CXX11_ABI inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } #endif /** * @defgroup filesystem Filesystem * * Utilities for performing operations on file systems and their components, * such as paths, regular files, and directories. * * @{ */ class file_status; _GLIBCXX_BEGIN_NAMESPACE_CXX11 class path; class filesystem_error; class directory_entry; class directory_iterator; class recursive_directory_iterator; _GLIBCXX_END_NAMESPACE_CXX11 struct space_info { uintmax_t capacity; uintmax_t free; uintmax_t available; }; enum class file_type : signed char { none = 0, not_found = -1, regular = 1, directory = 2, symlink = 3, block = 4, character = 5, fifo = 6, socket = 7, unknown = 8 }; /// Bitmask type enum class copy_options : unsigned short { none = 0, skip_existing = 1, overwrite_existing = 2, update_existing = 4, recursive = 8, copy_symlinks = 16, skip_symlinks = 32, directories_only = 64, create_symlinks = 128, create_hard_links = 256 }; constexpr copy_options operator&(copy_options __x, copy_options __y) noexcept { using __utype = typename std::underlying_type<copy_options>::type; return static_cast<copy_options>( static_cast<__utype>(__x) & static_cast<__utype>(__y)); } constexpr copy_options operator|(copy_options __x, copy_options __y) noexcept { using __utype = typename std::underlying_type<copy_options>::type; return static_cast<copy_options>( static_cast<__utype>(__x) | static_cast<__utype>(__y)); } constexpr copy_options operator^(copy_options __x, copy_options __y) noexcept { using __utype = typename std::underlying_type<copy_options>::type; return static_cast<copy_options>( static_cast<__utype>(__x) ^ static_cast<__utype>(__y)); } constexpr copy_options operator~(copy_options __x) noexcept { using __utype = typename std::underlying_type<copy_options>::type; return static_cast<copy_options>(~static_cast<__utype>(__x)); } inline copy_options& operator&=(copy_options& __x, copy_options __y) noexcept { return __x = __x & __y; } inline copy_options& operator|=(copy_options& __x, copy_options __y) noexcept { return __x = __x | __y; } inline copy_options& operator^=(copy_options& __x, copy_options __y) noexcept { return __x = __x ^ __y; } /// Bitmask type enum class perms : unsigned { none = 0, owner_read = 0400, owner_write = 0200, owner_exec = 0100, owner_all = 0700, group_read = 040, group_write = 020, group_exec = 010, group_all = 070, others_read = 04, others_write = 02, others_exec = 01, others_all = 07, all = 0777, set_uid = 04000, set_gid = 02000, sticky_bit = 01000, mask = 07777, unknown = 0xFFFF, }; constexpr perms operator&(perms __x, perms __y) noexcept { using __utype = typename std::underlying_type<perms>::type; return static_cast<perms>( static_cast<__utype>(__x) & static_cast<__utype>(__y)); } constexpr perms operator|(perms __x, perms __y) noexcept { using __utype = typename std::underlying_type<perms>::type; return static_cast<perms>( static_cast<__utype>(__x) | static_cast<__utype>(__y)); } constexpr perms operator^(perms __x, perms __y) noexcept { using __utype = typename std::underlying_type<perms>::type; return static_cast<perms>( static_cast<__utype>(__x) ^ static_cast<__utype>(__y)); } constexpr perms operator~(perms __x) noexcept { using __utype = typename std::underlying_type<perms>::type; return static_cast<perms>(~static_cast<__utype>(__x)); } inline perms& operator&=(perms& __x, perms __y) noexcept { return __x = __x & __y; } inline perms& operator|=(perms& __x, perms __y) noexcept { return __x = __x | __y; } inline perms& operator^=(perms& __x, perms __y) noexcept { return __x = __x ^ __y; } /// Bitmask type enum class perm_options : unsigned { replace = 0x1, add = 0x2, remove = 0x4, nofollow = 0x8 }; constexpr perm_options operator&(perm_options __x, perm_options __y) noexcept { using __utype = typename std::underlying_type<perm_options>::type; return static_cast<perm_options>( static_cast<__utype>(__x) & static_cast<__utype>(__y)); } constexpr perm_options operator|(perm_options __x, perm_options __y) noexcept { using __utype = typename std::underlying_type<perm_options>::type; return static_cast<perm_options>( static_cast<__utype>(__x) | static_cast<__utype>(__y)); } constexpr perm_options operator^(perm_options __x, perm_options __y) noexcept { using __utype = typename std::underlying_type<perm_options>::type; return static_cast<perm_options>( static_cast<__utype>(__x) ^ static_cast<__utype>(__y)); } constexpr perm_options operator~(perm_options __x) noexcept { using __utype = typename std::underlying_type<perm_options>::type; return static_cast<perm_options>(~static_cast<__utype>(__x)); } inline perm_options& operator&=(perm_options& __x, perm_options __y) noexcept { return __x = __x & __y; } inline perm_options& operator|=(perm_options& __x, perm_options __y) noexcept { return __x = __x | __y; } inline perm_options& operator^=(perm_options& __x, perm_options __y) noexcept { return __x = __x ^ __y; } // Bitmask type enum class directory_options : unsigned char { none = 0, follow_directory_symlink = 1, skip_permission_denied = 2 }; constexpr directory_options operator&(directory_options __x, directory_options __y) noexcept { using __utype = typename std::underlying_type<directory_options>::type; return static_cast<directory_options>( static_cast<__utype>(__x) & static_cast<__utype>(__y)); } constexpr directory_options operator|(directory_options __x, directory_options __y) noexcept { using __utype = typename std::underlying_type<directory_options>::type; return static_cast<directory_options>( static_cast<__utype>(__x) | static_cast<__utype>(__y)); } constexpr directory_options operator^(directory_options __x, directory_options __y) noexcept { using __utype = typename std::underlying_type<directory_options>::type; return static_cast<directory_options>( static_cast<__utype>(__x) ^ static_cast<__utype>(__y)); } constexpr directory_options operator~(directory_options __x) noexcept { using __utype = typename std::underlying_type<directory_options>::type; return static_cast<directory_options>(~static_cast<__utype>(__x)); } inline directory_options& operator&=(directory_options& __x, directory_options __y) noexcept { return __x = __x & __y; } inline directory_options& operator|=(directory_options& __x, directory_options __y) noexcept { return __x = __x | __y; } inline directory_options& operator^=(directory_options& __x, directory_options __y) noexcept { return __x = __x ^ __y; } using file_time_type = std::chrono::system_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; // @} group filesystem } // namespace filesystem _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++17 #endif // _GLIBCXX_FS_FWD_H c++/8/bits/locale_facets_nonio.h 0000644 00000206564 15146341150 0012400 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 2007-2018 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/locale_facets_nonio.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.1 Locales // #ifndef _LOCALE_FACETS_NONIO_H #define _LOCALE_FACETS_NONIO_H 1 #pragma GCC system_header #include <ctime> // For struct tm namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Time format ordering data. * @ingroup locales * * This class provides an enum representing different orderings of * time: day, month, and year. */ class time_base { public: enum dateorder { no_order, dmy, mdy, ymd, ydm }; }; template<typename _CharT> struct __timepunct_cache : public locale::facet { // List of all known timezones, with GMT first. static const _CharT* _S_timezones[14]; const _CharT* _M_date_format; const _CharT* _M_date_era_format; const _CharT* _M_time_format; const _CharT* _M_time_era_format; const _CharT* _M_date_time_format; const _CharT* _M_date_time_era_format; const _CharT* _M_am; const _CharT* _M_pm; const _CharT* _M_am_pm_format; // Day names, starting with "C"'s Sunday. const _CharT* _M_day1; const _CharT* _M_day2; const _CharT* _M_day3; const _CharT* _M_day4; const _CharT* _M_day5; const _CharT* _M_day6; const _CharT* _M_day7; // Abbreviated day names, starting with "C"'s Sun. const _CharT* _M_aday1; const _CharT* _M_aday2; const _CharT* _M_aday3; const _CharT* _M_aday4; const _CharT* _M_aday5; const _CharT* _M_aday6; const _CharT* _M_aday7; // Month names, starting with "C"'s January. const _CharT* _M_month01; const _CharT* _M_month02; const _CharT* _M_month03; const _CharT* _M_month04; const _CharT* _M_month05; const _CharT* _M_month06; const _CharT* _M_month07; const _CharT* _M_month08; const _CharT* _M_month09; const _CharT* _M_month10; const _CharT* _M_month11; const _CharT* _M_month12; // Abbreviated month names, starting with "C"'s Jan. const _CharT* _M_amonth01; const _CharT* _M_amonth02; const _CharT* _M_amonth03; const _CharT* _M_amonth04; const _CharT* _M_amonth05; const _CharT* _M_amonth06; const _CharT* _M_amonth07; const _CharT* _M_amonth08; const _CharT* _M_amonth09; const _CharT* _M_amonth10; const _CharT* _M_amonth11; const _CharT* _M_amonth12; bool _M_allocated; __timepunct_cache(size_t __refs = 0) : facet(__refs), _M_date_format(0), _M_date_era_format(0), _M_time_format(0), _M_time_era_format(0), _M_date_time_format(0), _M_date_time_era_format(0), _M_am(0), _M_pm(0), _M_am_pm_format(0), _M_day1(0), _M_day2(0), _M_day3(0), _M_day4(0), _M_day5(0), _M_day6(0), _M_day7(0), _M_aday1(0), _M_aday2(0), _M_aday3(0), _M_aday4(0), _M_aday5(0), _M_aday6(0), _M_aday7(0), _M_month01(0), _M_month02(0), _M_month03(0), _M_month04(0), _M_month05(0), _M_month06(0), _M_month07(0), _M_month08(0), _M_month09(0), _M_month10(0), _M_month11(0), _M_month12(0), _M_amonth01(0), _M_amonth02(0), _M_amonth03(0), _M_amonth04(0), _M_amonth05(0), _M_amonth06(0), _M_amonth07(0), _M_amonth08(0), _M_amonth09(0), _M_amonth10(0), _M_amonth11(0), _M_amonth12(0), _M_allocated(false) { } ~__timepunct_cache(); private: __timepunct_cache& operator=(const __timepunct_cache&); explicit __timepunct_cache(const __timepunct_cache&); }; template<typename _CharT> __timepunct_cache<_CharT>::~__timepunct_cache() { if (_M_allocated) { // Unused. } } // Specializations. template<> const char* __timepunct_cache<char>::_S_timezones[14]; #ifdef _GLIBCXX_USE_WCHAR_T template<> const wchar_t* __timepunct_cache<wchar_t>::_S_timezones[14]; #endif // Generic. template<typename _CharT> const _CharT* __timepunct_cache<_CharT>::_S_timezones[14]; template<typename _CharT> class __timepunct : public locale::facet { public: // Types: typedef _CharT __char_type; typedef __timepunct_cache<_CharT> __cache_type; protected: __cache_type* _M_data; __c_locale _M_c_locale_timepunct; const char* _M_name_timepunct; public: /// Numpunct facet id. static locale::id id; explicit __timepunct(size_t __refs = 0); explicit __timepunct(__cache_type* __cache, size_t __refs = 0); /** * @brief Internal constructor. Not for general use. * * This is a constructor for use by the library itself to set up new * locales. * * @param __cloc The C locale. * @param __s The name of a locale. * @param refs Passed to the base facet class. */ explicit __timepunct(__c_locale __cloc, const char* __s, size_t __refs = 0); // FIXME: for error checking purposes _M_put should return the return // value of strftime/wcsftime. void _M_put(_CharT* __s, size_t __maxlen, const _CharT* __format, const tm* __tm) const throw (); void _M_date_formats(const _CharT** __date) const { // Always have default first. __date[0] = _M_data->_M_date_format; __date[1] = _M_data->_M_date_era_format; } void _M_time_formats(const _CharT** __time) const { // Always have default first. __time[0] = _M_data->_M_time_format; __time[1] = _M_data->_M_time_era_format; } void _M_date_time_formats(const _CharT** __dt) const { // Always have default first. __dt[0] = _M_data->_M_date_time_format; __dt[1] = _M_data->_M_date_time_era_format; } #if !_GLIBCXX_INLINE_VERSION void _M_am_pm_format(const _CharT*) const { /* Kept for ABI compatibility, see PR65927 */ } #endif void _M_am_pm(const _CharT** __ampm) const { __ampm[0] = _M_data->_M_am; __ampm[1] = _M_data->_M_pm; } void _M_days(const _CharT** __days) const { __days[0] = _M_data->_M_day1; __days[1] = _M_data->_M_day2; __days[2] = _M_data->_M_day3; __days[3] = _M_data->_M_day4; __days[4] = _M_data->_M_day5; __days[5] = _M_data->_M_day6; __days[6] = _M_data->_M_day7; } void _M_days_abbreviated(const _CharT** __days) const { __days[0] = _M_data->_M_aday1; __days[1] = _M_data->_M_aday2; __days[2] = _M_data->_M_aday3; __days[3] = _M_data->_M_aday4; __days[4] = _M_data->_M_aday5; __days[5] = _M_data->_M_aday6; __days[6] = _M_data->_M_aday7; } void _M_months(const _CharT** __months) const { __months[0] = _M_data->_M_month01; __months[1] = _M_data->_M_month02; __months[2] = _M_data->_M_month03; __months[3] = _M_data->_M_month04; __months[4] = _M_data->_M_month05; __months[5] = _M_data->_M_month06; __months[6] = _M_data->_M_month07; __months[7] = _M_data->_M_month08; __months[8] = _M_data->_M_month09; __months[9] = _M_data->_M_month10; __months[10] = _M_data->_M_month11; __months[11] = _M_data->_M_month12; } void _M_months_abbreviated(const _CharT** __months) const { __months[0] = _M_data->_M_amonth01; __months[1] = _M_data->_M_amonth02; __months[2] = _M_data->_M_amonth03; __months[3] = _M_data->_M_amonth04; __months[4] = _M_data->_M_amonth05; __months[5] = _M_data->_M_amonth06; __months[6] = _M_data->_M_amonth07; __months[7] = _M_data->_M_amonth08; __months[8] = _M_data->_M_amonth09; __months[9] = _M_data->_M_amonth10; __months[10] = _M_data->_M_amonth11; __months[11] = _M_data->_M_amonth12; } protected: virtual ~__timepunct(); // For use at construction time only. void _M_initialize_timepunct(__c_locale __cloc = 0); }; template<typename _CharT> locale::id __timepunct<_CharT>::id; // Specializations. template<> void __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc); template<> void __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const throw (); #ifdef _GLIBCXX_USE_WCHAR_T template<> void __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc); template<> void __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*, const tm*) const throw (); #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace // Include host and configuration specific timepunct functions. #include <bits/time_members.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * @brief Primary class template time_get. * @ingroup locales * * This facet encapsulates the code to parse and return a date or * time from a string. It is used by the istream numeric * extraction operators. * * The time_get template uses protected virtual functions to provide the * actual results. The public accessors forward the call to the virtual * functions. These virtual functions are hooks for developers to * implement the behavior they require from the time_get facet. */ template<typename _CharT, typename _InIter> class time_get : public locale::facet, public time_base { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef _InIter iter_type; //@} /// Numpunct facet id. static locale::id id; /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __refs Passed to the base facet class. */ explicit time_get(size_t __refs = 0) : facet (__refs) { } /** * @brief Return preferred order of month, day, and year. * * This function returns an enum from time_base::dateorder giving the * preferred ordering if the format @a x given to time_put::put() only * uses month, day, and year. If the format @a x for the associated * locale uses other fields, this function returns * time_base::dateorder::noorder. * * NOTE: The library always returns noorder at the moment. * * @return A member of time_base::dateorder. */ dateorder date_order() const { return this->do_date_order(); } /** * @brief Parse input time string. * * This function parses a time according to the format @a X and puts the * results into a user-supplied struct tm. The result is returned by * calling time_get::do_get_time(). * * If there is a valid time string according to format @a X, @a tm will * be filled in accordingly and the returned iterator will point to the * first character beyond the time string. If an error occurs before * the end, err |= ios_base::failbit. If parsing reads all the * characters, err |= ios_base::eofbit. * * @param __beg Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @return Iterator to first char beyond time string. */ iter_type get_time(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { return this->do_get_time(__beg, __end, __io, __err, __tm); } /** * @brief Parse input date string. * * This function parses a date according to the format @a x and puts the * results into a user-supplied struct tm. The result is returned by * calling time_get::do_get_date(). * * If there is a valid date string according to format @a x, @a tm will * be filled in accordingly and the returned iterator will point to the * first character beyond the date string. If an error occurs before * the end, err |= ios_base::failbit. If parsing reads all the * characters, err |= ios_base::eofbit. * * @param __beg Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @return Iterator to first char beyond date string. */ iter_type get_date(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { return this->do_get_date(__beg, __end, __io, __err, __tm); } /** * @brief Parse input weekday string. * * This function parses a weekday name and puts the results into a * user-supplied struct tm. The result is returned by calling * time_get::do_get_weekday(). * * Parsing starts by parsing an abbreviated weekday name. If a valid * abbreviation is followed by a character that would lead to the full * weekday name, parsing continues until the full name is found or an * error occurs. Otherwise parsing finishes at the end of the * abbreviated name. * * If an error occurs before the end, err |= ios_base::failbit. If * parsing reads all the characters, err |= ios_base::eofbit. * * @param __beg Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @return Iterator to first char beyond weekday name. */ iter_type get_weekday(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { return this->do_get_weekday(__beg, __end, __io, __err, __tm); } /** * @brief Parse input month string. * * This function parses a month name and puts the results into a * user-supplied struct tm. The result is returned by calling * time_get::do_get_monthname(). * * Parsing starts by parsing an abbreviated month name. If a valid * abbreviation is followed by a character that would lead to the full * month name, parsing continues until the full name is found or an * error occurs. Otherwise parsing finishes at the end of the * abbreviated name. * * If an error occurs before the end, err |= ios_base::failbit. If * parsing reads all the characters, err |= * ios_base::eofbit. * * @param __beg Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @return Iterator to first char beyond month name. */ iter_type get_monthname(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { return this->do_get_monthname(__beg, __end, __io, __err, __tm); } /** * @brief Parse input year string. * * This function reads up to 4 characters to parse a year string and * puts the results into a user-supplied struct tm. The result is * returned by calling time_get::do_get_year(). * * 4 consecutive digits are interpreted as a full year. If there are * exactly 2 consecutive digits, the library interprets this as the * number of years since 1900. * * If an error occurs before the end, err |= ios_base::failbit. If * parsing reads all the characters, err |= ios_base::eofbit. * * @param __beg Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @return Iterator to first char beyond year. */ iter_type get_year(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { return this->do_get_year(__beg, __end, __io, __err, __tm); } #if __cplusplus >= 201103L /** * @brief Parse input string according to format. * * This function calls time_get::do_get with the provided * parameters. @see do_get() and get(). * * @param __s Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @param __format Format specifier. * @param __modifier Format modifier. * @return Iterator to first char not parsed. */ inline iter_type get(iter_type __s, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm, char __format, char __modifier = 0) const { return this->do_get(__s, __end, __io, __err, __tm, __format, __modifier); } /** * @brief Parse input string according to format. * * This function parses the input string according to a * provided format string. It does the inverse of * time_put::put. The format string follows the format * specified for strftime(3)/strptime(3). The actual parsing * is done by time_get::do_get. * * @param __s Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @param __fmt Start of the format string. * @param __fmtend End of the format string. * @return Iterator to first char not parsed. */ iter_type get(iter_type __s, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm, const char_type* __fmt, const char_type* __fmtend) const; #endif // __cplusplus >= 201103L protected: /// Destructor. virtual ~time_get() { } /** * @brief Return preferred order of month, day, and year. * * This function returns an enum from time_base::dateorder giving the * preferred ordering if the format @a x given to time_put::put() only * uses month, day, and year. This function is a hook for derived * classes to change the value returned. * * @return A member of time_base::dateorder. */ virtual dateorder do_date_order() const; /** * @brief Parse input time string. * * This function parses a time according to the format @a x and puts the * results into a user-supplied struct tm. This function is a hook for * derived classes to change the value returned. @see get_time() for * details. * * @param __beg Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @return Iterator to first char beyond time string. */ virtual iter_type do_get_time(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const; /** * @brief Parse input date string. * * This function parses a date according to the format @a X and puts the * results into a user-supplied struct tm. This function is a hook for * derived classes to change the value returned. @see get_date() for * details. * * @param __beg Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @return Iterator to first char beyond date string. */ virtual iter_type do_get_date(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const; /** * @brief Parse input weekday string. * * This function parses a weekday name and puts the results into a * user-supplied struct tm. This function is a hook for derived * classes to change the value returned. @see get_weekday() for * details. * * @param __beg Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @return Iterator to first char beyond weekday name. */ virtual iter_type do_get_weekday(iter_type __beg, iter_type __end, ios_base&, ios_base::iostate& __err, tm* __tm) const; /** * @brief Parse input month string. * * This function parses a month name and puts the results into a * user-supplied struct tm. This function is a hook for derived * classes to change the value returned. @see get_monthname() for * details. * * @param __beg Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @return Iterator to first char beyond month name. */ virtual iter_type do_get_monthname(iter_type __beg, iter_type __end, ios_base&, ios_base::iostate& __err, tm* __tm) const; /** * @brief Parse input year string. * * This function reads up to 4 characters to parse a year string and * puts the results into a user-supplied struct tm. This function is a * hook for derived classes to change the value returned. @see * get_year() for details. * * @param __beg Start of string to parse. * @param __end End of string to parse. * @param __io Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @return Iterator to first char beyond year. */ virtual iter_type do_get_year(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const; #if __cplusplus >= 201103L /** * @brief Parse input string according to format. * * This function parses the string according to the provided * format and optional modifier. This function is a hook for * derived classes to change the value returned. @see get() * for more details. * * @param __s Start of string to parse. * @param __end End of string to parse. * @param __f Source of the locale. * @param __err Error flags to set. * @param __tm Pointer to struct tm to fill in. * @param __format Format specifier. * @param __modifier Format modifier. * @return Iterator to first char not parsed. */ #if _GLIBCXX_USE_CXX11_ABI virtual #endif iter_type do_get(iter_type __s, iter_type __end, ios_base& __f, ios_base::iostate& __err, tm* __tm, char __format, char __modifier) const; #endif // __cplusplus >= 201103L // Extract numeric component of length __len. iter_type _M_extract_num(iter_type __beg, iter_type __end, int& __member, int __min, int __max, size_t __len, ios_base& __io, ios_base::iostate& __err) const; // Extract any unique array of string literals in a const _CharT* array. iter_type _M_extract_name(iter_type __beg, iter_type __end, int& __member, const _CharT** __names, size_t __indexlen, ios_base& __io, ios_base::iostate& __err) const; // Extract day or month name in a const _CharT* array. iter_type _M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member, const _CharT** __names, size_t __indexlen, ios_base& __io, ios_base::iostate& __err) const; // Extract on a component-by-component basis, via __format argument. iter_type _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm, const _CharT* __format) const; }; template<typename _CharT, typename _InIter> locale::id time_get<_CharT, _InIter>::id; /// class time_get_byname [22.2.5.2]. template<typename _CharT, typename _InIter> class time_get_byname : public time_get<_CharT, _InIter> { public: // Types: typedef _CharT char_type; typedef _InIter iter_type; explicit time_get_byname(const char*, size_t __refs = 0) : time_get<_CharT, _InIter>(__refs) { } #if __cplusplus >= 201103L explicit time_get_byname(const string& __s, size_t __refs = 0) : time_get_byname(__s.c_str(), __refs) { } #endif protected: virtual ~time_get_byname() { } }; _GLIBCXX_END_NAMESPACE_CXX11 /** * @brief Primary class template time_put. * @ingroup locales * * This facet encapsulates the code to format and output dates and times * according to formats used by strftime(). * * The time_put template uses protected virtual functions to provide the * actual results. The public accessors forward the call to the virtual * functions. These virtual functions are hooks for developers to * implement the behavior they require from the time_put facet. */ template<typename _CharT, typename _OutIter> class time_put : public locale::facet { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef _OutIter iter_type; //@} /// Numpunct facet id. static locale::id id; /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __refs Passed to the base facet class. */ explicit time_put(size_t __refs = 0) : facet(__refs) { } /** * @brief Format and output a time or date. * * This function formats the data in struct tm according to the * provided format string. The format string is interpreted as by * strftime(). * * @param __s The stream to write to. * @param __io Source of locale. * @param __fill char_type to use for padding. * @param __tm Struct tm with date and time info to format. * @param __beg Start of format string. * @param __end End of format string. * @return Iterator after writing. */ iter_type put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, const _CharT* __beg, const _CharT* __end) const; /** * @brief Format and output a time or date. * * This function formats the data in struct tm according to the * provided format char and optional modifier. The format and modifier * are interpreted as by strftime(). It does so by returning * time_put::do_put(). * * @param __s The stream to write to. * @param __io Source of locale. * @param __fill char_type to use for padding. * @param __tm Struct tm with date and time info to format. * @param __format Format char. * @param __mod Optional modifier char. * @return Iterator after writing. */ iter_type put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, char __format, char __mod = 0) const { return this->do_put(__s, __io, __fill, __tm, __format, __mod); } protected: /// Destructor. virtual ~time_put() { } /** * @brief Format and output a time or date. * * This function formats the data in struct tm according to the * provided format char and optional modifier. This function is a hook * for derived classes to change the value returned. @see put() for * more details. * * @param __s The stream to write to. * @param __io Source of locale. * @param __fill char_type to use for padding. * @param __tm Struct tm with date and time info to format. * @param __format Format char. * @param __mod Optional modifier char. * @return Iterator after writing. */ virtual iter_type do_put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, char __format, char __mod) const; }; template<typename _CharT, typename _OutIter> locale::id time_put<_CharT, _OutIter>::id; /// class time_put_byname [22.2.5.4]. template<typename _CharT, typename _OutIter> class time_put_byname : public time_put<_CharT, _OutIter> { public: // Types: typedef _CharT char_type; typedef _OutIter iter_type; explicit time_put_byname(const char*, size_t __refs = 0) : time_put<_CharT, _OutIter>(__refs) { } #if __cplusplus >= 201103L explicit time_put_byname(const string& __s, size_t __refs = 0) : time_put_byname(__s.c_str(), __refs) { } #endif protected: virtual ~time_put_byname() { } }; /** * @brief Money format ordering data. * @ingroup locales * * This class contains an ordered array of 4 fields to represent the * pattern for formatting a money amount. Each field may contain one entry * from the part enum. symbol, sign, and value must be present and the * remaining field must contain either none or space. @see * moneypunct::pos_format() and moneypunct::neg_format() for details of how * these fields are interpreted. */ class money_base { public: enum part { none, space, symbol, sign, value }; struct pattern { char field[4]; }; static const pattern _S_default_pattern; enum { _S_minus, _S_zero, _S_end = 11 }; // String literal of acceptable (narrow) input/output, for // money_get/money_put. "-0123456789" static const char* _S_atoms; // Construct and return valid pattern consisting of some combination of: // space none symbol sign value _GLIBCXX_CONST static pattern _S_construct_pattern(char __precedes, char __space, char __posn) throw (); }; template<typename _CharT, bool _Intl> struct __moneypunct_cache : public locale::facet { const char* _M_grouping; size_t _M_grouping_size; bool _M_use_grouping; _CharT _M_decimal_point; _CharT _M_thousands_sep; const _CharT* _M_curr_symbol; size_t _M_curr_symbol_size; const _CharT* _M_positive_sign; size_t _M_positive_sign_size; const _CharT* _M_negative_sign; size_t _M_negative_sign_size; int _M_frac_digits; money_base::pattern _M_pos_format; money_base::pattern _M_neg_format; // A list of valid numeric literals for input and output: in the standard // "C" locale, this is "-0123456789". This array contains the chars after // having been passed through the current locale's ctype<_CharT>.widen(). _CharT _M_atoms[money_base::_S_end]; bool _M_allocated; __moneypunct_cache(size_t __refs = 0) : facet(__refs), _M_grouping(0), _M_grouping_size(0), _M_use_grouping(false), _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), _M_curr_symbol(0), _M_curr_symbol_size(0), _M_positive_sign(0), _M_positive_sign_size(0), _M_negative_sign(0), _M_negative_sign_size(0), _M_frac_digits(0), _M_pos_format(money_base::pattern()), _M_neg_format(money_base::pattern()), _M_allocated(false) { } ~__moneypunct_cache(); void _M_cache(const locale& __loc); private: __moneypunct_cache& operator=(const __moneypunct_cache&); explicit __moneypunct_cache(const __moneypunct_cache&); }; template<typename _CharT, bool _Intl> __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache() { if (_M_allocated) { delete [] _M_grouping; delete [] _M_curr_symbol; delete [] _M_positive_sign; delete [] _M_negative_sign; } } _GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * @brief Primary class template moneypunct. * @ingroup locales * * This facet encapsulates the punctuation, grouping and other formatting * features of money amount string representations. */ template<typename _CharT, bool _Intl> class moneypunct : public locale::facet, public money_base { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef basic_string<_CharT> string_type; //@} typedef __moneypunct_cache<_CharT, _Intl> __cache_type; private: __cache_type* _M_data; public: /// This value is provided by the standard, but no reason for its /// existence. static const bool intl = _Intl; /// Numpunct facet id. static locale::id id; /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __refs Passed to the base facet class. */ explicit moneypunct(size_t __refs = 0) : facet(__refs), _M_data(0) { _M_initialize_moneypunct(); } /** * @brief Constructor performs initialization. * * This is an internal constructor. * * @param __cache Cache for optimization. * @param __refs Passed to the base facet class. */ explicit moneypunct(__cache_type* __cache, size_t __refs = 0) : facet(__refs), _M_data(__cache) { _M_initialize_moneypunct(); } /** * @brief Internal constructor. Not for general use. * * This is a constructor for use by the library itself to set up new * locales. * * @param __cloc The C locale. * @param __s The name of a locale. * @param __refs Passed to the base facet class. */ explicit moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0) : facet(__refs), _M_data(0) { _M_initialize_moneypunct(__cloc, __s); } /** * @brief Return decimal point character. * * This function returns a char_type to use as a decimal point. It * does so by returning returning * moneypunct<char_type>::do_decimal_point(). * * @return @a char_type representing a decimal point. */ char_type decimal_point() const { return this->do_decimal_point(); } /** * @brief Return thousands separator character. * * This function returns a char_type to use as a thousands * separator. It does so by returning returning * moneypunct<char_type>::do_thousands_sep(). * * @return char_type representing a thousands separator. */ char_type thousands_sep() const { return this->do_thousands_sep(); } /** * @brief Return grouping specification. * * This function returns a string representing groupings for the * integer part of an amount. Groupings indicate where thousands * separators should be inserted. * * Each char in the return string is interpret as an integer rather * than a character. These numbers represent the number of digits in a * group. The first char in the string represents the number of digits * in the least significant group. If a char is negative, it indicates * an unlimited number of digits for the group. If more chars from the * string are required to group a number, the last char is used * repeatedly. * * For example, if the grouping() returns <code>\003\002</code> * and is applied to the number 123456789, this corresponds to * 12,34,56,789. Note that if the string was <code>32</code>, this would * put more than 50 digits into the least significant group if * the character set is ASCII. * * The string is returned by calling * moneypunct<char_type>::do_grouping(). * * @return string representing grouping specification. */ string grouping() const { return this->do_grouping(); } /** * @brief Return currency symbol string. * * This function returns a string_type to use as a currency symbol. It * does so by returning returning * moneypunct<char_type>::do_curr_symbol(). * * @return @a string_type representing a currency symbol. */ string_type curr_symbol() const { return this->do_curr_symbol(); } /** * @brief Return positive sign string. * * This function returns a string_type to use as a sign for positive * amounts. It does so by returning returning * moneypunct<char_type>::do_positive_sign(). * * If the return value contains more than one character, the first * character appears in the position indicated by pos_format() and the * remainder appear at the end of the formatted string. * * @return @a string_type representing a positive sign. */ string_type positive_sign() const { return this->do_positive_sign(); } /** * @brief Return negative sign string. * * This function returns a string_type to use as a sign for negative * amounts. It does so by returning returning * moneypunct<char_type>::do_negative_sign(). * * If the return value contains more than one character, the first * character appears in the position indicated by neg_format() and the * remainder appear at the end of the formatted string. * * @return @a string_type representing a negative sign. */ string_type negative_sign() const { return this->do_negative_sign(); } /** * @brief Return number of digits in fraction. * * This function returns the exact number of digits that make up the * fractional part of a money amount. It does so by returning * returning moneypunct<char_type>::do_frac_digits(). * * The fractional part of a money amount is optional. But if it is * present, there must be frac_digits() digits. * * @return Number of digits in amount fraction. */ int frac_digits() const { return this->do_frac_digits(); } //@{ /** * @brief Return pattern for money values. * * This function returns a pattern describing the formatting of a * positive or negative valued money amount. It does so by returning * returning moneypunct<char_type>::do_pos_format() or * moneypunct<char_type>::do_neg_format(). * * The pattern has 4 fields describing the ordering of symbol, sign, * value, and none or space. There must be one of each in the pattern. * The none and space enums may not appear in the first field and space * may not appear in the final field. * * The parts of a money string must appear in the order indicated by * the fields of the pattern. The symbol field indicates that the * value of curr_symbol() may be present. The sign field indicates * that the value of positive_sign() or negative_sign() must be * present. The value field indicates that the absolute value of the * money amount is present. none indicates 0 or more whitespace * characters, except at the end, where it permits no whitespace. * space indicates that 1 or more whitespace characters must be * present. * * For example, for the US locale and pos_format() pattern * {symbol,sign,value,none}, curr_symbol() == '$' * positive_sign() == '+', and value 10.01, and * options set to force the symbol, the corresponding string is * <code>$+10.01</code>. * * @return Pattern for money values. */ pattern pos_format() const { return this->do_pos_format(); } pattern neg_format() const { return this->do_neg_format(); } //@} protected: /// Destructor. virtual ~moneypunct(); /** * @brief Return decimal point character. * * Returns a char_type to use as a decimal point. This function is a * hook for derived classes to change the value returned. * * @return @a char_type representing a decimal point. */ virtual char_type do_decimal_point() const { return _M_data->_M_decimal_point; } /** * @brief Return thousands separator character. * * Returns a char_type to use as a thousands separator. This function * is a hook for derived classes to change the value returned. * * @return @a char_type representing a thousands separator. */ virtual char_type do_thousands_sep() const { return _M_data->_M_thousands_sep; } /** * @brief Return grouping specification. * * Returns a string representing groupings for the integer part of a * number. This function is a hook for derived classes to change the * value returned. @see grouping() for details. * * @return String representing grouping specification. */ virtual string do_grouping() const { return _M_data->_M_grouping; } /** * @brief Return currency symbol string. * * This function returns a string_type to use as a currency symbol. * This function is a hook for derived classes to change the value * returned. @see curr_symbol() for details. * * @return @a string_type representing a currency symbol. */ virtual string_type do_curr_symbol() const { return _M_data->_M_curr_symbol; } /** * @brief Return positive sign string. * * This function returns a string_type to use as a sign for positive * amounts. This function is a hook for derived classes to change the * value returned. @see positive_sign() for details. * * @return @a string_type representing a positive sign. */ virtual string_type do_positive_sign() const { return _M_data->_M_positive_sign; } /** * @brief Return negative sign string. * * This function returns a string_type to use as a sign for negative * amounts. This function is a hook for derived classes to change the * value returned. @see negative_sign() for details. * * @return @a string_type representing a negative sign. */ virtual string_type do_negative_sign() const { return _M_data->_M_negative_sign; } /** * @brief Return number of digits in fraction. * * This function returns the exact number of digits that make up the * fractional part of a money amount. This function is a hook for * derived classes to change the value returned. @see frac_digits() * for details. * * @return Number of digits in amount fraction. */ virtual int do_frac_digits() const { return _M_data->_M_frac_digits; } /** * @brief Return pattern for money values. * * This function returns a pattern describing the formatting of a * positive valued money amount. This function is a hook for derived * classes to change the value returned. @see pos_format() for * details. * * @return Pattern for money values. */ virtual pattern do_pos_format() const { return _M_data->_M_pos_format; } /** * @brief Return pattern for money values. * * This function returns a pattern describing the formatting of a * negative valued money amount. This function is a hook for derived * classes to change the value returned. @see neg_format() for * details. * * @return Pattern for money values. */ virtual pattern do_neg_format() const { return _M_data->_M_neg_format; } // For use at construction time only. void _M_initialize_moneypunct(__c_locale __cloc = 0, const char* __name = 0); }; template<typename _CharT, bool _Intl> locale::id moneypunct<_CharT, _Intl>::id; template<typename _CharT, bool _Intl> const bool moneypunct<_CharT, _Intl>::intl; template<> moneypunct<char, true>::~moneypunct(); template<> moneypunct<char, false>::~moneypunct(); template<> void moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*); template<> void moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*); #ifdef _GLIBCXX_USE_WCHAR_T template<> moneypunct<wchar_t, true>::~moneypunct(); template<> moneypunct<wchar_t, false>::~moneypunct(); template<> void moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale, const char*); template<> void moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale, const char*); #endif /// class moneypunct_byname [22.2.6.4]. template<typename _CharT, bool _Intl> class moneypunct_byname : public moneypunct<_CharT, _Intl> { public: typedef _CharT char_type; typedef basic_string<_CharT> string_type; static const bool intl = _Intl; explicit moneypunct_byname(const char* __s, size_t __refs = 0) : moneypunct<_CharT, _Intl>(__refs) { if (__builtin_strcmp(__s, "C") != 0 && __builtin_strcmp(__s, "POSIX") != 0) { __c_locale __tmp; this->_S_create_c_locale(__tmp, __s); this->_M_initialize_moneypunct(__tmp); this->_S_destroy_c_locale(__tmp); } } #if __cplusplus >= 201103L explicit moneypunct_byname(const string& __s, size_t __refs = 0) : moneypunct_byname(__s.c_str(), __refs) { } #endif protected: virtual ~moneypunct_byname() { } }; template<typename _CharT, bool _Intl> const bool moneypunct_byname<_CharT, _Intl>::intl; _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 /** * @brief Primary class template money_get. * @ingroup locales * * This facet encapsulates the code to parse and return a monetary * amount from a string. * * The money_get template uses protected virtual functions to * provide the actual results. The public accessors forward the * call to the virtual functions. These virtual functions are * hooks for developers to implement the behavior they require from * the money_get facet. */ template<typename _CharT, typename _InIter> class money_get : public locale::facet { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef _InIter iter_type; typedef basic_string<_CharT> string_type; //@} /// Numpunct facet id. static locale::id id; /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __refs Passed to the base facet class. */ explicit money_get(size_t __refs = 0) : facet(__refs) { } /** * @brief Read and parse a monetary value. * * This function reads characters from @a __s, interprets them as a * monetary value according to moneypunct and ctype facets retrieved * from io.getloc(), and returns the result in @a units as an integral * value moneypunct::frac_digits() * the actual amount. For example, * the string $10.01 in a US locale would store 1001 in @a units. * * Any characters not part of a valid money amount are not consumed. * * If a money value cannot be parsed from the input stream, sets * err=(err|io.failbit). If the stream is consumed before finishing * parsing, sets err=(err|io.failbit|io.eofbit). @a units is * unchanged if parsing fails. * * This function works by returning the result of do_get(). * * @param __s Start of characters to parse. * @param __end End of characters to parse. * @param __intl Parameter to use_facet<moneypunct<CharT,intl> >. * @param __io Source of facets and io state. * @param __err Error field to set if parsing fails. * @param __units Place to store result of parsing. * @return Iterator referencing first character beyond valid money * amount. */ iter_type get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, long double& __units) const { return this->do_get(__s, __end, __intl, __io, __err, __units); } /** * @brief Read and parse a monetary value. * * This function reads characters from @a __s, interprets them as * a monetary value according to moneypunct and ctype facets * retrieved from io.getloc(), and returns the result in @a * digits. For example, the string $10.01 in a US locale would * store <code>1001</code> in @a digits. * * Any characters not part of a valid money amount are not consumed. * * If a money value cannot be parsed from the input stream, sets * err=(err|io.failbit). If the stream is consumed before finishing * parsing, sets err=(err|io.failbit|io.eofbit). * * This function works by returning the result of do_get(). * * @param __s Start of characters to parse. * @param __end End of characters to parse. * @param __intl Parameter to use_facet<moneypunct<CharT,intl> >. * @param __io Source of facets and io state. * @param __err Error field to set if parsing fails. * @param __digits Place to store result of parsing. * @return Iterator referencing first character beyond valid money * amount. */ iter_type get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, string_type& __digits) const { return this->do_get(__s, __end, __intl, __io, __err, __digits); } protected: /// Destructor. virtual ~money_get() { } /** * @brief Read and parse a monetary value. * * This function reads and parses characters representing a monetary * value. This function is a hook for derived classes to change the * value returned. @see get() for details. */ // XXX GLIBCXX_ABI Deprecated #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, double& __units) const; #else virtual iter_type do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, long double& __units) const; #endif /** * @brief Read and parse a monetary value. * * This function reads and parses characters representing a monetary * value. This function is a hook for derived classes to change the * value returned. @see get() for details. */ virtual iter_type do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, string_type& __digits) const; // XXX GLIBCXX_ABI Deprecated #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, long double& __units) const; #endif template<bool _Intl> iter_type _M_extract(iter_type __s, iter_type __end, ios_base& __io, ios_base::iostate& __err, string& __digits) const; }; template<typename _CharT, typename _InIter> locale::id money_get<_CharT, _InIter>::id; /** * @brief Primary class template money_put. * @ingroup locales * * This facet encapsulates the code to format and output a monetary * amount. * * The money_put template uses protected virtual functions to * provide the actual results. The public accessors forward the * call to the virtual functions. These virtual functions are * hooks for developers to implement the behavior they require from * the money_put facet. */ template<typename _CharT, typename _OutIter> class money_put : public locale::facet { public: //@{ /// Public typedefs typedef _CharT char_type; typedef _OutIter iter_type; typedef basic_string<_CharT> string_type; //@} /// Numpunct facet id. static locale::id id; /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __refs Passed to the base facet class. */ explicit money_put(size_t __refs = 0) : facet(__refs) { } /** * @brief Format and output a monetary value. * * This function formats @a units as a monetary value according to * moneypunct and ctype facets retrieved from io.getloc(), and writes * the resulting characters to @a __s. For example, the value 1001 in a * US locale would write <code>$10.01</code> to @a __s. * * This function works by returning the result of do_put(). * * @param __s The stream to write to. * @param __intl Parameter to use_facet<moneypunct<CharT,intl> >. * @param __io Source of facets and io state. * @param __fill char_type to use for padding. * @param __units Place to store result of parsing. * @return Iterator after writing. */ iter_type put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, long double __units) const { return this->do_put(__s, __intl, __io, __fill, __units); } /** * @brief Format and output a monetary value. * * This function formats @a digits as a monetary value * according to moneypunct and ctype facets retrieved from * io.getloc(), and writes the resulting characters to @a __s. * For example, the string <code>1001</code> in a US locale * would write <code>$10.01</code> to @a __s. * * This function works by returning the result of do_put(). * * @param __s The stream to write to. * @param __intl Parameter to use_facet<moneypunct<CharT,intl> >. * @param __io Source of facets and io state. * @param __fill char_type to use for padding. * @param __digits Place to store result of parsing. * @return Iterator after writing. */ iter_type put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, const string_type& __digits) const { return this->do_put(__s, __intl, __io, __fill, __digits); } protected: /// Destructor. virtual ~money_put() { } /** * @brief Format and output a monetary value. * * This function formats @a units as a monetary value according to * moneypunct and ctype facets retrieved from io.getloc(), and writes * the resulting characters to @a __s. For example, the value 1001 in a * US locale would write <code>$10.01</code> to @a __s. * * This function is a hook for derived classes to change the value * returned. @see put(). * * @param __s The stream to write to. * @param __intl Parameter to use_facet<moneypunct<CharT,intl> >. * @param __io Source of facets and io state. * @param __fill char_type to use for padding. * @param __units Place to store result of parsing. * @return Iterator after writing. */ // XXX GLIBCXX_ABI Deprecated #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, double __units) const; #else virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, long double __units) const; #endif /** * @brief Format and output a monetary value. * * This function formats @a digits as a monetary value * according to moneypunct and ctype facets retrieved from * io.getloc(), and writes the resulting characters to @a __s. * For example, the string <code>1001</code> in a US locale * would write <code>$10.01</code> to @a __s. * * This function is a hook for derived classes to change the value * returned. @see put(). * * @param __s The stream to write to. * @param __intl Parameter to use_facet<moneypunct<CharT,intl> >. * @param __io Source of facets and io state. * @param __fill char_type to use for padding. * @param __digits Place to store result of parsing. * @return Iterator after writing. */ virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, const string_type& __digits) const; // XXX GLIBCXX_ABI Deprecated #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, long double __units) const; #endif template<bool _Intl> iter_type _M_insert(iter_type __s, ios_base& __io, char_type __fill, const string_type& __digits) const; }; template<typename _CharT, typename _OutIter> locale::id money_put<_CharT, _OutIter>::id; _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 /** * @brief Messages facet base class providing catalog typedef. * @ingroup locales */ struct messages_base { typedef int catalog; }; _GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * @brief Primary class template messages. * @ingroup locales * * This facet encapsulates the code to retrieve messages from * message catalogs. The only thing defined by the standard for this facet * is the interface. All underlying functionality is * implementation-defined. * * This library currently implements 3 versions of the message facet. The * first version (gnu) is a wrapper around gettext, provided by libintl. * The second version (ieee) is a wrapper around catgets. The final * version (default) does no actual translation. These implementations are * only provided for char and wchar_t instantiations. * * The messages template uses protected virtual functions to * provide the actual results. The public accessors forward the * call to the virtual functions. These virtual functions are * hooks for developers to implement the behavior they require from * the messages facet. */ template<typename _CharT> class messages : public locale::facet, public messages_base { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef basic_string<_CharT> string_type; //@} protected: // Underlying "C" library locale information saved from // initialization, needed by messages_byname as well. __c_locale _M_c_locale_messages; const char* _M_name_messages; public: /// Numpunct facet id. static locale::id id; /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __refs Passed to the base facet class. */ explicit messages(size_t __refs = 0); // Non-standard. /** * @brief Internal constructor. Not for general use. * * This is a constructor for use by the library itself to set up new * locales. * * @param __cloc The C locale. * @param __s The name of a locale. * @param __refs Refcount to pass to the base class. */ explicit messages(__c_locale __cloc, const char* __s, size_t __refs = 0); /* * @brief Open a message catalog. * * This function opens and returns a handle to a message catalog by * returning do_open(__s, __loc). * * @param __s The catalog to open. * @param __loc Locale to use for character set conversions. * @return Handle to the catalog or value < 0 if open fails. */ catalog open(const basic_string<char>& __s, const locale& __loc) const { return this->do_open(__s, __loc); } // Non-standard and unorthodox, yet effective. /* * @brief Open a message catalog. * * This non-standard function opens and returns a handle to a message * catalog by returning do_open(s, loc). The third argument provides a * message catalog root directory for gnu gettext and is ignored * otherwise. * * @param __s The catalog to open. * @param __loc Locale to use for character set conversions. * @param __dir Message catalog root directory. * @return Handle to the catalog or value < 0 if open fails. */ catalog open(const basic_string<char>&, const locale&, const char*) const; /* * @brief Look up a string in a message catalog. * * This function retrieves and returns a message from a catalog by * returning do_get(c, set, msgid, s). * * For gnu, @a __set and @a msgid are ignored. Returns gettext(s). * For default, returns s. For ieee, returns catgets(c,set,msgid,s). * * @param __c The catalog to access. * @param __set Implementation-defined. * @param __msgid Implementation-defined. * @param __s Default return value if retrieval fails. * @return Retrieved message or @a __s if get fails. */ string_type get(catalog __c, int __set, int __msgid, const string_type& __s) const { return this->do_get(__c, __set, __msgid, __s); } /* * @brief Close a message catalog. * * Closes catalog @a c by calling do_close(c). * * @param __c The catalog to close. */ void close(catalog __c) const { return this->do_close(__c); } protected: /// Destructor. virtual ~messages(); /* * @brief Open a message catalog. * * This function opens and returns a handle to a message catalog in an * implementation-defined manner. This function is a hook for derived * classes to change the value returned. * * @param __s The catalog to open. * @param __loc Locale to use for character set conversions. * @return Handle to the opened catalog, value < 0 if open failed. */ virtual catalog do_open(const basic_string<char>&, const locale&) const; /* * @brief Look up a string in a message catalog. * * This function retrieves and returns a message from a catalog in an * implementation-defined manner. This function is a hook for derived * classes to change the value returned. * * For gnu, @a __set and @a __msgid are ignored. Returns gettext(s). * For default, returns s. For ieee, returns catgets(c,set,msgid,s). * * @param __c The catalog to access. * @param __set Implementation-defined. * @param __msgid Implementation-defined. * @param __s Default return value if retrieval fails. * @return Retrieved message or @a __s if get fails. */ virtual string_type do_get(catalog, int, int, const string_type& __dfault) const; /* * @brief Close a message catalog. * * @param __c The catalog to close. */ virtual void do_close(catalog) const; // Returns a locale and codeset-converted string, given a char* message. char* _M_convert_to_char(const string_type& __msg) const { // XXX return reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str())); } // Returns a locale and codeset-converted string, given a char* message. string_type _M_convert_from_char(char*) const { // XXX return string_type(); } }; template<typename _CharT> locale::id messages<_CharT>::id; /// Specializations for required instantiations. template<> string messages<char>::do_get(catalog, int, int, const string&) const; #ifdef _GLIBCXX_USE_WCHAR_T template<> wstring messages<wchar_t>::do_get(catalog, int, int, const wstring&) const; #endif /// class messages_byname [22.2.7.2]. template<typename _CharT> class messages_byname : public messages<_CharT> { public: typedef _CharT char_type; typedef basic_string<_CharT> string_type; explicit messages_byname(const char* __s, size_t __refs = 0); #if __cplusplus >= 201103L explicit messages_byname(const string& __s, size_t __refs = 0) : messages_byname(__s.c_str(), __refs) { } #endif protected: virtual ~messages_byname() { } }; _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace // Include host and configuration specific messages functions. #include <bits/messages_members.h> // 22.2.1.5 Template class codecvt #include <bits/codecvt.h> #include <bits/locale_facets_nonio.tcc> #endif c++/8/bits/atomic_lockfree_defines.h 0000644 00000004315 15146341150 0013223 0 ustar 00 // -*- C++ -*- header. // Copyright (C) 2008-2018 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 #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 c++/8/bits/stl_iterator_base_types.h 0000644 00000020750 15146341150 0013332 0 ustar 00 // Types used in iterator implementation -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_iterator_base_types.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iterator} * * This file contains all of the general iterator-related utility types, * such as iterator_traits and struct iterator. */ #ifndef _STL_ITERATOR_BASE_TYPES_H #define _STL_ITERATOR_BASE_TYPES_H 1 #pragma GCC system_header #include <bits/c++config.h> #if __cplusplus >= 201103L # include <type_traits> // For __void_t, is_convertible #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup iterators Iterators * Abstractions for uniform iterating through various underlying types. */ //@{ /** * @defgroup iterator_tags Iterator Tags * These are empty types, used to distinguish different iterators. The * distinction is not made by what they contain, but simply by what they * are. Different underlying algorithms can then be used based on the * different operations supported by different iterator types. */ //@{ /// Marking input iterators. struct input_iterator_tag { }; /// Marking output iterators. struct output_iterator_tag { }; /// Forward iterators support a superset of input iterator operations. struct forward_iterator_tag : public input_iterator_tag { }; /// Bidirectional iterators support a superset of forward iterator /// operations. struct bidirectional_iterator_tag : public forward_iterator_tag { }; /// Random-access iterators support a superset of bidirectional /// iterator operations. struct random_access_iterator_tag : public bidirectional_iterator_tag { }; //@} /** * @brief Common %iterator class. * * This class does nothing but define nested typedefs. %Iterator classes * can inherit from this class to save some work. The typedefs are then * used in specializations and overloading. * * In particular, there are no default implementations of requirements * such as @c operator++ and the like. (How could there be?) */ template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t, typename _Pointer = _Tp*, typename _Reference = _Tp&> struct iterator { /// One of the @link iterator_tags tag types@endlink. typedef _Category iterator_category; /// The type "pointed to" by the iterator. typedef _Tp value_type; /// Distance between iterators is represented as this type. typedef _Distance difference_type; /// This type represents a pointer-to-value_type. typedef _Pointer pointer; /// This type represents a reference-to-value_type. typedef _Reference reference; }; /** * @brief Traits class for iterators. * * This class does nothing but define nested typedefs. The general * version simply @a forwards the nested typedefs from the Iterator * argument. Specialized versions for pointers and pointers-to-const * provide tighter, more correct semantics. */ #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2408. SFINAE-friendly common_type/iterator_traits is missing in C++14 template<typename _Iterator, typename = __void_t<>> struct __iterator_traits { }; template<typename _Iterator> struct __iterator_traits<_Iterator, __void_t<typename _Iterator::iterator_category, typename _Iterator::value_type, typename _Iterator::difference_type, typename _Iterator::pointer, typename _Iterator::reference>> { typedef typename _Iterator::iterator_category iterator_category; typedef typename _Iterator::value_type value_type; typedef typename _Iterator::difference_type difference_type; typedef typename _Iterator::pointer pointer; typedef typename _Iterator::reference reference; }; template<typename _Iterator> struct iterator_traits : public __iterator_traits<_Iterator> { }; #else template<typename _Iterator> struct iterator_traits { typedef typename _Iterator::iterator_category iterator_category; typedef typename _Iterator::value_type value_type; typedef typename _Iterator::difference_type difference_type; typedef typename _Iterator::pointer pointer; typedef typename _Iterator::reference reference; }; #endif /// Partial specialization for pointer types. template<typename _Tp> struct iterator_traits<_Tp*> { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef _Tp& reference; }; /// Partial specialization for const pointer types. template<typename _Tp> struct iterator_traits<const _Tp*> { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef ptrdiff_t difference_type; typedef const _Tp* pointer; typedef const _Tp& reference; }; /** * This function is not a part of the C++ standard but is syntactic * sugar for internal library use only. */ template<typename _Iter> inline _GLIBCXX_CONSTEXPR typename iterator_traits<_Iter>::iterator_category __iterator_category(const _Iter&) { return typename iterator_traits<_Iter>::iterator_category(); } //@} #if __cplusplus < 201103L // If _Iterator has a base returns it otherwise _Iterator is returned // untouched template<typename _Iterator, bool _HasBase> struct _Iter_base { typedef _Iterator iterator_type; static iterator_type _S_base(_Iterator __it) { return __it; } }; template<typename _Iterator> struct _Iter_base<_Iterator, true> { typedef typename _Iterator::iterator_type iterator_type; static iterator_type _S_base(_Iterator __it) { return __it.base(); } }; #endif #if __cplusplus >= 201103L template<typename _InIter> using _RequireInputIter = typename enable_if<is_convertible<typename iterator_traits<_InIter>::iterator_category, input_iterator_tag>::value>::type; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _STL_ITERATOR_BASE_TYPES_H */ c++/8/bits/list.tcc 0000644 00000037150 15146341150 0007700 0 ustar 00 // List implementation (out of line) -*- C++ -*- // Copyright (C) 2001-2018 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 bits/list.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{list} */ #ifndef _LIST_TCC #define _LIST_TCC 1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Alloc> void _List_base<_Tp, _Alloc>:: _M_clear() _GLIBCXX_NOEXCEPT { typedef _List_node<_Tp> _Node; __detail::_List_node_base* __cur = _M_impl._M_node._M_next; while (__cur != &_M_impl._M_node) { _Node* __tmp = static_cast<_Node*>(__cur); __cur = __tmp->_M_next; _Tp* __val = __tmp->_M_valptr(); #if __cplusplus >= 201103L _Node_alloc_traits::destroy(_M_get_Node_allocator(), __val); #else _Tp_alloc_type(_M_get_Node_allocator()).destroy(__val); #endif _M_put_node(__tmp); } } #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> template<typename... _Args> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>:: emplace(const_iterator __position, _Args&&... __args) { _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...); __tmp->_M_hook(__position._M_const_cast()._M_node); this->_M_inc_size(1); return iterator(__tmp); } #endif template<typename _Tp, typename _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>:: #if __cplusplus >= 201103L insert(const_iterator __position, const value_type& __x) #else insert(iterator __position, const value_type& __x) #endif { _Node* __tmp = _M_create_node(__x); __tmp->_M_hook(__position._M_const_cast()._M_node); this->_M_inc_size(1); return iterator(__tmp); } #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>:: insert(const_iterator __position, size_type __n, const value_type& __x) { if (__n) { list __tmp(__n, __x, get_allocator()); iterator __it = __tmp.begin(); splice(__position, __tmp); return __it; } return __position._M_const_cast(); } template<typename _Tp, typename _Alloc> template<typename _InputIterator, typename> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>:: insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { list __tmp(__first, __last, get_allocator()); if (!__tmp.empty()) { iterator __it = __tmp.begin(); splice(__position, __tmp); return __it; } return __position._M_const_cast(); } #endif template<typename _Tp, typename _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>:: #if __cplusplus >= 201103L erase(const_iterator __position) noexcept #else erase(iterator __position) #endif { iterator __ret = iterator(__position._M_node->_M_next); _M_erase(__position._M_const_cast()); return __ret; } // Return a const_iterator indicating the position to start inserting or // erasing elements (depending whether the list is growing or shrinking), // and set __new_size to the number of new elements that must be appended. // Equivalent to the following, but performed optimally: // if (__new_size < size()) { // __new_size = 0; // return std::next(begin(), __new_size); // } else { // __newsize -= size(); // return end(); // } template<typename _Tp, typename _Alloc> typename list<_Tp, _Alloc>::const_iterator list<_Tp, _Alloc>:: _M_resize_pos(size_type& __new_size) const { const_iterator __i; #if _GLIBCXX_USE_CXX11_ABI const size_type __len = size(); if (__new_size < __len) { if (__new_size <= __len / 2) { __i = begin(); std::advance(__i, __new_size); } else { __i = end(); ptrdiff_t __num_erase = __len - __new_size; std::advance(__i, -__num_erase); } __new_size = 0; return __i; } else __i = end(); #else size_type __len = 0; for (__i = begin(); __i != end() && __len < __new_size; ++__i, ++__len) ; #endif __new_size -= __len; return __i; } #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>:: _M_default_append(size_type __n) { size_type __i = 0; __try { for (; __i < __n; ++__i) emplace_back(); } __catch(...) { for (; __i; --__i) pop_back(); __throw_exception_again; } } template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>:: resize(size_type __new_size) { const_iterator __i = _M_resize_pos(__new_size); if (__new_size) _M_default_append(__new_size); else erase(__i, end()); } template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>:: resize(size_type __new_size, const value_type& __x) { const_iterator __i = _M_resize_pos(__new_size); if (__new_size) insert(end(), __new_size, __x); else erase(__i, end()); } #else template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>:: resize(size_type __new_size, value_type __x) { const_iterator __i = _M_resize_pos(__new_size); if (__new_size) insert(end(), __new_size, __x); else erase(__i._M_const_cast(), end()); } #endif template<typename _Tp, typename _Alloc> list<_Tp, _Alloc>& list<_Tp, _Alloc>:: operator=(const list& __x) { if (this != std::__addressof(__x)) { #if __cplusplus >= 201103L if (_Node_alloc_traits::_S_propagate_on_copy_assign()) { auto& __this_alloc = this->_M_get_Node_allocator(); auto& __that_alloc = __x._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); } #endif _M_assign_dispatch(__x.begin(), __x.end(), __false_type()); } return *this; } template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>:: _M_fill_assign(size_type __n, const value_type& __val) { iterator __i = begin(); for (; __i != end() && __n > 0; ++__i, --__n) *__i = __val; if (__n > 0) insert(end(), __n, __val); else erase(__i, end()); } template<typename _Tp, typename _Alloc> template <typename _InputIterator> void list<_Tp, _Alloc>:: _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2, __false_type) { iterator __first1 = begin(); iterator __last1 = end(); for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) *__first1 = *__first2; if (__first2 == __last2) erase(__first1, __last1); else insert(__last1, __first2, __last2); } template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>:: remove(const value_type& __value) { iterator __first = begin(); iterator __last = end(); iterator __extra = __last; while (__first != __last) { iterator __next = __first; ++__next; if (*__first == __value) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 526. Is it undefined if a function in the standard changes // in parameters? if (std::__addressof(*__first) != std::__addressof(__value)) _M_erase(__first); else __extra = __first; } __first = __next; } if (__extra != __last) _M_erase(__extra); } template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>:: unique() { iterator __first = begin(); iterator __last = end(); if (__first == __last) return; iterator __next = __first; while (++__next != __last) { if (*__first == *__next) _M_erase(__next); else __first = __next; __next = __first; } } template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>:: #if __cplusplus >= 201103L merge(list&& __x) #else merge(list& __x) #endif { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 300. list::merge() specification incomplete if (this != std::__addressof(__x)) { _M_check_equal_allocators(__x); iterator __first1 = begin(); iterator __last1 = end(); iterator __first2 = __x.begin(); iterator __last2 = __x.end(); const size_t __orig_size = __x.size(); __try { while (__first1 != __last1 && __first2 != __last2) if (*__first2 < *__first1) { iterator __next = __first2; _M_transfer(__first1, __first2, ++__next); __first2 = __next; } else ++__first1; if (__first2 != __last2) _M_transfer(__last1, __first2, __last2); this->_M_inc_size(__x._M_get_size()); __x._M_set_size(0); } __catch(...) { const size_t __dist = std::distance(__first2, __last2); this->_M_inc_size(__orig_size - __dist); __x._M_set_size(__dist); __throw_exception_again; } } } template<typename _Tp, typename _Alloc> template <typename _StrictWeakOrdering> void list<_Tp, _Alloc>:: #if __cplusplus >= 201103L merge(list&& __x, _StrictWeakOrdering __comp) #else merge(list& __x, _StrictWeakOrdering __comp) #endif { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 300. list::merge() specification incomplete if (this != std::__addressof(__x)) { _M_check_equal_allocators(__x); iterator __first1 = begin(); iterator __last1 = end(); iterator __first2 = __x.begin(); iterator __last2 = __x.end(); const size_t __orig_size = __x.size(); __try { while (__first1 != __last1 && __first2 != __last2) if (__comp(*__first2, *__first1)) { iterator __next = __first2; _M_transfer(__first1, __first2, ++__next); __first2 = __next; } else ++__first1; if (__first2 != __last2) _M_transfer(__last1, __first2, __last2); this->_M_inc_size(__x._M_get_size()); __x._M_set_size(0); } __catch(...) { const size_t __dist = std::distance(__first2, __last2); this->_M_inc_size(__orig_size - __dist); __x._M_set_size(__dist); __throw_exception_again; } } } template<typename _Tp, typename _Alloc> void list<_Tp, _Alloc>:: sort() { // Do nothing if the list has length 0 or 1. if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) { list __carry; list __tmp[64]; list * __fill = __tmp; list * __counter; __try { do { __carry.splice(__carry.begin(), *this, begin()); for(__counter = __tmp; __counter != __fill && !__counter->empty(); ++__counter) { __counter->merge(__carry); __carry.swap(*__counter); } __carry.swap(*__counter); if (__counter == __fill) ++__fill; } while ( !empty() ); for (__counter = __tmp + 1; __counter != __fill; ++__counter) __counter->merge(*(__counter - 1)); swap( *(__fill - 1) ); } __catch(...) { this->splice(this->end(), __carry); for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i) this->splice(this->end(), __tmp[__i]); __throw_exception_again; } } } template<typename _Tp, typename _Alloc> template <typename _Predicate> void list<_Tp, _Alloc>:: remove_if(_Predicate __pred) { iterator __first = begin(); iterator __last = end(); while (__first != __last) { iterator __next = __first; ++__next; if (__pred(*__first)) _M_erase(__first); __first = __next; } } template<typename _Tp, typename _Alloc> template <typename _BinaryPredicate> void list<_Tp, _Alloc>:: unique(_BinaryPredicate __binary_pred) { iterator __first = begin(); iterator __last = end(); if (__first == __last) return; iterator __next = __first; while (++__next != __last) { if (__binary_pred(*__first, *__next)) _M_erase(__next); else __first = __next; __next = __first; } } template<typename _Tp, typename _Alloc> template <typename _StrictWeakOrdering> void list<_Tp, _Alloc>:: sort(_StrictWeakOrdering __comp) { // Do nothing if the list has length 0 or 1. if (this->_M_impl._M_node._M_next != &this->_M_impl._M_node && this->_M_impl._M_node._M_next->_M_next != &this->_M_impl._M_node) { list __carry; list __tmp[64]; list * __fill = __tmp; list * __counter; __try { do { __carry.splice(__carry.begin(), *this, begin()); for(__counter = __tmp; __counter != __fill && !__counter->empty(); ++__counter) { __counter->merge(__carry, __comp); __carry.swap(*__counter); } __carry.swap(*__counter); if (__counter == __fill) ++__fill; } while ( !empty() ); for (__counter = __tmp + 1; __counter != __fill; ++__counter) __counter->merge(*(__counter - 1), __comp); swap(*(__fill - 1)); } __catch(...) { this->splice(this->end(), __carry); for (int __i = 0; __i < sizeof(__tmp)/sizeof(__tmp[0]); ++__i) this->splice(this->end(), __tmp[__i]); __throw_exception_again; } } } _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _LIST_TCC */ c++/8/bits/predefined_ops.h 0000644 00000021573 15146341150 0011373 0 ustar 00 // Default predicates for internal use -*- C++ -*- // Copyright (C) 2013-2018 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 predefined_ops.h * This is an internal header file, included by other library headers. * You should not attempt to use it directly. @headername{algorithm} */ #ifndef _GLIBCXX_PREDEFINED_OPS_H #define _GLIBCXX_PREDEFINED_OPS_H 1 namespace __gnu_cxx { namespace __ops { struct _Iter_less_iter { template<typename _Iterator1, typename _Iterator2> _GLIBCXX14_CONSTEXPR bool operator()(_Iterator1 __it1, _Iterator2 __it2) const { return *__it1 < *__it2; } }; _GLIBCXX14_CONSTEXPR inline _Iter_less_iter __iter_less_iter() { return _Iter_less_iter(); } struct _Iter_less_val { #if __cplusplus >= 201103L constexpr _Iter_less_val() = default; #else _Iter_less_val() { } #endif explicit _Iter_less_val(_Iter_less_iter) { } template<typename _Iterator, typename _Value> bool operator()(_Iterator __it, _Value& __val) const { return *__it < __val; } }; inline _Iter_less_val __iter_less_val() { return _Iter_less_val(); } inline _Iter_less_val __iter_comp_val(_Iter_less_iter) { return _Iter_less_val(); } struct _Val_less_iter { #if __cplusplus >= 201103L constexpr _Val_less_iter() = default; #else _Val_less_iter() { } #endif explicit _Val_less_iter(_Iter_less_iter) { } template<typename _Value, typename _Iterator> bool operator()(_Value& __val, _Iterator __it) const { return __val < *__it; } }; inline _Val_less_iter __val_less_iter() { return _Val_less_iter(); } inline _Val_less_iter __val_comp_iter(_Iter_less_iter) { return _Val_less_iter(); } struct _Iter_equal_to_iter { template<typename _Iterator1, typename _Iterator2> bool operator()(_Iterator1 __it1, _Iterator2 __it2) const { return *__it1 == *__it2; } }; inline _Iter_equal_to_iter __iter_equal_to_iter() { return _Iter_equal_to_iter(); } struct _Iter_equal_to_val { template<typename _Iterator, typename _Value> bool operator()(_Iterator __it, _Value& __val) const { return *__it == __val; } }; inline _Iter_equal_to_val __iter_equal_to_val() { return _Iter_equal_to_val(); } inline _Iter_equal_to_val __iter_comp_val(_Iter_equal_to_iter) { return _Iter_equal_to_val(); } template<typename _Compare> struct _Iter_comp_iter { _Compare _M_comp; explicit _GLIBCXX14_CONSTEXPR _Iter_comp_iter(_Compare __comp) : _M_comp(_GLIBCXX_MOVE(__comp)) { } template<typename _Iterator1, typename _Iterator2> _GLIBCXX14_CONSTEXPR bool operator()(_Iterator1 __it1, _Iterator2 __it2) { return bool(_M_comp(*__it1, *__it2)); } }; template<typename _Compare> _GLIBCXX14_CONSTEXPR inline _Iter_comp_iter<_Compare> __iter_comp_iter(_Compare __comp) { return _Iter_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); } template<typename _Compare> struct _Iter_comp_val { _Compare _M_comp; explicit _Iter_comp_val(_Compare __comp) : _M_comp(_GLIBCXX_MOVE(__comp)) { } explicit _Iter_comp_val(const _Iter_comp_iter<_Compare>& __comp) : _M_comp(__comp._M_comp) { } #if __cplusplus >= 201103L explicit _Iter_comp_val(_Iter_comp_iter<_Compare>&& __comp) : _M_comp(std::move(__comp._M_comp)) { } #endif template<typename _Iterator, typename _Value> bool operator()(_Iterator __it, _Value& __val) { return bool(_M_comp(*__it, __val)); } }; template<typename _Compare> inline _Iter_comp_val<_Compare> __iter_comp_val(_Compare __comp) { return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); } template<typename _Compare> inline _Iter_comp_val<_Compare> __iter_comp_val(_Iter_comp_iter<_Compare> __comp) { return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); } template<typename _Compare> struct _Val_comp_iter { _Compare _M_comp; explicit _Val_comp_iter(_Compare __comp) : _M_comp(_GLIBCXX_MOVE(__comp)) { } explicit _Val_comp_iter(const _Iter_comp_iter<_Compare>& __comp) : _M_comp(__comp._M_comp) { } #if __cplusplus >= 201103L explicit _Val_comp_iter(_Iter_comp_iter<_Compare>&& __comp) : _M_comp(std::move(__comp._M_comp)) { } #endif template<typename _Value, typename _Iterator> bool operator()(_Value& __val, _Iterator __it) { return bool(_M_comp(__val, *__it)); } }; template<typename _Compare> inline _Val_comp_iter<_Compare> __val_comp_iter(_Compare __comp) { return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); } template<typename _Compare> inline _Val_comp_iter<_Compare> __val_comp_iter(_Iter_comp_iter<_Compare> __comp) { return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); } template<typename _Value> struct _Iter_equals_val { _Value& _M_value; explicit _Iter_equals_val(_Value& __value) : _M_value(__value) { } template<typename _Iterator> bool operator()(_Iterator __it) { return *__it == _M_value; } }; template<typename _Value> inline _Iter_equals_val<_Value> __iter_equals_val(_Value& __val) { return _Iter_equals_val<_Value>(__val); } template<typename _Iterator1> struct _Iter_equals_iter { _Iterator1 _M_it1; explicit _Iter_equals_iter(_Iterator1 __it1) : _M_it1(__it1) { } template<typename _Iterator2> bool operator()(_Iterator2 __it2) { return *__it2 == *_M_it1; } }; template<typename _Iterator> inline _Iter_equals_iter<_Iterator> __iter_comp_iter(_Iter_equal_to_iter, _Iterator __it) { return _Iter_equals_iter<_Iterator>(__it); } template<typename _Predicate> struct _Iter_pred { _Predicate _M_pred; explicit _Iter_pred(_Predicate __pred) : _M_pred(_GLIBCXX_MOVE(__pred)) { } template<typename _Iterator> bool operator()(_Iterator __it) { return bool(_M_pred(*__it)); } }; template<typename _Predicate> inline _Iter_pred<_Predicate> __pred_iter(_Predicate __pred) { return _Iter_pred<_Predicate>(_GLIBCXX_MOVE(__pred)); } template<typename _Compare, typename _Value> struct _Iter_comp_to_val { _Compare _M_comp; _Value& _M_value; _Iter_comp_to_val(_Compare __comp, _Value& __value) : _M_comp(_GLIBCXX_MOVE(__comp)), _M_value(__value) { } template<typename _Iterator> bool operator()(_Iterator __it) { return bool(_M_comp(*__it, _M_value)); } }; template<typename _Compare, typename _Value> _Iter_comp_to_val<_Compare, _Value> __iter_comp_val(_Compare __comp, _Value &__val) { return _Iter_comp_to_val<_Compare, _Value>(_GLIBCXX_MOVE(__comp), __val); } template<typename _Compare, typename _Iterator1> struct _Iter_comp_to_iter { _Compare _M_comp; _Iterator1 _M_it1; _Iter_comp_to_iter(_Compare __comp, _Iterator1 __it1) : _M_comp(_GLIBCXX_MOVE(__comp)), _M_it1(__it1) { } template<typename _Iterator2> bool operator()(_Iterator2 __it2) { return bool(_M_comp(*__it2, *_M_it1)); } }; template<typename _Compare, typename _Iterator> inline _Iter_comp_to_iter<_Compare, _Iterator> __iter_comp_iter(_Iter_comp_iter<_Compare> __comp, _Iterator __it) { return _Iter_comp_to_iter<_Compare, _Iterator>( _GLIBCXX_MOVE(__comp._M_comp), __it); } template<typename _Predicate> struct _Iter_negate { _Predicate _M_pred; explicit _Iter_negate(_Predicate __pred) : _M_pred(_GLIBCXX_MOVE(__pred)) { } template<typename _Iterator> bool operator()(_Iterator __it) { return !bool(_M_pred(*__it)); } }; template<typename _Predicate> inline _Iter_negate<_Predicate> __negate(_Iter_pred<_Predicate> __pred) { return _Iter_negate<_Predicate>(_GLIBCXX_MOVE(__pred._M_pred)); } } // namespace __ops } // namespace __gnu_cxx #endif c++/8/bits/parse_numbers.h 0000644 00000017410 15146341150 0011245 0 ustar 00 // Components for compile-time parsing of numbers -*- C++ -*- // Copyright (C) 2013-2018 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/parse_numbers.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{chrono} */ #ifndef _GLIBCXX_PARSE_NUMBERS_H #define _GLIBCXX_PARSE_NUMBERS_H 1 #pragma GCC system_header // From n3642.pdf except I added binary literals and digit separator '\''. #if __cplusplus > 201103L #include <limits> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __parse_int { template<unsigned _Base, char _Dig> struct _Digit; template<unsigned _Base> struct _Digit<_Base, '0'> : integral_constant<unsigned, 0> { using __valid = true_type; }; template<unsigned _Base> struct _Digit<_Base, '1'> : integral_constant<unsigned, 1> { using __valid = true_type; }; template<unsigned _Base, unsigned _Val> struct _Digit_impl : integral_constant<unsigned, _Val> { static_assert(_Base > _Val, "invalid digit"); using __valid = true_type; }; template<unsigned _Base> struct _Digit<_Base, '2'> : _Digit_impl<_Base, 2> { }; template<unsigned _Base> struct _Digit<_Base, '3'> : _Digit_impl<_Base, 3> { }; template<unsigned _Base> struct _Digit<_Base, '4'> : _Digit_impl<_Base, 4> { }; template<unsigned _Base> struct _Digit<_Base, '5'> : _Digit_impl<_Base, 5> { }; template<unsigned _Base> struct _Digit<_Base, '6'> : _Digit_impl<_Base, 6> { }; template<unsigned _Base> struct _Digit<_Base, '7'> : _Digit_impl<_Base, 7> { }; template<unsigned _Base> struct _Digit<_Base, '8'> : _Digit_impl<_Base, 8> { }; template<unsigned _Base> struct _Digit<_Base, '9'> : _Digit_impl<_Base, 9> { }; template<unsigned _Base> struct _Digit<_Base, 'a'> : _Digit_impl<_Base, 0xa> { }; template<unsigned _Base> struct _Digit<_Base, 'A'> : _Digit_impl<_Base, 0xa> { }; template<unsigned _Base> struct _Digit<_Base, 'b'> : _Digit_impl<_Base, 0xb> { }; template<unsigned _Base> struct _Digit<_Base, 'B'> : _Digit_impl<_Base, 0xb> { }; template<unsigned _Base> struct _Digit<_Base, 'c'> : _Digit_impl<_Base, 0xc> { }; template<unsigned _Base> struct _Digit<_Base, 'C'> : _Digit_impl<_Base, 0xc> { }; template<unsigned _Base> struct _Digit<_Base, 'd'> : _Digit_impl<_Base, 0xd> { }; template<unsigned _Base> struct _Digit<_Base, 'D'> : _Digit_impl<_Base, 0xd> { }; template<unsigned _Base> struct _Digit<_Base, 'e'> : _Digit_impl<_Base, 0xe> { }; template<unsigned _Base> struct _Digit<_Base, 'E'> : _Digit_impl<_Base, 0xe> { }; template<unsigned _Base> struct _Digit<_Base, 'f'> : _Digit_impl<_Base, 0xf> { }; template<unsigned _Base> struct _Digit<_Base, 'F'> : _Digit_impl<_Base, 0xf> { }; // Digit separator template<unsigned _Base> struct _Digit<_Base, '\''> : integral_constant<unsigned, 0> { using __valid = false_type; }; //------------------------------------------------------------------------------ template<unsigned long long _Val> using __ull_constant = integral_constant<unsigned long long, _Val>; template<unsigned _Base, char _Dig, char... _Digs> struct _Power_help { using __next = typename _Power_help<_Base, _Digs...>::type; using __valid_digit = typename _Digit<_Base, _Dig>::__valid; using type = __ull_constant<__next::value * (__valid_digit{} ? _Base : 1ULL)>; }; template<unsigned _Base, char _Dig> struct _Power_help<_Base, _Dig> { using __valid_digit = typename _Digit<_Base, _Dig>::__valid; using type = __ull_constant<__valid_digit::value>; }; template<unsigned _Base, char... _Digs> struct _Power : _Power_help<_Base, _Digs...>::type { }; template<unsigned _Base> struct _Power<_Base> : __ull_constant<0> { }; //------------------------------------------------------------------------------ template<unsigned _Base, unsigned long long _Pow, char _Dig, char... _Digs> struct _Number_help { using __digit = _Digit<_Base, _Dig>; using __valid_digit = typename __digit::__valid; using __next = _Number_help<_Base, __valid_digit::value ? _Pow / _Base : _Pow, _Digs...>; using type = __ull_constant<_Pow * __digit::value + __next::type::value>; static_assert((type::value / _Pow) == __digit::value, "integer literal does not fit in unsigned long long"); }; // Skip past digit separators: template<unsigned _Base, unsigned long long _Pow, char _Dig, char..._Digs> struct _Number_help<_Base, _Pow, '\'', _Dig, _Digs...> : _Number_help<_Base, _Pow, _Dig, _Digs...> { }; // Terminating case for recursion: template<unsigned _Base, char _Dig> struct _Number_help<_Base, 1ULL, _Dig> { using type = __ull_constant<_Digit<_Base, _Dig>::value>; }; template<unsigned _Base, char... _Digs> struct _Number : _Number_help<_Base, _Power<_Base, _Digs...>::value, _Digs...>::type { }; template<unsigned _Base> struct _Number<_Base> : __ull_constant<0> { }; //------------------------------------------------------------------------------ template<char... _Digs> struct _Parse_int; template<char... _Digs> struct _Parse_int<'0', 'b', _Digs...> : _Number<2U, _Digs...>::type { }; template<char... _Digs> struct _Parse_int<'0', 'B', _Digs...> : _Number<2U, _Digs...>::type { }; template<char... _Digs> struct _Parse_int<'0', 'x', _Digs...> : _Number<16U, _Digs...>::type { }; template<char... _Digs> struct _Parse_int<'0', 'X', _Digs...> : _Number<16U, _Digs...>::type { }; template<char... _Digs> struct _Parse_int<'0', _Digs...> : _Number<8U, _Digs...>::type { }; template<char... _Digs> struct _Parse_int : _Number<10U, _Digs...>::type { }; } // namespace __parse_int namespace __select_int { template<unsigned long long _Val, typename... _Ints> struct _Select_int_base; template<unsigned long long _Val, typename _IntType, typename... _Ints> struct _Select_int_base<_Val, _IntType, _Ints...> : conditional_t<(_Val <= std::numeric_limits<_IntType>::max()), integral_constant<_IntType, _Val>, _Select_int_base<_Val, _Ints...>> { }; template<unsigned long long _Val> struct _Select_int_base<_Val> { }; template<char... _Digs> using _Select_int = typename _Select_int_base< __parse_int::_Parse_int<_Digs...>::value, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long >::type; } // namespace __select_int _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // __cplusplus > 201103L #endif // _GLIBCXX_PARSE_NUMBERS_H c++/8/bits/uniform_int_dist.h 0000644 00000023541 15146341150 0011756 0 ustar 00 // Class template uniform_int_distribution -*- C++ -*- // Copyright (C) 2009-2018 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/uniform_int_dist.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{random} */ #ifndef _GLIBCXX_BITS_UNIFORM_INT_DIST_H #define _GLIBCXX_BITS_UNIFORM_INT_DIST_H #include <type_traits> #include <limits> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { /* Determine whether number is a power of 2. */ template<typename _Tp> inline bool _Power_of_2(_Tp __x) { return ((__x - 1) & __x) == 0; } } /** * @brief Uniform discrete distribution for random numbers. * A discrete random distribution on the range @f$[min, max]@f$ with equal * probability throughout the range. */ template<typename _IntType = int> class uniform_int_distribution { static_assert(std::is_integral<_IntType>::value, "template argument must be an integral type"); public: /** The type of the range of the distribution. */ typedef _IntType result_type; /** Parameter type. */ struct param_type { typedef uniform_int_distribution<_IntType> distribution_type; explicit param_type(_IntType __a = 0, _IntType __b = std::numeric_limits<_IntType>::max()) : _M_a(__a), _M_b(__b) { __glibcxx_assert(_M_a <= _M_b); } result_type a() const { return _M_a; } result_type b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _IntType _M_a; _IntType _M_b; }; public: /** * @brief Constructs a uniform distribution object. */ explicit uniform_int_distribution(_IntType __a = 0, _IntType __b = std::numeric_limits<_IntType>::max()) : _M_param(__a, __b) { } explicit uniform_int_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. * * Does nothing for the uniform integer distribution. */ void reset() { } result_type a() const { return _M_param.a(); } result_type b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the inclusive lower bound of the distribution range. */ result_type min() const { return this->a(); } /** * @brief Returns the inclusive upper bound of the distribution range. */ result_type max() const { return this->b(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two uniform integer distributions have * the same parameters. */ friend bool operator==(const uniform_int_distribution& __d1, const uniform_int_distribution& __d2) { return __d1._M_param == __d2._M_param; } private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; template<typename _IntType> template<typename _UniformRandomNumberGenerator> typename uniform_int_distribution<_IntType>::result_type uniform_int_distribution<_IntType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { typedef typename _UniformRandomNumberGenerator::result_type _Gresult_type; typedef typename std::make_unsigned<result_type>::type __utype; typedef typename std::common_type<_Gresult_type, __utype>::type __uctype; const __uctype __urngmin = __urng.min(); const __uctype __urngmax = __urng.max(); const __uctype __urngrange = __urngmax - __urngmin; const __uctype __urange = __uctype(__param.b()) - __uctype(__param.a()); __uctype __ret; if (__urngrange > __urange) { // downscaling const __uctype __uerange = __urange + 1; // __urange can be zero const __uctype __scaling = __urngrange / __uerange; const __uctype __past = __uerange * __scaling; do __ret = __uctype(__urng()) - __urngmin; while (__ret >= __past); __ret /= __scaling; } else if (__urngrange < __urange) { // upscaling /* Note that every value in [0, urange] can be written uniquely as (urngrange + 1) * high + low where high in [0, urange / (urngrange + 1)] and low in [0, urngrange]. */ __uctype __tmp; // wraparound control do { const __uctype __uerngrange = __urngrange + 1; __tmp = (__uerngrange * operator() (__urng, param_type(0, __urange / __uerngrange))); __ret = __tmp + (__uctype(__urng()) - __urngmin); } while (__ret > __urange || __ret < __tmp); } else __ret = __uctype(__urng()) - __urngmin; return __ret + __param.a(); } template<typename _IntType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void uniform_int_distribution<_IntType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) typedef typename _UniformRandomNumberGenerator::result_type _Gresult_type; typedef typename std::make_unsigned<result_type>::type __utype; typedef typename std::common_type<_Gresult_type, __utype>::type __uctype; const __uctype __urngmin = __urng.min(); const __uctype __urngmax = __urng.max(); const __uctype __urngrange = __urngmax - __urngmin; const __uctype __urange = __uctype(__param.b()) - __uctype(__param.a()); __uctype __ret; if (__urngrange > __urange) { if (__detail::_Power_of_2(__urngrange + 1) && __detail::_Power_of_2(__urange + 1)) { while (__f != __t) { __ret = __uctype(__urng()) - __urngmin; *__f++ = (__ret & __urange) + __param.a(); } } else { // downscaling const __uctype __uerange = __urange + 1; // __urange can be zero const __uctype __scaling = __urngrange / __uerange; const __uctype __past = __uerange * __scaling; while (__f != __t) { do __ret = __uctype(__urng()) - __urngmin; while (__ret >= __past); *__f++ = __ret / __scaling + __param.a(); } } } else if (__urngrange < __urange) { // upscaling /* Note that every value in [0, urange] can be written uniquely as (urngrange + 1) * high + low where high in [0, urange / (urngrange + 1)] and low in [0, urngrange]. */ __uctype __tmp; // wraparound control while (__f != __t) { do { const __uctype __uerngrange = __urngrange + 1; __tmp = (__uerngrange * operator() (__urng, param_type(0, __urange / __uerngrange))); __ret = __tmp + (__uctype(__urng()) - __urngmin); } while (__ret > __urange || __ret < __tmp); *__f++ = __ret; } } else while (__f != __t) *__f++ = __uctype(__urng()) - __urngmin + __param.a(); } // operator!= and operator<< and operator>> are defined in <bits/random.h> _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/stl_tree.h 0000644 00000222230 15146341150 0010217 0 ustar 00 // RB tree implementation -*- C++ -*- // Copyright (C) 2001-2018 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. * * * 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 bits/stl_tree.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{map,set} */ #ifndef _STL_TREE_H #define _STL_TREE_H 1 #pragma GCC system_header #include <bits/stl_algobase.h> #include <bits/allocator.h> #include <bits/stl_function.h> #include <bits/cpp_type_traits.h> #include <ext/alloc_traits.h> #if __cplusplus >= 201103L # include <ext/aligned_buffer.h> #endif #if __cplusplus > 201402L # include <bits/node_handle.h> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus > 201103L # define __cpp_lib_generic_associative_lookup 201304 #endif // Red-black tree class, designed for use in implementing STL // associative containers (set, multiset, map, and multimap). The // insertion and deletion algorithms are based on those in Cormen, // Leiserson, and Rivest, Introduction to Algorithms (MIT Press, // 1990), except that // // (1) the header cell is maintained with links not only to the root // but also to the leftmost node of the tree, to enable constant // time begin(), and to the rightmost node of the tree, to enable // linear time performance when used with the generic set algorithms // (set_union, etc.) // // (2) when a node being deleted has two children its successor node // is relinked into its place, rather than copied, so that the only // iterators invalidated are those referring to the deleted node. enum _Rb_tree_color { _S_red = false, _S_black = true }; struct _Rb_tree_node_base { typedef _Rb_tree_node_base* _Base_ptr; typedef const _Rb_tree_node_base* _Const_Base_ptr; _Rb_tree_color _M_color; _Base_ptr _M_parent; _Base_ptr _M_left; _Base_ptr _M_right; static _Base_ptr _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT { while (__x->_M_left != 0) __x = __x->_M_left; return __x; } static _Const_Base_ptr _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { while (__x->_M_left != 0) __x = __x->_M_left; return __x; } static _Base_ptr _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT { while (__x->_M_right != 0) __x = __x->_M_right; return __x; } static _Const_Base_ptr _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { while (__x->_M_right != 0) __x = __x->_M_right; return __x; } }; // Helper type offering value initialization guarantee on the compare functor. template<typename _Key_compare> struct _Rb_tree_key_compare { _Key_compare _M_key_compare; _Rb_tree_key_compare() _GLIBCXX_NOEXCEPT_IF( is_nothrow_default_constructible<_Key_compare>::value) : _M_key_compare() { } _Rb_tree_key_compare(const _Key_compare& __comp) : _M_key_compare(__comp) { } #if __cplusplus >= 201103L // Copy constructor added for consistency with C++98 mode. _Rb_tree_key_compare(const _Rb_tree_key_compare&) = default; _Rb_tree_key_compare(_Rb_tree_key_compare&& __x) noexcept(is_nothrow_copy_constructible<_Key_compare>::value) : _M_key_compare(__x._M_key_compare) { } #endif }; // Helper type to manage default initialization of node count and header. struct _Rb_tree_header { _Rb_tree_node_base _M_header; size_t _M_node_count; // Keeps track of size of tree. _Rb_tree_header() _GLIBCXX_NOEXCEPT { _M_header._M_color = _S_red; _M_reset(); } #if __cplusplus >= 201103L _Rb_tree_header(_Rb_tree_header&& __x) noexcept { if (__x._M_header._M_parent != nullptr) _M_move_data(__x); else { _M_header._M_color = _S_red; _M_reset(); } } #endif void _M_move_data(_Rb_tree_header& __from) { _M_header._M_color = __from._M_header._M_color; _M_header._M_parent = __from._M_header._M_parent; _M_header._M_left = __from._M_header._M_left; _M_header._M_right = __from._M_header._M_right; _M_header._M_parent->_M_parent = &_M_header; _M_node_count = __from._M_node_count; __from._M_reset(); } void _M_reset() { _M_header._M_parent = 0; _M_header._M_left = &_M_header; _M_header._M_right = &_M_header; _M_node_count = 0; } }; template<typename _Val> struct _Rb_tree_node : public _Rb_tree_node_base { typedef _Rb_tree_node<_Val>* _Link_type; #if __cplusplus < 201103L _Val _M_value_field; _Val* _M_valptr() { return std::__addressof(_M_value_field); } const _Val* _M_valptr() const { return std::__addressof(_M_value_field); } #else __gnu_cxx::__aligned_membuf<_Val> _M_storage; _Val* _M_valptr() { return _M_storage._M_ptr(); } const _Val* _M_valptr() const { return _M_storage._M_ptr(); } #endif }; _GLIBCXX_PURE _Rb_tree_node_base* _Rb_tree_increment(_Rb_tree_node_base* __x) throw (); _GLIBCXX_PURE const _Rb_tree_node_base* _Rb_tree_increment(const _Rb_tree_node_base* __x) throw (); _GLIBCXX_PURE _Rb_tree_node_base* _Rb_tree_decrement(_Rb_tree_node_base* __x) throw (); _GLIBCXX_PURE const _Rb_tree_node_base* _Rb_tree_decrement(const _Rb_tree_node_base* __x) throw (); template<typename _Tp> struct _Rb_tree_iterator { typedef _Tp value_type; typedef _Tp& reference; typedef _Tp* pointer; typedef bidirectional_iterator_tag iterator_category; typedef ptrdiff_t difference_type; typedef _Rb_tree_iterator<_Tp> _Self; typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; typedef _Rb_tree_node<_Tp>* _Link_type; _Rb_tree_iterator() _GLIBCXX_NOEXCEPT : _M_node() { } explicit _Rb_tree_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT : _M_node(__x) { } reference operator*() const _GLIBCXX_NOEXCEPT { return *static_cast<_Link_type>(_M_node)->_M_valptr(); } pointer operator->() const _GLIBCXX_NOEXCEPT { return static_cast<_Link_type> (_M_node)->_M_valptr(); } _Self& operator++() _GLIBCXX_NOEXCEPT { _M_node = _Rb_tree_increment(_M_node); return *this; } _Self operator++(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _Rb_tree_increment(_M_node); return __tmp; } _Self& operator--() _GLIBCXX_NOEXCEPT { _M_node = _Rb_tree_decrement(_M_node); return *this; } _Self operator--(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _Rb_tree_decrement(_M_node); return __tmp; } bool operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node == __x._M_node; } bool operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node != __x._M_node; } _Base_ptr _M_node; }; template<typename _Tp> struct _Rb_tree_const_iterator { typedef _Tp value_type; typedef const _Tp& reference; typedef const _Tp* pointer; typedef _Rb_tree_iterator<_Tp> iterator; typedef bidirectional_iterator_tag iterator_category; typedef ptrdiff_t difference_type; typedef _Rb_tree_const_iterator<_Tp> _Self; typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; typedef const _Rb_tree_node<_Tp>* _Link_type; _Rb_tree_const_iterator() _GLIBCXX_NOEXCEPT : _M_node() { } explicit _Rb_tree_const_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT : _M_node(__x) { } _Rb_tree_const_iterator(const iterator& __it) _GLIBCXX_NOEXCEPT : _M_node(__it._M_node) { } iterator _M_const_cast() const _GLIBCXX_NOEXCEPT { return iterator(const_cast<typename iterator::_Base_ptr>(_M_node)); } reference operator*() const _GLIBCXX_NOEXCEPT { return *static_cast<_Link_type>(_M_node)->_M_valptr(); } pointer operator->() const _GLIBCXX_NOEXCEPT { return static_cast<_Link_type>(_M_node)->_M_valptr(); } _Self& operator++() _GLIBCXX_NOEXCEPT { _M_node = _Rb_tree_increment(_M_node); return *this; } _Self operator++(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _Rb_tree_increment(_M_node); return __tmp; } _Self& operator--() _GLIBCXX_NOEXCEPT { _M_node = _Rb_tree_decrement(_M_node); return *this; } _Self operator--(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _Rb_tree_decrement(_M_node); return __tmp; } bool operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node == __x._M_node; } bool operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node != __x._M_node; } _Base_ptr _M_node; }; template<typename _Val> inline bool operator==(const _Rb_tree_iterator<_Val>& __x, const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT { return __x._M_node == __y._M_node; } template<typename _Val> inline bool operator!=(const _Rb_tree_iterator<_Val>& __x, const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT { return __x._M_node != __y._M_node; } void _Rb_tree_insert_and_rebalance(const bool __insert_left, _Rb_tree_node_base* __x, _Rb_tree_node_base* __p, _Rb_tree_node_base& __header) throw (); _Rb_tree_node_base* _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, _Rb_tree_node_base& __header) throw (); #if __cplusplus > 201103L template<typename _Cmp, typename _SfinaeType, typename = __void_t<>> struct __has_is_transparent { }; template<typename _Cmp, typename _SfinaeType> struct __has_is_transparent<_Cmp, _SfinaeType, __void_t<typename _Cmp::is_transparent>> { typedef void type; }; #endif #if __cplusplus > 201402L template<typename _Tree1, typename _Cmp2> struct _Rb_tree_merge_helper { }; #endif template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc = allocator<_Val> > class _Rb_tree { typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Rb_tree_node<_Val> >::other _Node_allocator; typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits; protected: typedef _Rb_tree_node_base* _Base_ptr; typedef const _Rb_tree_node_base* _Const_Base_ptr; typedef _Rb_tree_node<_Val>* _Link_type; typedef const _Rb_tree_node<_Val>* _Const_Link_type; private: // Functor recycling a pool of nodes and using allocation once the pool // is empty. struct _Reuse_or_alloc_node { _Reuse_or_alloc_node(_Rb_tree& __t) : _M_root(__t._M_root()), _M_nodes(__t._M_rightmost()), _M_t(__t) { if (_M_root) { _M_root->_M_parent = 0; if (_M_nodes->_M_left) _M_nodes = _M_nodes->_M_left; } else _M_nodes = 0; } #if __cplusplus >= 201103L _Reuse_or_alloc_node(const _Reuse_or_alloc_node&) = delete; #endif ~_Reuse_or_alloc_node() { _M_t._M_erase(static_cast<_Link_type>(_M_root)); } template<typename _Arg> _Link_type #if __cplusplus < 201103L operator()(const _Arg& __arg) #else operator()(_Arg&& __arg) #endif { _Link_type __node = static_cast<_Link_type>(_M_extract()); if (__node) { _M_t._M_destroy_node(__node); _M_t._M_construct_node(__node, _GLIBCXX_FORWARD(_Arg, __arg)); return __node; } return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)); } private: _Base_ptr _M_extract() { if (!_M_nodes) return _M_nodes; _Base_ptr __node = _M_nodes; _M_nodes = _M_nodes->_M_parent; if (_M_nodes) { if (_M_nodes->_M_right == __node) { _M_nodes->_M_right = 0; if (_M_nodes->_M_left) { _M_nodes = _M_nodes->_M_left; while (_M_nodes->_M_right) _M_nodes = _M_nodes->_M_right; if (_M_nodes->_M_left) _M_nodes = _M_nodes->_M_left; } } else // __node is on the left. _M_nodes->_M_left = 0; } else _M_root = 0; return __node; } _Base_ptr _M_root; _Base_ptr _M_nodes; _Rb_tree& _M_t; }; // Functor similar to the previous one but without any pool of nodes to // recycle. struct _Alloc_node { _Alloc_node(_Rb_tree& __t) : _M_t(__t) { } template<typename _Arg> _Link_type #if __cplusplus < 201103L operator()(const _Arg& __arg) const #else operator()(_Arg&& __arg) const #endif { return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)); } private: _Rb_tree& _M_t; }; public: typedef _Key key_type; typedef _Val value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Alloc allocator_type; _Node_allocator& _M_get_Node_allocator() _GLIBCXX_NOEXCEPT { return this->_M_impl; } const _Node_allocator& _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT { return this->_M_impl; } allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_get_Node_allocator()); } protected: _Link_type _M_get_node() { return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); } void _M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT { _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); } #if __cplusplus < 201103L void _M_construct_node(_Link_type __node, const value_type& __x) { __try { get_allocator().construct(__node->_M_valptr(), __x); } __catch(...) { _M_put_node(__node); __throw_exception_again; } } _Link_type _M_create_node(const value_type& __x) { _Link_type __tmp = _M_get_node(); _M_construct_node(__tmp, __x); return __tmp; } void _M_destroy_node(_Link_type __p) { get_allocator().destroy(__p->_M_valptr()); } #else template<typename... _Args> void _M_construct_node(_Link_type __node, _Args&&... __args) { __try { ::new(__node) _Rb_tree_node<_Val>; _Alloc_traits::construct(_M_get_Node_allocator(), __node->_M_valptr(), std::forward<_Args>(__args)...); } __catch(...) { __node->~_Rb_tree_node<_Val>(); _M_put_node(__node); __throw_exception_again; } } template<typename... _Args> _Link_type _M_create_node(_Args&&... __args) { _Link_type __tmp = _M_get_node(); _M_construct_node(__tmp, std::forward<_Args>(__args)...); return __tmp; } void _M_destroy_node(_Link_type __p) noexcept { _Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr()); __p->~_Rb_tree_node<_Val>(); } #endif void _M_drop_node(_Link_type __p) _GLIBCXX_NOEXCEPT { _M_destroy_node(__p); _M_put_node(__p); } template<typename _NodeGen> _Link_type _M_clone_node(_Const_Link_type __x, _NodeGen& __node_gen) { _Link_type __tmp = __node_gen(*__x->_M_valptr()); __tmp->_M_color = __x->_M_color; __tmp->_M_left = 0; __tmp->_M_right = 0; return __tmp; } protected: #if _GLIBCXX_INLINE_VERSION template<typename _Key_compare> #else // Unused _Is_pod_comparator is kept as it is part of mangled name. template<typename _Key_compare, bool /* _Is_pod_comparator */ = __is_pod(_Key_compare)> #endif struct _Rb_tree_impl : public _Node_allocator , public _Rb_tree_key_compare<_Key_compare> , public _Rb_tree_header { typedef _Rb_tree_key_compare<_Key_compare> _Base_key_compare; _Rb_tree_impl() _GLIBCXX_NOEXCEPT_IF( is_nothrow_default_constructible<_Node_allocator>::value && is_nothrow_default_constructible<_Base_key_compare>::value ) : _Node_allocator() { } _Rb_tree_impl(const _Rb_tree_impl& __x) : _Node_allocator(_Alloc_traits::_S_select_on_copy(__x)) , _Base_key_compare(__x._M_key_compare) { } #if __cplusplus < 201103L _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a) : _Node_allocator(__a), _Base_key_compare(__comp) { } #else _Rb_tree_impl(_Rb_tree_impl&&) = default; _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a) : _Node_allocator(std::move(__a)), _Base_key_compare(__comp) { } #endif }; _Rb_tree_impl<_Compare> _M_impl; protected: _Base_ptr& _M_root() _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_parent; } _Const_Base_ptr _M_root() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_parent; } _Base_ptr& _M_leftmost() _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_left; } _Const_Base_ptr _M_leftmost() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_left; } _Base_ptr& _M_rightmost() _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_right; } _Const_Base_ptr _M_rightmost() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_right; } _Link_type _M_begin() _GLIBCXX_NOEXCEPT { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } _Const_Link_type _M_begin() const _GLIBCXX_NOEXCEPT { return static_cast<_Const_Link_type> (this->_M_impl._M_header._M_parent); } _Base_ptr _M_end() _GLIBCXX_NOEXCEPT { return &this->_M_impl._M_header; } _Const_Base_ptr _M_end() const _GLIBCXX_NOEXCEPT { return &this->_M_impl._M_header; } static const_reference _S_value(_Const_Link_type __x) { return *__x->_M_valptr(); } static const _Key& _S_key(_Const_Link_type __x) { #if __cplusplus >= 201103L // If we're asking for the key we're presumably using the comparison // object, and so this is a good place to sanity check it. static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{}, "comparison object must be invocable " "with two arguments of key type"); # if __cplusplus >= 201703L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2542. Missing const requirements for associative containers if constexpr (__is_invocable<_Compare&, const _Key&, const _Key&>{}) static_assert( is_invocable_v<const _Compare&, const _Key&, const _Key&>, "comparison object must be invocable as const"); # endif // C++17 #endif // C++11 return _KeyOfValue()(*__x->_M_valptr()); } static _Link_type _S_left(_Base_ptr __x) _GLIBCXX_NOEXCEPT { return static_cast<_Link_type>(__x->_M_left); } static _Const_Link_type _S_left(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { return static_cast<_Const_Link_type>(__x->_M_left); } static _Link_type _S_right(_Base_ptr __x) _GLIBCXX_NOEXCEPT { return static_cast<_Link_type>(__x->_M_right); } static _Const_Link_type _S_right(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { return static_cast<_Const_Link_type>(__x->_M_right); } static const_reference _S_value(_Const_Base_ptr __x) { return *static_cast<_Const_Link_type>(__x)->_M_valptr(); } static const _Key& _S_key(_Const_Base_ptr __x) { return _S_key(static_cast<_Const_Link_type>(__x)); } static _Base_ptr _S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT { return _Rb_tree_node_base::_S_minimum(__x); } static _Const_Base_ptr _S_minimum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { return _Rb_tree_node_base::_S_minimum(__x); } static _Base_ptr _S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT { return _Rb_tree_node_base::_S_maximum(__x); } static _Const_Base_ptr _S_maximum(_Const_Base_ptr __x) _GLIBCXX_NOEXCEPT { return _Rb_tree_node_base::_S_maximum(__x); } public: typedef _Rb_tree_iterator<value_type> iterator; typedef _Rb_tree_const_iterator<value_type> const_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; #if __cplusplus > 201402L using node_type = _Node_handle<_Key, _Val, _Node_allocator>; using insert_return_type = _Node_insert_return< conditional_t<is_same_v<_Key, _Val>, const_iterator, iterator>, node_type>; #endif pair<_Base_ptr, _Base_ptr> _M_get_insert_unique_pos(const key_type& __k); pair<_Base_ptr, _Base_ptr> _M_get_insert_equal_pos(const key_type& __k); pair<_Base_ptr, _Base_ptr> _M_get_insert_hint_unique_pos(const_iterator __pos, const key_type& __k); pair<_Base_ptr, _Base_ptr> _M_get_insert_hint_equal_pos(const_iterator __pos, const key_type& __k); private: #if __cplusplus >= 201103L template<typename _Arg, typename _NodeGen> iterator _M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v, _NodeGen&); iterator _M_insert_node(_Base_ptr __x, _Base_ptr __y, _Link_type __z); template<typename _Arg> iterator _M_insert_lower(_Base_ptr __y, _Arg&& __v); template<typename _Arg> iterator _M_insert_equal_lower(_Arg&& __x); iterator _M_insert_lower_node(_Base_ptr __p, _Link_type __z); iterator _M_insert_equal_lower_node(_Link_type __z); #else template<typename _NodeGen> iterator _M_insert_(_Base_ptr __x, _Base_ptr __y, const value_type& __v, _NodeGen&); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 233. Insertion hints in associative containers. iterator _M_insert_lower(_Base_ptr __y, const value_type& __v); iterator _M_insert_equal_lower(const value_type& __x); #endif template<typename _NodeGen> _Link_type _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen&); template<typename _NodeGen> _Link_type _M_copy(const _Rb_tree& __x, _NodeGen& __gen) { _Link_type __root = _M_copy(__x._M_begin(), _M_end(), __gen); _M_leftmost() = _S_minimum(__root); _M_rightmost() = _S_maximum(__root); _M_impl._M_node_count = __x._M_impl._M_node_count; return __root; } _Link_type _M_copy(const _Rb_tree& __x) { _Alloc_node __an(*this); return _M_copy(__x, __an); } void _M_erase(_Link_type __x); iterator _M_lower_bound(_Link_type __x, _Base_ptr __y, const _Key& __k); const_iterator _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y, const _Key& __k) const; iterator _M_upper_bound(_Link_type __x, _Base_ptr __y, const _Key& __k); const_iterator _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y, const _Key& __k) const; public: // allocation/deallocation #if __cplusplus < 201103L _Rb_tree() { } #else _Rb_tree() = default; #endif _Rb_tree(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_impl(__comp, _Node_allocator(__a)) { } _Rb_tree(const _Rb_tree& __x) : _M_impl(__x._M_impl) { if (__x._M_root() != 0) _M_root() = _M_copy(__x); } #if __cplusplus >= 201103L _Rb_tree(const allocator_type& __a) : _M_impl(_Compare(), _Node_allocator(__a)) { } _Rb_tree(const _Rb_tree& __x, const allocator_type& __a) : _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a)) { if (__x._M_root() != nullptr) _M_root() = _M_copy(__x); } _Rb_tree(_Rb_tree&&) = default; _Rb_tree(_Rb_tree&& __x, const allocator_type& __a) : _Rb_tree(std::move(__x), _Node_allocator(__a)) { } _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a); #endif ~_Rb_tree() _GLIBCXX_NOEXCEPT { _M_erase(_M_begin()); } _Rb_tree& operator=(const _Rb_tree& __x); // Accessors. _Compare key_comp() const { return _M_impl._M_key_compare; } iterator begin() _GLIBCXX_NOEXCEPT { return iterator(this->_M_impl._M_header._M_left); } const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(this->_M_impl._M_header._M_left); } iterator end() _GLIBCXX_NOEXCEPT { return iterator(&this->_M_impl._M_header); } const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(&this->_M_impl._M_header); } reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(begin()); } bool empty() const _GLIBCXX_NOEXCEPT { return _M_impl._M_node_count == 0; } size_type size() const _GLIBCXX_NOEXCEPT { return _M_impl._M_node_count; } size_type max_size() const _GLIBCXX_NOEXCEPT { return _Alloc_traits::max_size(_M_get_Node_allocator()); } void swap(_Rb_tree& __t) _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value); // Insert/erase. #if __cplusplus >= 201103L template<typename _Arg> pair<iterator, bool> _M_insert_unique(_Arg&& __x); template<typename _Arg> iterator _M_insert_equal(_Arg&& __x); template<typename _Arg, typename _NodeGen> iterator _M_insert_unique_(const_iterator __pos, _Arg&& __x, _NodeGen&); template<typename _Arg> iterator _M_insert_unique_(const_iterator __pos, _Arg&& __x) { _Alloc_node __an(*this); return _M_insert_unique_(__pos, std::forward<_Arg>(__x), __an); } template<typename _Arg, typename _NodeGen> iterator _M_insert_equal_(const_iterator __pos, _Arg&& __x, _NodeGen&); template<typename _Arg> iterator _M_insert_equal_(const_iterator __pos, _Arg&& __x) { _Alloc_node __an(*this); return _M_insert_equal_(__pos, std::forward<_Arg>(__x), __an); } template<typename... _Args> pair<iterator, bool> _M_emplace_unique(_Args&&... __args); template<typename... _Args> iterator _M_emplace_equal(_Args&&... __args); template<typename... _Args> iterator _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args); template<typename... _Args> iterator _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args); #else pair<iterator, bool> _M_insert_unique(const value_type& __x); iterator _M_insert_equal(const value_type& __x); template<typename _NodeGen> iterator _M_insert_unique_(const_iterator __pos, const value_type& __x, _NodeGen&); iterator _M_insert_unique_(const_iterator __pos, const value_type& __x) { _Alloc_node __an(*this); return _M_insert_unique_(__pos, __x, __an); } template<typename _NodeGen> iterator _M_insert_equal_(const_iterator __pos, const value_type& __x, _NodeGen&); iterator _M_insert_equal_(const_iterator __pos, const value_type& __x) { _Alloc_node __an(*this); return _M_insert_equal_(__pos, __x, __an); } #endif template<typename _InputIterator> void _M_insert_unique(_InputIterator __first, _InputIterator __last); template<typename _InputIterator> void _M_insert_equal(_InputIterator __first, _InputIterator __last); private: void _M_erase_aux(const_iterator __position); void _M_erase_aux(const_iterator __first, const_iterator __last); public: #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. _GLIBCXX_ABI_TAG_CXX11 iterator erase(const_iterator __position) { __glibcxx_assert(__position != end()); const_iterator __result = __position; ++__result; _M_erase_aux(__position); return __result._M_const_cast(); } // LWG 2059. _GLIBCXX_ABI_TAG_CXX11 iterator erase(iterator __position) { __glibcxx_assert(__position != end()); iterator __result = __position; ++__result; _M_erase_aux(__position); return __result; } #else void erase(iterator __position) { __glibcxx_assert(__position != end()); _M_erase_aux(__position); } void erase(const_iterator __position) { __glibcxx_assert(__position != end()); _M_erase_aux(__position); } #endif size_type erase(const key_type& __x); #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. _GLIBCXX_ABI_TAG_CXX11 iterator erase(const_iterator __first, const_iterator __last) { _M_erase_aux(__first, __last); return __last._M_const_cast(); } #else void erase(iterator __first, iterator __last) { _M_erase_aux(__first, __last); } void erase(const_iterator __first, const_iterator __last) { _M_erase_aux(__first, __last); } #endif void erase(const key_type* __first, const key_type* __last); void clear() _GLIBCXX_NOEXCEPT { _M_erase(_M_begin()); _M_impl._M_reset(); } // Set operations. iterator find(const key_type& __k); const_iterator find(const key_type& __k) const; size_type count(const key_type& __k) const; iterator lower_bound(const key_type& __k) { return _M_lower_bound(_M_begin(), _M_end(), __k); } const_iterator lower_bound(const key_type& __k) const { return _M_lower_bound(_M_begin(), _M_end(), __k); } iterator upper_bound(const key_type& __k) { return _M_upper_bound(_M_begin(), _M_end(), __k); } const_iterator upper_bound(const key_type& __k) const { return _M_upper_bound(_M_begin(), _M_end(), __k); } pair<iterator, iterator> equal_range(const key_type& __k); pair<const_iterator, const_iterator> equal_range(const key_type& __k) const; #if __cplusplus > 201103L template<typename _Kt, typename _Req = typename __has_is_transparent<_Compare, _Kt>::type> iterator _M_find_tr(const _Kt& __k) { const _Rb_tree* __const_this = this; return __const_this->_M_find_tr(__k)._M_const_cast(); } template<typename _Kt, typename _Req = typename __has_is_transparent<_Compare, _Kt>::type> const_iterator _M_find_tr(const _Kt& __k) const { auto __j = _M_lower_bound_tr(__k); if (__j != end() && _M_impl._M_key_compare(__k, _S_key(__j._M_node))) __j = end(); return __j; } template<typename _Kt, typename _Req = typename __has_is_transparent<_Compare, _Kt>::type> size_type _M_count_tr(const _Kt& __k) const { auto __p = _M_equal_range_tr(__k); return std::distance(__p.first, __p.second); } template<typename _Kt, typename _Req = typename __has_is_transparent<_Compare, _Kt>::type> iterator _M_lower_bound_tr(const _Kt& __k) { const _Rb_tree* __const_this = this; return __const_this->_M_lower_bound_tr(__k)._M_const_cast(); } template<typename _Kt, typename _Req = typename __has_is_transparent<_Compare, _Kt>::type> const_iterator _M_lower_bound_tr(const _Kt& __k) const { auto __x = _M_begin(); auto __y = _M_end(); while (__x != 0) if (!_M_impl._M_key_compare(_S_key(__x), __k)) { __y = __x; __x = _S_left(__x); } else __x = _S_right(__x); return const_iterator(__y); } template<typename _Kt, typename _Req = typename __has_is_transparent<_Compare, _Kt>::type> iterator _M_upper_bound_tr(const _Kt& __k) { const _Rb_tree* __const_this = this; return __const_this->_M_upper_bound_tr(__k)._M_const_cast(); } template<typename _Kt, typename _Req = typename __has_is_transparent<_Compare, _Kt>::type> const_iterator _M_upper_bound_tr(const _Kt& __k) const { auto __x = _M_begin(); auto __y = _M_end(); while (__x != 0) if (_M_impl._M_key_compare(__k, _S_key(__x))) { __y = __x; __x = _S_left(__x); } else __x = _S_right(__x); return const_iterator(__y); } template<typename _Kt, typename _Req = typename __has_is_transparent<_Compare, _Kt>::type> pair<iterator, iterator> _M_equal_range_tr(const _Kt& __k) { const _Rb_tree* __const_this = this; auto __ret = __const_this->_M_equal_range_tr(__k); return { __ret.first._M_const_cast(), __ret.second._M_const_cast() }; } template<typename _Kt, typename _Req = typename __has_is_transparent<_Compare, _Kt>::type> pair<const_iterator, const_iterator> _M_equal_range_tr(const _Kt& __k) const { auto __low = _M_lower_bound_tr(__k); auto __high = __low; auto& __cmp = _M_impl._M_key_compare; while (__high != end() && !__cmp(__k, _S_key(__high._M_node))) ++__high; return { __low, __high }; } #endif // Debugging. bool __rb_verify() const; #if __cplusplus >= 201103L _Rb_tree& operator=(_Rb_tree&&) noexcept(_Alloc_traits::_S_nothrow_move() && is_nothrow_move_assignable<_Compare>::value); template<typename _Iterator> void _M_assign_unique(_Iterator, _Iterator); template<typename _Iterator> void _M_assign_equal(_Iterator, _Iterator); private: // Move elements from container with equal allocator. void _M_move_data(_Rb_tree& __x, std::true_type) { _M_impl._M_move_data(__x._M_impl); } // Move elements from container with possibly non-equal allocator, // which might result in a copy not a move. void _M_move_data(_Rb_tree&, std::false_type); // Move assignment from container with equal allocator. void _M_move_assign(_Rb_tree&, std::true_type); // Move assignment from container with possibly non-equal allocator, // which might result in a copy not a move. void _M_move_assign(_Rb_tree&, std::false_type); #endif #if __cplusplus > 201402L public: /// Re-insert an extracted node. insert_return_type _M_reinsert_node_unique(node_type&& __nh) { insert_return_type __ret; if (__nh.empty()) __ret.position = end(); else { __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc); auto __res = _M_get_insert_unique_pos(__nh._M_key()); if (__res.second) { __ret.position = _M_insert_node(__res.first, __res.second, __nh._M_ptr); __nh._M_ptr = nullptr; __ret.inserted = true; } else { __ret.node = std::move(__nh); __ret.position = iterator(__res.first); __ret.inserted = false; } } return __ret; } /// Re-insert an extracted node. iterator _M_reinsert_node_equal(node_type&& __nh) { iterator __ret; if (__nh.empty()) __ret = end(); else { __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc); auto __res = _M_get_insert_equal_pos(__nh._M_key()); if (__res.second) __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr); else __ret = _M_insert_equal_lower_node(__nh._M_ptr); __nh._M_ptr = nullptr; } return __ret; } /// Re-insert an extracted node. iterator _M_reinsert_node_hint_unique(const_iterator __hint, node_type&& __nh) { iterator __ret; if (__nh.empty()) __ret = end(); else { __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc); auto __res = _M_get_insert_hint_unique_pos(__hint, __nh._M_key()); if (__res.second) { __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr); __nh._M_ptr = nullptr; } else __ret = iterator(__res.first); } return __ret; } /// Re-insert an extracted node. iterator _M_reinsert_node_hint_equal(const_iterator __hint, node_type&& __nh) { iterator __ret; if (__nh.empty()) __ret = end(); else { __glibcxx_assert(_M_get_Node_allocator() == *__nh._M_alloc); auto __res = _M_get_insert_hint_equal_pos(__hint, __nh._M_key()); if (__res.second) __ret = _M_insert_node(__res.first, __res.second, __nh._M_ptr); else __ret = _M_insert_equal_lower_node(__nh._M_ptr); __nh._M_ptr = nullptr; } return __ret; } /// Extract a node. node_type extract(const_iterator __pos) { auto __ptr = _Rb_tree_rebalance_for_erase( __pos._M_const_cast()._M_node, _M_impl._M_header); --_M_impl._M_node_count; return { static_cast<_Link_type>(__ptr), _M_get_Node_allocator() }; } /// Extract a node. node_type extract(const key_type& __k) { node_type __nh; auto __pos = find(__k); if (__pos != end()) __nh = extract(const_iterator(__pos)); return __nh; } template<typename _Compare2> using _Compatible_tree = _Rb_tree<_Key, _Val, _KeyOfValue, _Compare2, _Alloc>; template<typename, typename> friend class _Rb_tree_merge_helper; /// Merge from a compatible container into one with unique keys. template<typename _Compare2> void _M_merge_unique(_Compatible_tree<_Compare2>& __src) noexcept { using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>; for (auto __i = __src.begin(), __end = __src.end(); __i != __end;) { auto __pos = __i++; auto __res = _M_get_insert_unique_pos(_KeyOfValue()(*__pos)); if (__res.second) { auto& __src_impl = _Merge_helper::_S_get_impl(__src); auto __ptr = _Rb_tree_rebalance_for_erase( __pos._M_node, __src_impl._M_header); --__src_impl._M_node_count; _M_insert_node(__res.first, __res.second, static_cast<_Link_type>(__ptr)); } } } /// Merge from a compatible container into one with equivalent keys. template<typename _Compare2> void _M_merge_equal(_Compatible_tree<_Compare2>& __src) noexcept { using _Merge_helper = _Rb_tree_merge_helper<_Rb_tree, _Compare2>; for (auto __i = __src.begin(), __end = __src.end(); __i != __end;) { auto __pos = __i++; auto __res = _M_get_insert_equal_pos(_KeyOfValue()(*__pos)); if (__res.second) { auto& __src_impl = _Merge_helper::_S_get_impl(__src); auto __ptr = _Rb_tree_rebalance_for_erase( __pos._M_node, __src_impl._M_header); --__src_impl._M_node_count; _M_insert_node(__res.first, __res.second, static_cast<_Link_type>(__ptr)); } } } #endif // C++17 }; template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> inline bool operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) { return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> inline bool operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) { return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> inline bool operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) { return !(__x == __y); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> inline bool operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) { return __y < __x; } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> inline bool operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) { return !(__y < __x); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> inline bool operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) { return !(__x < __y); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> inline void swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) { __x.swap(__y); } #if __cplusplus >= 201103L template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a) : _M_impl(__x._M_impl._M_key_compare, std::move(__a)) { using __eq = typename _Alloc_traits::is_always_equal; if (__x._M_root() != nullptr) _M_move_data(__x, __eq()); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_move_data(_Rb_tree& __x, std::false_type) { if (_M_get_Node_allocator() == __x._M_get_Node_allocator()) _M_move_data(__x, std::true_type()); else { _Alloc_node __an(*this); auto __lbd = [&__an](const value_type& __cval) { auto& __val = const_cast<value_type&>(__cval); return __an(std::move_if_noexcept(__val)); }; _M_root() = _M_copy(__x, __lbd); } } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> inline void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_move_assign(_Rb_tree& __x, true_type) { clear(); if (__x._M_root() != nullptr) _M_move_data(__x, std::true_type()); std::__alloc_on_move(_M_get_Node_allocator(), __x._M_get_Node_allocator()); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_move_assign(_Rb_tree& __x, false_type) { if (_M_get_Node_allocator() == __x._M_get_Node_allocator()) return _M_move_assign(__x, true_type{}); // Try to move each node reusing existing nodes and copying __x nodes // structure. _Reuse_or_alloc_node __roan(*this); _M_impl._M_reset(); if (__x._M_root() != nullptr) { auto __lbd = [&__roan](const value_type& __cval) { auto& __val = const_cast<value_type&>(__cval); return __roan(std::move_if_noexcept(__val)); }; _M_root() = _M_copy(__x, __lbd); __x.clear(); } } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> inline _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: operator=(_Rb_tree&& __x) noexcept(_Alloc_traits::_S_nothrow_move() && is_nothrow_move_assignable<_Compare>::value) { _M_impl._M_key_compare = std::move(__x._M_impl._M_key_compare); _M_move_assign(__x, __bool_constant<_Alloc_traits::_S_nothrow_move()>()); return *this; } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> template<typename _Iterator> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_assign_unique(_Iterator __first, _Iterator __last) { _Reuse_or_alloc_node __roan(*this); _M_impl._M_reset(); for (; __first != __last; ++__first) _M_insert_unique_(end(), *__first, __roan); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> template<typename _Iterator> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_assign_equal(_Iterator __first, _Iterator __last) { _Reuse_or_alloc_node __roan(*this); _M_impl._M_reset(); for (; __first != __last; ++__first) _M_insert_equal_(end(), *__first, __roan); } #endif template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: operator=(const _Rb_tree& __x) { if (this != &__x) { // Note that _Key may be a constant type. #if __cplusplus >= 201103L if (_Alloc_traits::_S_propagate_on_copy_assign()) { auto& __this_alloc = this->_M_get_Node_allocator(); auto& __that_alloc = __x._M_get_Node_allocator(); if (!_Alloc_traits::_S_always_equal() && __this_alloc != __that_alloc) { // Replacement allocator cannot free existing storage, we need // to erase nodes first. clear(); std::__alloc_on_copy(__this_alloc, __that_alloc); } } #endif _Reuse_or_alloc_node __roan(*this); _M_impl._M_reset(); _M_impl._M_key_compare = __x._M_impl._M_key_compare; if (__x._M_root() != 0) _M_root() = _M_copy(__x, __roan); } return *this; } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> #if __cplusplus >= 201103L template<typename _Arg, typename _NodeGen> #else template<typename _NodeGen> #endif typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_insert_(_Base_ptr __x, _Base_ptr __p, #if __cplusplus >= 201103L _Arg&& __v, #else const _Val& __v, #endif _NodeGen& __node_gen) { bool __insert_left = (__x != 0 || __p == _M_end() || _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__p))); _Link_type __z = __node_gen(_GLIBCXX_FORWARD(_Arg, __v)); _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, this->_M_impl._M_header); ++_M_impl._M_node_count; return iterator(__z); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> #if __cplusplus >= 201103L template<typename _Arg> #endif typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: #if __cplusplus >= 201103L _M_insert_lower(_Base_ptr __p, _Arg&& __v) #else _M_insert_lower(_Base_ptr __p, const _Val& __v) #endif { bool __insert_left = (__p == _M_end() || !_M_impl._M_key_compare(_S_key(__p), _KeyOfValue()(__v))); _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v)); _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, this->_M_impl._M_header); ++_M_impl._M_node_count; return iterator(__z); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> #if __cplusplus >= 201103L template<typename _Arg> #endif typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: #if __cplusplus >= 201103L _M_insert_equal_lower(_Arg&& __v) #else _M_insert_equal_lower(const _Val& __v) #endif { _Link_type __x = _M_begin(); _Base_ptr __y = _M_end(); while (__x != 0) { __y = __x; __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ? _S_left(__x) : _S_right(__x); } return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v)); } template<typename _Key, typename _Val, typename _KoV, typename _Compare, typename _Alloc> template<typename _NodeGen> typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>:: _M_copy(_Const_Link_type __x, _Base_ptr __p, _NodeGen& __node_gen) { // Structural copy. __x and __p must be non-null. _Link_type __top = _M_clone_node(__x, __node_gen); __top->_M_parent = __p; __try { if (__x->_M_right) __top->_M_right = _M_copy(_S_right(__x), __top, __node_gen); __p = __top; __x = _S_left(__x); while (__x != 0) { _Link_type __y = _M_clone_node(__x, __node_gen); __p->_M_left = __y; __y->_M_parent = __p; if (__x->_M_right) __y->_M_right = _M_copy(_S_right(__x), __y, __node_gen); __p = __y; __x = _S_left(__x); } } __catch(...) { _M_erase(__top); __throw_exception_again; } return __top; } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_erase(_Link_type __x) { // Erase without rebalancing. while (__x != 0) { _M_erase(_S_right(__x)); _Link_type __y = _S_left(__x); _M_drop_node(__x); __x = __y; } } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_lower_bound(_Link_type __x, _Base_ptr __y, const _Key& __k) { while (__x != 0) if (!_M_impl._M_key_compare(_S_key(__x), __k)) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); return iterator(__y); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_lower_bound(_Const_Link_type __x, _Const_Base_ptr __y, const _Key& __k) const { while (__x != 0) if (!_M_impl._M_key_compare(_S_key(__x), __k)) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); return const_iterator(__y); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_upper_bound(_Link_type __x, _Base_ptr __y, const _Key& __k) { while (__x != 0) if (_M_impl._M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); return iterator(__y); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_upper_bound(_Const_Link_type __x, _Const_Base_ptr __y, const _Key& __k) const { while (__x != 0) if (_M_impl._M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); return const_iterator(__y); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: equal_range(const _Key& __k) { _Link_type __x = _M_begin(); _Base_ptr __y = _M_end(); while (__x != 0) { if (_M_impl._M_key_compare(_S_key(__x), __k)) __x = _S_right(__x); else if (_M_impl._M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else { _Link_type __xu(__x); _Base_ptr __yu(__y); __y = __x, __x = _S_left(__x); __xu = _S_right(__xu); return pair<iterator, iterator>(_M_lower_bound(__x, __y, __k), _M_upper_bound(__xu, __yu, __k)); } } return pair<iterator, iterator>(iterator(__y), iterator(__y)); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: equal_range(const _Key& __k) const { _Const_Link_type __x = _M_begin(); _Const_Base_ptr __y = _M_end(); while (__x != 0) { if (_M_impl._M_key_compare(_S_key(__x), __k)) __x = _S_right(__x); else if (_M_impl._M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else { _Const_Link_type __xu(__x); _Const_Base_ptr __yu(__y); __y = __x, __x = _S_left(__x); __xu = _S_right(__xu); return pair<const_iterator, const_iterator>(_M_lower_bound(__x, __y, __k), _M_upper_bound(__xu, __yu, __k)); } } return pair<const_iterator, const_iterator>(const_iterator(__y), const_iterator(__y)); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: swap(_Rb_tree& __t) _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value) { if (_M_root() == 0) { if (__t._M_root() != 0) _M_impl._M_move_data(__t._M_impl); } else if (__t._M_root() == 0) __t._M_impl._M_move_data(_M_impl); else { std::swap(_M_root(),__t._M_root()); std::swap(_M_leftmost(),__t._M_leftmost()); std::swap(_M_rightmost(),__t._M_rightmost()); _M_root()->_M_parent = _M_end(); __t._M_root()->_M_parent = __t._M_end(); std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count); } // No need to swap header's color as it does not change. std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare); _Alloc_traits::_S_on_swap(_M_get_Node_allocator(), __t._M_get_Node_allocator()); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_get_insert_unique_pos(const key_type& __k) { typedef pair<_Base_ptr, _Base_ptr> _Res; _Link_type __x = _M_begin(); _Base_ptr __y = _M_end(); bool __comp = true; while (__x != 0) { __y = __x; __comp = _M_impl._M_key_compare(__k, _S_key(__x)); __x = __comp ? _S_left(__x) : _S_right(__x); } iterator __j = iterator(__y); if (__comp) { if (__j == begin()) return _Res(__x, __y); else --__j; } if (_M_impl._M_key_compare(_S_key(__j._M_node), __k)) return _Res(__x, __y); return _Res(__j._M_node, 0); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_get_insert_equal_pos(const key_type& __k) { typedef pair<_Base_ptr, _Base_ptr> _Res; _Link_type __x = _M_begin(); _Base_ptr __y = _M_end(); while (__x != 0) { __y = __x; __x = _M_impl._M_key_compare(__k, _S_key(__x)) ? _S_left(__x) : _S_right(__x); } return _Res(__x, __y); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> #if __cplusplus >= 201103L template<typename _Arg> #endif pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: #if __cplusplus >= 201103L _M_insert_unique(_Arg&& __v) #else _M_insert_unique(const _Val& __v) #endif { typedef pair<iterator, bool> _Res; pair<_Base_ptr, _Base_ptr> __res = _M_get_insert_unique_pos(_KeyOfValue()(__v)); if (__res.second) { _Alloc_node __an(*this); return _Res(_M_insert_(__res.first, __res.second, _GLIBCXX_FORWARD(_Arg, __v), __an), true); } return _Res(iterator(__res.first), false); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> #if __cplusplus >= 201103L template<typename _Arg> #endif typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: #if __cplusplus >= 201103L _M_insert_equal(_Arg&& __v) #else _M_insert_equal(const _Val& __v) #endif { pair<_Base_ptr, _Base_ptr> __res = _M_get_insert_equal_pos(_KeyOfValue()(__v)); _Alloc_node __an(*this); return _M_insert_(__res.first, __res.second, _GLIBCXX_FORWARD(_Arg, __v), __an); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_get_insert_hint_unique_pos(const_iterator __position, const key_type& __k) { iterator __pos = __position._M_const_cast(); typedef pair<_Base_ptr, _Base_ptr> _Res; // end() if (__pos._M_node == _M_end()) { if (size() > 0 && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k)) return _Res(0, _M_rightmost()); else return _M_get_insert_unique_pos(__k); } else if (_M_impl._M_key_compare(__k, _S_key(__pos._M_node))) { // First, try before... iterator __before = __pos; if (__pos._M_node == _M_leftmost()) // begin() return _Res(_M_leftmost(), _M_leftmost()); else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k)) { if (_S_right(__before._M_node) == 0) return _Res(0, __before._M_node); else return _Res(__pos._M_node, __pos._M_node); } else return _M_get_insert_unique_pos(__k); } else if (_M_impl._M_key_compare(_S_key(__pos._M_node), __k)) { // ... then try after. iterator __after = __pos; if (__pos._M_node == _M_rightmost()) return _Res(0, _M_rightmost()); else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node))) { if (_S_right(__pos._M_node) == 0) return _Res(0, __pos._M_node); else return _Res(__after._M_node, __after._M_node); } else return _M_get_insert_unique_pos(__k); } else // Equivalent keys. return _Res(__pos._M_node, 0); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> #if __cplusplus >= 201103L template<typename _Arg, typename _NodeGen> #else template<typename _NodeGen> #endif typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_insert_unique_(const_iterator __position, #if __cplusplus >= 201103L _Arg&& __v, #else const _Val& __v, #endif _NodeGen& __node_gen) { pair<_Base_ptr, _Base_ptr> __res = _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v)); if (__res.second) return _M_insert_(__res.first, __res.second, _GLIBCXX_FORWARD(_Arg, __v), __node_gen); return iterator(__res.first); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_get_insert_hint_equal_pos(const_iterator __position, const key_type& __k) { iterator __pos = __position._M_const_cast(); typedef pair<_Base_ptr, _Base_ptr> _Res; // end() if (__pos._M_node == _M_end()) { if (size() > 0 && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost()))) return _Res(0, _M_rightmost()); else return _M_get_insert_equal_pos(__k); } else if (!_M_impl._M_key_compare(_S_key(__pos._M_node), __k)) { // First, try before... iterator __before = __pos; if (__pos._M_node == _M_leftmost()) // begin() return _Res(_M_leftmost(), _M_leftmost()); else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node))) { if (_S_right(__before._M_node) == 0) return _Res(0, __before._M_node); else return _Res(__pos._M_node, __pos._M_node); } else return _M_get_insert_equal_pos(__k); } else { // ... then try after. iterator __after = __pos; if (__pos._M_node == _M_rightmost()) return _Res(0, _M_rightmost()); else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k)) { if (_S_right(__pos._M_node) == 0) return _Res(0, __pos._M_node); else return _Res(__after._M_node, __after._M_node); } else return _Res(0, 0); } } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> #if __cplusplus >= 201103L template<typename _Arg, typename _NodeGen> #else template<typename _NodeGen> #endif typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_insert_equal_(const_iterator __position, #if __cplusplus >= 201103L _Arg&& __v, #else const _Val& __v, #endif _NodeGen& __node_gen) { pair<_Base_ptr, _Base_ptr> __res = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v)); if (__res.second) return _M_insert_(__res.first, __res.second, _GLIBCXX_FORWARD(_Arg, __v), __node_gen); return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v)); } #if __cplusplus >= 201103L template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_insert_node(_Base_ptr __x, _Base_ptr __p, _Link_type __z) { bool __insert_left = (__x != 0 || __p == _M_end() || _M_impl._M_key_compare(_S_key(__z), _S_key(__p))); _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, this->_M_impl._M_header); ++_M_impl._M_node_count; return iterator(__z); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_insert_lower_node(_Base_ptr __p, _Link_type __z) { bool __insert_left = (__p == _M_end() || !_M_impl._M_key_compare(_S_key(__p), _S_key(__z))); _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, this->_M_impl._M_header); ++_M_impl._M_node_count; return iterator(__z); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_insert_equal_lower_node(_Link_type __z) { _Link_type __x = _M_begin(); _Base_ptr __y = _M_end(); while (__x != 0) { __y = __x; __x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ? _S_left(__x) : _S_right(__x); } return _M_insert_lower_node(__y, __z); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> template<typename... _Args> pair<typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_emplace_unique(_Args&&... __args) { _Link_type __z = _M_create_node(std::forward<_Args>(__args)...); __try { typedef pair<iterator, bool> _Res; auto __res = _M_get_insert_unique_pos(_S_key(__z)); if (__res.second) return _Res(_M_insert_node(__res.first, __res.second, __z), true); _M_drop_node(__z); return _Res(iterator(__res.first), false); } __catch(...) { _M_drop_node(__z); __throw_exception_again; } } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> template<typename... _Args> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_emplace_equal(_Args&&... __args) { _Link_type __z = _M_create_node(std::forward<_Args>(__args)...); __try { auto __res = _M_get_insert_equal_pos(_S_key(__z)); return _M_insert_node(__res.first, __res.second, __z); } __catch(...) { _M_drop_node(__z); __throw_exception_again; } } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> template<typename... _Args> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_emplace_hint_unique(const_iterator __pos, _Args&&... __args) { _Link_type __z = _M_create_node(std::forward<_Args>(__args)...); __try { auto __res = _M_get_insert_hint_unique_pos(__pos, _S_key(__z)); if (__res.second) return _M_insert_node(__res.first, __res.second, __z); _M_drop_node(__z); return iterator(__res.first); } __catch(...) { _M_drop_node(__z); __throw_exception_again; } } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> template<typename... _Args> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_emplace_hint_equal(const_iterator __pos, _Args&&... __args) { _Link_type __z = _M_create_node(std::forward<_Args>(__args)...); __try { auto __res = _M_get_insert_hint_equal_pos(__pos, _S_key(__z)); if (__res.second) return _M_insert_node(__res.first, __res.second, __z); return _M_insert_equal_lower_node(__z); } __catch(...) { _M_drop_node(__z); __throw_exception_again; } } #endif template<typename _Key, typename _Val, typename _KoV, typename _Cmp, typename _Alloc> template<class _II> void _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: _M_insert_unique(_II __first, _II __last) { _Alloc_node __an(*this); for (; __first != __last; ++__first) _M_insert_unique_(end(), *__first, __an); } template<typename _Key, typename _Val, typename _KoV, typename _Cmp, typename _Alloc> template<class _II> void _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: _M_insert_equal(_II __first, _II __last) { _Alloc_node __an(*this); for (; __first != __last; ++__first) _M_insert_equal_(end(), *__first, __an); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_erase_aux(const_iterator __position) { _Link_type __y = static_cast<_Link_type>(_Rb_tree_rebalance_for_erase (const_cast<_Base_ptr>(__position._M_node), this->_M_impl._M_header)); _M_drop_node(__y); --_M_impl._M_node_count; } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: _M_erase_aux(const_iterator __first, const_iterator __last) { if (__first == begin() && __last == end()) clear(); else while (__first != __last) _M_erase_aux(__first++); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: erase(const _Key& __x) { pair<iterator, iterator> __p = equal_range(__x); const size_type __old_size = size(); _M_erase_aux(__p.first, __p.second); return __old_size - size(); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: erase(const _Key* __first, const _Key* __last) { while (__first != __last) erase(*__first++); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: find(const _Key& __k) { iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k); return (__j == end() || _M_impl._M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: find(const _Key& __k) const { const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k); return (__j == end() || _M_impl._M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: count(const _Key& __k) const { pair<const_iterator, const_iterator> __p = equal_range(__k); const size_type __n = std::distance(__p.first, __p.second); return __n; } _GLIBCXX_PURE unsigned int _Rb_tree_black_count(const _Rb_tree_node_base* __node, const _Rb_tree_node_base* __root) throw (); template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> bool _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const { if (_M_impl._M_node_count == 0 || begin() == end()) return _M_impl._M_node_count == 0 && begin() == end() && this->_M_impl._M_header._M_left == _M_end() && this->_M_impl._M_header._M_right == _M_end(); unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root()); for (const_iterator __it = begin(); __it != end(); ++__it) { _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node); _Const_Link_type __L = _S_left(__x); _Const_Link_type __R = _S_right(__x); if (__x->_M_color == _S_red) if ((__L && __L->_M_color == _S_red) || (__R && __R->_M_color == _S_red)) return false; if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) return false; if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) return false; if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) return false; } if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) return false; if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) return false; return true; } #if __cplusplus > 201402L // Allow access to internals of compatible _Rb_tree specializations. template<typename _Key, typename _Val, typename _Sel, typename _Cmp1, typename _Alloc, typename _Cmp2> struct _Rb_tree_merge_helper<_Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>, _Cmp2> { private: friend class _Rb_tree<_Key, _Val, _Sel, _Cmp1, _Alloc>; static auto& _S_get_impl(_Rb_tree<_Key, _Val, _Sel, _Cmp2, _Alloc>& __tree) { return __tree._M_impl; } }; #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/bits/stl_iterator.h 0000644 00000122463 15146341150 0011120 0 ustar 00 // Iterators -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_iterator.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iterator} * * This file implements reverse_iterator, back_insert_iterator, * front_insert_iterator, insert_iterator, __normal_iterator, and their * supporting functions and overloaded operators. */ #ifndef _STL_ITERATOR_H #define _STL_ITERATOR_H 1 #include <bits/cpp_type_traits.h> #include <ext/type_traits.h> #include <bits/move.h> #include <bits/ptr_traits.h> #if __cplusplus > 201402L # define __cpp_lib_array_constexpr 201603 #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup iterators * @{ */ // 24.4.1 Reverse iterators /** * Bidirectional and random access iterators have corresponding reverse * %iterator adaptors that iterate through the data structure in the * opposite direction. They have the same signatures as the corresponding * iterators. The fundamental relation between a reverse %iterator and its * corresponding %iterator @c i is established by the identity: * @code * &*(reverse_iterator(i)) == &*(i - 1) * @endcode * * <em>This mapping is dictated by the fact that while there is always a * pointer past the end of an array, there might not be a valid pointer * before the beginning of an array.</em> [24.4.1]/1,2 * * Reverse iterators can be tricky and surprising at first. Their * semantics make sense, however, and the trickiness is a side effect of * the requirement that the iterators must be safe. */ template<typename _Iterator> class reverse_iterator : public iterator<typename iterator_traits<_Iterator>::iterator_category, typename iterator_traits<_Iterator>::value_type, typename iterator_traits<_Iterator>::difference_type, typename iterator_traits<_Iterator>::pointer, typename iterator_traits<_Iterator>::reference> { protected: _Iterator current; typedef iterator_traits<_Iterator> __traits_type; public: typedef _Iterator iterator_type; typedef typename __traits_type::difference_type difference_type; typedef typename __traits_type::pointer pointer; typedef typename __traits_type::reference reference; /** * The default constructor value-initializes member @p current. * If it is a pointer, that means it is zero-initialized. */ // _GLIBCXX_RESOLVE_LIB_DEFECTS // 235 No specification of default ctor for reverse_iterator // 1012. reverse_iterator default ctor should value initialize _GLIBCXX17_CONSTEXPR reverse_iterator() : current() { } /** * This %iterator will move in the opposite direction that @p x does. */ explicit _GLIBCXX17_CONSTEXPR reverse_iterator(iterator_type __x) : current(__x) { } /** * The copy constructor is normal. */ _GLIBCXX17_CONSTEXPR reverse_iterator(const reverse_iterator& __x) : current(__x.current) { } /** * A %reverse_iterator across other types can be copied if the * underlying %iterator can be converted to the type of @c current. */ template<typename _Iter> _GLIBCXX17_CONSTEXPR reverse_iterator(const reverse_iterator<_Iter>& __x) : current(__x.base()) { } /** * @return @c current, the %iterator used for underlying work. */ _GLIBCXX17_CONSTEXPR iterator_type base() const { return current; } /** * @return A reference to the value at @c --current * * This requires that @c --current is dereferenceable. * * @warning This implementation requires that for an iterator of the * underlying iterator type, @c x, a reference obtained by * @c *x remains valid after @c x has been modified or * destroyed. This is a bug: http://gcc.gnu.org/PR51823 */ _GLIBCXX17_CONSTEXPR reference operator*() const { _Iterator __tmp = current; return *--__tmp; } /** * @return A pointer to the value at @c --current * * This requires that @c --current is dereferenceable. */ // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2188. Reverse iterator does not fully support targets that overload & _GLIBCXX17_CONSTEXPR pointer operator->() const { return std::__addressof(operator*()); } /** * @return @c *this * * Decrements the underlying iterator. */ _GLIBCXX17_CONSTEXPR reverse_iterator& operator++() { --current; return *this; } /** * @return The original value of @c *this * * Decrements the underlying iterator. */ _GLIBCXX17_CONSTEXPR reverse_iterator operator++(int) { reverse_iterator __tmp = *this; --current; return __tmp; } /** * @return @c *this * * Increments the underlying iterator. */ _GLIBCXX17_CONSTEXPR reverse_iterator& operator--() { ++current; return *this; } /** * @return A reverse_iterator with the previous value of @c *this * * Increments the underlying iterator. */ _GLIBCXX17_CONSTEXPR reverse_iterator operator--(int) { reverse_iterator __tmp = *this; ++current; return __tmp; } /** * @return A reverse_iterator that refers to @c current - @a __n * * The underlying iterator must be a Random Access Iterator. */ _GLIBCXX17_CONSTEXPR reverse_iterator operator+(difference_type __n) const { return reverse_iterator(current - __n); } /** * @return *this * * Moves the underlying iterator backwards @a __n steps. * The underlying iterator must be a Random Access Iterator. */ _GLIBCXX17_CONSTEXPR reverse_iterator& operator+=(difference_type __n) { current -= __n; return *this; } /** * @return A reverse_iterator that refers to @c current - @a __n * * The underlying iterator must be a Random Access Iterator. */ _GLIBCXX17_CONSTEXPR reverse_iterator operator-(difference_type __n) const { return reverse_iterator(current + __n); } /** * @return *this * * Moves the underlying iterator forwards @a __n steps. * The underlying iterator must be a Random Access Iterator. */ _GLIBCXX17_CONSTEXPR reverse_iterator& operator-=(difference_type __n) { current += __n; return *this; } /** * @return The value at @c current - @a __n - 1 * * The underlying iterator must be a Random Access Iterator. */ _GLIBCXX17_CONSTEXPR reference operator[](difference_type __n) const { return *(*this + __n); } }; //@{ /** * @param __x A %reverse_iterator. * @param __y A %reverse_iterator. * @return A simple bool. * * Reverse iterators forward many operations to their underlying base() * iterators. Others are implemented in terms of one another. * */ template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator==(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __x.base() == __y.base(); } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator<(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __y.base() < __x.base(); } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator!=(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__x == __y); } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator>(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __y < __x; } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator<=(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__y < __x); } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator>=(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return !(__x < __y); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 280. Comparison of reverse_iterator to const reverse_iterator. template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator==(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return __x.base() == __y.base(); } template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator<(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return __y.base() < __x.base(); } template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator!=(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return !(__x == __y); } template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator>(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return __y < __x; } template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator<=(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return !(__y < __x); } template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator>=(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return !(__x < __y); } //@} #if __cplusplus < 201103L template<typename _Iterator> inline typename reverse_iterator<_Iterator>::difference_type operator-(const reverse_iterator<_Iterator>& __x, const reverse_iterator<_Iterator>& __y) { return __y.base() - __x.base(); } template<typename _IteratorL, typename _IteratorR> inline typename reverse_iterator<_IteratorL>::difference_type operator-(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) { return __y.base() - __x.base(); } #else // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 685. reverse_iterator/move_iterator difference has invalid signatures template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR auto operator-(const reverse_iterator<_IteratorL>& __x, const reverse_iterator<_IteratorR>& __y) -> decltype(__y.base() - __x.base()) { return __y.base() - __x.base(); } #endif template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator> operator+(typename reverse_iterator<_Iterator>::difference_type __n, const reverse_iterator<_Iterator>& __x) { return reverse_iterator<_Iterator>(__x.base() - __n); } #if __cplusplus >= 201103L // Same as C++14 make_reverse_iterator but used in C++03 mode too. template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator> __make_reverse_iterator(_Iterator __i) { return reverse_iterator<_Iterator>(__i); } # if __cplusplus > 201103L # define __cpp_lib_make_reverse_iterator 201402 // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 2285. make_reverse_iterator /// Generator function for reverse_iterator. template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator> make_reverse_iterator(_Iterator __i) { return reverse_iterator<_Iterator>(__i); } # endif #endif #if __cplusplus >= 201103L template<typename _Iterator> auto __niter_base(reverse_iterator<_Iterator> __it) -> decltype(__make_reverse_iterator(__niter_base(__it.base()))) { return __make_reverse_iterator(__niter_base(__it.base())); } template<typename _Iterator> struct __is_move_iterator<reverse_iterator<_Iterator> > : __is_move_iterator<_Iterator> { }; template<typename _Iterator> auto __miter_base(reverse_iterator<_Iterator> __it) -> decltype(__make_reverse_iterator(__miter_base(__it.base()))) { return __make_reverse_iterator(__miter_base(__it.base())); } #endif // 24.4.2.2.1 back_insert_iterator /** * @brief Turns assignment into insertion. * * These are output iterators, constructed from a container-of-T. * Assigning a T to the iterator appends it to the container using * push_back. * * Tip: Using the back_inserter function to create these iterators can * save typing. */ template<typename _Container> class back_insert_iterator : public iterator<output_iterator_tag, void, void, void, void> { protected: _Container* container; public: /// A nested typedef for the type of whatever container you used. typedef _Container container_type; /// The only way to create this %iterator is with a container. explicit back_insert_iterator(_Container& __x) : container(std::__addressof(__x)) { } /** * @param __value An instance of whatever type * container_type::const_reference is; presumably a * reference-to-const T for container<T>. * @return This %iterator, for chained operations. * * This kind of %iterator doesn't really have a @a position in the * container (you can think of the position as being permanently at * the end, if you like). Assigning a value to the %iterator will * always append the value to the end of the container. */ #if __cplusplus < 201103L back_insert_iterator& operator=(typename _Container::const_reference __value) { container->push_back(__value); return *this; } #else back_insert_iterator& operator=(const typename _Container::value_type& __value) { container->push_back(__value); return *this; } back_insert_iterator& operator=(typename _Container::value_type&& __value) { container->push_back(std::move(__value)); return *this; } #endif /// Simply returns *this. back_insert_iterator& operator*() { return *this; } /// Simply returns *this. (This %iterator does not @a move.) back_insert_iterator& operator++() { return *this; } /// Simply returns *this. (This %iterator does not @a move.) back_insert_iterator operator++(int) { return *this; } }; /** * @param __x A container of arbitrary type. * @return An instance of back_insert_iterator working on @p __x. * * This wrapper function helps in creating back_insert_iterator instances. * Typing the name of the %iterator requires knowing the precise full * type of the container, which can be tedious and impedes generic * programming. Using this function lets you take advantage of automatic * template parameter deduction, making the compiler match the correct * types for you. */ template<typename _Container> inline back_insert_iterator<_Container> back_inserter(_Container& __x) { return back_insert_iterator<_Container>(__x); } /** * @brief Turns assignment into insertion. * * These are output iterators, constructed from a container-of-T. * Assigning a T to the iterator prepends it to the container using * push_front. * * Tip: Using the front_inserter function to create these iterators can * save typing. */ template<typename _Container> class front_insert_iterator : public iterator<output_iterator_tag, void, void, void, void> { protected: _Container* container; public: /// A nested typedef for the type of whatever container you used. typedef _Container container_type; /// The only way to create this %iterator is with a container. explicit front_insert_iterator(_Container& __x) : container(std::__addressof(__x)) { } /** * @param __value An instance of whatever type * container_type::const_reference is; presumably a * reference-to-const T for container<T>. * @return This %iterator, for chained operations. * * This kind of %iterator doesn't really have a @a position in the * container (you can think of the position as being permanently at * the front, if you like). Assigning a value to the %iterator will * always prepend the value to the front of the container. */ #if __cplusplus < 201103L front_insert_iterator& operator=(typename _Container::const_reference __value) { container->push_front(__value); return *this; } #else front_insert_iterator& operator=(const typename _Container::value_type& __value) { container->push_front(__value); return *this; } front_insert_iterator& operator=(typename _Container::value_type&& __value) { container->push_front(std::move(__value)); return *this; } #endif /// Simply returns *this. front_insert_iterator& operator*() { return *this; } /// Simply returns *this. (This %iterator does not @a move.) front_insert_iterator& operator++() { return *this; } /// Simply returns *this. (This %iterator does not @a move.) front_insert_iterator operator++(int) { return *this; } }; /** * @param __x A container of arbitrary type. * @return An instance of front_insert_iterator working on @p x. * * This wrapper function helps in creating front_insert_iterator instances. * Typing the name of the %iterator requires knowing the precise full * type of the container, which can be tedious and impedes generic * programming. Using this function lets you take advantage of automatic * template parameter deduction, making the compiler match the correct * types for you. */ template<typename _Container> inline front_insert_iterator<_Container> front_inserter(_Container& __x) { return front_insert_iterator<_Container>(__x); } /** * @brief Turns assignment into insertion. * * These are output iterators, constructed from a container-of-T. * Assigning a T to the iterator inserts it in the container at the * %iterator's position, rather than overwriting the value at that * position. * * (Sequences will actually insert a @e copy of the value before the * %iterator's position.) * * Tip: Using the inserter function to create these iterators can * save typing. */ template<typename _Container> class insert_iterator : public iterator<output_iterator_tag, void, void, void, void> { protected: _Container* container; typename _Container::iterator iter; public: /// A nested typedef for the type of whatever container you used. typedef _Container container_type; /** * The only way to create this %iterator is with a container and an * initial position (a normal %iterator into the container). */ insert_iterator(_Container& __x, typename _Container::iterator __i) : container(std::__addressof(__x)), iter(__i) {} /** * @param __value An instance of whatever type * container_type::const_reference is; presumably a * reference-to-const T for container<T>. * @return This %iterator, for chained operations. * * This kind of %iterator maintains its own position in the * container. Assigning a value to the %iterator will insert the * value into the container at the place before the %iterator. * * The position is maintained such that subsequent assignments will * insert values immediately after one another. For example, * @code * // vector v contains A and Z * * insert_iterator i (v, ++v.begin()); * i = 1; * i = 2; * i = 3; * * // vector v contains A, 1, 2, 3, and Z * @endcode */ #if __cplusplus < 201103L insert_iterator& operator=(typename _Container::const_reference __value) { iter = container->insert(iter, __value); ++iter; return *this; } #else insert_iterator& operator=(const typename _Container::value_type& __value) { iter = container->insert(iter, __value); ++iter; return *this; } insert_iterator& operator=(typename _Container::value_type&& __value) { iter = container->insert(iter, std::move(__value)); ++iter; return *this; } #endif /// Simply returns *this. insert_iterator& operator*() { return *this; } /// Simply returns *this. (This %iterator does not @a move.) insert_iterator& operator++() { return *this; } /// Simply returns *this. (This %iterator does not @a move.) insert_iterator& operator++(int) { return *this; } }; /** * @param __x A container of arbitrary type. * @param __i An iterator into the container. * @return An instance of insert_iterator working on @p __x. * * This wrapper function helps in creating insert_iterator instances. * Typing the name of the %iterator requires knowing the precise full * type of the container, which can be tedious and impedes generic * programming. Using this function lets you take advantage of automatic * template parameter deduction, making the compiler match the correct * types for you. */ template<typename _Container, typename _Iterator> inline insert_iterator<_Container> inserter(_Container& __x, _Iterator __i) { return insert_iterator<_Container>(__x, typename _Container::iterator(__i)); } // @} group iterators _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // This iterator adapter is @a normal in the sense that it does not // change the semantics of any of the operators of its iterator // parameter. Its primary purpose is to convert an iterator that is // not a class, e.g. a pointer, into an iterator that is a class. // The _Container parameter exists solely so that different containers // using this template can instantiate different types, even if the // _Iterator parameter is the same. using std::iterator_traits; using std::iterator; template<typename _Iterator, typename _Container> class __normal_iterator { protected: _Iterator _M_current; typedef iterator_traits<_Iterator> __traits_type; public: typedef _Iterator iterator_type; typedef typename __traits_type::iterator_category iterator_category; typedef typename __traits_type::value_type value_type; typedef typename __traits_type::difference_type difference_type; typedef typename __traits_type::reference reference; typedef typename __traits_type::pointer pointer; _GLIBCXX_CONSTEXPR __normal_iterator() _GLIBCXX_NOEXCEPT : _M_current(_Iterator()) { } explicit __normal_iterator(const _Iterator& __i) _GLIBCXX_NOEXCEPT : _M_current(__i) { } // Allow iterator to const_iterator conversion template<typename _Iter> __normal_iterator(const __normal_iterator<_Iter, typename __enable_if< (std::__are_same<_Iter, typename _Container::pointer>::__value), _Container>::__type>& __i) _GLIBCXX_NOEXCEPT : _M_current(__i.base()) { } // Forward iterator requirements reference operator*() const _GLIBCXX_NOEXCEPT { return *_M_current; } pointer operator->() const _GLIBCXX_NOEXCEPT { return _M_current; } __normal_iterator& operator++() _GLIBCXX_NOEXCEPT { ++_M_current; return *this; } __normal_iterator operator++(int) _GLIBCXX_NOEXCEPT { return __normal_iterator(_M_current++); } // Bidirectional iterator requirements __normal_iterator& operator--() _GLIBCXX_NOEXCEPT { --_M_current; return *this; } __normal_iterator operator--(int) _GLIBCXX_NOEXCEPT { return __normal_iterator(_M_current--); } // Random access iterator requirements reference operator[](difference_type __n) const _GLIBCXX_NOEXCEPT { return _M_current[__n]; } __normal_iterator& operator+=(difference_type __n) _GLIBCXX_NOEXCEPT { _M_current += __n; return *this; } __normal_iterator operator+(difference_type __n) const _GLIBCXX_NOEXCEPT { return __normal_iterator(_M_current + __n); } __normal_iterator& operator-=(difference_type __n) _GLIBCXX_NOEXCEPT { _M_current -= __n; return *this; } __normal_iterator operator-(difference_type __n) const _GLIBCXX_NOEXCEPT { return __normal_iterator(_M_current - __n); } const _Iterator& base() const _GLIBCXX_NOEXCEPT { return _M_current; } }; // Note: In what follows, the left- and right-hand-side iterators are // allowed to vary in types (conceptually in cv-qualification) so that // comparison between cv-qualified and non-cv-qualified iterators be // valid. However, the greedy and unfriendly operators in std::rel_ops // will make overload resolution ambiguous (when in scope) if we don't // provide overloads whose operands are of the same type. Can someone // remind me what generic programming is about? -- Gaby // Forward iterator requirements template<typename _IteratorL, typename _IteratorR, typename _Container> inline bool operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() == __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator==(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() == __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> inline bool operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() != __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() != __rhs.base(); } // Random access iterator requirements template<typename _IteratorL, typename _IteratorR, typename _Container> inline bool operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() < __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator<(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() < __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> inline bool operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() > __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator>(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() > __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> inline bool operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() <= __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() <= __rhs.base(); } template<typename _IteratorL, typename _IteratorR, typename _Container> inline bool operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() >= __rhs.base(); } template<typename _Iterator, typename _Container> inline bool operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() >= __rhs.base(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // According to the resolution of DR179 not only the various comparison // operators but also operator- must accept mixed iterator/const_iterator // parameters. template<typename _IteratorL, typename _IteratorR, typename _Container> #if __cplusplus >= 201103L // DR 685. inline auto operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept -> decltype(__lhs.base() - __rhs.base()) #else inline typename __normal_iterator<_IteratorL, _Container>::difference_type operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) #endif { return __lhs.base() - __rhs.base(); } template<typename _Iterator, typename _Container> inline typename __normal_iterator<_Iterator, _Container>::difference_type operator-(const __normal_iterator<_Iterator, _Container>& __lhs, const __normal_iterator<_Iterator, _Container>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.base() - __rhs.base(); } template<typename _Iterator, typename _Container> inline __normal_iterator<_Iterator, _Container> operator+(typename __normal_iterator<_Iterator, _Container>::difference_type __n, const __normal_iterator<_Iterator, _Container>& __i) _GLIBCXX_NOEXCEPT { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Iterator, typename _Container> _Iterator __niter_base(__gnu_cxx::__normal_iterator<_Iterator, _Container> __it) { return __it.base(); } #if __cplusplus >= 201103L /** * @addtogroup iterators * @{ */ // 24.4.3 Move iterators /** * Class template move_iterator is an iterator adapter with the same * behavior as the underlying iterator except that its dereference * operator implicitly converts the value returned by the underlying * iterator's dereference operator to an rvalue reference. Some * generic algorithms can be called with move iterators to replace * copying with moving. */ template<typename _Iterator> class move_iterator { protected: _Iterator _M_current; typedef iterator_traits<_Iterator> __traits_type; typedef typename __traits_type::reference __base_ref; public: typedef _Iterator iterator_type; typedef typename __traits_type::iterator_category iterator_category; typedef typename __traits_type::value_type value_type; typedef typename __traits_type::difference_type difference_type; // NB: DR 680. typedef _Iterator pointer; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2106. move_iterator wrapping iterators returning prvalues typedef typename conditional<is_reference<__base_ref>::value, typename remove_reference<__base_ref>::type&&, __base_ref>::type reference; _GLIBCXX17_CONSTEXPR move_iterator() : _M_current() { } explicit _GLIBCXX17_CONSTEXPR move_iterator(iterator_type __i) : _M_current(__i) { } template<typename _Iter> _GLIBCXX17_CONSTEXPR move_iterator(const move_iterator<_Iter>& __i) : _M_current(__i.base()) { } _GLIBCXX17_CONSTEXPR iterator_type base() const { return _M_current; } _GLIBCXX17_CONSTEXPR reference operator*() const { return static_cast<reference>(*_M_current); } _GLIBCXX17_CONSTEXPR pointer operator->() const { return _M_current; } _GLIBCXX17_CONSTEXPR move_iterator& operator++() { ++_M_current; return *this; } _GLIBCXX17_CONSTEXPR move_iterator operator++(int) { move_iterator __tmp = *this; ++_M_current; return __tmp; } _GLIBCXX17_CONSTEXPR move_iterator& operator--() { --_M_current; return *this; } _GLIBCXX17_CONSTEXPR move_iterator operator--(int) { move_iterator __tmp = *this; --_M_current; return __tmp; } _GLIBCXX17_CONSTEXPR move_iterator operator+(difference_type __n) const { return move_iterator(_M_current + __n); } _GLIBCXX17_CONSTEXPR move_iterator& operator+=(difference_type __n) { _M_current += __n; return *this; } _GLIBCXX17_CONSTEXPR move_iterator operator-(difference_type __n) const { return move_iterator(_M_current - __n); } _GLIBCXX17_CONSTEXPR move_iterator& operator-=(difference_type __n) { _M_current -= __n; return *this; } _GLIBCXX17_CONSTEXPR reference operator[](difference_type __n) const { return std::move(_M_current[__n]); } }; // Note: See __normal_iterator operators note from Gaby to understand // why there are always 2 versions for most of the move_iterator // operators. template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator==(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return __x.base() == __y.base(); } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator==(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y) { return __x.base() == __y.base(); } template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator!=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return !(__x == __y); } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator!=(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y) { return !(__x == __y); } template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator<(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return __x.base() < __y.base(); } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator<(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y) { return __x.base() < __y.base(); } template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator<=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return !(__y < __x); } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator<=(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y) { return !(__y < __x); } template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator>(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return __y < __x; } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator>(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y) { return __y < __x; } template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR bool operator>=(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) { return !(__x < __y); } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR bool operator>=(const move_iterator<_Iterator>& __x, const move_iterator<_Iterator>& __y) { return !(__x < __y); } // DR 685. template<typename _IteratorL, typename _IteratorR> inline _GLIBCXX17_CONSTEXPR auto operator-(const move_iterator<_IteratorL>& __x, const move_iterator<_IteratorR>& __y) -> decltype(__x.base() - __y.base()) { return __x.base() - __y.base(); } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator> operator+(typename move_iterator<_Iterator>::difference_type __n, const move_iterator<_Iterator>& __x) { return __x + __n; } template<typename _Iterator> inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator> make_move_iterator(_Iterator __i) { return move_iterator<_Iterator>(__i); } template<typename _Iterator, typename _ReturnType = typename conditional<__move_if_noexcept_cond <typename iterator_traits<_Iterator>::value_type>::value, _Iterator, move_iterator<_Iterator>>::type> inline _GLIBCXX17_CONSTEXPR _ReturnType __make_move_if_noexcept_iterator(_Iterator __i) { return _ReturnType(__i); } // Overload for pointers that matches std::move_if_noexcept more closely, // returning a constant iterator when we don't want to move. template<typename _Tp, typename _ReturnType = typename conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp*, move_iterator<_Tp*>>::type> inline _GLIBCXX17_CONSTEXPR _ReturnType __make_move_if_noexcept_iterator(_Tp* __i) { return _ReturnType(__i); } // @} group iterators template<typename _Iterator> auto __niter_base(move_iterator<_Iterator> __it) -> decltype(make_move_iterator(__niter_base(__it.base()))) { return make_move_iterator(__niter_base(__it.base())); } template<typename _Iterator> struct __is_move_iterator<move_iterator<_Iterator> > { enum { __value = 1 }; typedef __true_type __type; }; template<typename _Iterator> auto __miter_base(move_iterator<_Iterator> __it) -> decltype(__miter_base(__it.base())) { return __miter_base(__it.base()); } #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) std::make_move_iterator(_Iter) #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) \ std::__make_move_if_noexcept_iterator(_Iter) #else #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) (_Iter) #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) (_Iter) #endif // C++11 #if __cpp_deduction_guides >= 201606 // These helper traits are used for deduction guides // of associative containers. template<typename _InputIterator> using __iter_key_t = remove_const_t< typename iterator_traits<_InputIterator>::value_type::first_type>; template<typename _InputIterator> using __iter_val_t = typename iterator_traits<_InputIterator>::value_type::second_type; template<typename _T1, typename _T2> struct pair; template<typename _InputIterator> using __iter_to_alloc_t = pair<add_const_t<__iter_key_t<_InputIterator>>, __iter_val_t<_InputIterator>>; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #ifdef _GLIBCXX_DEBUG # include <debug/stl_iterator.h> #endif #endif c++/8/bits/ostream.tcc 0000644 00000030033 15146341150 0010370 0 ustar 00 // ostream classes -*- C++ -*- // Copyright (C) 1997-2018 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/ostream.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ostream} */ // // ISO C++ 14882: 27.6.2 Output streams // #ifndef _OSTREAM_TCC #define _OSTREAM_TCC 1 #pragma GCC system_header #include <bits/cxxabi_forced.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>::sentry:: sentry(basic_ostream<_CharT, _Traits>& __os) : _M_ok(false), _M_os(__os) { // XXX MT if (__os.tie() && __os.good()) __os.tie()->flush(); if (__os.good()) _M_ok = true; else __os.setstate(ios_base::failbit); } template<typename _CharT, typename _Traits> template<typename _ValueT> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: _M_insert(_ValueT __v) { sentry __cerb(*this); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { const __num_put_type& __np = __check_facet(this->_M_num_put); if (__np.put(*this, *this, this->fill(), __v).failed()) __err |= ios_base::badbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: operator<<(short __n) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 117. basic_ostream uses nonexistent num_put member functions. const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; if (__fmt == ios_base::oct || __fmt == ios_base::hex) return _M_insert(static_cast<long>(static_cast<unsigned short>(__n))); else return _M_insert(static_cast<long>(__n)); } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: operator<<(int __n) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 117. basic_ostream uses nonexistent num_put member functions. const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; if (__fmt == ios_base::oct || __fmt == ios_base::hex) return _M_insert(static_cast<long>(static_cast<unsigned int>(__n))); else return _M_insert(static_cast<long>(__n)); } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: operator<<(__streambuf_type* __sbin) { ios_base::iostate __err = ios_base::goodbit; sentry __cerb(*this); if (__cerb && __sbin) { __try { if (!__copy_streambufs(__sbin, this->rdbuf())) __err |= ios_base::failbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::failbit); } } else if (!__sbin) __err |= ios_base::badbit; if (__err) this->setstate(__err); return *this; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: put(char_type __c) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // basic_ostream::put(char_type) is an unformatted output function. // DR 63. Exception-handling policy for unformatted output. // Unformatted output functions should catch exceptions thrown // from streambuf members. sentry __cerb(*this); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { const int_type __put = this->rdbuf()->sputc(__c); if (traits_type::eq_int_type(__put, traits_type::eof())) __err |= ios_base::badbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: write(const _CharT* __s, streamsize __n) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // basic_ostream::write(const char_type*, streamsize) is an // unformatted output function. // DR 63. Exception-handling policy for unformatted output. // Unformatted output functions should catch exceptions thrown // from streambuf members. sentry __cerb(*this); if (__cerb) { __try { _M_write(__s, __n); } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } } return *this; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: flush() { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // basic_ostream::flush() is *not* an unformatted output function. ios_base::iostate __err = ios_base::goodbit; __try { if (this->rdbuf() && this->rdbuf()->pubsync() == -1) __err |= ios_base::badbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); return *this; } template<typename _CharT, typename _Traits> typename basic_ostream<_CharT, _Traits>::pos_type basic_ostream<_CharT, _Traits>:: tellp() { pos_type __ret = pos_type(-1); __try { if (!this->fail()) __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } return __ret; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: seekp(pos_type __pos) { ios_base::iostate __err = ios_base::goodbit; __try { if (!this->fail()) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 136. seekp, seekg setting wrong streams? const pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::out); // 129. Need error indication from seekp() and seekg() if (__p == pos_type(off_type(-1))) __err |= ios_base::failbit; } } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); return *this; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>:: seekp(off_type __off, ios_base::seekdir __dir) { ios_base::iostate __err = ios_base::goodbit; __try { if (!this->fail()) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 136. seekp, seekg setting wrong streams? const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, ios_base::out); // 129. Need error indication from seekp() and seekg() if (__p == pos_type(off_type(-1))) __err |= ios_base::failbit; } } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); return *this; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) { if (!__s) __out.setstate(ios_base::badbit); else { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 167. Improper use of traits_type::length() const size_t __clen = char_traits<char>::length(__s); __try { struct __ptr_guard { _CharT *__p; __ptr_guard (_CharT *__ip): __p(__ip) { } ~__ptr_guard() { delete[] __p; } _CharT* __get() { return __p; } } __pg (new _CharT[__clen]); _CharT *__ws = __pg.__get(); for (size_t __i = 0; __i < __clen; ++__i) __ws[__i] = __out.widen(__s[__i]); __ostream_insert(__out, __ws, __clen); } __catch(__cxxabiv1::__forced_unwind&) { __out._M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { __out._M_setstate(ios_base::badbit); } } return __out; } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_ostream<char>; extern template ostream& endl(ostream&); extern template ostream& ends(ostream&); extern template ostream& flush(ostream&); extern template ostream& operator<<(ostream&, char); extern template ostream& operator<<(ostream&, unsigned char); extern template ostream& operator<<(ostream&, signed char); extern template ostream& operator<<(ostream&, const char*); extern template ostream& operator<<(ostream&, const unsigned char*); extern template ostream& operator<<(ostream&, const signed char*); extern template ostream& ostream::_M_insert(long); extern template ostream& ostream::_M_insert(unsigned long); extern template ostream& ostream::_M_insert(bool); #ifdef _GLIBCXX_USE_LONG_LONG extern template ostream& ostream::_M_insert(long long); extern template ostream& ostream::_M_insert(unsigned long long); #endif extern template ostream& ostream::_M_insert(double); extern template ostream& ostream::_M_insert(long double); extern template ostream& ostream::_M_insert(const void*); #ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_ostream<wchar_t>; extern template wostream& endl(wostream&); extern template wostream& ends(wostream&); extern template wostream& flush(wostream&); extern template wostream& operator<<(wostream&, wchar_t); extern template wostream& operator<<(wostream&, char); extern template wostream& operator<<(wostream&, const wchar_t*); extern template wostream& operator<<(wostream&, const char*); extern template wostream& wostream::_M_insert(long); extern template wostream& wostream::_M_insert(unsigned long); extern template wostream& wostream::_M_insert(bool); #ifdef _GLIBCXX_USE_LONG_LONG extern template wostream& wostream::_M_insert(long long); extern template wostream& wostream::_M_insert(unsigned long long); #endif extern template wostream& wostream::_M_insert(double); extern template wostream& wostream::_M_insert(long double); extern template wostream& wostream::_M_insert(const void*); #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/unordered_set.h 0000644 00000163414 15146341150 0011250 0 ustar 00 // unordered_set implementation -*- C++ -*- // Copyright (C) 2010-2018 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/unordered_set.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{unordered_set} */ #ifndef _UNORDERED_SET_H #define _UNORDERED_SET_H namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /// Base types for unordered_set. template<bool _Cache> using __uset_traits = __detail::_Hashtable_traits<_Cache, true, true>; template<typename _Value, typename _Hash = hash<_Value>, typename _Pred = std::equal_to<_Value>, typename _Alloc = std::allocator<_Value>, typename _Tr = __uset_traits<__cache_default<_Value, _Hash>::value>> using __uset_hashtable = _Hashtable<_Value, _Value, _Alloc, __detail::_Identity, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, __detail::_Prime_rehash_policy, _Tr>; /// Base types for unordered_multiset. template<bool _Cache> using __umset_traits = __detail::_Hashtable_traits<_Cache, true, false>; template<typename _Value, typename _Hash = hash<_Value>, typename _Pred = std::equal_to<_Value>, typename _Alloc = std::allocator<_Value>, typename _Tr = __umset_traits<__cache_default<_Value, _Hash>::value>> using __umset_hashtable = _Hashtable<_Value, _Value, _Alloc, __detail::_Identity, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, __detail::_Prime_rehash_policy, _Tr>; template<class _Value, class _Hash, class _Pred, class _Alloc> class unordered_multiset; /** * @brief A standard container composed of unique keys (containing * at most one of each key value) in which the elements' keys are * the elements themselves. * * @ingroup unordered_associative_containers * * @tparam _Value Type of key objects. * @tparam _Hash Hashing function object type, defaults to hash<_Value>. * @tparam _Pred Predicate function object type, defaults to * equal_to<_Value>. * * @tparam _Alloc Allocator type, defaults to allocator<_Key>. * * Meets the requirements of a <a href="tables.html#65">container</a>, and * <a href="tables.html#xx">unordered associative container</a> * * Base is _Hashtable, dispatched at compile time via template * alias __uset_hashtable. */ template<typename _Value, typename _Hash = hash<_Value>, typename _Pred = equal_to<_Value>, typename _Alloc = allocator<_Value>> class unordered_set { typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable; _Hashtable _M_h; public: // typedefs: //@{ /// Public typedefs. typedef typename _Hashtable::key_type key_type; typedef typename _Hashtable::value_type value_type; typedef typename _Hashtable::hasher hasher; typedef typename _Hashtable::key_equal key_equal; typedef typename _Hashtable::allocator_type allocator_type; //@} //@{ /// Iterator-related typedefs. typedef typename _Hashtable::pointer pointer; typedef typename _Hashtable::const_pointer const_pointer; typedef typename _Hashtable::reference reference; typedef typename _Hashtable::const_reference const_reference; typedef typename _Hashtable::iterator iterator; typedef typename _Hashtable::const_iterator const_iterator; typedef typename _Hashtable::local_iterator local_iterator; typedef typename _Hashtable::const_local_iterator const_local_iterator; typedef typename _Hashtable::size_type size_type; typedef typename _Hashtable::difference_type difference_type; //@} #if __cplusplus > 201402L using node_type = typename _Hashtable::node_type; using insert_return_type = typename _Hashtable::insert_return_type; #endif // construct/destroy/copy /// Default constructor. unordered_set() = default; /** * @brief Default constructor creates no elements. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. */ explicit unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__n, __hf, __eql, __a) { } /** * @brief Builds an %unordered_set from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. * * Create an %unordered_set consisting of copies of the elements from * [__first,__last). This is linear in N (where N is * distance(__first,__last)). */ template<typename _InputIterator> unordered_set(_InputIterator __first, _InputIterator __last, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__first, __last, __n, __hf, __eql, __a) { } /// Copy constructor. unordered_set(const unordered_set&) = default; /// Move constructor. unordered_set(unordered_set&&) = default; /** * @brief Creates an %unordered_set with no elements. * @param __a An allocator object. */ explicit unordered_set(const allocator_type& __a) : _M_h(__a) { } /* * @brief Copy constructor with allocator argument. * @param __uset Input %unordered_set to copy. * @param __a An allocator object. */ unordered_set(const unordered_set& __uset, const allocator_type& __a) : _M_h(__uset._M_h, __a) { } /* * @brief Move constructor with allocator argument. * @param __uset Input %unordered_set to move. * @param __a An allocator object. */ unordered_set(unordered_set&& __uset, const allocator_type& __a) : _M_h(std::move(__uset._M_h), __a) { } /** * @brief Builds an %unordered_set from an initializer_list. * @param __l An initializer_list. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. * * Create an %unordered_set consisting of copies of the elements in the * list. This is linear in N (where N is @a __l.size()). */ unordered_set(initializer_list<value_type> __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__l, __n, __hf, __eql, __a) { } unordered_set(size_type __n, const allocator_type& __a) : unordered_set(__n, hasher(), key_equal(), __a) { } unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__n, __hf, key_equal(), __a) { } template<typename _InputIterator> unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) { } template<typename _InputIterator> unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__first, __last, __n, __hf, key_equal(), __a) { } unordered_set(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) : unordered_set(__l, __n, hasher(), key_equal(), __a) { } unordered_set(initializer_list<value_type> __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__l, __n, __hf, key_equal(), __a) { } /// Copy assignment operator. unordered_set& operator=(const unordered_set&) = default; /// Move assignment operator. unordered_set& operator=(unordered_set&&) = default; /** * @brief %Unordered_set list assignment operator. * @param __l An initializer_list. * * This function fills an %unordered_set with copies of the elements in * the initializer list @a __l. * * Note that the assignment completely changes the %unordered_set and * that the resulting %unordered_set's size is the same as the number * of elements assigned. */ unordered_set& operator=(initializer_list<value_type> __l) { _M_h = __l; return *this; } /// Returns the allocator object used by the %unordered_set. allocator_type get_allocator() const noexcept { return _M_h.get_allocator(); } // size and capacity: /// Returns true if the %unordered_set is empty. bool empty() const noexcept { return _M_h.empty(); } /// Returns the size of the %unordered_set. size_type size() const noexcept { return _M_h.size(); } /// Returns the maximum size of the %unordered_set. size_type max_size() const noexcept { return _M_h.max_size(); } // iterators. //@{ /** * Returns a read-only (constant) iterator that points to the first * element in the %unordered_set. */ iterator begin() noexcept { return _M_h.begin(); } const_iterator begin() const noexcept { return _M_h.begin(); } //@} //@{ /** * Returns a read-only (constant) iterator that points one past the last * element in the %unordered_set. */ iterator end() noexcept { return _M_h.end(); } const_iterator end() const noexcept { return _M_h.end(); } //@} /** * Returns a read-only (constant) iterator that points to the first * element in the %unordered_set. */ const_iterator cbegin() const noexcept { return _M_h.begin(); } /** * Returns a read-only (constant) iterator that points one past the last * element in the %unordered_set. */ const_iterator cend() const noexcept { return _M_h.end(); } // modifiers. /** * @brief Attempts to build and insert an element into the * %unordered_set. * @param __args Arguments used to generate an element. * @return A pair, of which the first element is an iterator that points * to the possibly inserted element, and the second is a bool * that is true if the element was actually inserted. * * This function attempts to build and insert an element into the * %unordered_set. An %unordered_set relies on unique keys and thus an * element is only inserted if it is not already present in the * %unordered_set. * * Insertion requires amortized constant time. */ template<typename... _Args> std::pair<iterator, bool> emplace(_Args&&... __args) { return _M_h.emplace(std::forward<_Args>(__args)...); } /** * @brief Attempts to insert an element into the %unordered_set. * @param __pos An iterator that serves as a hint as to where the * element should be inserted. * @param __args Arguments used to generate the element to be * inserted. * @return An iterator that points to the element with key equivalent to * the one generated from @a __args (may or may not be the * element itself). * * This function is not concerned about whether the insertion took place, * and thus does not return a boolean like the single-argument emplace() * does. Note that the first parameter is only a hint and can * potentially improve the performance of the insertion process. A bad * hint would cause no gains in efficiency. * * For more on @a hinting, see: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * * Insertion requires amortized constant time. */ template<typename... _Args> iterator emplace_hint(const_iterator __pos, _Args&&... __args) { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); } //@{ /** * @brief Attempts to insert an element into the %unordered_set. * @param __x Element to be inserted. * @return A pair, of which the first element is an iterator that points * to the possibly inserted element, and the second is a bool * that is true if the element was actually inserted. * * This function attempts to insert an element into the %unordered_set. * An %unordered_set relies on unique keys and thus an element is only * inserted if it is not already present in the %unordered_set. * * Insertion requires amortized constant time. */ std::pair<iterator, bool> insert(const value_type& __x) { return _M_h.insert(__x); } std::pair<iterator, bool> insert(value_type&& __x) { return _M_h.insert(std::move(__x)); } //@} //@{ /** * @brief Attempts to insert an element into the %unordered_set. * @param __hint An iterator that serves as a hint as to where the * element should be inserted. * @param __x Element to be inserted. * @return An iterator that points to the element with key of * @a __x (may or may not be the element passed in). * * This function is not concerned about whether the insertion took place, * and thus does not return a boolean like the single-argument insert() * does. Note that the first parameter is only a hint and can * potentially improve the performance of the insertion process. A bad * hint would cause no gains in efficiency. * * For more on @a hinting, see: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * * Insertion requires amortized constant. */ iterator insert(const_iterator __hint, const value_type& __x) { return _M_h.insert(__hint, __x); } iterator insert(const_iterator __hint, value_type&& __x) { return _M_h.insert(__hint, std::move(__x)); } //@} /** * @brief A template function that attempts to insert a range of * elements. * @param __first Iterator pointing to the start of the range to be * inserted. * @param __last Iterator pointing to the end of the range. * * Complexity similar to that of the range constructor. */ template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_h.insert(__first, __last); } /** * @brief Attempts to insert a list of elements into the %unordered_set. * @param __l A std::initializer_list<value_type> of elements * to be inserted. * * Complexity similar to that of the range constructor. */ void insert(initializer_list<value_type> __l) { _M_h.insert(__l); } #if __cplusplus > 201402L /// Extract a node. node_type extract(const_iterator __pos) { __glibcxx_assert(__pos != end()); return _M_h.extract(__pos); } /// Extract a node. node_type extract(const key_type& __key) { return _M_h.extract(__key); } /// Re-insert an extracted node. insert_return_type insert(node_type&& __nh) { return _M_h._M_reinsert_node(std::move(__nh)); } /// Re-insert an extracted node. iterator insert(const_iterator, node_type&& __nh) { return _M_h._M_reinsert_node(std::move(__nh)).position; } #endif // C++17 //@{ /** * @brief Erases an element from an %unordered_set. * @param __position An iterator pointing to the element to be erased. * @return An iterator pointing to the element immediately following * @a __position prior to the element being erased. If no such * element exists, end() is returned. * * This function erases an element, pointed to by the given iterator, * from an %unordered_set. Note that this function only erases the * element, and that if the element is itself a pointer, the pointed-to * memory is not touched in any way. Managing the pointer is the user's * responsibility. */ iterator erase(const_iterator __position) { return _M_h.erase(__position); } // LWG 2059. iterator erase(iterator __position) { return _M_h.erase(__position); } //@} /** * @brief Erases elements according to the provided key. * @param __x Key of element to be erased. * @return The number of elements erased. * * This function erases all the elements located by the given key from * an %unordered_set. For an %unordered_set the result of this function * can only be 0 (not present) or 1 (present). * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ size_type erase(const key_type& __x) { return _M_h.erase(__x); } /** * @brief Erases a [__first,__last) range of elements from an * %unordered_set. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to * be erased. * @return The iterator @a __last. * * This function erases a sequence of elements from an %unordered_set. * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ iterator erase(const_iterator __first, const_iterator __last) { return _M_h.erase(__first, __last); } /** * Erases all elements in an %unordered_set. Note that this function only * erases the elements, and that if the elements themselves are pointers, * the pointed-to memory is not touched in any way. Managing the pointer * is the user's responsibility. */ void clear() noexcept { _M_h.clear(); } /** * @brief Swaps data with another %unordered_set. * @param __x An %unordered_set of the same element and allocator * types. * * This exchanges the elements between two sets in constant time. * Note that the global std::swap() function is specialized such that * std::swap(s1,s2) will feed to this function. */ void swap(unordered_set& __x) noexcept( noexcept(_M_h.swap(__x._M_h)) ) { _M_h.swap(__x._M_h); } #if __cplusplus > 201402L template<typename, typename, typename> friend class std::_Hash_merge_helper; template<typename _H2, typename _P2> void merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source) { using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>; _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source)); } template<typename _H2, typename _P2> void merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source) { merge(__source); } template<typename _H2, typename _P2> void merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source) { using _Merge_helper = _Hash_merge_helper<unordered_set, _H2, _P2>; _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source)); } template<typename _H2, typename _P2> void merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source) { merge(__source); } #endif // C++17 // observers. /// Returns the hash functor object with which the %unordered_set was /// constructed. hasher hash_function() const { return _M_h.hash_function(); } /// Returns the key comparison object with which the %unordered_set was /// constructed. key_equal key_eq() const { return _M_h.key_eq(); } // lookup. //@{ /** * @brief Tries to locate an element in an %unordered_set. * @param __x Element to be located. * @return Iterator pointing to sought-after element, or end() if not * found. * * This function takes a key and tries to locate the element with which * the key matches. If successful the function returns an iterator * pointing to the sought after element. If unsuccessful it returns the * past-the-end ( @c end() ) iterator. */ iterator find(const key_type& __x) { return _M_h.find(__x); } const_iterator find(const key_type& __x) const { return _M_h.find(__x); } //@} /** * @brief Finds the number of elements. * @param __x Element to located. * @return Number of elements with specified key. * * This function only makes sense for unordered_multisets; for * unordered_set the result will either be 0 (not present) or 1 * (present). */ size_type count(const key_type& __x) const { return _M_h.count(__x); } //@{ /** * @brief Finds a subsequence matching given key. * @param __x Key to be located. * @return Pair of iterators that possibly points to the subsequence * matching given key. * * This function probably only makes sense for multisets. */ std::pair<iterator, iterator> equal_range(const key_type& __x) { return _M_h.equal_range(__x); } std::pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { return _M_h.equal_range(__x); } //@} // bucket interface. /// Returns the number of buckets of the %unordered_set. size_type bucket_count() const noexcept { return _M_h.bucket_count(); } /// Returns the maximum number of buckets of the %unordered_set. size_type max_bucket_count() const noexcept { return _M_h.max_bucket_count(); } /* * @brief Returns the number of elements in a given bucket. * @param __n A bucket index. * @return The number of elements in the bucket. */ size_type bucket_size(size_type __n) const { return _M_h.bucket_size(__n); } /* * @brief Returns the bucket index of a given element. * @param __key A key instance. * @return The key bucket index. */ size_type bucket(const key_type& __key) const { return _M_h.bucket(__key); } //@{ /** * @brief Returns a read-only (constant) iterator pointing to the first * bucket element. * @param __n The bucket index. * @return A read-only local iterator. */ local_iterator begin(size_type __n) { return _M_h.begin(__n); } const_local_iterator begin(size_type __n) const { return _M_h.begin(__n); } const_local_iterator cbegin(size_type __n) const { return _M_h.cbegin(__n); } //@} //@{ /** * @brief Returns a read-only (constant) iterator pointing to one past * the last bucket elements. * @param __n The bucket index. * @return A read-only local iterator. */ local_iterator end(size_type __n) { return _M_h.end(__n); } const_local_iterator end(size_type __n) const { return _M_h.end(__n); } const_local_iterator cend(size_type __n) const { return _M_h.cend(__n); } //@} // hash policy. /// Returns the average number of elements per bucket. float load_factor() const noexcept { return _M_h.load_factor(); } /// Returns a positive number that the %unordered_set tries to keep the /// load factor less than or equal to. float max_load_factor() const noexcept { return _M_h.max_load_factor(); } /** * @brief Change the %unordered_set maximum load factor. * @param __z The new maximum load factor. */ void max_load_factor(float __z) { _M_h.max_load_factor(__z); } /** * @brief May rehash the %unordered_set. * @param __n The new number of buckets. * * Rehash will occur only if the new number of buckets respect the * %unordered_set maximum load factor. */ void rehash(size_type __n) { _M_h.rehash(__n); } /** * @brief Prepare the %unordered_set for a specified number of * elements. * @param __n Number of elements required. * * Same as rehash(ceil(n / max_load_factor())). */ void reserve(size_type __n) { _M_h.reserve(__n); } template<typename _Value1, typename _Hash1, typename _Pred1, typename _Alloc1> friend bool operator==(const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&, const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&); }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _Hash = hash<typename iterator_traits<_InputIterator>::value_type>, typename _Pred = equal_to<typename iterator_traits<_InputIterator>::value_type>, typename _Allocator = allocator<typename iterator_traits<_InputIterator>::value_type>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_set(_InputIterator, _InputIterator, unordered_set<int>::size_type = {}, _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) -> unordered_set<typename iterator_traits<_InputIterator>::value_type, _Hash, _Pred, _Allocator>; template<typename _Tp, typename _Hash = hash<_Tp>, typename _Pred = equal_to<_Tp>, typename _Allocator = allocator<_Tp>, typename = _RequireAllocator<_Allocator>> unordered_set(initializer_list<_Tp>, unordered_set<int>::size_type = {}, _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) -> unordered_set<_Tp, _Hash, _Pred, _Allocator>; template<typename _InputIterator, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_set(_InputIterator, _InputIterator, unordered_set<int>::size_type, _Allocator) -> unordered_set<typename iterator_traits<_InputIterator>::value_type, hash< typename iterator_traits<_InputIterator>::value_type>, equal_to< typename iterator_traits<_InputIterator>::value_type>, _Allocator>; template<typename _InputIterator, typename _Hash, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_set(_InputIterator, _InputIterator, unordered_set<int>::size_type, _Hash, _Allocator) -> unordered_set<typename iterator_traits<_InputIterator>::value_type, _Hash, equal_to< typename iterator_traits<_InputIterator>::value_type>, _Allocator>; template<typename _Tp, typename _Allocator, typename = _RequireAllocator<_Allocator>> unordered_set(initializer_list<_Tp>, unordered_set<int>::size_type, _Allocator) -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; template<typename _Tp, typename _Hash, typename _Allocator, typename = _RequireAllocator<_Allocator>> unordered_set(initializer_list<_Tp>, unordered_set<int>::size_type, _Hash, _Allocator) -> unordered_set<_Tp, _Hash, equal_to<_Tp>, _Allocator>; #endif /** * @brief A standard container composed of equivalent keys * (possibly containing multiple of each key value) in which the * elements' keys are the elements themselves. * * @ingroup unordered_associative_containers * * @tparam _Value Type of key objects. * @tparam _Hash Hashing function object type, defaults to hash<_Value>. * @tparam _Pred Predicate function object type, defaults * to equal_to<_Value>. * @tparam _Alloc Allocator type, defaults to allocator<_Key>. * * Meets the requirements of a <a href="tables.html#65">container</a>, and * <a href="tables.html#xx">unordered associative container</a> * * Base is _Hashtable, dispatched at compile time via template * alias __umset_hashtable. */ template<typename _Value, typename _Hash = hash<_Value>, typename _Pred = equal_to<_Value>, typename _Alloc = allocator<_Value>> class unordered_multiset { typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable; _Hashtable _M_h; public: // typedefs: //@{ /// Public typedefs. typedef typename _Hashtable::key_type key_type; typedef typename _Hashtable::value_type value_type; typedef typename _Hashtable::hasher hasher; typedef typename _Hashtable::key_equal key_equal; typedef typename _Hashtable::allocator_type allocator_type; //@} //@{ /// Iterator-related typedefs. typedef typename _Hashtable::pointer pointer; typedef typename _Hashtable::const_pointer const_pointer; typedef typename _Hashtable::reference reference; typedef typename _Hashtable::const_reference const_reference; typedef typename _Hashtable::iterator iterator; typedef typename _Hashtable::const_iterator const_iterator; typedef typename _Hashtable::local_iterator local_iterator; typedef typename _Hashtable::const_local_iterator const_local_iterator; typedef typename _Hashtable::size_type size_type; typedef typename _Hashtable::difference_type difference_type; //@} #if __cplusplus > 201402L using node_type = typename _Hashtable::node_type; #endif // construct/destroy/copy /// Default constructor. unordered_multiset() = default; /** * @brief Default constructor creates no elements. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. */ explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__n, __hf, __eql, __a) { } /** * @brief Builds an %unordered_multiset from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. * * Create an %unordered_multiset consisting of copies of the elements * from [__first,__last). This is linear in N (where N is * distance(__first,__last)). */ template<typename _InputIterator> unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__first, __last, __n, __hf, __eql, __a) { } /// Copy constructor. unordered_multiset(const unordered_multiset&) = default; /// Move constructor. unordered_multiset(unordered_multiset&&) = default; /** * @brief Builds an %unordered_multiset from an initializer_list. * @param __l An initializer_list. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. * * Create an %unordered_multiset consisting of copies of the elements in * the list. This is linear in N (where N is @a __l.size()). */ unordered_multiset(initializer_list<value_type> __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__l, __n, __hf, __eql, __a) { } /// Copy assignment operator. unordered_multiset& operator=(const unordered_multiset&) = default; /// Move assignment operator. unordered_multiset& operator=(unordered_multiset&&) = default; /** * @brief Creates an %unordered_multiset with no elements. * @param __a An allocator object. */ explicit unordered_multiset(const allocator_type& __a) : _M_h(__a) { } /* * @brief Copy constructor with allocator argument. * @param __uset Input %unordered_multiset to copy. * @param __a An allocator object. */ unordered_multiset(const unordered_multiset& __umset, const allocator_type& __a) : _M_h(__umset._M_h, __a) { } /* * @brief Move constructor with allocator argument. * @param __umset Input %unordered_multiset to move. * @param __a An allocator object. */ unordered_multiset(unordered_multiset&& __umset, const allocator_type& __a) : _M_h(std::move(__umset._M_h), __a) { } unordered_multiset(size_type __n, const allocator_type& __a) : unordered_multiset(__n, hasher(), key_equal(), __a) { } unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__n, __hf, key_equal(), __a) { } template<typename _InputIterator> unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) { } template<typename _InputIterator> unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) { } unordered_multiset(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) : unordered_multiset(__l, __n, hasher(), key_equal(), __a) { } unordered_multiset(initializer_list<value_type> __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__l, __n, __hf, key_equal(), __a) { } /** * @brief %Unordered_multiset list assignment operator. * @param __l An initializer_list. * * This function fills an %unordered_multiset with copies of the elements * in the initializer list @a __l. * * Note that the assignment completely changes the %unordered_multiset * and that the resulting %unordered_multiset's size is the same as the * number of elements assigned. */ unordered_multiset& operator=(initializer_list<value_type> __l) { _M_h = __l; return *this; } /// Returns the allocator object used by the %unordered_multiset. allocator_type get_allocator() const noexcept { return _M_h.get_allocator(); } // size and capacity: /// Returns true if the %unordered_multiset is empty. bool empty() const noexcept { return _M_h.empty(); } /// Returns the size of the %unordered_multiset. size_type size() const noexcept { return _M_h.size(); } /// Returns the maximum size of the %unordered_multiset. size_type max_size() const noexcept { return _M_h.max_size(); } // iterators. //@{ /** * Returns a read-only (constant) iterator that points to the first * element in the %unordered_multiset. */ iterator begin() noexcept { return _M_h.begin(); } const_iterator begin() const noexcept { return _M_h.begin(); } //@} //@{ /** * Returns a read-only (constant) iterator that points one past the last * element in the %unordered_multiset. */ iterator end() noexcept { return _M_h.end(); } const_iterator end() const noexcept { return _M_h.end(); } //@} /** * Returns a read-only (constant) iterator that points to the first * element in the %unordered_multiset. */ const_iterator cbegin() const noexcept { return _M_h.begin(); } /** * Returns a read-only (constant) iterator that points one past the last * element in the %unordered_multiset. */ const_iterator cend() const noexcept { return _M_h.end(); } // modifiers. /** * @brief Builds and insert an element into the %unordered_multiset. * @param __args Arguments used to generate an element. * @return An iterator that points to the inserted element. * * Insertion requires amortized constant time. */ template<typename... _Args> iterator emplace(_Args&&... __args) { return _M_h.emplace(std::forward<_Args>(__args)...); } /** * @brief Inserts an element into the %unordered_multiset. * @param __pos An iterator that serves as a hint as to where the * element should be inserted. * @param __args Arguments used to generate the element to be * inserted. * @return An iterator that points to the inserted element. * * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * For more on @a hinting, see: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * * Insertion requires amortized constant time. */ template<typename... _Args> iterator emplace_hint(const_iterator __pos, _Args&&... __args) { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); } //@{ /** * @brief Inserts an element into the %unordered_multiset. * @param __x Element to be inserted. * @return An iterator that points to the inserted element. * * Insertion requires amortized constant time. */ iterator insert(const value_type& __x) { return _M_h.insert(__x); } iterator insert(value_type&& __x) { return _M_h.insert(std::move(__x)); } //@} //@{ /** * @brief Inserts an element into the %unordered_multiset. * @param __hint An iterator that serves as a hint as to where the * element should be inserted. * @param __x Element to be inserted. * @return An iterator that points to the inserted element. * * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * For more on @a hinting, see: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * * Insertion requires amortized constant. */ iterator insert(const_iterator __hint, const value_type& __x) { return _M_h.insert(__hint, __x); } iterator insert(const_iterator __hint, value_type&& __x) { return _M_h.insert(__hint, std::move(__x)); } //@} /** * @brief A template function that inserts a range of elements. * @param __first Iterator pointing to the start of the range to be * inserted. * @param __last Iterator pointing to the end of the range. * * Complexity similar to that of the range constructor. */ template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_h.insert(__first, __last); } /** * @brief Inserts a list of elements into the %unordered_multiset. * @param __l A std::initializer_list<value_type> of elements to be * inserted. * * Complexity similar to that of the range constructor. */ void insert(initializer_list<value_type> __l) { _M_h.insert(__l); } #if __cplusplus > 201402L /// Extract a node. node_type extract(const_iterator __pos) { __glibcxx_assert(__pos != end()); return _M_h.extract(__pos); } /// Extract a node. node_type extract(const key_type& __key) { return _M_h.extract(__key); } /// Re-insert an extracted node. iterator insert(node_type&& __nh) { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); } /// Re-insert an extracted node. iterator insert(const_iterator __hint, node_type&& __nh) { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); } #endif // C++17 //@{ /** * @brief Erases an element from an %unordered_multiset. * @param __position An iterator pointing to the element to be erased. * @return An iterator pointing to the element immediately following * @a __position prior to the element being erased. If no such * element exists, end() is returned. * * This function erases an element, pointed to by the given iterator, * from an %unordered_multiset. * * Note that this function only erases the element, and that if the * element is itself a pointer, the pointed-to memory is not touched in * any way. Managing the pointer is the user's responsibility. */ iterator erase(const_iterator __position) { return _M_h.erase(__position); } // LWG 2059. iterator erase(iterator __position) { return _M_h.erase(__position); } //@} /** * @brief Erases elements according to the provided key. * @param __x Key of element to be erased. * @return The number of elements erased. * * This function erases all the elements located by the given key from * an %unordered_multiset. * * Note that this function only erases the element, and that if the * element is itself a pointer, the pointed-to memory is not touched in * any way. Managing the pointer is the user's responsibility. */ size_type erase(const key_type& __x) { return _M_h.erase(__x); } /** * @brief Erases a [__first,__last) range of elements from an * %unordered_multiset. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to * be erased. * @return The iterator @a __last. * * This function erases a sequence of elements from an * %unordered_multiset. * * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ iterator erase(const_iterator __first, const_iterator __last) { return _M_h.erase(__first, __last); } /** * Erases all elements in an %unordered_multiset. * * Note that this function only erases the elements, and that if the * elements themselves are pointers, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ void clear() noexcept { _M_h.clear(); } /** * @brief Swaps data with another %unordered_multiset. * @param __x An %unordered_multiset of the same element and allocator * types. * * This exchanges the elements between two sets in constant time. * Note that the global std::swap() function is specialized such that * std::swap(s1,s2) will feed to this function. */ void swap(unordered_multiset& __x) noexcept( noexcept(_M_h.swap(__x._M_h)) ) { _M_h.swap(__x._M_h); } #if __cplusplus > 201402L template<typename, typename, typename> friend class std::_Hash_merge_helper; template<typename _H2, typename _P2> void merge(unordered_multiset<_Value, _H2, _P2, _Alloc>& __source) { using _Merge_helper = _Hash_merge_helper<unordered_multiset, _H2, _P2>; _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source)); } template<typename _H2, typename _P2> void merge(unordered_multiset<_Value, _H2, _P2, _Alloc>&& __source) { merge(__source); } template<typename _H2, typename _P2> void merge(unordered_set<_Value, _H2, _P2, _Alloc>& __source) { using _Merge_helper = _Hash_merge_helper<unordered_multiset, _H2, _P2>; _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source)); } template<typename _H2, typename _P2> void merge(unordered_set<_Value, _H2, _P2, _Alloc>&& __source) { merge(__source); } #endif // C++17 // observers. /// Returns the hash functor object with which the %unordered_multiset /// was constructed. hasher hash_function() const { return _M_h.hash_function(); } /// Returns the key comparison object with which the %unordered_multiset /// was constructed. key_equal key_eq() const { return _M_h.key_eq(); } // lookup. //@{ /** * @brief Tries to locate an element in an %unordered_multiset. * @param __x Element to be located. * @return Iterator pointing to sought-after element, or end() if not * found. * * This function takes a key and tries to locate the element with which * the key matches. If successful the function returns an iterator * pointing to the sought after element. If unsuccessful it returns the * past-the-end ( @c end() ) iterator. */ iterator find(const key_type& __x) { return _M_h.find(__x); } const_iterator find(const key_type& __x) const { return _M_h.find(__x); } //@} /** * @brief Finds the number of elements. * @param __x Element to located. * @return Number of elements with specified key. */ size_type count(const key_type& __x) const { return _M_h.count(__x); } //@{ /** * @brief Finds a subsequence matching given key. * @param __x Key to be located. * @return Pair of iterators that possibly points to the subsequence * matching given key. */ std::pair<iterator, iterator> equal_range(const key_type& __x) { return _M_h.equal_range(__x); } std::pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { return _M_h.equal_range(__x); } //@} // bucket interface. /// Returns the number of buckets of the %unordered_multiset. size_type bucket_count() const noexcept { return _M_h.bucket_count(); } /// Returns the maximum number of buckets of the %unordered_multiset. size_type max_bucket_count() const noexcept { return _M_h.max_bucket_count(); } /* * @brief Returns the number of elements in a given bucket. * @param __n A bucket index. * @return The number of elements in the bucket. */ size_type bucket_size(size_type __n) const { return _M_h.bucket_size(__n); } /* * @brief Returns the bucket index of a given element. * @param __key A key instance. * @return The key bucket index. */ size_type bucket(const key_type& __key) const { return _M_h.bucket(__key); } //@{ /** * @brief Returns a read-only (constant) iterator pointing to the first * bucket element. * @param __n The bucket index. * @return A read-only local iterator. */ local_iterator begin(size_type __n) { return _M_h.begin(__n); } const_local_iterator begin(size_type __n) const { return _M_h.begin(__n); } const_local_iterator cbegin(size_type __n) const { return _M_h.cbegin(__n); } //@} //@{ /** * @brief Returns a read-only (constant) iterator pointing to one past * the last bucket elements. * @param __n The bucket index. * @return A read-only local iterator. */ local_iterator end(size_type __n) { return _M_h.end(__n); } const_local_iterator end(size_type __n) const { return _M_h.end(__n); } const_local_iterator cend(size_type __n) const { return _M_h.cend(__n); } //@} // hash policy. /// Returns the average number of elements per bucket. float load_factor() const noexcept { return _M_h.load_factor(); } /// Returns a positive number that the %unordered_multiset tries to keep the /// load factor less than or equal to. float max_load_factor() const noexcept { return _M_h.max_load_factor(); } /** * @brief Change the %unordered_multiset maximum load factor. * @param __z The new maximum load factor. */ void max_load_factor(float __z) { _M_h.max_load_factor(__z); } /** * @brief May rehash the %unordered_multiset. * @param __n The new number of buckets. * * Rehash will occur only if the new number of buckets respect the * %unordered_multiset maximum load factor. */ void rehash(size_type __n) { _M_h.rehash(__n); } /** * @brief Prepare the %unordered_multiset for a specified number of * elements. * @param __n Number of elements required. * * Same as rehash(ceil(n / max_load_factor())). */ void reserve(size_type __n) { _M_h.reserve(__n); } template<typename _Value1, typename _Hash1, typename _Pred1, typename _Alloc1> friend bool operator==(const unordered_multiset<_Value1, _Hash1, _Pred1, _Alloc1>&, const unordered_multiset<_Value1, _Hash1, _Pred1, _Alloc1>&); }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _Hash = hash<typename iterator_traits<_InputIterator>::value_type>, typename _Pred = equal_to<typename iterator_traits<_InputIterator>::value_type>, typename _Allocator = allocator<typename iterator_traits<_InputIterator>::value_type>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_multiset(_InputIterator, _InputIterator, unordered_multiset<int>::size_type = {}, _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type, _Hash, _Pred, _Allocator>; template<typename _Tp, typename _Hash = hash<_Tp>, typename _Pred = equal_to<_Tp>, typename _Allocator = allocator<_Tp>, typename = _RequireAllocator<_Allocator>> unordered_multiset(initializer_list<_Tp>, unordered_multiset<int>::size_type = {}, _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>; template<typename _InputIterator, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_multiset(_InputIterator, _InputIterator, unordered_multiset<int>::size_type, _Allocator) -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type, hash<typename iterator_traits<_InputIterator>::value_type>, equal_to<typename iterator_traits<_InputIterator>::value_type>, _Allocator>; template<typename _InputIterator, typename _Hash, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_multiset(_InputIterator, _InputIterator, unordered_multiset<int>::size_type, _Hash, _Allocator) -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type, _Hash, equal_to< typename iterator_traits<_InputIterator>::value_type>, _Allocator>; template<typename _Tp, typename _Allocator, typename = _RequireAllocator<_Allocator>> unordered_multiset(initializer_list<_Tp>, unordered_multiset<int>::size_type, _Allocator) -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; template<typename _Tp, typename _Hash, typename _Allocator, typename = _RequireAllocator<_Allocator>> unordered_multiset(initializer_list<_Tp>, unordered_multiset<int>::size_type, _Hash, _Allocator) -> unordered_multiset<_Tp, _Hash, equal_to<_Tp>, _Allocator>; #endif template<class _Value, class _Hash, class _Pred, class _Alloc> inline void swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<class _Value, class _Hash, class _Pred, class _Alloc> inline void swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<class _Value, class _Hash, class _Pred, class _Alloc> inline bool operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) { return __x._M_h._M_equal(__y._M_h); } template<class _Value, class _Hash, class _Pred, class _Alloc> inline bool operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } template<class _Value, class _Hash, class _Pred, class _Alloc> inline bool operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) { return __x._M_h._M_equal(__y._M_h); } template<class _Value, class _Hash, class _Pred, class _Alloc> inline bool operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } _GLIBCXX_END_NAMESPACE_CONTAINER #if __cplusplus > 201402L // Allow std::unordered_set access to internals of compatible sets. template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc, typename _Hash2, typename _Eq2> struct _Hash_merge_helper< _GLIBCXX_STD_C::unordered_set<_Val, _Hash1, _Eq1, _Alloc>, _Hash2, _Eq2> { private: template<typename... _Tp> using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>; template<typename... _Tp> using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>; friend unordered_set<_Val, _Hash1, _Eq1, _Alloc>; static auto& _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set) { return __set._M_h; } static auto& _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set) { return __set._M_h; } }; // Allow std::unordered_multiset access to internals of compatible sets. template<typename _Val, typename _Hash1, typename _Eq1, typename _Alloc, typename _Hash2, typename _Eq2> struct _Hash_merge_helper< _GLIBCXX_STD_C::unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>, _Hash2, _Eq2> { private: template<typename... _Tp> using unordered_set = _GLIBCXX_STD_C::unordered_set<_Tp...>; template<typename... _Tp> using unordered_multiset = _GLIBCXX_STD_C::unordered_multiset<_Tp...>; friend unordered_multiset<_Val, _Hash1, _Eq1, _Alloc>; static auto& _S_get_table(unordered_set<_Val, _Hash2, _Eq2, _Alloc>& __set) { return __set._M_h; } static auto& _S_get_table(unordered_multiset<_Val, _Hash2, _Eq2, _Alloc>& __set) { return __set._M_h; } }; #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _UNORDERED_SET_H */ c++/8/bits/boost_concept_check.h 0000644 00000065031 15146341150 0012400 0 ustar 00 // -*- C++ -*- // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. // (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, // sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. // /** @file bits/boost_concept_check.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iterator} */ // GCC Note: based on version 1.12.0 of the Boost library. #ifndef _BOOST_CONCEPT_CHECK_H #define _BOOST_CONCEPT_CHECK_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/stl_iterator_base_types.h> // for traits and tags namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #define _IsUnused __attribute__ ((__unused__)) // When the C-C code is in use, we would like this function to do as little // as possible at runtime, use as few resources as possible, and hopefully // be elided out of existence... hmmm. template <class _Concept> inline void __function_requires() { void (_Concept::*__x)() _IsUnused = &_Concept::__constraints; } // No definition: if this is referenced, there's a problem with // the instantiating type not being one of the required integer types. // Unfortunately, this results in a link-time error, not a compile-time error. void __error_type_must_be_an_integer_type(); void __error_type_must_be_an_unsigned_integer_type(); void __error_type_must_be_a_signed_integer_type(); // ??? Should the "concept_checking*" structs begin with more than _ ? #define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \ typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \ template <_func##_type_var##_concept _Tp1> \ struct _concept_checking##_type_var##_concept { }; \ typedef _concept_checking##_type_var##_concept< \ &_ns::_concept <_type_var>::__constraints> \ _concept_checking_typedef##_type_var##_concept #define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \ typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \ template <_func##_type_var1##_type_var2##_concept _Tp1> \ struct _concept_checking##_type_var1##_type_var2##_concept { }; \ typedef _concept_checking##_type_var1##_type_var2##_concept< \ &_ns::_concept <_type_var1,_type_var2>::__constraints> \ _concept_checking_typedef##_type_var1##_type_var2##_concept #define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \ typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \ template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \ struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \ typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \ &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \ _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept #define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \ typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \ template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \ struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \ typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \ &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \ _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept template <class _Tp1, class _Tp2> struct _Aux_require_same { }; template <class _Tp> struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; template <class _Tp1, class _Tp2> struct _SameTypeConcept { void __constraints() { typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required; } }; template <class _Tp> struct _IntegerConcept { void __constraints() { __error_type_must_be_an_integer_type(); } }; template <> struct _IntegerConcept<short> { void __constraints() {} }; template <> struct _IntegerConcept<unsigned short> { void __constraints(){} }; template <> struct _IntegerConcept<int> { void __constraints() {} }; template <> struct _IntegerConcept<unsigned int> { void __constraints() {} }; template <> struct _IntegerConcept<long> { void __constraints() {} }; template <> struct _IntegerConcept<unsigned long> { void __constraints() {} }; template <> struct _IntegerConcept<long long> { void __constraints() {} }; template <> struct _IntegerConcept<unsigned long long> { void __constraints() {} }; template <class _Tp> struct _SignedIntegerConcept { void __constraints() { __error_type_must_be_a_signed_integer_type(); } }; template <> struct _SignedIntegerConcept<short> { void __constraints() {} }; template <> struct _SignedIntegerConcept<int> { void __constraints() {} }; template <> struct _SignedIntegerConcept<long> { void __constraints() {} }; template <> struct _SignedIntegerConcept<long long> { void __constraints(){}}; template <class _Tp> struct _UnsignedIntegerConcept { void __constraints() { __error_type_must_be_an_unsigned_integer_type(); } }; template <> struct _UnsignedIntegerConcept<unsigned short> { void __constraints() {} }; template <> struct _UnsignedIntegerConcept<unsigned int> { void __constraints() {} }; template <> struct _UnsignedIntegerConcept<unsigned long> { void __constraints() {} }; template <> struct _UnsignedIntegerConcept<unsigned long long> { void __constraints() {} }; //=========================================================================== // Basic Concepts template <class _Tp> struct _DefaultConstructibleConcept { void __constraints() { _Tp __a _IsUnused; // require default constructor } }; template <class _Tp> struct _AssignableConcept { void __constraints() { __a = __a; // require assignment operator __const_constraints(__a); } void __const_constraints(const _Tp& __b) { __a = __b; // const required for argument to assignment } _Tp __a; // possibly should be "Tp* a;" and then dereference "a" in constraint // functions? present way would require a default ctor, i think... }; template <class _Tp> struct _CopyConstructibleConcept { void __constraints() { _Tp __a(__b); // require copy constructor _Tp* __ptr _IsUnused = &__a; // require address of operator __const_constraints(__a); } void __const_constraints(const _Tp& __a) { _Tp __c _IsUnused(__a); // require const copy constructor const _Tp* __ptr _IsUnused = &__a; // require const address of operator } _Tp __b; }; // The SGI STL version of Assignable requires copy constructor and operator= template <class _Tp> struct _SGIAssignableConcept { void __constraints() { _Tp __b _IsUnused(__a); __a = __a; // require assignment operator __const_constraints(__a); } void __const_constraints(const _Tp& __b) { _Tp __c _IsUnused(__b); __a = __b; // const required for argument to assignment } _Tp __a; }; template <class _From, class _To> struct _ConvertibleConcept { void __constraints() { _To __y _IsUnused = __x; } _From __x; }; // The C++ standard requirements for many concepts talk about return // types that must be "convertible to bool". The problem with this // requirement is that it leaves the door open for evil proxies that // define things like operator|| with strange return types. Two // possible solutions are: // 1) require the return type to be exactly bool // 2) stay with convertible to bool, and also // specify stuff about all the logical operators. // For now we just test for convertible to bool. template <class _Tp> void __aux_require_boolean_expr(const _Tp& __t) { bool __x _IsUnused = __t; } // FIXME template <class _Tp> struct _EqualityComparableConcept { void __constraints() { __aux_require_boolean_expr(__a == __b); } _Tp __a, __b; }; template <class _Tp> struct _LessThanComparableConcept { void __constraints() { __aux_require_boolean_expr(__a < __b); } _Tp __a, __b; }; // This is equivalent to SGI STL's LessThanComparable. template <class _Tp> struct _ComparableConcept { void __constraints() { __aux_require_boolean_expr(__a < __b); __aux_require_boolean_expr(__a > __b); __aux_require_boolean_expr(__a <= __b); __aux_require_boolean_expr(__a >= __b); } _Tp __a, __b; }; #define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \ template <class _First, class _Second> \ struct _NAME { \ void __constraints() { (void)__constraints_(); } \ bool __constraints_() { \ return __a _OP __b; \ } \ _First __a; \ _Second __b; \ } #define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \ template <class _Ret, class _First, class _Second> \ struct _NAME { \ void __constraints() { (void)__constraints_(); } \ _Ret __constraints_() { \ return __a _OP __b; \ } \ _First __a; \ _Second __b; \ } _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept); _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept); _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept); _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept); _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept); _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept); _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept); _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept); _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept); _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept); _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept); #undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT #undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT //=========================================================================== // Function Object Concepts template <class _Func, class _Return> struct _GeneratorConcept { void __constraints() { const _Return& __r _IsUnused = __f();// require operator() member function } _Func __f; }; template <class _Func> struct _GeneratorConcept<_Func,void> { void __constraints() { __f(); // require operator() member function } _Func __f; }; template <class _Func, class _Return, class _Arg> struct _UnaryFunctionConcept { void __constraints() { __r = __f(__arg); // require operator() } _Func __f; _Arg __arg; _Return __r; }; template <class _Func, class _Arg> struct _UnaryFunctionConcept<_Func, void, _Arg> { void __constraints() { __f(__arg); // require operator() } _Func __f; _Arg __arg; }; template <class _Func, class _Return, class _First, class _Second> struct _BinaryFunctionConcept { void __constraints() { __r = __f(__first, __second); // require operator() } _Func __f; _First __first; _Second __second; _Return __r; }; template <class _Func, class _First, class _Second> struct _BinaryFunctionConcept<_Func, void, _First, _Second> { void __constraints() { __f(__first, __second); // require operator() } _Func __f; _First __first; _Second __second; }; template <class _Func, class _Arg> struct _UnaryPredicateConcept { void __constraints() { __aux_require_boolean_expr(__f(__arg)); // require op() returning bool } _Func __f; _Arg __arg; }; template <class _Func, class _First, class _Second> struct _BinaryPredicateConcept { void __constraints() { __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool } _Func __f; _First __a; _Second __b; }; // use this when functor is used inside a container class like std::set template <class _Func, class _First, class _Second> struct _Const_BinaryPredicateConcept { void __constraints() { __const_constraints(__f); } void __const_constraints(const _Func& __fun) { __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >(); // operator() must be a const member function __aux_require_boolean_expr(__fun(__a, __b)); } _Func __f; _First __a; _Second __b; }; //=========================================================================== // Iterator Concepts template <class _Tp> struct _TrivialIteratorConcept { void __constraints() { // __function_requires< _DefaultConstructibleConcept<_Tp> >(); __function_requires< _AssignableConcept<_Tp> >(); __function_requires< _EqualityComparableConcept<_Tp> >(); // typedef typename std::iterator_traits<_Tp>::value_type _V; (void)*__i; // require dereference operator } _Tp __i; }; template <class _Tp> struct _Mutable_TrivialIteratorConcept { void __constraints() { __function_requires< _TrivialIteratorConcept<_Tp> >(); *__i = *__j; // require dereference and assignment } _Tp __i, __j; }; template <class _Tp> struct _InputIteratorConcept { void __constraints() { __function_requires< _TrivialIteratorConcept<_Tp> >(); // require iterator_traits typedef's typedef typename std::iterator_traits<_Tp>::difference_type _Diff; // __function_requires< _SignedIntegerConcept<_Diff> >(); typedef typename std::iterator_traits<_Tp>::reference _Ref; typedef typename std::iterator_traits<_Tp>::pointer _Pt; typedef typename std::iterator_traits<_Tp>::iterator_category _Cat; __function_requires< _ConvertibleConcept< typename std::iterator_traits<_Tp>::iterator_category, std::input_iterator_tag> >(); ++__i; // require preincrement operator __i++; // require postincrement operator } _Tp __i; }; template <class _Tp, class _ValueT> struct _OutputIteratorConcept { void __constraints() { __function_requires< _AssignableConcept<_Tp> >(); ++__i; // require preincrement operator __i++; // require postincrement operator *__i++ = __t; // require postincrement and assignment } _Tp __i; _ValueT __t; }; template <class _Tp> struct _ForwardIteratorConcept { void __constraints() { __function_requires< _InputIteratorConcept<_Tp> >(); __function_requires< _DefaultConstructibleConcept<_Tp> >(); __function_requires< _ConvertibleConcept< typename std::iterator_traits<_Tp>::iterator_category, std::forward_iterator_tag> >(); typedef typename std::iterator_traits<_Tp>::reference _Ref; _Ref __r _IsUnused = *__i; } _Tp __i; }; template <class _Tp> struct _Mutable_ForwardIteratorConcept { void __constraints() { __function_requires< _ForwardIteratorConcept<_Tp> >(); *__i++ = *__i; // require postincrement and assignment } _Tp __i; }; template <class _Tp> struct _BidirectionalIteratorConcept { void __constraints() { __function_requires< _ForwardIteratorConcept<_Tp> >(); __function_requires< _ConvertibleConcept< typename std::iterator_traits<_Tp>::iterator_category, std::bidirectional_iterator_tag> >(); --__i; // require predecrement operator __i--; // require postdecrement operator } _Tp __i; }; template <class _Tp> struct _Mutable_BidirectionalIteratorConcept { void __constraints() { __function_requires< _BidirectionalIteratorConcept<_Tp> >(); __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >(); *__i-- = *__i; // require postdecrement and assignment } _Tp __i; }; template <class _Tp> struct _RandomAccessIteratorConcept { void __constraints() { __function_requires< _BidirectionalIteratorConcept<_Tp> >(); __function_requires< _ComparableConcept<_Tp> >(); __function_requires< _ConvertibleConcept< typename std::iterator_traits<_Tp>::iterator_category, std::random_access_iterator_tag> >(); // ??? We don't use _Ref, are we just checking for "referenceability"? typedef typename std::iterator_traits<_Tp>::reference _Ref; __i += __n; // require assignment addition operator __i = __i + __n; __i = __n + __i; // require addition with difference type __i -= __n; // require assignment subtraction op __i = __i - __n; // require subtraction with // difference type __n = __i - __j; // require difference operator (void)__i[__n]; // require element access operator } _Tp __a, __b; _Tp __i, __j; typename std::iterator_traits<_Tp>::difference_type __n; }; template <class _Tp> struct _Mutable_RandomAccessIteratorConcept { void __constraints() { __function_requires< _RandomAccessIteratorConcept<_Tp> >(); __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >(); __i[__n] = *__i; // require element access and assignment } _Tp __i; typename std::iterator_traits<_Tp>::difference_type __n; }; //=========================================================================== // Container Concepts template <class _Container> struct _ContainerConcept { typedef typename _Container::value_type _Value_type; typedef typename _Container::difference_type _Difference_type; typedef typename _Container::size_type _Size_type; typedef typename _Container::const_reference _Const_reference; typedef typename _Container::const_pointer _Const_pointer; typedef typename _Container::const_iterator _Const_iterator; void __constraints() { __function_requires< _InputIteratorConcept<_Const_iterator> >(); __function_requires< _AssignableConcept<_Container> >(); const _Container __c; __i = __c.begin(); __i = __c.end(); __n = __c.size(); __n = __c.max_size(); __b = __c.empty(); } bool __b; _Const_iterator __i; _Size_type __n; }; template <class _Container> struct _Mutable_ContainerConcept { typedef typename _Container::value_type _Value_type; typedef typename _Container::reference _Reference; typedef typename _Container::iterator _Iterator; typedef typename _Container::pointer _Pointer; void __constraints() { __function_requires< _ContainerConcept<_Container> >(); __function_requires< _AssignableConcept<_Value_type> >(); __function_requires< _InputIteratorConcept<_Iterator> >(); __i = __c.begin(); __i = __c.end(); __c.swap(__c2); } _Iterator __i; _Container __c, __c2; }; template <class _ForwardContainer> struct _ForwardContainerConcept { void __constraints() { __function_requires< _ContainerConcept<_ForwardContainer> >(); typedef typename _ForwardContainer::const_iterator _Const_iterator; __function_requires< _ForwardIteratorConcept<_Const_iterator> >(); } }; template <class _ForwardContainer> struct _Mutable_ForwardContainerConcept { void __constraints() { __function_requires< _ForwardContainerConcept<_ForwardContainer> >(); __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >(); typedef typename _ForwardContainer::iterator _Iterator; __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >(); } }; template <class _ReversibleContainer> struct _ReversibleContainerConcept { typedef typename _ReversibleContainer::const_iterator _Const_iterator; typedef typename _ReversibleContainer::const_reverse_iterator _Const_reverse_iterator; void __constraints() { __function_requires< _ForwardContainerConcept<_ReversibleContainer> >(); __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >(); __function_requires< _BidirectionalIteratorConcept<_Const_reverse_iterator> >(); const _ReversibleContainer __c; _Const_reverse_iterator __i = __c.rbegin(); __i = __c.rend(); } }; template <class _ReversibleContainer> struct _Mutable_ReversibleContainerConcept { typedef typename _ReversibleContainer::iterator _Iterator; typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator; void __constraints() { __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >(); __function_requires< _Mutable_ForwardContainerConcept<_ReversibleContainer> >(); __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >(); __function_requires< _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >(); _Reverse_iterator __i = __c.rbegin(); __i = __c.rend(); } _ReversibleContainer __c; }; template <class _RandomAccessContainer> struct _RandomAccessContainerConcept { typedef typename _RandomAccessContainer::size_type _Size_type; typedef typename _RandomAccessContainer::const_reference _Const_reference; typedef typename _RandomAccessContainer::const_iterator _Const_iterator; typedef typename _RandomAccessContainer::const_reverse_iterator _Const_reverse_iterator; void __constraints() { __function_requires< _ReversibleContainerConcept<_RandomAccessContainer> >(); __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >(); __function_requires< _RandomAccessIteratorConcept<_Const_reverse_iterator> >(); const _RandomAccessContainer __c; _Const_reference __r _IsUnused = __c[__n]; } _Size_type __n; }; template <class _RandomAccessContainer> struct _Mutable_RandomAccessContainerConcept { typedef typename _RandomAccessContainer::size_type _Size_type; typedef typename _RandomAccessContainer::reference _Reference; typedef typename _RandomAccessContainer::iterator _Iterator; typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator; void __constraints() { __function_requires< _RandomAccessContainerConcept<_RandomAccessContainer> >(); __function_requires< _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >(); __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >(); __function_requires< _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >(); _Reference __r _IsUnused = __c[__i]; } _Size_type __i; _RandomAccessContainer __c; }; // A Sequence is inherently mutable template <class _Sequence> struct _SequenceConcept { typedef typename _Sequence::reference _Reference; typedef typename _Sequence::const_reference _Const_reference; void __constraints() { // Matt Austern's book puts DefaultConstructible here, the C++ // standard places it in Container // function_requires< DefaultConstructible<Sequence> >(); __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >(); __function_requires< _DefaultConstructibleConcept<_Sequence> >(); _Sequence __c _IsUnused(__n, __t), __c2 _IsUnused(__first, __last); __c.insert(__p, __t); __c.insert(__p, __n, __t); __c.insert(__p, __first, __last); __c.erase(__p); __c.erase(__p, __q); _Reference __r _IsUnused = __c.front(); __const_constraints(__c); } void __const_constraints(const _Sequence& __c) { _Const_reference __r _IsUnused = __c.front(); } typename _Sequence::value_type __t; typename _Sequence::size_type __n; typename _Sequence::value_type *__first, *__last; typename _Sequence::iterator __p, __q; }; template <class _FrontInsertionSequence> struct _FrontInsertionSequenceConcept { void __constraints() { __function_requires< _SequenceConcept<_FrontInsertionSequence> >(); __c.push_front(__t); __c.pop_front(); } _FrontInsertionSequence __c; typename _FrontInsertionSequence::value_type __t; }; template <class _BackInsertionSequence> struct _BackInsertionSequenceConcept { typedef typename _BackInsertionSequence::reference _Reference; typedef typename _BackInsertionSequence::const_reference _Const_reference; void __constraints() { __function_requires< _SequenceConcept<_BackInsertionSequence> >(); __c.push_back(__t); __c.pop_back(); _Reference __r _IsUnused = __c.back(); } void __const_constraints(const _BackInsertionSequence& __c) { _Const_reference __r _IsUnused = __c.back(); }; _BackInsertionSequence __c; typename _BackInsertionSequence::value_type __t; }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #pragma GCC diagnostic pop #undef _IsUnused #endif // _GLIBCXX_BOOST_CONCEPT_CHECK c++/8/bits/random.tcc 0000644 00000316166 15146341150 0010214 0 ustar 00 // random number generation (out of line) -*- C++ -*- // Copyright (C) 2009-2018 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/random.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{random} */ #ifndef _RANDOM_TCC #define _RANDOM_TCC 1 #include <numeric> // std::accumulate and std::partial_sum namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /* * (Further) implementation-space details. */ namespace __detail { // General case for x = (ax + c) mod m -- use Schrage's algorithm // to avoid integer overflow. // // Preconditions: a > 0, m > 0. // // Note: only works correctly for __m % __a < __m / __a. template<typename _Tp, _Tp __m, _Tp __a, _Tp __c> _Tp _Mod<_Tp, __m, __a, __c, false, true>:: __calc(_Tp __x) { if (__a == 1) __x %= __m; else { static const _Tp __q = __m / __a; static const _Tp __r = __m % __a; _Tp __t1 = __a * (__x % __q); _Tp __t2 = __r * (__x / __q); if (__t1 >= __t2) __x = __t1 - __t2; else __x = __m - __t2 + __t1; } if (__c != 0) { const _Tp __d = __m - __x; if (__d > __c) __x += __c; else __x = __c - __d; } return __x; } template<typename _InputIterator, typename _OutputIterator, typename _Tp> _OutputIterator __normalize(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __factor) { for (; __first != __last; ++__first, ++__result) *__result = *__first / __factor; return __result; } } // namespace __detail template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> constexpr _UIntType linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier; template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> constexpr _UIntType linear_congruential_engine<_UIntType, __a, __c, __m>::increment; template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> constexpr _UIntType linear_congruential_engine<_UIntType, __a, __c, __m>::modulus; template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> constexpr _UIntType linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed; /** * Seeds the LCR with integral value @p __s, adjusted so that the * ring identity is never a member of the convergence set. */ template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> void linear_congruential_engine<_UIntType, __a, __c, __m>:: seed(result_type __s) { if ((__detail::__mod<_UIntType, __m>(__c) == 0) && (__detail::__mod<_UIntType, __m>(__s) == 0)) _M_x = 1; else _M_x = __detail::__mod<_UIntType, __m>(__s); } /** * Seeds the LCR engine with a value generated by @p __q. */ template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> template<typename _Sseq> typename std::enable_if<std::is_class<_Sseq>::value>::type linear_congruential_engine<_UIntType, __a, __c, __m>:: seed(_Sseq& __q) { const _UIntType __k0 = __m == 0 ? std::numeric_limits<_UIntType>::digits : std::__lg(__m); const _UIntType __k = (__k0 + 31) / 32; uint_least32_t __arr[__k + 3]; __q.generate(__arr + 0, __arr + __k + 3); _UIntType __factor = 1u; _UIntType __sum = 0u; for (size_t __j = 0; __j < __k; ++__j) { __sum += __arr[__j + 3] * __factor; __factor *= __detail::_Shift<_UIntType, 32>::__value; } seed(__sum); } template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const linear_congruential_engine<_UIntType, __a, __c, __m>& __lcr) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); __os.fill(__os.widen(' ')); __os << __lcr._M_x; __os.flags(__flags); __os.fill(__fill); return __os; } template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, linear_congruential_engine<_UIntType, __a, __c, __m>& __lcr) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec); __is >> __lcr._M_x; __is.flags(__flags); return __is; } template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr size_t mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::word_size; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr size_t mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::state_size; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr size_t mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::shift_size; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr size_t mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::mask_bits; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr _UIntType mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::xor_mask; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr size_t mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_u; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr _UIntType mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_d; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr size_t mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_s; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr _UIntType mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_b; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr size_t mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_t; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr _UIntType mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_c; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr size_t mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_l; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr _UIntType mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>:: initialization_multiplier; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> constexpr _UIntType mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::default_seed; template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>:: seed(result_type __sd) { _M_x[0] = __detail::__mod<_UIntType, __detail::_Shift<_UIntType, __w>::__value>(__sd); for (size_t __i = 1; __i < state_size; ++__i) { _UIntType __x = _M_x[__i - 1]; __x ^= __x >> (__w - 2); __x *= __f; __x += __detail::__mod<_UIntType, __n>(__i); _M_x[__i] = __detail::__mod<_UIntType, __detail::_Shift<_UIntType, __w>::__value>(__x); } _M_p = state_size; } template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> template<typename _Sseq> typename std::enable_if<std::is_class<_Sseq>::value>::type mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>:: seed(_Sseq& __q) { const _UIntType __upper_mask = (~_UIntType()) << __r; const size_t __k = (__w + 31) / 32; uint_least32_t __arr[__n * __k]; __q.generate(__arr + 0, __arr + __n * __k); bool __zero = true; for (size_t __i = 0; __i < state_size; ++__i) { _UIntType __factor = 1u; _UIntType __sum = 0u; for (size_t __j = 0; __j < __k; ++__j) { __sum += __arr[__k * __i + __j] * __factor; __factor *= __detail::_Shift<_UIntType, 32>::__value; } _M_x[__i] = __detail::__mod<_UIntType, __detail::_Shift<_UIntType, __w>::__value>(__sum); if (__zero) { if (__i == 0) { if ((_M_x[0] & __upper_mask) != 0u) __zero = false; } else if (_M_x[__i] != 0u) __zero = false; } } if (__zero) _M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value; _M_p = state_size; } template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>:: _M_gen_rand(void) { const _UIntType __upper_mask = (~_UIntType()) << __r; const _UIntType __lower_mask = ~__upper_mask; for (size_t __k = 0; __k < (__n - __m); ++__k) { _UIntType __y = ((_M_x[__k] & __upper_mask) | (_M_x[__k + 1] & __lower_mask)); _M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1) ^ ((__y & 0x01) ? __a : 0)); } for (size_t __k = (__n - __m); __k < (__n - 1); ++__k) { _UIntType __y = ((_M_x[__k] & __upper_mask) | (_M_x[__k + 1] & __lower_mask)); _M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1) ^ ((__y & 0x01) ? __a : 0)); } _UIntType __y = ((_M_x[__n - 1] & __upper_mask) | (_M_x[0] & __lower_mask)); _M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1) ^ ((__y & 0x01) ? __a : 0)); _M_p = 0; } template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> void mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>:: discard(unsigned long long __z) { while (__z > state_size - _M_p) { __z -= state_size - _M_p; _M_gen_rand(); } _M_p += __z; } template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>:: operator()() { // Reload the vector - cost is O(n) amortized over n calls. if (_M_p >= state_size) _M_gen_rand(); // Calculate o(x(i)). result_type __z = _M_x[_M_p++]; __z ^= (__z >> __u) & __d; __z ^= (__z << __s) & __b; __z ^= (__z << __t) & __c; __z ^= (__z >> __l); return __z; } template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); __os.fill(__space); for (size_t __i = 0; __i < __n; ++__i) __os << __x._M_x[__i] << __space; __os << __x._M_p; __os.flags(__flags); __os.fill(__fill); return __os; } template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); for (size_t __i = 0; __i < __n; ++__i) __is >> __x._M_x[__i]; __is >> __x._M_p; __is.flags(__flags); return __is; } template<typename _UIntType, size_t __w, size_t __s, size_t __r> constexpr size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size; template<typename _UIntType, size_t __w, size_t __s, size_t __r> constexpr size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag; template<typename _UIntType, size_t __w, size_t __s, size_t __r> constexpr size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag; template<typename _UIntType, size_t __w, size_t __s, size_t __r> constexpr _UIntType subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed; template<typename _UIntType, size_t __w, size_t __s, size_t __r> void subtract_with_carry_engine<_UIntType, __w, __s, __r>:: seed(result_type __value) { std::linear_congruential_engine<result_type, 40014u, 0u, 2147483563u> __lcg(__value == 0u ? default_seed : __value); const size_t __n = (__w + 31) / 32; for (size_t __i = 0; __i < long_lag; ++__i) { _UIntType __sum = 0u; _UIntType __factor = 1u; for (size_t __j = 0; __j < __n; ++__j) { __sum += __detail::__mod<uint_least32_t, __detail::_Shift<uint_least32_t, 32>::__value> (__lcg()) * __factor; __factor *= __detail::_Shift<_UIntType, 32>::__value; } _M_x[__i] = __detail::__mod<_UIntType, __detail::_Shift<_UIntType, __w>::__value>(__sum); } _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; _M_p = 0; } template<typename _UIntType, size_t __w, size_t __s, size_t __r> template<typename _Sseq> typename std::enable_if<std::is_class<_Sseq>::value>::type subtract_with_carry_engine<_UIntType, __w, __s, __r>:: seed(_Sseq& __q) { const size_t __k = (__w + 31) / 32; uint_least32_t __arr[__r * __k]; __q.generate(__arr + 0, __arr + __r * __k); for (size_t __i = 0; __i < long_lag; ++__i) { _UIntType __sum = 0u; _UIntType __factor = 1u; for (size_t __j = 0; __j < __k; ++__j) { __sum += __arr[__k * __i + __j] * __factor; __factor *= __detail::_Shift<_UIntType, 32>::__value; } _M_x[__i] = __detail::__mod<_UIntType, __detail::_Shift<_UIntType, __w>::__value>(__sum); } _M_carry = (_M_x[long_lag - 1] == 0) ? 1 : 0; _M_p = 0; } template<typename _UIntType, size_t __w, size_t __s, size_t __r> typename subtract_with_carry_engine<_UIntType, __w, __s, __r>:: result_type subtract_with_carry_engine<_UIntType, __w, __s, __r>:: operator()() { // Derive short lag index from current index. long __ps = _M_p - short_lag; if (__ps < 0) __ps += long_lag; // Calculate new x(i) without overflow or division. // NB: Thanks to the requirements for _UIntType, _M_x[_M_p] + _M_carry // cannot overflow. _UIntType __xi; if (_M_x[__ps] >= _M_x[_M_p] + _M_carry) { __xi = _M_x[__ps] - _M_x[_M_p] - _M_carry; _M_carry = 0; } else { __xi = (__detail::_Shift<_UIntType, __w>::__value - _M_x[_M_p] - _M_carry + _M_x[__ps]); _M_carry = 1; } _M_x[_M_p] = __xi; // Adjust current index to loop around in ring buffer. if (++_M_p >= long_lag) _M_p = 0; return __xi; } template<typename _UIntType, size_t __w, size_t __s, size_t __r, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const subtract_with_carry_engine<_UIntType, __w, __s, __r>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); __os.fill(__space); for (size_t __i = 0; __i < __r; ++__i) __os << __x._M_x[__i] << __space; __os << __x._M_carry << __space << __x._M_p; __os.flags(__flags); __os.fill(__fill); return __os; } template<typename _UIntType, size_t __w, size_t __s, size_t __r, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, subtract_with_carry_engine<_UIntType, __w, __s, __r>& __x) { typedef std::basic_ostream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); for (size_t __i = 0; __i < __r; ++__i) __is >> __x._M_x[__i]; __is >> __x._M_carry; __is >> __x._M_p; __is.flags(__flags); return __is; } template<typename _RandomNumberEngine, size_t __p, size_t __r> constexpr size_t discard_block_engine<_RandomNumberEngine, __p, __r>::block_size; template<typename _RandomNumberEngine, size_t __p, size_t __r> constexpr size_t discard_block_engine<_RandomNumberEngine, __p, __r>::used_block; template<typename _RandomNumberEngine, size_t __p, size_t __r> typename discard_block_engine<_RandomNumberEngine, __p, __r>::result_type discard_block_engine<_RandomNumberEngine, __p, __r>:: operator()() { if (_M_n >= used_block) { _M_b.discard(block_size - _M_n); _M_n = 0; } ++_M_n; return _M_b(); } template<typename _RandomNumberEngine, size_t __p, size_t __r, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const discard_block_engine<_RandomNumberEngine, __p, __r>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); __os.fill(__space); __os << __x.base() << __space << __x._M_n; __os.flags(__flags); __os.fill(__fill); return __os; } template<typename _RandomNumberEngine, size_t __p, size_t __r, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, discard_block_engine<_RandomNumberEngine, __p, __r>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); __is >> __x._M_b >> __x._M_n; __is.flags(__flags); return __is; } template<typename _RandomNumberEngine, size_t __w, typename _UIntType> typename independent_bits_engine<_RandomNumberEngine, __w, _UIntType>:: result_type independent_bits_engine<_RandomNumberEngine, __w, _UIntType>:: operator()() { typedef typename _RandomNumberEngine::result_type _Eresult_type; const _Eresult_type __r = (_M_b.max() - _M_b.min() < std::numeric_limits<_Eresult_type>::max() ? _M_b.max() - _M_b.min() + 1 : 0); const unsigned __edig = std::numeric_limits<_Eresult_type>::digits; const unsigned __m = __r ? std::__lg(__r) : __edig; typedef typename std::common_type<_Eresult_type, result_type>::type __ctype; const unsigned __cdig = std::numeric_limits<__ctype>::digits; unsigned __n, __n0; __ctype __s0, __s1, __y0, __y1; for (size_t __i = 0; __i < 2; ++__i) { __n = (__w + __m - 1) / __m + __i; __n0 = __n - __w % __n; const unsigned __w0 = __w / __n; // __w0 <= __m __s0 = 0; __s1 = 0; if (__w0 < __cdig) { __s0 = __ctype(1) << __w0; __s1 = __s0 << 1; } __y0 = 0; __y1 = 0; if (__r) { __y0 = __s0 * (__r / __s0); if (__s1) __y1 = __s1 * (__r / __s1); if (__r - __y0 <= __y0 / __n) break; } else break; } result_type __sum = 0; for (size_t __k = 0; __k < __n0; ++__k) { __ctype __u; do __u = _M_b() - _M_b.min(); while (__y0 && __u >= __y0); __sum = __s0 * __sum + (__s0 ? __u % __s0 : __u); } for (size_t __k = __n0; __k < __n; ++__k) { __ctype __u; do __u = _M_b() - _M_b.min(); while (__y1 && __u >= __y1); __sum = __s1 * __sum + (__s1 ? __u % __s1 : __u); } return __sum; } template<typename _RandomNumberEngine, size_t __k> constexpr size_t shuffle_order_engine<_RandomNumberEngine, __k>::table_size; template<typename _RandomNumberEngine, size_t __k> typename shuffle_order_engine<_RandomNumberEngine, __k>::result_type shuffle_order_engine<_RandomNumberEngine, __k>:: operator()() { size_t __j = __k * ((_M_y - _M_b.min()) / (_M_b.max() - _M_b.min() + 1.0L)); _M_y = _M_v[__j]; _M_v[__j] = _M_b(); return _M_y; } template<typename _RandomNumberEngine, size_t __k, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const shuffle_order_engine<_RandomNumberEngine, __k>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::dec | __ios_base::fixed | __ios_base::left); __os.fill(__space); __os << __x.base(); for (size_t __i = 0; __i < __k; ++__i) __os << __space << __x._M_v[__i]; __os << __space << __x._M_y; __os.flags(__flags); __os.fill(__fill); return __os; } template<typename _RandomNumberEngine, size_t __k, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, shuffle_order_engine<_RandomNumberEngine, __k>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); __is >> __x._M_b; for (size_t __i = 0; __i < __k; ++__i) __is >> __x._M_v[__i]; __is >> __x._M_y; __is.flags(__flags); return __is; } template<typename _IntType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const uniform_int_distribution<_IntType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os << __x.a() << __space << __x.b(); __os.flags(__flags); __os.fill(__fill); return __os; } template<typename _IntType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, uniform_int_distribution<_IntType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _IntType __a, __b; if (__is >> __a >> __b) __x.param(typename uniform_int_distribution<_IntType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void uniform_real_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); auto __range = __p.b() - __p.a(); while (__f != __t) *__f++ = __aurng() * __range + __p.a(); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const uniform_real_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, uniform_real_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::skipws); _RealType __a, __b; if (__is >> __a >> __b) __x.param(typename uniform_real_distribution<_RealType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void std::bernoulli_distribution:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); auto __limit = __p.p() * (__aurng.max() - __aurng.min()); while (__f != __t) *__f++ = (__aurng() - __aurng.min()) < __limit; } template<typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__os.widen(' ')); __os.precision(std::numeric_limits<double>::max_digits10); __os << __x.p(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _IntType> template<typename _UniformRandomNumberGenerator> typename geometric_distribution<_IntType>::result_type geometric_distribution<_IntType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { // About the epsilon thing see this thread: // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html const double __naf = (1 - std::numeric_limits<double>::epsilon()) / 2; // The largest _RealType convertible to _IntType. const double __thr = std::numeric_limits<_IntType>::max() + __naf; __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); double __cand; do __cand = std::floor(std::log(1.0 - __aurng()) / __param._M_log_1_p); while (__cand >= __thr); return result_type(__cand + __naf); } template<typename _IntType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void geometric_distribution<_IntType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) // About the epsilon thing see this thread: // http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00971.html const double __naf = (1 - std::numeric_limits<double>::epsilon()) / 2; // The largest _RealType convertible to _IntType. const double __thr = std::numeric_limits<_IntType>::max() + __naf; __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); while (__f != __t) { double __cand; do __cand = std::floor(std::log(1.0 - __aurng()) / __param._M_log_1_p); while (__cand >= __thr); *__f++ = __cand + __naf; } } template<typename _IntType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const geometric_distribution<_IntType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__os.widen(' ')); __os.precision(std::numeric_limits<double>::max_digits10); __os << __x.p(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _IntType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, geometric_distribution<_IntType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::skipws); double __p; if (__is >> __p) __x.param(typename geometric_distribution<_IntType>::param_type(__p)); __is.flags(__flags); return __is; } // This is Leger's algorithm, also in Devroye, Ch. X, Example 1.5. template<typename _IntType> template<typename _UniformRandomNumberGenerator> typename negative_binomial_distribution<_IntType>::result_type negative_binomial_distribution<_IntType>:: operator()(_UniformRandomNumberGenerator& __urng) { const double __y = _M_gd(__urng); // XXX Is the constructor too slow? std::poisson_distribution<result_type> __poisson(__y); return __poisson(__urng); } template<typename _IntType> template<typename _UniformRandomNumberGenerator> typename negative_binomial_distribution<_IntType>::result_type negative_binomial_distribution<_IntType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typedef typename std::gamma_distribution<double>::param_type param_type; const double __y = _M_gd(__urng, param_type(__p.k(), (1.0 - __p.p()) / __p.p())); std::poisson_distribution<result_type> __poisson(__y); return __poisson(__urng); } template<typename _IntType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void negative_binomial_distribution<_IntType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) while (__f != __t) { const double __y = _M_gd(__urng); // XXX Is the constructor too slow? std::poisson_distribution<result_type> __poisson(__y); *__f++ = __poisson(__urng); } } template<typename _IntType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void negative_binomial_distribution<_IntType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) typename std::gamma_distribution<result_type>::param_type __p2(__p.k(), (1.0 - __p.p()) / __p.p()); while (__f != __t) { const double __y = _M_gd(__urng, __p2); std::poisson_distribution<result_type> __poisson(__y); *__f++ = __poisson(__urng); } } template<typename _IntType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const negative_binomial_distribution<_IntType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__os.widen(' ')); __os.precision(std::numeric_limits<double>::max_digits10); __os << __x.k() << __space << __x.p() << __space << __x._M_gd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _IntType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, negative_binomial_distribution<_IntType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::skipws); _IntType __k; double __p; if (__is >> __k >> __p >> __x._M_gd) __x.param(typename negative_binomial_distribution<_IntType>:: param_type(__k, __p)); __is.flags(__flags); return __is; } template<typename _IntType> void poisson_distribution<_IntType>::param_type:: _M_initialize() { #if _GLIBCXX_USE_C99_MATH_TR1 if (_M_mean >= 12) { const double __m = std::floor(_M_mean); _M_lm_thr = std::log(_M_mean); _M_lfm = std::lgamma(__m + 1); _M_sm = std::sqrt(__m); const double __pi_4 = 0.7853981633974483096156608458198757L; const double __dx = std::sqrt(2 * __m * std::log(32 * __m / __pi_4)); _M_d = std::round(std::max<double>(6.0, std::min(__m, __dx))); const double __cx = 2 * __m + _M_d; _M_scx = std::sqrt(__cx / 2); _M_1cx = 1 / __cx; _M_c2b = std::sqrt(__pi_4 * __cx) * std::exp(_M_1cx); _M_cb = 2 * __cx * std::exp(-_M_d * _M_1cx * (1 + _M_d / 2)) / _M_d; } else #endif _M_lm_thr = std::exp(-_M_mean); } /** * A rejection algorithm when mean >= 12 and a simple method based * upon the multiplication of uniform random variates otherwise. * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 * is defined. * * Reference: * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, * New York, 1986, Ch. X, Sects. 3.3 & 3.4 (+ Errata!). */ template<typename _IntType> template<typename _UniformRandomNumberGenerator> typename poisson_distribution<_IntType>::result_type poisson_distribution<_IntType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); #if _GLIBCXX_USE_C99_MATH_TR1 if (__param.mean() >= 12) { double __x; // See comments above... const double __naf = (1 - std::numeric_limits<double>::epsilon()) / 2; const double __thr = std::numeric_limits<_IntType>::max() + __naf; const double __m = std::floor(__param.mean()); // sqrt(pi / 2) const double __spi_2 = 1.2533141373155002512078826424055226L; const double __c1 = __param._M_sm * __spi_2; const double __c2 = __param._M_c2b + __c1; const double __c3 = __c2 + 1; const double __c4 = __c3 + 1; // 1 / 78 const double __178 = 0.0128205128205128205128205128205128L; // e^(1 / 78) const double __e178 = 1.0129030479320018583185514777512983L; const double __c5 = __c4 + __e178; const double __c = __param._M_cb + __c5; const double __2cx = 2 * (2 * __m + __param._M_d); bool __reject = true; do { const double __u = __c * __aurng(); const double __e = -std::log(1.0 - __aurng()); double __w = 0.0; if (__u <= __c1) { const double __n = _M_nd(__urng); const double __y = -std::abs(__n) * __param._M_sm - 1; __x = std::floor(__y); __w = -__n * __n / 2; if (__x < -__m) continue; } else if (__u <= __c2) { const double __n = _M_nd(__urng); const double __y = 1 + std::abs(__n) * __param._M_scx; __x = std::ceil(__y); __w = __y * (2 - __y) * __param._M_1cx; if (__x > __param._M_d) continue; } else if (__u <= __c3) // NB: This case not in the book, nor in the Errata, // but should be ok... __x = -1; else if (__u <= __c4) __x = 0; else if (__u <= __c5) { __x = 1; // Only in the Errata, see libstdc++/83237. __w = __178; } else { const double __v = -std::log(1.0 - __aurng()); const double __y = __param._M_d + __v * __2cx / __param._M_d; __x = std::ceil(__y); __w = -__param._M_d * __param._M_1cx * (1 + __y / 2); } __reject = (__w - __e - __x * __param._M_lm_thr > __param._M_lfm - std::lgamma(__x + __m + 1)); __reject |= __x + __m >= __thr; } while (__reject); return result_type(__x + __m + __naf); } else #endif { _IntType __x = 0; double __prod = 1.0; do { __prod *= __aurng(); __x += 1; } while (__prod > __param._M_lm_thr); return __x - 1; } } template<typename _IntType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void poisson_distribution<_IntType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) // We could duplicate everything from operator()... while (__f != __t) *__f++ = this->operator()(__urng, __param); } template<typename _IntType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const poisson_distribution<_IntType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<double>::max_digits10); __os << __x.mean() << __space << __x._M_nd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _IntType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, poisson_distribution<_IntType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::skipws); double __mean; if (__is >> __mean >> __x._M_nd) __x.param(typename poisson_distribution<_IntType>::param_type(__mean)); __is.flags(__flags); return __is; } template<typename _IntType> void binomial_distribution<_IntType>::param_type:: _M_initialize() { const double __p12 = _M_p <= 0.5 ? _M_p : 1.0 - _M_p; _M_easy = true; #if _GLIBCXX_USE_C99_MATH_TR1 if (_M_t * __p12 >= 8) { _M_easy = false; const double __np = std::floor(_M_t * __p12); const double __pa = __np / _M_t; const double __1p = 1 - __pa; const double __pi_4 = 0.7853981633974483096156608458198757L; const double __d1x = std::sqrt(__np * __1p * std::log(32 * __np / (81 * __pi_4 * __1p))); _M_d1 = std::round(std::max<double>(1.0, __d1x)); const double __d2x = std::sqrt(__np * __1p * std::log(32 * _M_t * __1p / (__pi_4 * __pa))); _M_d2 = std::round(std::max<double>(1.0, __d2x)); // sqrt(pi / 2) const double __spi_2 = 1.2533141373155002512078826424055226L; _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np)); _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p)); _M_c = 2 * _M_d1 / __np; _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2; const double __a12 = _M_a1 + _M_s2 * __spi_2; const double __s1s = _M_s1 * _M_s1; _M_a123 = __a12 + (std::exp(_M_d1 / (_M_t * __1p)) * 2 * __s1s / _M_d1 * std::exp(-_M_d1 * _M_d1 / (2 * __s1s))); const double __s2s = _M_s2 * _M_s2; _M_s = (_M_a123 + 2 * __s2s / _M_d2 * std::exp(-_M_d2 * _M_d2 / (2 * __s2s))); _M_lf = (std::lgamma(__np + 1) + std::lgamma(_M_t - __np + 1)); _M_lp1p = std::log(__pa / __1p); _M_q = -std::log(1 - (__p12 - __pa) / __1p); } else #endif _M_q = -std::log(1 - __p12); } template<typename _IntType> template<typename _UniformRandomNumberGenerator> typename binomial_distribution<_IntType>::result_type binomial_distribution<_IntType>:: _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t, double __q) { _IntType __x = 0; double __sum = 0.0; __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); do { if (__t == __x) return __x; const double __e = -std::log(1.0 - __aurng()); __sum += __e / (__t - __x); __x += 1; } while (__sum <= __q); return __x - 1; } /** * A rejection algorithm when t * p >= 8 and a simple waiting time * method - the second in the referenced book - otherwise. * NB: The former is available only if _GLIBCXX_USE_C99_MATH_TR1 * is defined. * * Reference: * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, * New York, 1986, Ch. X, Sect. 4 (+ Errata!). */ template<typename _IntType> template<typename _UniformRandomNumberGenerator> typename binomial_distribution<_IntType>::result_type binomial_distribution<_IntType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { result_type __ret; const _IntType __t = __param.t(); const double __p = __param.p(); const double __p12 = __p <= 0.5 ? __p : 1.0 - __p; __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); #if _GLIBCXX_USE_C99_MATH_TR1 if (!__param._M_easy) { double __x; // See comments above... const double __naf = (1 - std::numeric_limits<double>::epsilon()) / 2; const double __thr = std::numeric_limits<_IntType>::max() + __naf; const double __np = std::floor(__t * __p12); // sqrt(pi / 2) const double __spi_2 = 1.2533141373155002512078826424055226L; const double __a1 = __param._M_a1; const double __a12 = __a1 + __param._M_s2 * __spi_2; const double __a123 = __param._M_a123; const double __s1s = __param._M_s1 * __param._M_s1; const double __s2s = __param._M_s2 * __param._M_s2; bool __reject; do { const double __u = __param._M_s * __aurng(); double __v; if (__u <= __a1) { const double __n = _M_nd(__urng); const double __y = __param._M_s1 * std::abs(__n); __reject = __y >= __param._M_d1; if (!__reject) { const double __e = -std::log(1.0 - __aurng()); __x = std::floor(__y); __v = -__e - __n * __n / 2 + __param._M_c; } } else if (__u <= __a12) { const double __n = _M_nd(__urng); const double __y = __param._M_s2 * std::abs(__n); __reject = __y >= __param._M_d2; if (!__reject) { const double __e = -std::log(1.0 - __aurng()); __x = std::floor(-__y); __v = -__e - __n * __n / 2; } } else if (__u <= __a123) { const double __e1 = -std::log(1.0 - __aurng()); const double __e2 = -std::log(1.0 - __aurng()); const double __y = __param._M_d1 + 2 * __s1s * __e1 / __param._M_d1; __x = std::floor(__y); __v = (-__e2 + __param._M_d1 * (1 / (__t - __np) -__y / (2 * __s1s))); __reject = false; } else { const double __e1 = -std::log(1.0 - __aurng()); const double __e2 = -std::log(1.0 - __aurng()); const double __y = __param._M_d2 + 2 * __s2s * __e1 / __param._M_d2; __x = std::floor(-__y); __v = -__e2 - __param._M_d2 * __y / (2 * __s2s); __reject = false; } __reject = __reject || __x < -__np || __x > __t - __np; if (!__reject) { const double __lfx = std::lgamma(__np + __x + 1) + std::lgamma(__t - (__np + __x) + 1); __reject = __v > __param._M_lf - __lfx + __x * __param._M_lp1p; } __reject |= __x + __np >= __thr; } while (__reject); __x += __np + __naf; const _IntType __z = _M_waiting(__urng, __t - _IntType(__x), __param._M_q); __ret = _IntType(__x) + __z; } else #endif __ret = _M_waiting(__urng, __t, __param._M_q); if (__p12 != __p) __ret = __t - __ret; return __ret; } template<typename _IntType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void binomial_distribution<_IntType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) // We could duplicate everything from operator()... while (__f != __t) *__f++ = this->operator()(__urng, __param); } template<typename _IntType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const binomial_distribution<_IntType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<double>::max_digits10); __os << __x.t() << __space << __x.p() << __space << __x._M_nd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _IntType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, binomial_distribution<_IntType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _IntType __t; double __p; if (__is >> __t >> __p >> __x._M_nd) __x.param(typename binomial_distribution<_IntType>:: param_type(__t, __p)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void std::exponential_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); while (__f != __t) *__f++ = -std::log(result_type(1) - __aurng()) / __p.lambda(); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const exponential_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__os.widen(' ')); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.lambda(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, exponential_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __lambda; if (__is >> __lambda) __x.param(typename exponential_distribution<_RealType>:: param_type(__lambda)); __is.flags(__flags); return __is; } /** * Polar method due to Marsaglia. * * Devroye, L. Non-Uniform Random Variates Generation. Springer-Verlag, * New York, 1986, Ch. V, Sect. 4.4. */ template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename normal_distribution<_RealType>::result_type normal_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { result_type __ret; __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); if (_M_saved_available) { _M_saved_available = false; __ret = _M_saved; } else { result_type __x, __y, __r2; do { __x = result_type(2.0) * __aurng() - 1.0; __y = result_type(2.0) * __aurng() - 1.0; __r2 = __x * __x + __y * __y; } while (__r2 > 1.0 || __r2 == 0.0); const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); _M_saved = __x * __mult; _M_saved_available = true; __ret = __y * __mult; } __ret = __ret * __param.stddev() + __param.mean(); return __ret; } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void normal_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) if (__f == __t) return; if (_M_saved_available) { _M_saved_available = false; *__f++ = _M_saved * __param.stddev() + __param.mean(); if (__f == __t) return; } __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); while (__f + 1 < __t) { result_type __x, __y, __r2; do { __x = result_type(2.0) * __aurng() - 1.0; __y = result_type(2.0) * __aurng() - 1.0; __r2 = __x * __x + __y * __y; } while (__r2 > 1.0 || __r2 == 0.0); const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); *__f++ = __y * __mult * __param.stddev() + __param.mean(); *__f++ = __x * __mult * __param.stddev() + __param.mean(); } if (__f != __t) { result_type __x, __y, __r2; do { __x = result_type(2.0) * __aurng() - 1.0; __y = result_type(2.0) * __aurng() - 1.0; __r2 = __x * __x + __y * __y; } while (__r2 > 1.0 || __r2 == 0.0); const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); _M_saved = __x * __mult; _M_saved_available = true; *__f = __y * __mult * __param.stddev() + __param.mean(); } } template<typename _RealType> bool operator==(const std::normal_distribution<_RealType>& __d1, const std::normal_distribution<_RealType>& __d2) { if (__d1._M_param == __d2._M_param && __d1._M_saved_available == __d2._M_saved_available) { if (__d1._M_saved_available && __d1._M_saved == __d2._M_saved) return true; else if(!__d1._M_saved_available) return true; else return false; } else return false; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const normal_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.mean() << __space << __x.stddev() << __space << __x._M_saved_available; if (__x._M_saved_available) __os << __space << __x._M_saved; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, normal_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); double __mean, __stddev; bool __saved_avail; if (__is >> __mean >> __stddev >> __saved_avail) { if (!__saved_avail || (__is >> __x._M_saved)) { __x._M_saved_available = __saved_avail; __x.param(typename normal_distribution<_RealType>:: param_type(__mean, __stddev)); } } __is.flags(__flags); return __is; } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void lognormal_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) while (__f != __t) *__f++ = std::exp(__p.s() * _M_nd(__urng) + __p.m()); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const lognormal_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.m() << __space << __x.s() << __space << __x._M_nd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, lognormal_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __m, __s; if (__is >> __m >> __s >> __x._M_nd) __x.param(typename lognormal_distribution<_RealType>:: param_type(__m, __s)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void std::chi_squared_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) while (__f != __t) *__f++ = 2 * _M_gd(__urng); } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void std::chi_squared_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const typename std::gamma_distribution<result_type>::param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) while (__f != __t) *__f++ = 2 * _M_gd(__urng, __p); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const chi_squared_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.n() << __space << __x._M_gd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, chi_squared_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __n; if (__is >> __n >> __x._M_gd) __x.param(typename chi_squared_distribution<_RealType>:: param_type(__n)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename cauchy_distribution<_RealType>::result_type cauchy_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); _RealType __u; do __u = __aurng(); while (__u == 0.5); const _RealType __pi = 3.1415926535897932384626433832795029L; return __p.a() + __p.b() * std::tan(__pi * __u); } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void cauchy_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) const _RealType __pi = 3.1415926535897932384626433832795029L; __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); while (__f != __t) { _RealType __u; do __u = __aurng(); while (__u == 0.5); *__f++ = __p.a() + __p.b() * std::tan(__pi * __u); } } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const cauchy_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, cauchy_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b; if (__is >> __a >> __b) __x.param(typename cauchy_distribution<_RealType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void std::fisher_f_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) while (__f != __t) *__f++ = ((_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m())); } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void std::fisher_f_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) typedef typename std::gamma_distribution<result_type>::param_type param_type; param_type __p1(__p.m() / 2); param_type __p2(__p.n() / 2); while (__f != __t) *__f++ = ((_M_gd_x(__urng, __p1) * n()) / (_M_gd_y(__urng, __p2) * m())); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const fisher_f_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.m() << __space << __x.n() << __space << __x._M_gd_x << __space << __x._M_gd_y; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, fisher_f_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __m, __n; if (__is >> __m >> __n >> __x._M_gd_x >> __x._M_gd_y) __x.param(typename fisher_f_distribution<_RealType>:: param_type(__m, __n)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void std::student_t_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) while (__f != __t) *__f++ = _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void std::student_t_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) typename std::gamma_distribution<result_type>::param_type __p2(__p.n() / 2, 2); while (__f != __t) *__f++ = _M_nd(__urng) * std::sqrt(__p.n() / _M_gd(__urng, __p2)); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const student_t_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.n() << __space << __x._M_nd << __space << __x._M_gd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, student_t_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __n; if (__is >> __n >> __x._M_nd >> __x._M_gd) __x.param(typename student_t_distribution<_RealType>::param_type(__n)); __is.flags(__flags); return __is; } template<typename _RealType> void gamma_distribution<_RealType>::param_type:: _M_initialize() { _M_malpha = _M_alpha < 1.0 ? _M_alpha + _RealType(1.0) : _M_alpha; const _RealType __a1 = _M_malpha - _RealType(1.0) / _RealType(3.0); _M_a2 = _RealType(1.0) / std::sqrt(_RealType(9.0) * __a1); } /** * Marsaglia, G. and Tsang, W. W. * "A Simple Method for Generating Gamma Variables" * ACM Transactions on Mathematical Software, 26, 3, 363-372, 2000. */ template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename gamma_distribution<_RealType>::result_type gamma_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __u, __v, __n; const result_type __a1 = (__param._M_malpha - _RealType(1.0) / _RealType(3.0)); do { do { __n = _M_nd(__urng); __v = result_type(1.0) + __param._M_a2 * __n; } while (__v <= 0.0); __v = __v * __v * __v; __u = __aurng(); } while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n && (std::log(__u) > (0.5 * __n * __n + __a1 * (1.0 - __v + std::log(__v))))); if (__param.alpha() == __param._M_malpha) return __a1 * __v * __param.beta(); else { do __u = __aurng(); while (__u == 0.0); return (std::pow(__u, result_type(1.0) / __param.alpha()) * __a1 * __v * __param.beta()); } } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void gamma_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); result_type __u, __v, __n; const result_type __a1 = (__param._M_malpha - _RealType(1.0) / _RealType(3.0)); if (__param.alpha() == __param._M_malpha) while (__f != __t) { do { do { __n = _M_nd(__urng); __v = result_type(1.0) + __param._M_a2 * __n; } while (__v <= 0.0); __v = __v * __v * __v; __u = __aurng(); } while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n && (std::log(__u) > (0.5 * __n * __n + __a1 * (1.0 - __v + std::log(__v))))); *__f++ = __a1 * __v * __param.beta(); } else while (__f != __t) { do { do { __n = _M_nd(__urng); __v = result_type(1.0) + __param._M_a2 * __n; } while (__v <= 0.0); __v = __v * __v * __v; __u = __aurng(); } while (__u > result_type(1.0) - 0.0331 * __n * __n * __n * __n && (std::log(__u) > (0.5 * __n * __n + __a1 * (1.0 - __v + std::log(__v))))); do __u = __aurng(); while (__u == 0.0); *__f++ = (std::pow(__u, result_type(1.0) / __param.alpha()) * __a1 * __v * __param.beta()); } } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const gamma_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.alpha() << __space << __x.beta() << __space << __x._M_nd; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, gamma_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __alpha_val, __beta_val; if (__is >> __alpha_val >> __beta_val >> __x._M_nd) __x.param(typename gamma_distribution<_RealType>:: param_type(__alpha_val, __beta_val)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename weibull_distribution<_RealType>::result_type weibull_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); return __p.b() * std::pow(-std::log(result_type(1) - __aurng()), result_type(1) / __p.a()); } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void weibull_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); auto __inv_a = result_type(1) / __p.a(); while (__f != __t) *__f++ = __p.b() * std::pow(-std::log(result_type(1) - __aurng()), __inv_a); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const weibull_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, weibull_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b; if (__is >> __a >> __b) __x.param(typename weibull_distribution<_RealType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename extreme_value_distribution<_RealType>::result_type extreme_value_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); return __p.a() - __p.b() * std::log(-std::log(result_type(1) - __aurng())); } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void extreme_value_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); while (__f != __t) *__f++ = __p.a() - __p.b() * std::log(-std::log(result_type(1) - __aurng())); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const extreme_value_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); __os << __x.a() << __space << __x.b(); __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, extreme_value_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); _RealType __a, __b; if (__is >> __a >> __b) __x.param(typename extreme_value_distribution<_RealType>:: param_type(__a, __b)); __is.flags(__flags); return __is; } template<typename _IntType> void discrete_distribution<_IntType>::param_type:: _M_initialize() { if (_M_prob.size() < 2) { _M_prob.clear(); return; } const double __sum = std::accumulate(_M_prob.begin(), _M_prob.end(), 0.0); // Now normalize the probabilites. __detail::__normalize(_M_prob.begin(), _M_prob.end(), _M_prob.begin(), __sum); // Accumulate partial sums. _M_cp.reserve(_M_prob.size()); std::partial_sum(_M_prob.begin(), _M_prob.end(), std::back_inserter(_M_cp)); // Make sure the last cumulative probability is one. _M_cp[_M_cp.size() - 1] = 1.0; } template<typename _IntType> template<typename _Func> discrete_distribution<_IntType>::param_type:: param_type(size_t __nw, double __xmin, double __xmax, _Func __fw) : _M_prob(), _M_cp() { const size_t __n = __nw == 0 ? 1 : __nw; const double __delta = (__xmax - __xmin) / __n; _M_prob.reserve(__n); for (size_t __k = 0; __k < __nw; ++__k) _M_prob.push_back(__fw(__xmin + __k * __delta + 0.5 * __delta)); _M_initialize(); } template<typename _IntType> template<typename _UniformRandomNumberGenerator> typename discrete_distribution<_IntType>::result_type discrete_distribution<_IntType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { if (__param._M_cp.empty()) return result_type(0); __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); const double __p = __aurng(); auto __pos = std::lower_bound(__param._M_cp.begin(), __param._M_cp.end(), __p); return __pos - __param._M_cp.begin(); } template<typename _IntType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void discrete_distribution<_IntType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) if (__param._M_cp.empty()) { while (__f != __t) *__f++ = result_type(0); return; } __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); while (__f != __t) { const double __p = __aurng(); auto __pos = std::lower_bound(__param._M_cp.begin(), __param._M_cp.end(), __p); *__f++ = __pos - __param._M_cp.begin(); } } template<typename _IntType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const discrete_distribution<_IntType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<double>::max_digits10); std::vector<double> __prob = __x.probabilities(); __os << __prob.size(); for (auto __dit = __prob.begin(); __dit != __prob.end(); ++__dit) __os << __space << *__dit; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } namespace __detail { template<typename _ValT, typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& __extract_params(basic_istream<_CharT, _Traits>& __is, vector<_ValT>& __vals, size_t __n) { __vals.reserve(__n); while (__n--) { _ValT __val; if (__is >> __val) __vals.push_back(__val); else break; } return __is; } } // namespace __detail template<typename _IntType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, discrete_distribution<_IntType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); size_t __n; if (__is >> __n) { std::vector<double> __prob_vec; if (__detail::__extract_params(__is, __prob_vec, __n)) __x.param({__prob_vec.begin(), __prob_vec.end()}); } __is.flags(__flags); return __is; } template<typename _RealType> void piecewise_constant_distribution<_RealType>::param_type:: _M_initialize() { if (_M_int.size() < 2 || (_M_int.size() == 2 && _M_int[0] == _RealType(0) && _M_int[1] == _RealType(1))) { _M_int.clear(); _M_den.clear(); return; } const double __sum = std::accumulate(_M_den.begin(), _M_den.end(), 0.0); __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(), __sum); _M_cp.reserve(_M_den.size()); std::partial_sum(_M_den.begin(), _M_den.end(), std::back_inserter(_M_cp)); // Make sure the last cumulative probability is one. _M_cp[_M_cp.size() - 1] = 1.0; for (size_t __k = 0; __k < _M_den.size(); ++__k) _M_den[__k] /= _M_int[__k + 1] - _M_int[__k]; } template<typename _RealType> template<typename _InputIteratorB, typename _InputIteratorW> piecewise_constant_distribution<_RealType>::param_type:: param_type(_InputIteratorB __bbegin, _InputIteratorB __bend, _InputIteratorW __wbegin) : _M_int(), _M_den(), _M_cp() { if (__bbegin != __bend) { for (;;) { _M_int.push_back(*__bbegin); ++__bbegin; if (__bbegin == __bend) break; _M_den.push_back(*__wbegin); ++__wbegin; } } _M_initialize(); } template<typename _RealType> template<typename _Func> piecewise_constant_distribution<_RealType>::param_type:: param_type(initializer_list<_RealType> __bl, _Func __fw) : _M_int(), _M_den(), _M_cp() { _M_int.reserve(__bl.size()); for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter) _M_int.push_back(*__biter); _M_den.reserve(_M_int.size() - 1); for (size_t __k = 0; __k < _M_int.size() - 1; ++__k) _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k]))); _M_initialize(); } template<typename _RealType> template<typename _Func> piecewise_constant_distribution<_RealType>::param_type:: param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw) : _M_int(), _M_den(), _M_cp() { const size_t __n = __nw == 0 ? 1 : __nw; const _RealType __delta = (__xmax - __xmin) / __n; _M_int.reserve(__n + 1); for (size_t __k = 0; __k <= __nw; ++__k) _M_int.push_back(__xmin + __k * __delta); _M_den.reserve(__n); for (size_t __k = 0; __k < __nw; ++__k) _M_den.push_back(__fw(_M_int[__k] + 0.5 * __delta)); _M_initialize(); } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename piecewise_constant_distribution<_RealType>::result_type piecewise_constant_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); const double __p = __aurng(); if (__param._M_cp.empty()) return __p; auto __pos = std::lower_bound(__param._M_cp.begin(), __param._M_cp.end(), __p); const size_t __i = __pos - __param._M_cp.begin(); const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; return __param._M_int[__i] + (__p - __pref) / __param._M_den[__i]; } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void piecewise_constant_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); if (__param._M_cp.empty()) { while (__f != __t) *__f++ = __aurng(); return; } while (__f != __t) { const double __p = __aurng(); auto __pos = std::lower_bound(__param._M_cp.begin(), __param._M_cp.end(), __p); const size_t __i = __pos - __param._M_cp.begin(); const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; *__f++ = (__param._M_int[__i] + (__p - __pref) / __param._M_den[__i]); } } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const piecewise_constant_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); std::vector<_RealType> __int = __x.intervals(); __os << __int.size() - 1; for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit) __os << __space << *__xit; std::vector<double> __den = __x.densities(); for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit) __os << __space << *__dit; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, piecewise_constant_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); size_t __n; if (__is >> __n) { std::vector<_RealType> __int_vec; if (__detail::__extract_params(__is, __int_vec, __n + 1)) { std::vector<double> __den_vec; if (__detail::__extract_params(__is, __den_vec, __n)) { __x.param({ __int_vec.begin(), __int_vec.end(), __den_vec.begin() }); } } } __is.flags(__flags); return __is; } template<typename _RealType> void piecewise_linear_distribution<_RealType>::param_type:: _M_initialize() { if (_M_int.size() < 2 || (_M_int.size() == 2 && _M_int[0] == _RealType(0) && _M_int[1] == _RealType(1) && _M_den[0] == _M_den[1])) { _M_int.clear(); _M_den.clear(); return; } double __sum = 0.0; _M_cp.reserve(_M_int.size() - 1); _M_m.reserve(_M_int.size() - 1); for (size_t __k = 0; __k < _M_int.size() - 1; ++__k) { const _RealType __delta = _M_int[__k + 1] - _M_int[__k]; __sum += 0.5 * (_M_den[__k + 1] + _M_den[__k]) * __delta; _M_cp.push_back(__sum); _M_m.push_back((_M_den[__k + 1] - _M_den[__k]) / __delta); } // Now normalize the densities... __detail::__normalize(_M_den.begin(), _M_den.end(), _M_den.begin(), __sum); // ... and partial sums... __detail::__normalize(_M_cp.begin(), _M_cp.end(), _M_cp.begin(), __sum); // ... and slopes. __detail::__normalize(_M_m.begin(), _M_m.end(), _M_m.begin(), __sum); // Make sure the last cumulative probablility is one. _M_cp[_M_cp.size() - 1] = 1.0; } template<typename _RealType> template<typename _InputIteratorB, typename _InputIteratorW> piecewise_linear_distribution<_RealType>::param_type:: param_type(_InputIteratorB __bbegin, _InputIteratorB __bend, _InputIteratorW __wbegin) : _M_int(), _M_den(), _M_cp(), _M_m() { for (; __bbegin != __bend; ++__bbegin, ++__wbegin) { _M_int.push_back(*__bbegin); _M_den.push_back(*__wbegin); } _M_initialize(); } template<typename _RealType> template<typename _Func> piecewise_linear_distribution<_RealType>::param_type:: param_type(initializer_list<_RealType> __bl, _Func __fw) : _M_int(), _M_den(), _M_cp(), _M_m() { _M_int.reserve(__bl.size()); _M_den.reserve(__bl.size()); for (auto __biter = __bl.begin(); __biter != __bl.end(); ++__biter) { _M_int.push_back(*__biter); _M_den.push_back(__fw(*__biter)); } _M_initialize(); } template<typename _RealType> template<typename _Func> piecewise_linear_distribution<_RealType>::param_type:: param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw) : _M_int(), _M_den(), _M_cp(), _M_m() { const size_t __n = __nw == 0 ? 1 : __nw; const _RealType __delta = (__xmax - __xmin) / __n; _M_int.reserve(__n + 1); _M_den.reserve(__n + 1); for (size_t __k = 0; __k <= __nw; ++__k) { _M_int.push_back(__xmin + __k * __delta); _M_den.push_back(__fw(_M_int[__k] + __delta)); } _M_initialize(); } template<typename _RealType> template<typename _UniformRandomNumberGenerator> typename piecewise_linear_distribution<_RealType>::result_type piecewise_linear_distribution<_RealType>:: operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); const double __p = __aurng(); if (__param._M_cp.empty()) return __p; auto __pos = std::lower_bound(__param._M_cp.begin(), __param._M_cp.end(), __p); const size_t __i = __pos - __param._M_cp.begin(); const double __pref = __i > 0 ? __param._M_cp[__i - 1] : 0.0; const double __a = 0.5 * __param._M_m[__i]; const double __b = __param._M_den[__i]; const double __cm = __p - __pref; _RealType __x = __param._M_int[__i]; if (__a == 0) __x += __cm / __b; else { const double __d = __b * __b + 4.0 * __a * __cm; __x += 0.5 * (std::sqrt(__d) - __b) / __a; } return __x; } template<typename _RealType> template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void piecewise_linear_distribution<_RealType>:: __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) // We could duplicate everything from operator()... while (__f != __t) *__f++ = this->operator()(__urng, __param); } template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const piecewise_linear_distribution<_RealType>& __x) { typedef std::basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __os.flags(); const _CharT __fill = __os.fill(); const std::streamsize __precision = __os.precision(); const _CharT __space = __os.widen(' '); __os.flags(__ios_base::scientific | __ios_base::left); __os.fill(__space); __os.precision(std::numeric_limits<_RealType>::max_digits10); std::vector<_RealType> __int = __x.intervals(); __os << __int.size() - 1; for (auto __xit = __int.begin(); __xit != __int.end(); ++__xit) __os << __space << *__xit; std::vector<double> __den = __x.densities(); for (auto __dit = __den.begin(); __dit != __den.end(); ++__dit) __os << __space << *__dit; __os.flags(__flags); __os.fill(__fill); __os.precision(__precision); return __os; } template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, piecewise_linear_distribution<_RealType>& __x) { typedef std::basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::ios_base __ios_base; const typename __ios_base::fmtflags __flags = __is.flags(); __is.flags(__ios_base::dec | __ios_base::skipws); size_t __n; if (__is >> __n) { vector<_RealType> __int_vec; if (__detail::__extract_params(__is, __int_vec, __n + 1)) { vector<double> __den_vec; if (__detail::__extract_params(__is, __den_vec, __n + 1)) { __x.param({ __int_vec.begin(), __int_vec.end(), __den_vec.begin() }); } } } __is.flags(__flags); return __is; } template<typename _IntType> seed_seq::seed_seq(std::initializer_list<_IntType> __il) { for (auto __iter = __il.begin(); __iter != __il.end(); ++__iter) _M_v.push_back(__detail::__mod<result_type, __detail::_Shift<result_type, 32>::__value>(*__iter)); } template<typename _InputIterator> seed_seq::seed_seq(_InputIterator __begin, _InputIterator __end) { for (_InputIterator __iter = __begin; __iter != __end; ++__iter) _M_v.push_back(__detail::__mod<result_type, __detail::_Shift<result_type, 32>::__value>(*__iter)); } template<typename _RandomAccessIterator> void seed_seq::generate(_RandomAccessIterator __begin, _RandomAccessIterator __end) { typedef typename iterator_traits<_RandomAccessIterator>::value_type _Type; if (__begin == __end) return; std::fill(__begin, __end, _Type(0x8b8b8b8bu)); const size_t __n = __end - __begin; const size_t __s = _M_v.size(); const size_t __t = (__n >= 623) ? 11 : (__n >= 68) ? 7 : (__n >= 39) ? 5 : (__n >= 7) ? 3 : (__n - 1) / 2; const size_t __p = (__n - __t) / 2; const size_t __q = __p + __t; const size_t __m = std::max(size_t(__s + 1), __n); for (size_t __k = 0; __k < __m; ++__k) { _Type __arg = (__begin[__k % __n] ^ __begin[(__k + __p) % __n] ^ __begin[(__k - 1) % __n]); _Type __r1 = __arg ^ (__arg >> 27); __r1 = __detail::__mod<_Type, __detail::_Shift<_Type, 32>::__value>(1664525u * __r1); _Type __r2 = __r1; if (__k == 0) __r2 += __s; else if (__k <= __s) __r2 += __k % __n + _M_v[__k - 1]; else __r2 += __k % __n; __r2 = __detail::__mod<_Type, __detail::_Shift<_Type, 32>::__value>(__r2); __begin[(__k + __p) % __n] += __r1; __begin[(__k + __q) % __n] += __r2; __begin[__k % __n] = __r2; } for (size_t __k = __m; __k < __m + __n; ++__k) { _Type __arg = (__begin[__k % __n] + __begin[(__k + __p) % __n] + __begin[(__k - 1) % __n]); _Type __r3 = __arg ^ (__arg >> 27); __r3 = __detail::__mod<_Type, __detail::_Shift<_Type, 32>::__value>(1566083941u * __r3); _Type __r4 = __r3 - __k % __n; __r4 = __detail::__mod<_Type, __detail::_Shift<_Type, 32>::__value>(__r4); __begin[(__k + __p) % __n] ^= __r3; __begin[(__k + __q) % __n] ^= __r4; __begin[__k % __n] = __r4; } } template<typename _RealType, size_t __bits, typename _UniformRandomNumberGenerator> _RealType generate_canonical(_UniformRandomNumberGenerator& __urng) { static_assert(std::is_floating_point<_RealType>::value, "template argument must be a floating point type"); const size_t __b = std::min(static_cast<size_t>(std::numeric_limits<_RealType>::digits), __bits); const long double __r = static_cast<long double>(__urng.max()) - static_cast<long double>(__urng.min()) + 1.0L; const size_t __log2r = std::log(__r) / std::log(2.0L); const size_t __m = std::max<size_t>(1UL, (__b + __log2r - 1UL) / __log2r); _RealType __ret; _RealType __sum = _RealType(0); _RealType __tmp = _RealType(1); for (size_t __k = __m; __k != 0; --__k) { __sum += _RealType(__urng() - __urng.min()) * __tmp; __tmp *= __r; } __ret = __sum / __tmp; if (__builtin_expect(__ret >= _RealType(1), 0)) { #if _GLIBCXX_USE_C99_MATH_TR1 __ret = std::nextafter(_RealType(1), _RealType(0)); #else __ret = _RealType(1) - std::numeric_limits<_RealType>::epsilon() / _RealType(2); #endif } return __ret; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/bits/streambuf.tcc 0000644 00000011501 15146341150 0010705 0 ustar 00 // Stream buffer classes -*- C++ -*- // Copyright (C) 1997-2018 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/streambuf.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{streambuf} */ // // ISO C++ 14882: 27.5 Stream buffers // #ifndef _STREAMBUF_TCC #define _STREAMBUF_TCC 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits> streamsize basic_streambuf<_CharT, _Traits>:: xsgetn(char_type* __s, streamsize __n) { streamsize __ret = 0; while (__ret < __n) { const streamsize __buf_len = this->egptr() - this->gptr(); if (__buf_len) { const streamsize __remaining = __n - __ret; const streamsize __len = std::min(__buf_len, __remaining); traits_type::copy(__s, this->gptr(), __len); __ret += __len; __s += __len; this->__safe_gbump(__len); } if (__ret < __n) { const int_type __c = this->uflow(); if (!traits_type::eq_int_type(__c, traits_type::eof())) { traits_type::assign(*__s++, traits_type::to_char_type(__c)); ++__ret; } else break; } } return __ret; } template<typename _CharT, typename _Traits> streamsize basic_streambuf<_CharT, _Traits>:: xsputn(const char_type* __s, streamsize __n) { streamsize __ret = 0; while (__ret < __n) { const streamsize __buf_len = this->epptr() - this->pptr(); if (__buf_len) { const streamsize __remaining = __n - __ret; const streamsize __len = std::min(__buf_len, __remaining); traits_type::copy(this->pptr(), __s, __len); __ret += __len; __s += __len; this->__safe_pbump(__len); } if (__ret < __n) { int_type __c = this->overflow(traits_type::to_int_type(*__s)); if (!traits_type::eq_int_type(__c, traits_type::eof())) { ++__ret; ++__s; } else break; } } return __ret; } // Conceivably, this could be used to implement buffer-to-buffer // copies, if this was ever desired in an un-ambiguous way by the // standard. template<typename _CharT, typename _Traits> streamsize __copy_streambufs_eof(basic_streambuf<_CharT, _Traits>* __sbin, basic_streambuf<_CharT, _Traits>* __sbout, bool& __ineof) { streamsize __ret = 0; __ineof = true; typename _Traits::int_type __c = __sbin->sgetc(); while (!_Traits::eq_int_type(__c, _Traits::eof())) { __c = __sbout->sputc(_Traits::to_char_type(__c)); if (_Traits::eq_int_type(__c, _Traits::eof())) { __ineof = false; break; } ++__ret; __c = __sbin->snextc(); } return __ret; } template<typename _CharT, typename _Traits> inline streamsize __copy_streambufs(basic_streambuf<_CharT, _Traits>* __sbin, basic_streambuf<_CharT, _Traits>* __sbout) { bool __ineof; return __copy_streambufs_eof(__sbin, __sbout, __ineof); } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_streambuf<char>; extern template streamsize __copy_streambufs(basic_streambuf<char>*, basic_streambuf<char>*); extern template streamsize __copy_streambufs_eof(basic_streambuf<char>*, basic_streambuf<char>*, bool&); #ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_streambuf<wchar_t>; extern template streamsize __copy_streambufs(basic_streambuf<wchar_t>*, basic_streambuf<wchar_t>*); extern template streamsize __copy_streambufs_eof(basic_streambuf<wchar_t>*, basic_streambuf<wchar_t>*, bool&); #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/atomic_base.h 0000644 00000056442 15146341150 0010656 0 ustar 00 // -*- C++ -*- header. // Copyright (C) 2008-2018 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_base.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{atomic} */ #ifndef _GLIBCXX_ATOMIC_BASE_H #define _GLIBCXX_ATOMIC_BASE_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <stdint.h> #include <bits/atomic_lockfree_defines.h> #ifndef _GLIBCXX_ALWAYS_INLINE #define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup atomics Atomics * * Components for performing atomic operations. * @{ */ /// Enumeration for memory_order typedef enum memory_order { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst } memory_order; enum __memory_order_modifier { __memory_order_mask = 0x0ffff, __memory_order_modifier_mask = 0xffff0000, __memory_order_hle_acquire = 0x10000, __memory_order_hle_release = 0x20000 }; constexpr memory_order operator|(memory_order __m, __memory_order_modifier __mod) { return memory_order(__m | int(__mod)); } constexpr memory_order operator&(memory_order __m, __memory_order_modifier __mod) { return memory_order(__m & int(__mod)); } // Drop release ordering as per [atomics.types.operations.req]/21 constexpr memory_order __cmpexch_failure_order2(memory_order __m) noexcept { return __m == memory_order_acq_rel ? memory_order_acquire : __m == memory_order_release ? memory_order_relaxed : __m; } constexpr memory_order __cmpexch_failure_order(memory_order __m) noexcept { return memory_order(__cmpexch_failure_order2(__m & __memory_order_mask) | (__m & __memory_order_modifier_mask)); } _GLIBCXX_ALWAYS_INLINE void atomic_thread_fence(memory_order __m) noexcept { __atomic_thread_fence(__m); } _GLIBCXX_ALWAYS_INLINE void atomic_signal_fence(memory_order __m) noexcept { __atomic_signal_fence(__m); } /// kill_dependency template<typename _Tp> inline _Tp kill_dependency(_Tp __y) noexcept { _Tp __ret(__y); return __ret; } // Base types for atomics. template<typename _IntTp> struct __atomic_base; #define ATOMIC_VAR_INIT(_VI) { _VI } template<typename _Tp> struct atomic; template<typename _Tp> struct atomic<_Tp*>; /* The target's "set" value for test-and-set may not be exactly 1. */ #if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1 typedef bool __atomic_flag_data_type; #else typedef unsigned char __atomic_flag_data_type; #endif /** * @brief Base type for atomic_flag. * * Base type is POD with data, allowing atomic_flag to derive from * it and meet the standard layout type requirement. In addition to * compatibility with a C interface, this allows different * implementations of atomic_flag to use the same atomic operation * functions, via a standard conversion to the __atomic_flag_base * argument. */ _GLIBCXX_BEGIN_EXTERN_C struct __atomic_flag_base { __atomic_flag_data_type _M_i; }; _GLIBCXX_END_EXTERN_C #define ATOMIC_FLAG_INIT { 0 } /// atomic_flag struct atomic_flag : public __atomic_flag_base { atomic_flag() noexcept = default; ~atomic_flag() noexcept = default; atomic_flag(const atomic_flag&) = delete; atomic_flag& operator=(const atomic_flag&) = delete; atomic_flag& operator=(const atomic_flag&) volatile = delete; // Conversion to ATOMIC_FLAG_INIT. constexpr atomic_flag(bool __i) noexcept : __atomic_flag_base{ _S_init(__i) } { } _GLIBCXX_ALWAYS_INLINE bool test_and_set(memory_order __m = memory_order_seq_cst) noexcept { return __atomic_test_and_set (&_M_i, __m); } _GLIBCXX_ALWAYS_INLINE bool test_and_set(memory_order __m = memory_order_seq_cst) volatile noexcept { return __atomic_test_and_set (&_M_i, __m); } _GLIBCXX_ALWAYS_INLINE void clear(memory_order __m = memory_order_seq_cst) noexcept { memory_order __b = __m & __memory_order_mask; __glibcxx_assert(__b != memory_order_consume); __glibcxx_assert(__b != memory_order_acquire); __glibcxx_assert(__b != memory_order_acq_rel); __atomic_clear (&_M_i, __m); } _GLIBCXX_ALWAYS_INLINE void clear(memory_order __m = memory_order_seq_cst) volatile noexcept { memory_order __b = __m & __memory_order_mask; __glibcxx_assert(__b != memory_order_consume); __glibcxx_assert(__b != memory_order_acquire); __glibcxx_assert(__b != memory_order_acq_rel); __atomic_clear (&_M_i, __m); } private: static constexpr __atomic_flag_data_type _S_init(bool __i) { return __i ? __GCC_ATOMIC_TEST_AND_SET_TRUEVAL : 0; } }; /// Base class for atomic integrals. // // For each of the integral types, define atomic_[integral type] struct // // atomic_bool bool // atomic_char char // atomic_schar signed char // atomic_uchar unsigned char // atomic_short short // atomic_ushort unsigned short // atomic_int int // atomic_uint unsigned int // atomic_long long // atomic_ulong unsigned long // atomic_llong long long // atomic_ullong unsigned long long // atomic_char16_t char16_t // atomic_char32_t char32_t // atomic_wchar_t wchar_t // // NB: Assuming _ITp is an integral scalar type that is 1, 2, 4, or // 8 bytes, since that is what GCC built-in functions for atomic // memory access expect. template<typename _ITp> struct __atomic_base { private: typedef _ITp __int_type; static constexpr int _S_alignment = sizeof(_ITp) > alignof(_ITp) ? sizeof(_ITp) : alignof(_ITp); alignas(_S_alignment) __int_type _M_i; public: __atomic_base() noexcept = default; ~__atomic_base() noexcept = default; __atomic_base(const __atomic_base&) = delete; __atomic_base& operator=(const __atomic_base&) = delete; __atomic_base& operator=(const __atomic_base&) volatile = delete; // Requires __int_type convertible to _M_i. constexpr __atomic_base(__int_type __i) noexcept : _M_i (__i) { } operator __int_type() const noexcept { return load(); } operator __int_type() const volatile noexcept { return load(); } __int_type operator=(__int_type __i) noexcept { store(__i); return __i; } __int_type operator=(__int_type __i) volatile noexcept { store(__i); return __i; } __int_type operator++(int) noexcept { return fetch_add(1); } __int_type operator++(int) volatile noexcept { return fetch_add(1); } __int_type operator--(int) noexcept { return fetch_sub(1); } __int_type operator--(int) volatile noexcept { return fetch_sub(1); } __int_type operator++() noexcept { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); } __int_type operator++() volatile noexcept { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); } __int_type operator--() noexcept { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); } __int_type operator--() volatile noexcept { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); } __int_type operator+=(__int_type __i) noexcept { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); } __int_type operator+=(__int_type __i) volatile noexcept { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); } __int_type operator-=(__int_type __i) noexcept { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); } __int_type operator-=(__int_type __i) volatile noexcept { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); } __int_type operator&=(__int_type __i) noexcept { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); } __int_type operator&=(__int_type __i) volatile noexcept { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); } __int_type operator|=(__int_type __i) noexcept { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); } __int_type operator|=(__int_type __i) volatile noexcept { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); } __int_type operator^=(__int_type __i) noexcept { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); } __int_type operator^=(__int_type __i) volatile noexcept { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); } bool is_lock_free() const noexcept { // Use a fake, minimally aligned pointer. return __atomic_is_lock_free(sizeof(_M_i), reinterpret_cast<void *>(-__alignof(_M_i))); } bool is_lock_free() const volatile noexcept { // Use a fake, minimally aligned pointer. return __atomic_is_lock_free(sizeof(_M_i), reinterpret_cast<void *>(-__alignof(_M_i))); } _GLIBCXX_ALWAYS_INLINE void store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept { memory_order __b = __m & __memory_order_mask; __glibcxx_assert(__b != memory_order_acquire); __glibcxx_assert(__b != memory_order_acq_rel); __glibcxx_assert(__b != memory_order_consume); __atomic_store_n(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE void store(__int_type __i, memory_order __m = memory_order_seq_cst) volatile noexcept { memory_order __b = __m & __memory_order_mask; __glibcxx_assert(__b != memory_order_acquire); __glibcxx_assert(__b != memory_order_acq_rel); __glibcxx_assert(__b != memory_order_consume); __atomic_store_n(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type load(memory_order __m = memory_order_seq_cst) const noexcept { memory_order __b = __m & __memory_order_mask; __glibcxx_assert(__b != memory_order_release); __glibcxx_assert(__b != memory_order_acq_rel); return __atomic_load_n(&_M_i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type load(memory_order __m = memory_order_seq_cst) const volatile noexcept { memory_order __b = __m & __memory_order_mask; __glibcxx_assert(__b != memory_order_release); __glibcxx_assert(__b != memory_order_acq_rel); return __atomic_load_n(&_M_i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type exchange(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept { return __atomic_exchange_n(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type exchange(__int_type __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return __atomic_exchange_n(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE bool compare_exchange_weak(__int_type& __i1, __int_type __i2, memory_order __m1, memory_order __m2) noexcept { memory_order __b2 = __m2 & __memory_order_mask; memory_order __b1 = __m1 & __memory_order_mask; __glibcxx_assert(__b2 != memory_order_release); __glibcxx_assert(__b2 != memory_order_acq_rel); __glibcxx_assert(__b2 <= __b1); return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2); } _GLIBCXX_ALWAYS_INLINE bool compare_exchange_weak(__int_type& __i1, __int_type __i2, memory_order __m1, memory_order __m2) volatile noexcept { memory_order __b2 = __m2 & __memory_order_mask; memory_order __b1 = __m1 & __memory_order_mask; __glibcxx_assert(__b2 != memory_order_release); __glibcxx_assert(__b2 != memory_order_acq_rel); __glibcxx_assert(__b2 <= __b1); return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2); } _GLIBCXX_ALWAYS_INLINE bool compare_exchange_weak(__int_type& __i1, __int_type __i2, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_weak(__i1, __i2, __m, __cmpexch_failure_order(__m)); } _GLIBCXX_ALWAYS_INLINE bool compare_exchange_weak(__int_type& __i1, __int_type __i2, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_weak(__i1, __i2, __m, __cmpexch_failure_order(__m)); } _GLIBCXX_ALWAYS_INLINE bool compare_exchange_strong(__int_type& __i1, __int_type __i2, memory_order __m1, memory_order __m2) noexcept { memory_order __b2 = __m2 & __memory_order_mask; memory_order __b1 = __m1 & __memory_order_mask; __glibcxx_assert(__b2 != memory_order_release); __glibcxx_assert(__b2 != memory_order_acq_rel); __glibcxx_assert(__b2 <= __b1); return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2); } _GLIBCXX_ALWAYS_INLINE bool compare_exchange_strong(__int_type& __i1, __int_type __i2, memory_order __m1, memory_order __m2) volatile noexcept { memory_order __b2 = __m2 & __memory_order_mask; memory_order __b1 = __m1 & __memory_order_mask; __glibcxx_assert(__b2 != memory_order_release); __glibcxx_assert(__b2 != memory_order_acq_rel); __glibcxx_assert(__b2 <= __b1); return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2); } _GLIBCXX_ALWAYS_INLINE bool compare_exchange_strong(__int_type& __i1, __int_type __i2, memory_order __m = memory_order_seq_cst) noexcept { return compare_exchange_strong(__i1, __i2, __m, __cmpexch_failure_order(__m)); } _GLIBCXX_ALWAYS_INLINE bool compare_exchange_strong(__int_type& __i1, __int_type __i2, memory_order __m = memory_order_seq_cst) volatile noexcept { return compare_exchange_strong(__i1, __i2, __m, __cmpexch_failure_order(__m)); } _GLIBCXX_ALWAYS_INLINE __int_type fetch_add(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept { return __atomic_fetch_add(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type fetch_add(__int_type __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return __atomic_fetch_add(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type fetch_sub(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept { return __atomic_fetch_sub(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type fetch_sub(__int_type __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return __atomic_fetch_sub(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type fetch_and(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept { return __atomic_fetch_and(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type fetch_and(__int_type __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return __atomic_fetch_and(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type fetch_or(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept { return __atomic_fetch_or(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type fetch_or(__int_type __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return __atomic_fetch_or(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type fetch_xor(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept { return __atomic_fetch_xor(&_M_i, __i, __m); } _GLIBCXX_ALWAYS_INLINE __int_type fetch_xor(__int_type __i, memory_order __m = memory_order_seq_cst) volatile noexcept { return __atomic_fetch_xor(&_M_i, __i, __m); } }; /// Partial specialization for pointer types. template<typename _PTp> struct __atomic_base<_PTp*> { private: typedef _PTp* __pointer_type; __pointer_type _M_p; // Factored out to facilitate explicit specialization. constexpr ptrdiff_t _M_type_size(ptrdiff_t __d) const { return __d * sizeof(_PTp); } constexpr ptrdiff_t _M_type_size(ptrdiff_t __d) const volatile { return __d * sizeof(_PTp); } public: __atomic_base() noexcept = default; ~__atomic_base() noexcept = default; __atomic_base(const __atomic_base&) = delete; __atomic_base& operator=(const __atomic_base&) = delete; __atomic_base& operator=(const __atomic_base&) volatile = delete; // Requires __pointer_type convertible to _M_p. constexpr __atomic_base(__pointer_type __p) noexcept : _M_p (__p) { } operator __pointer_type() const noexcept { return load(); } operator __pointer_type() const volatile noexcept { return load(); } __pointer_type operator=(__pointer_type __p) noexcept { store(__p); return __p; } __pointer_type operator=(__pointer_type __p) volatile noexcept { store(__p); return __p; } __pointer_type operator++(int) noexcept { return fetch_add(1); } __pointer_type operator++(int) volatile noexcept { return fetch_add(1); } __pointer_type operator--(int) noexcept { return fetch_sub(1); } __pointer_type operator--(int) volatile noexcept { return fetch_sub(1); } __pointer_type operator++() noexcept { return __atomic_add_fetch(&_M_p, _M_type_size(1), memory_order_seq_cst); } __pointer_type operator++() volatile noexcept { return __atomic_add_fetch(&_M_p, _M_type_size(1), memory_order_seq_cst); } __pointer_type operator--() noexcept { return __atomic_sub_fetch(&_M_p, _M_type_size(1), memory_order_seq_cst); } __pointer_type operator--() volatile noexcept { return __atomic_sub_fetch(&_M_p, _M_type_size(1), memory_order_seq_cst); } __pointer_type operator+=(ptrdiff_t __d) noexcept { return __atomic_add_fetch(&_M_p, _M_type_size(__d), memory_order_seq_cst); } __pointer_type operator+=(ptrdiff_t __d) volatile noexcept { return __atomic_add_fetch(&_M_p, _M_type_size(__d), memory_order_seq_cst); } __pointer_type operator-=(ptrdiff_t __d) noexcept { return __atomic_sub_fetch(&_M_p, _M_type_size(__d), memory_order_seq_cst); } __pointer_type operator-=(ptrdiff_t __d) volatile noexcept { return __atomic_sub_fetch(&_M_p, _M_type_size(__d), memory_order_seq_cst); } bool is_lock_free() const noexcept { // Produce a fake, minimally aligned pointer. return __atomic_is_lock_free(sizeof(_M_p), reinterpret_cast<void *>(-__alignof(_M_p))); } bool is_lock_free() const volatile noexcept { // Produce a fake, minimally aligned pointer. return __atomic_is_lock_free(sizeof(_M_p), reinterpret_cast<void *>(-__alignof(_M_p))); } _GLIBCXX_ALWAYS_INLINE void store(__pointer_type __p, memory_order __m = memory_order_seq_cst) noexcept { memory_order __b = __m & __memory_order_mask; __glibcxx_assert(__b != memory_order_acquire); __glibcxx_assert(__b != memory_order_acq_rel); __glibcxx_assert(__b != memory_order_consume); __atomic_store_n(&_M_p, __p, __m); } _GLIBCXX_ALWAYS_INLINE void store(__pointer_type __p, memory_order __m = memory_order_seq_cst) volatile noexcept { memory_order __b = __m & __memory_order_mask; __glibcxx_assert(__b != memory_order_acquire); __glibcxx_assert(__b != memory_order_acq_rel); __glibcxx_assert(__b != memory_order_consume); __atomic_store_n(&_M_p, __p, __m); } _GLIBCXX_ALWAYS_INLINE __pointer_type load(memory_order __m = memory_order_seq_cst) const noexcept { memory_order __b = __m & __memory_order_mask; __glibcxx_assert(__b != memory_order_release); __glibcxx_assert(__b != memory_order_acq_rel); return __atomic_load_n(&_M_p, __m); } _GLIBCXX_ALWAYS_INLINE __pointer_type load(memory_order __m = memory_order_seq_cst) const volatile noexcept { memory_order __b = __m & __memory_order_mask; __glibcxx_assert(__b != memory_order_release); __glibcxx_assert(__b != memory_order_acq_rel); return __atomic_load_n(&_M_p, __m); } _GLIBCXX_ALWAYS_INLINE __pointer_type exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst) noexcept { return __atomic_exchange_n(&_M_p, __p, __m); } _GLIBCXX_ALWAYS_INLINE __pointer_type exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst) volatile noexcept { return __atomic_exchange_n(&_M_p, __p, __m); } _GLIBCXX_ALWAYS_INLINE bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) noexcept { memory_order __b2 = __m2 & __memory_order_mask; memory_order __b1 = __m1 & __memory_order_mask; __glibcxx_assert(__b2 != memory_order_release); __glibcxx_assert(__b2 != memory_order_acq_rel); __glibcxx_assert(__b2 <= __b1); return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2); } _GLIBCXX_ALWAYS_INLINE bool compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, memory_order __m1, memory_order __m2) volatile noexcept { memory_order __b2 = __m2 & __memory_order_mask; memory_order __b1 = __m1 & __memory_order_mask; __glibcxx_assert(__b2 != memory_order_release); __glibcxx_assert(__b2 != memory_order_acq_rel); __glibcxx_assert(__b2 <= __b1); return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2); } _GLIBCXX_ALWAYS_INLINE __pointer_type fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) noexcept { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); } _GLIBCXX_ALWAYS_INLINE __pointer_type fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) volatile noexcept { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); } _GLIBCXX_ALWAYS_INLINE __pointer_type fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) noexcept { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); } _GLIBCXX_ALWAYS_INLINE __pointer_type fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) volatile noexcept { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); } }; // @} group atomics _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/locale_classes.h 0000644 00000060501 15146341150 0011353 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 1997-2018 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/locale_classes.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.1 Locales // #ifndef _LOCALE_CLASSES_H #define _LOCALE_CLASSES_H 1 #pragma GCC system_header #include <bits/localefwd.h> #include <string> #include <ext/atomicity.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // 22.1.1 Class locale /** * @brief Container class for localization functionality. * @ingroup locales * * The locale class is first a class wrapper for C library locales. It is * also an extensible container for user-defined localization. A locale is * a collection of facets that implement various localization features such * as money, time, and number printing. * * Constructing C++ locales does not change the C library locale. * * This library supports efficient construction and copying of locales * through a reference counting implementation of the locale class. */ class locale { public: // Types: /// Definition of locale::category. typedef int category; // Forward decls and friends: class facet; class id; class _Impl; friend class facet; friend class _Impl; template<typename _Facet> friend bool has_facet(const locale&) throw(); template<typename _Facet> friend const _Facet& use_facet(const locale&); template<typename _Cache> friend struct __use_cache; //@{ /** * @brief Category values. * * The standard category values are none, ctype, numeric, collate, time, * monetary, and messages. They form a bitmask that supports union and * intersection. The category all is the union of these values. * * NB: Order must match _S_facet_categories definition in locale.cc */ static const category none = 0; static const category ctype = 1L << 0; static const category numeric = 1L << 1; static const category collate = 1L << 2; static const category time = 1L << 3; static const category monetary = 1L << 4; static const category messages = 1L << 5; static const category all = (ctype | numeric | collate | time | monetary | messages); //@} // Construct/copy/destroy: /** * @brief Default constructor. * * Constructs a copy of the global locale. If no locale has been * explicitly set, this is the C locale. */ locale() throw(); /** * @brief Copy constructor. * * Constructs a copy of @a other. * * @param __other The locale to copy. */ locale(const locale& __other) throw(); /** * @brief Named locale constructor. * * Constructs a copy of the named C library locale. * * @param __s Name of the locale to construct. * @throw std::runtime_error if __s is null or an undefined locale. */ explicit locale(const char* __s); /** * @brief Construct locale with facets from another locale. * * Constructs a copy of the locale @a base. The facets specified by @a * cat are replaced with those from the locale named by @a s. If base is * named, this locale instance will also be named. * * @param __base The locale to copy. * @param __s Name of the locale to use facets from. * @param __cat Set of categories defining the facets to use from __s. * @throw std::runtime_error if __s is null or an undefined locale. */ locale(const locale& __base, const char* __s, category __cat); #if __cplusplus >= 201103L /** * @brief Named locale constructor. * * Constructs a copy of the named C library locale. * * @param __s Name of the locale to construct. * @throw std::runtime_error if __s is an undefined locale. */ explicit locale(const std::string& __s) : locale(__s.c_str()) { } /** * @brief Construct locale with facets from another locale. * * Constructs a copy of the locale @a base. The facets specified by @a * cat are replaced with those from the locale named by @a s. If base is * named, this locale instance will also be named. * * @param __base The locale to copy. * @param __s Name of the locale to use facets from. * @param __cat Set of categories defining the facets to use from __s. * @throw std::runtime_error if __s is an undefined locale. */ locale(const locale& __base, const std::string& __s, category __cat) : locale(__base, __s.c_str(), __cat) { } #endif /** * @brief Construct locale with facets from another locale. * * Constructs a copy of the locale @a base. The facets specified by @a * cat are replaced with those from the locale @a add. If @a base and @a * add are named, this locale instance will also be named. * * @param __base The locale to copy. * @param __add The locale to use facets from. * @param __cat Set of categories defining the facets to use from add. */ locale(const locale& __base, const locale& __add, category __cat); /** * @brief Construct locale with another facet. * * Constructs a copy of the locale @a __other. The facet @a __f * is added to @a __other, replacing an existing facet of type * Facet if there is one. If @a __f is null, this locale is a * copy of @a __other. * * @param __other The locale to copy. * @param __f The facet to add in. */ template<typename _Facet> locale(const locale& __other, _Facet* __f); /// Locale destructor. ~locale() throw(); /** * @brief Assignment operator. * * Set this locale to be a copy of @a other. * * @param __other The locale to copy. * @return A reference to this locale. */ const locale& operator=(const locale& __other) throw(); /** * @brief Construct locale with another facet. * * Constructs and returns a new copy of this locale. Adds or replaces an * existing facet of type Facet from the locale @a other into the new * locale. * * @tparam _Facet The facet type to copy from other * @param __other The locale to copy from. * @return Newly constructed locale. * @throw std::runtime_error if __other has no facet of type _Facet. */ template<typename _Facet> locale combine(const locale& __other) const; // Locale operations: /** * @brief Return locale name. * @return Locale name or "*" if unnamed. */ _GLIBCXX_DEFAULT_ABI_TAG string name() const; /** * @brief Locale equality. * * @param __other The locale to compare against. * @return True if other and this refer to the same locale instance, are * copies, or have the same name. False otherwise. */ bool operator==(const locale& __other) const throw(); /** * @brief Locale inequality. * * @param __other The locale to compare against. * @return ! (*this == __other) */ bool operator!=(const locale& __other) const throw() { return !(this->operator==(__other)); } /** * @brief Compare two strings according to collate. * * Template operator to compare two strings using the compare function of * the collate facet in this locale. One use is to provide the locale to * the sort function. For example, a vector v of strings could be sorted * according to locale loc by doing: * @code * std::sort(v.begin(), v.end(), loc); * @endcode * * @param __s1 First string to compare. * @param __s2 Second string to compare. * @return True if collate<_Char> facet compares __s1 < __s2, else false. */ template<typename _Char, typename _Traits, typename _Alloc> bool operator()(const basic_string<_Char, _Traits, _Alloc>& __s1, const basic_string<_Char, _Traits, _Alloc>& __s2) const; // Global locale objects: /** * @brief Set global locale * * This function sets the global locale to the argument and returns a * copy of the previous global locale. If the argument has a name, it * will also call std::setlocale(LC_ALL, loc.name()). * * @param __loc The new locale to make global. * @return Copy of the old global locale. */ static locale global(const locale& __loc); /** * @brief Return reference to the C locale. */ static const locale& classic(); private: // The (shared) implementation _Impl* _M_impl; // The "C" reference locale static _Impl* _S_classic; // Current global locale static _Impl* _S_global; // Names of underlying locale categories. // NB: locale::global() has to know how to modify all the // underlying categories, not just the ones required by the C++ // standard. static const char* const* const _S_categories; // Number of standard categories. For C++, these categories are // collate, ctype, monetary, numeric, time, and messages. These // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE, // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE // 1003.1-2001) specifies LC_MESSAGES. // In addition to the standard categories, the underlying // operating system is allowed to define extra LC_* // macros. For GNU systems, the following are also valid: // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT, // and LC_IDENTIFICATION. enum { _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES }; #ifdef __GTHREADS static __gthread_once_t _S_once; #endif explicit locale(_Impl*) throw(); static void _S_initialize(); static void _S_initialize_once() throw(); static category _S_normalize_category(category); void _M_coalesce(const locale& __base, const locale& __add, category __cat); #if _GLIBCXX_USE_CXX11_ABI static const id* const _S_twinned_facets[]; #endif }; // 22.1.1.1.2 Class locale::facet /** * @brief Localization functionality base class. * @ingroup locales * * The facet class is the base class for a localization feature, such as * money, time, and number printing. It provides common support for facets * and reference management. * * Facets may not be copied or assigned. */ class locale::facet { private: friend class locale; friend class locale::_Impl; mutable _Atomic_word _M_refcount; // Contains data from the underlying "C" library for the classic locale. static __c_locale _S_c_locale; // String literal for the name of the classic locale. static const char _S_c_name[2]; #ifdef __GTHREADS static __gthread_once_t _S_once; #endif static void _S_initialize_once(); protected: /** * @brief Facet constructor. * * This is the constructor provided by the standard. If refs is 0, the * facet is destroyed when the last referencing locale is destroyed. * Otherwise the facet will never be destroyed. * * @param __refs The initial value for reference count. */ explicit facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0) { } /// Facet destructor. virtual ~facet(); static void _S_create_c_locale(__c_locale& __cloc, const char* __s, __c_locale __old = 0); static __c_locale _S_clone_c_locale(__c_locale& __cloc) throw(); static void _S_destroy_c_locale(__c_locale& __cloc); static __c_locale _S_lc_ctype_c_locale(__c_locale __cloc, const char* __s); // Returns data from the underlying "C" library data for the // classic locale. static __c_locale _S_get_c_locale(); _GLIBCXX_CONST static const char* _S_get_c_name() throw(); #if __cplusplus < 201103L private: facet(const facet&); // Not defined. facet& operator=(const facet&); // Not defined. #else facet(const facet&) = delete; facet& operator=(const facet&) = delete; #endif private: void _M_add_reference() const throw() { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); } void _M_remove_reference() const throw() { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount); if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount); __try { delete this; } __catch(...) { } } } const facet* _M_sso_shim(const id*) const; const facet* _M_cow_shim(const id*) const; protected: class __shim; // For internal use only. }; // 22.1.1.1.3 Class locale::id /** * @brief Facet ID class. * @ingroup locales * * The ID class provides facets with an index used to identify them. * Every facet class must define a public static member locale::id, or be * derived from a facet that provides this member, otherwise the facet * cannot be used in a locale. The locale::id ensures that each class * type gets a unique identifier. */ class locale::id { private: friend class locale; friend class locale::_Impl; template<typename _Facet> friend const _Facet& use_facet(const locale&); template<typename _Facet> friend bool has_facet(const locale&) throw(); // NB: There is no accessor for _M_index because it may be used // before the constructor is run; the effect of calling a member // function (even an inline) would be undefined. mutable size_t _M_index; // Last id number assigned. static _Atomic_word _S_refcount; void operator=(const id&); // Not defined. id(const id&); // Not defined. public: // NB: This class is always a static data member, and thus can be // counted on to be zero-initialized. /// Constructor. id() { } size_t _M_id() const throw(); }; // Implementation object for locale. class locale::_Impl { public: // Friends. friend class locale; friend class locale::facet; template<typename _Facet> friend bool has_facet(const locale&) throw(); template<typename _Facet> friend const _Facet& use_facet(const locale&); template<typename _Cache> friend struct __use_cache; private: // Data Members. _Atomic_word _M_refcount; const facet** _M_facets; size_t _M_facets_size; const facet** _M_caches; char** _M_names; static const locale::id* const _S_id_ctype[]; static const locale::id* const _S_id_numeric[]; static const locale::id* const _S_id_collate[]; static const locale::id* const _S_id_time[]; static const locale::id* const _S_id_monetary[]; static const locale::id* const _S_id_messages[]; static const locale::id* const* const _S_facet_categories[]; void _M_add_reference() throw() { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); } void _M_remove_reference() throw() { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount); if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount); __try { delete this; } __catch(...) { } } } _Impl(const _Impl&, size_t); _Impl(const char*, size_t); _Impl(size_t) throw(); ~_Impl() throw(); _Impl(const _Impl&); // Not defined. void operator=(const _Impl&); // Not defined. bool _M_check_same_name() { bool __ret = true; if (_M_names[1]) // We must actually compare all the _M_names: can be all equal! for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i) __ret = __builtin_strcmp(_M_names[__i], _M_names[__i + 1]) == 0; return __ret; } void _M_replace_categories(const _Impl*, category); void _M_replace_category(const _Impl*, const locale::id* const*); void _M_replace_facet(const _Impl*, const locale::id*); void _M_install_facet(const locale::id*, const facet*); template<typename _Facet> void _M_init_facet(_Facet* __facet) { _M_install_facet(&_Facet::id, __facet); } template<typename _Facet> void _M_init_facet_unchecked(_Facet* __facet) { __facet->_M_add_reference(); _M_facets[_Facet::id._M_id()] = __facet; } void _M_install_cache(const facet*, size_t); void _M_init_extra(facet**); void _M_init_extra(void*, void*, const char*, const char*); }; /** * @brief Facet for localized string comparison. * * This facet encapsulates the code to compare strings in a localized * manner. * * The collate template uses protected virtual functions to provide * the actual results. The public accessors forward the call to * the virtual functions. These virtual functions are hooks for * developers to implement the behavior they require from the * collate facet. */ template<typename _CharT> class _GLIBCXX_NAMESPACE_CXX11 collate : public locale::facet { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef basic_string<_CharT> string_type; //@} protected: // Underlying "C" library locale information saved from // initialization, needed by collate_byname as well. __c_locale _M_c_locale_collate; public: /// Numpunct facet id. static locale::id id; /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __refs Passed to the base facet class. */ explicit collate(size_t __refs = 0) : facet(__refs), _M_c_locale_collate(_S_get_c_locale()) { } /** * @brief Internal constructor. Not for general use. * * This is a constructor for use by the library itself to set up new * locales. * * @param __cloc The C locale. * @param __refs Passed to the base facet class. */ explicit collate(__c_locale __cloc, size_t __refs = 0) : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc)) { } /** * @brief Compare two strings. * * This function compares two strings and returns the result by calling * collate::do_compare(). * * @param __lo1 Start of string 1. * @param __hi1 End of string 1. * @param __lo2 Start of string 2. * @param __hi2 End of string 2. * @return 1 if string1 > string2, -1 if string1 < string2, else 0. */ int compare(const _CharT* __lo1, const _CharT* __hi1, const _CharT* __lo2, const _CharT* __hi2) const { return this->do_compare(__lo1, __hi1, __lo2, __hi2); } /** * @brief Transform string to comparable form. * * This function is a wrapper for strxfrm functionality. It takes the * input string and returns a modified string that can be directly * compared to other transformed strings. In the C locale, this * function just returns a copy of the input string. In some other * locales, it may replace two chars with one, change a char for * another, etc. It does so by returning collate::do_transform(). * * @param __lo Start of string. * @param __hi End of string. * @return Transformed string_type. */ string_type transform(const _CharT* __lo, const _CharT* __hi) const { return this->do_transform(__lo, __hi); } /** * @brief Return hash of a string. * * This function computes and returns a hash on the input string. It * does so by returning collate::do_hash(). * * @param __lo Start of string. * @param __hi End of string. * @return Hash value. */ long hash(const _CharT* __lo, const _CharT* __hi) const { return this->do_hash(__lo, __hi); } // Used to abstract out _CharT bits in virtual member functions, below. int _M_compare(const _CharT*, const _CharT*) const throw(); size_t _M_transform(_CharT*, const _CharT*, size_t) const throw(); protected: /// Destructor. virtual ~collate() { _S_destroy_c_locale(_M_c_locale_collate); } /** * @brief Compare two strings. * * This function is a hook for derived classes to change the value * returned. @see compare(). * * @param __lo1 Start of string 1. * @param __hi1 End of string 1. * @param __lo2 Start of string 2. * @param __hi2 End of string 2. * @return 1 if string1 > string2, -1 if string1 < string2, else 0. */ virtual int do_compare(const _CharT* __lo1, const _CharT* __hi1, const _CharT* __lo2, const _CharT* __hi2) const; /** * @brief Transform string to comparable form. * * This function is a hook for derived classes to change the value * returned. * * @param __lo Start. * @param __hi End. * @return transformed string. */ virtual string_type do_transform(const _CharT* __lo, const _CharT* __hi) const; /** * @brief Return hash of a string. * * This function computes and returns a hash on the input string. This * function is a hook for derived classes to change the value returned. * * @param __lo Start of string. * @param __hi End of string. * @return Hash value. */ virtual long do_hash(const _CharT* __lo, const _CharT* __hi) const; }; template<typename _CharT> locale::id collate<_CharT>::id; // Specializations. template<> int collate<char>::_M_compare(const char*, const char*) const throw(); template<> size_t collate<char>::_M_transform(char*, const char*, size_t) const throw(); #ifdef _GLIBCXX_USE_WCHAR_T template<> int collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const throw(); template<> size_t collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const throw(); #endif /// class collate_byname [22.2.4.2]. template<typename _CharT> class _GLIBCXX_NAMESPACE_CXX11 collate_byname : public collate<_CharT> { public: //@{ /// Public typedefs typedef _CharT char_type; typedef basic_string<_CharT> string_type; //@} explicit collate_byname(const char* __s, size_t __refs = 0) : collate<_CharT>(__refs) { if (__builtin_strcmp(__s, "C") != 0 && __builtin_strcmp(__s, "POSIX") != 0) { this->_S_destroy_c_locale(this->_M_c_locale_collate); this->_S_create_c_locale(this->_M_c_locale_collate, __s); } } #if __cplusplus >= 201103L explicit collate_byname(const string& __s, size_t __refs = 0) : collate_byname(__s.c_str(), __refs) { } #endif protected: virtual ~collate_byname() { } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace # include <bits/locale_classes.tcc> #endif c++/8/bits/stl_deque.h 0000644 00000231357 15146341150 0010375 0 ustar 00 // Deque implementation -*- C++ -*- // Copyright (C) 2001-2018 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) 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/stl_deque.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{deque} */ #ifndef _STL_DEQUE_H #define _STL_DEQUE_H 1 #include <bits/concept_check.h> #include <bits/stl_iterator_base_types.h> #include <bits/stl_iterator_base_funcs.h> #if __cplusplus >= 201103L #include <initializer_list> #endif #include <debug/assertions.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** * @brief This function controls the size of memory nodes. * @param __size The size of an element. * @return The number (not byte size) of elements per node. * * This function started off as a compiler kludge from SGI, but * seems to be a useful wrapper around a repeated constant * expression. The @b 512 is tunable (and no other code needs to * change), but no investigation has been done since inheriting the * SGI code. Touch _GLIBCXX_DEQUE_BUF_SIZE only if you know what * you are doing, however: changing it breaks the binary * compatibility!! */ #ifndef _GLIBCXX_DEQUE_BUF_SIZE #define _GLIBCXX_DEQUE_BUF_SIZE 512 #endif _GLIBCXX_CONSTEXPR inline size_t __deque_buf_size(size_t __size) { return (__size < _GLIBCXX_DEQUE_BUF_SIZE ? size_t(_GLIBCXX_DEQUE_BUF_SIZE / __size) : size_t(1)); } /** * @brief A deque::iterator. * * Quite a bit of intelligence here. Much of the functionality of * deque is actually passed off to this class. A deque holds two * of these internally, marking its valid range. Access to * elements is done as offsets of either of those two, relying on * operator overloading in this class. * * All the functions are op overloads except for _M_set_node. */ template<typename _Tp, typename _Ref, typename _Ptr> struct _Deque_iterator { #if __cplusplus < 201103L typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; typedef _Tp* _Elt_pointer; typedef _Tp** _Map_pointer; #else private: template<typename _Up> using __ptr_to = typename pointer_traits<_Ptr>::template rebind<_Up>; template<typename _CvTp> using __iter = _Deque_iterator<_Tp, _CvTp&, __ptr_to<_CvTp>>; public: typedef __iter<_Tp> iterator; typedef __iter<const _Tp> const_iterator; typedef __ptr_to<_Tp> _Elt_pointer; typedef __ptr_to<_Elt_pointer> _Map_pointer; #endif static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT { return __deque_buf_size(sizeof(_Tp)); } typedef std::random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef _Ptr pointer; typedef _Ref reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Deque_iterator _Self; _Elt_pointer _M_cur; _Elt_pointer _M_first; _Elt_pointer _M_last; _Map_pointer _M_node; _Deque_iterator(_Elt_pointer __x, _Map_pointer __y) _GLIBCXX_NOEXCEPT : _M_cur(__x), _M_first(*__y), _M_last(*__y + _S_buffer_size()), _M_node(__y) { } _Deque_iterator() _GLIBCXX_NOEXCEPT : _M_cur(), _M_first(), _M_last(), _M_node() { } _Deque_iterator(const iterator& __x) _GLIBCXX_NOEXCEPT : _M_cur(__x._M_cur), _M_first(__x._M_first), _M_last(__x._M_last), _M_node(__x._M_node) { } iterator _M_const_cast() const _GLIBCXX_NOEXCEPT { return iterator(_M_cur, _M_node); } reference operator*() const _GLIBCXX_NOEXCEPT { return *_M_cur; } pointer operator->() const _GLIBCXX_NOEXCEPT { return _M_cur; } _Self& operator++() _GLIBCXX_NOEXCEPT { ++_M_cur; if (_M_cur == _M_last) { _M_set_node(_M_node + 1); _M_cur = _M_first; } return *this; } _Self operator++(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; ++*this; return __tmp; } _Self& operator--() _GLIBCXX_NOEXCEPT { if (_M_cur == _M_first) { _M_set_node(_M_node - 1); _M_cur = _M_last; } --_M_cur; return *this; } _Self operator--(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; --*this; return __tmp; } _Self& operator+=(difference_type __n) _GLIBCXX_NOEXCEPT { const difference_type __offset = __n + (_M_cur - _M_first); if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) _M_cur += __n; else { const difference_type __node_offset = __offset > 0 ? __offset / difference_type(_S_buffer_size()) : -difference_type((-__offset - 1) / _S_buffer_size()) - 1; _M_set_node(_M_node + __node_offset); _M_cur = _M_first + (__offset - __node_offset * difference_type(_S_buffer_size())); } return *this; } _Self operator+(difference_type __n) const _GLIBCXX_NOEXCEPT { _Self __tmp = *this; return __tmp += __n; } _Self& operator-=(difference_type __n) _GLIBCXX_NOEXCEPT { return *this += -__n; } _Self operator-(difference_type __n) const _GLIBCXX_NOEXCEPT { _Self __tmp = *this; return __tmp -= __n; } reference operator[](difference_type __n) const _GLIBCXX_NOEXCEPT { return *(*this + __n); } /** * Prepares to traverse new_node. Sets everything except * _M_cur, which should therefore be set by the caller * immediately afterwards, based on _M_first and _M_last. */ void _M_set_node(_Map_pointer __new_node) _GLIBCXX_NOEXCEPT { _M_node = __new_node; _M_first = *__new_node; _M_last = _M_first + difference_type(_S_buffer_size()); } }; // Note: we also provide overloads whose operands are of the same type in // order to avoid ambiguous overload resolution when std::rel_ops operators // are in scope (for additional details, see libstdc++/3628) template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return __x._M_cur == __y._M_cur; } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return __x._M_cur == __y._M_cur; } template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return !(__x == __y); } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return !(__x == __y); } template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node); } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node); } template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return __y < __x; } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return __y < __x; } template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return !(__y < __x); } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return !(__y < __x); } template<typename _Tp, typename _Ref, typename _Ptr> inline bool operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return !(__x < __y); } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline bool operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return !(__x < __y); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // According to the resolution of DR179 not only the various comparison // operators but also operator- must accept mixed iterator/const_iterator // parameters. template<typename _Tp, typename _Ref, typename _Ptr> inline typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type operator-(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT { return typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type (_Deque_iterator<_Tp, _Ref, _Ptr>::_S_buffer_size()) * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + (__y._M_last - __y._M_cur); } template<typename _Tp, typename _RefL, typename _PtrL, typename _RefR, typename _PtrR> inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT { return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + (__y._M_last - __y._M_cur); } template<typename _Tp, typename _Ref, typename _Ptr> inline _Deque_iterator<_Tp, _Ref, _Ptr> operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) _GLIBCXX_NOEXCEPT { return __x + __n; } template<typename _Tp> void fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>&, const _Deque_iterator<_Tp, _Tp&, _Tp*>&, const _Tp&); template<typename _Tp> _Deque_iterator<_Tp, _Tp&, _Tp*> copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, _Deque_iterator<_Tp, const _Tp&, const _Tp*>, _Deque_iterator<_Tp, _Tp&, _Tp*>); template<typename _Tp> inline _Deque_iterator<_Tp, _Tp&, _Tp*> copy(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, _Deque_iterator<_Tp, _Tp&, _Tp*> __last, _Deque_iterator<_Tp, _Tp&, _Tp*> __result) { return std::copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first), _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last), __result); } template<typename _Tp> _Deque_iterator<_Tp, _Tp&, _Tp*> copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, _Deque_iterator<_Tp, const _Tp&, const _Tp*>, _Deque_iterator<_Tp, _Tp&, _Tp*>); template<typename _Tp> inline _Deque_iterator<_Tp, _Tp&, _Tp*> copy_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, _Deque_iterator<_Tp, _Tp&, _Tp*> __last, _Deque_iterator<_Tp, _Tp&, _Tp*> __result) { return std::copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first), _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last), __result); } #if __cplusplus >= 201103L template<typename _Tp> _Deque_iterator<_Tp, _Tp&, _Tp*> move(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, _Deque_iterator<_Tp, const _Tp&, const _Tp*>, _Deque_iterator<_Tp, _Tp&, _Tp*>); template<typename _Tp> inline _Deque_iterator<_Tp, _Tp&, _Tp*> move(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, _Deque_iterator<_Tp, _Tp&, _Tp*> __last, _Deque_iterator<_Tp, _Tp&, _Tp*> __result) { return std::move(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first), _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last), __result); } template<typename _Tp> _Deque_iterator<_Tp, _Tp&, _Tp*> move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, _Deque_iterator<_Tp, const _Tp&, const _Tp*>, _Deque_iterator<_Tp, _Tp&, _Tp*>); template<typename _Tp> inline _Deque_iterator<_Tp, _Tp&, _Tp*> move_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, _Deque_iterator<_Tp, _Tp&, _Tp*> __last, _Deque_iterator<_Tp, _Tp&, _Tp*> __result) { return std::move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first), _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last), __result); } #endif /** * Deque base class. This class provides the unified face for %deque's * allocation. This class's constructor and destructor allocate and * deallocate (but do not initialize) storage. This makes %exception * safety easier. * * Nothing in this class ever constructs or destroys an actual Tp element. * (Deque handles that itself.) Only/All memory management is performed * here. */ template<typename _Tp, typename _Alloc> class _Deque_base { protected: typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type; typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits; #if __cplusplus < 201103L typedef _Tp* _Ptr; typedef const _Tp* _Ptr_const; #else typedef typename _Alloc_traits::pointer _Ptr; typedef typename _Alloc_traits::const_pointer _Ptr_const; #endif typedef typename _Alloc_traits::template rebind<_Ptr>::other _Map_alloc_type; typedef __gnu_cxx::__alloc_traits<_Map_alloc_type> _Map_alloc_traits; public: typedef _Alloc allocator_type; typedef typename _Alloc_traits::size_type size_type; allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_get_Tp_allocator()); } typedef _Deque_iterator<_Tp, _Tp&, _Ptr> iterator; typedef _Deque_iterator<_Tp, const _Tp&, _Ptr_const> const_iterator; _Deque_base() : _M_impl() { _M_initialize_map(0); } _Deque_base(size_t __num_elements) : _M_impl() { _M_initialize_map(__num_elements); } _Deque_base(const allocator_type& __a, size_t __num_elements) : _M_impl(__a) { _M_initialize_map(__num_elements); } _Deque_base(const allocator_type& __a) : _M_impl(__a) { /* Caller must initialize map. */ } #if __cplusplus >= 201103L _Deque_base(_Deque_base&& __x, false_type) : _M_impl(__x._M_move_impl()) { } _Deque_base(_Deque_base&& __x, true_type) : _M_impl(std::move(__x._M_get_Tp_allocator())) { _M_initialize_map(0); if (__x._M_impl._M_map) this->_M_impl._M_swap_data(__x._M_impl); } _Deque_base(_Deque_base&& __x) : _Deque_base(std::move(__x), typename _Alloc_traits::is_always_equal{}) { } _Deque_base(_Deque_base&& __x, const allocator_type& __a, size_type __n) : _M_impl(__a) { if (__x.get_allocator() == __a) { if (__x._M_impl._M_map) { _M_initialize_map(0); this->_M_impl._M_swap_data(__x._M_impl); } } else { _M_initialize_map(__n); } } #endif ~_Deque_base() _GLIBCXX_NOEXCEPT; protected: typedef typename iterator::_Map_pointer _Map_pointer; //This struct encapsulates the implementation of the std::deque //standard container and at the same time makes use of the EBO //for empty allocators. struct _Deque_impl : public _Tp_alloc_type { _Map_pointer _M_map; size_t _M_map_size; iterator _M_start; iterator _M_finish; _Deque_impl() : _Tp_alloc_type(), _M_map(), _M_map_size(0), _M_start(), _M_finish() { } _Deque_impl(const _Tp_alloc_type& __a) _GLIBCXX_NOEXCEPT : _Tp_alloc_type(__a), _M_map(), _M_map_size(0), _M_start(), _M_finish() { } #if __cplusplus >= 201103L _Deque_impl(_Deque_impl&&) = default; _Deque_impl(_Tp_alloc_type&& __a) noexcept : _Tp_alloc_type(std::move(__a)), _M_map(), _M_map_size(0), _M_start(), _M_finish() { } #endif void _M_swap_data(_Deque_impl& __x) _GLIBCXX_NOEXCEPT { using std::swap; swap(this->_M_start, __x._M_start); swap(this->_M_finish, __x._M_finish); swap(this->_M_map, __x._M_map); swap(this->_M_map_size, __x._M_map_size); } }; _Tp_alloc_type& _M_get_Tp_allocator() _GLIBCXX_NOEXCEPT { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } const _Tp_alloc_type& _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); } _Map_alloc_type _M_get_map_allocator() const _GLIBCXX_NOEXCEPT { return _Map_alloc_type(_M_get_Tp_allocator()); } _Ptr _M_allocate_node() { typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Traits; return _Traits::allocate(_M_impl, __deque_buf_size(sizeof(_Tp))); } void _M_deallocate_node(_Ptr __p) _GLIBCXX_NOEXCEPT { typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Traits; _Traits::deallocate(_M_impl, __p, __deque_buf_size(sizeof(_Tp))); } _Map_pointer _M_allocate_map(size_t __n) { _Map_alloc_type __map_alloc = _M_get_map_allocator(); return _Map_alloc_traits::allocate(__map_alloc, __n); } void _M_deallocate_map(_Map_pointer __p, size_t __n) _GLIBCXX_NOEXCEPT { _Map_alloc_type __map_alloc = _M_get_map_allocator(); _Map_alloc_traits::deallocate(__map_alloc, __p, __n); } protected: void _M_initialize_map(size_t); void _M_create_nodes(_Map_pointer __nstart, _Map_pointer __nfinish); void _M_destroy_nodes(_Map_pointer __nstart, _Map_pointer __nfinish) _GLIBCXX_NOEXCEPT; enum { _S_initial_map_size = 8 }; _Deque_impl _M_impl; #if __cplusplus >= 201103L private: _Deque_impl _M_move_impl() { if (!_M_impl._M_map) return std::move(_M_impl); // Create a copy of the current allocator. _Tp_alloc_type __alloc{_M_get_Tp_allocator()}; // Put that copy in a moved-from state. _Tp_alloc_type __sink __attribute((__unused__)) {std::move(__alloc)}; // Create an empty map that allocates using the moved-from allocator. _Deque_base __empty{__alloc}; __empty._M_initialize_map(0); // Now safe to modify current allocator and perform non-throwing swaps. _Deque_impl __ret{std::move(_M_get_Tp_allocator())}; _M_impl._M_swap_data(__ret); _M_impl._M_swap_data(__empty._M_impl); return __ret; } #endif }; template<typename _Tp, typename _Alloc> _Deque_base<_Tp, _Alloc>:: ~_Deque_base() _GLIBCXX_NOEXCEPT { if (this->_M_impl._M_map) { _M_destroy_nodes(this->_M_impl._M_start._M_node, this->_M_impl._M_finish._M_node + 1); _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); } } /** * @brief Layout storage. * @param __num_elements The count of T's for which to allocate space * at first. * @return Nothing. * * The initial underlying memory layout is a bit complicated... */ template<typename _Tp, typename _Alloc> void _Deque_base<_Tp, _Alloc>:: _M_initialize_map(size_t __num_elements) { const size_t __num_nodes = (__num_elements/ __deque_buf_size(sizeof(_Tp)) + 1); this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size, size_t(__num_nodes + 2)); this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size); // For "small" maps (needing less than _M_map_size nodes), allocation // starts in the middle elements and grows outwards. So nstart may be // the beginning of _M_map, but for small maps it may be as far in as // _M_map+3. _Map_pointer __nstart = (this->_M_impl._M_map + (this->_M_impl._M_map_size - __num_nodes) / 2); _Map_pointer __nfinish = __nstart + __num_nodes; __try { _M_create_nodes(__nstart, __nfinish); } __catch(...) { _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); this->_M_impl._M_map = _Map_pointer(); this->_M_impl._M_map_size = 0; __throw_exception_again; } this->_M_impl._M_start._M_set_node(__nstart); this->_M_impl._M_finish._M_set_node(__nfinish - 1); this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first; this->_M_impl._M_finish._M_cur = (this->_M_impl._M_finish._M_first + __num_elements % __deque_buf_size(sizeof(_Tp))); } template<typename _Tp, typename _Alloc> void _Deque_base<_Tp, _Alloc>:: _M_create_nodes(_Map_pointer __nstart, _Map_pointer __nfinish) { _Map_pointer __cur; __try { for (__cur = __nstart; __cur < __nfinish; ++__cur) *__cur = this->_M_allocate_node(); } __catch(...) { _M_destroy_nodes(__nstart, __cur); __throw_exception_again; } } template<typename _Tp, typename _Alloc> void _Deque_base<_Tp, _Alloc>:: _M_destroy_nodes(_Map_pointer __nstart, _Map_pointer __nfinish) _GLIBCXX_NOEXCEPT { for (_Map_pointer __n = __nstart; __n < __nfinish; ++__n) _M_deallocate_node(*__n); } /** * @brief A standard container using fixed-size memory allocation and * constant-time manipulation of elements at either end. * * @ingroup sequences * * @tparam _Tp Type of element. * @tparam _Alloc Allocator type, defaults to allocator<_Tp>. * * 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>, including the * <a href="tables.html#68">optional sequence requirements</a>. * * In previous HP/SGI versions of deque, there was an extra template * parameter so users could control the node size. This extension turned * out to violate the C++ standard (it can be detected using template * template parameters), and it was removed. * * Here's how a deque<Tp> manages memory. Each deque has 4 members: * * - Tp** _M_map * - size_t _M_map_size * - iterator _M_start, _M_finish * * map_size is at least 8. %map is an array of map_size * pointers-to-@a nodes. (The name %map has nothing to do with the * std::map class, and @b nodes should not be confused with * std::list's usage of @a node.) * * A @a node has no specific type name as such, but it is referred * to as @a node in this file. It is a simple array-of-Tp. If Tp * is very large, there will be one Tp element per node (i.e., an * @a array of one). For non-huge Tp's, node size is inversely * related to Tp size: the larger the Tp, the fewer Tp's will fit * in a node. The goal here is to keep the total size of a node * relatively small and constant over different Tp's, to improve * allocator efficiency. * * Not every pointer in the %map array will point to a node. If * the initial number of elements in the deque is small, the * /middle/ %map pointers will be valid, and the ones at the edges * will be unused. This same situation will arise as the %map * grows: available %map pointers, if any, will be on the ends. As * new nodes are created, only a subset of the %map's pointers need * to be copied @a outward. * * Class invariants: * - For any nonsingular iterator i: * - i.node points to a member of the %map array. (Yes, you read that * correctly: i.node does not actually point to a node.) The member of * the %map array is what actually points to the node. * - i.first == *(i.node) (This points to the node (first Tp element).) * - i.last == i.first + node_size * - i.cur is a pointer in the range [i.first, i.last). NOTE: * the implication of this is that i.cur is always a dereferenceable * pointer, even if i is a past-the-end iterator. * - Start and Finish are always nonsingular iterators. NOTE: this * means that an empty deque must have one node, a deque with <N * elements (where N is the node buffer size) must have one node, a * deque with N through (2N-1) elements must have two nodes, etc. * - For every node other than start.node and finish.node, every * element in the node is an initialized object. If start.node == * finish.node, then [start.cur, finish.cur) are initialized * objects, and the elements outside that range are uninitialized * storage. Otherwise, [start.cur, start.last) and [finish.first, * finish.cur) are initialized objects, and [start.first, start.cur) * and [finish.cur, finish.last) are uninitialized storage. * - [%map, %map + map_size) is a valid, non-empty range. * - [start.node, finish.node] is a valid range contained within * [%map, %map + map_size). * - A pointer in the range [%map, %map + map_size) points to an allocated * node if and only if the pointer is in the range * [start.node, finish.node]. * * Here's the magic: nothing in deque is @b aware of the discontiguous * storage! * * The memory setup and layout occurs in the parent, _Base, and the iterator * class is entirely responsible for @a leaping from one node to the next. * All the implementation routines for deque itself work only through the * start and finish iterators. This keeps the routines simple and sane, * and we can use other standard algorithms as well. */ template<typename _Tp, typename _Alloc = std::allocator<_Tp> > class deque : protected _Deque_base<_Tp, _Alloc> { #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename _Alloc::value_type _Alloc_value_type; # if __cplusplus < 201103L __glibcxx_class_requires(_Tp, _SGIAssignableConcept) # endif __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) #endif #if __cplusplus >= 201103L static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value, "std::deque must have a non-const, non-volatile value_type"); # ifdef __STRICT_ANSI__ static_assert(is_same<typename _Alloc::value_type, _Tp>::value, "std::deque must have the same value_type as its allocator"); # endif #endif typedef _Deque_base<_Tp, _Alloc> _Base; typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; typedef typename _Base::_Alloc_traits _Alloc_traits; typedef typename _Base::_Map_pointer _Map_pointer; public: typedef _Tp value_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 _Base::iterator iterator; typedef typename _Base::const_iterator const_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Alloc allocator_type; protected: static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT { return __deque_buf_size(sizeof(_Tp)); } // Functions controlling memory layout, and nothing else. using _Base::_M_initialize_map; using _Base::_M_create_nodes; using _Base::_M_destroy_nodes; using _Base::_M_allocate_node; using _Base::_M_deallocate_node; using _Base::_M_allocate_map; using _Base::_M_deallocate_map; using _Base::_M_get_Tp_allocator; /** * A total of four data members accumulated down the hierarchy. * May be accessed via _M_impl.* */ using _Base::_M_impl; public: // [23.2.1.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) /** * @brief Creates a %deque with no elements. */ deque() : _Base() { } /** * @brief Creates a %deque with no elements. * @param __a An allocator object. */ explicit deque(const allocator_type& __a) : _Base(__a, 0) { } #if __cplusplus >= 201103L /** * @brief Creates a %deque with default constructed elements. * @param __n The number of elements to initially create. * @param __a An allocator. * * This constructor fills the %deque with @a n default * constructed elements. */ explicit deque(size_type __n, const allocator_type& __a = allocator_type()) : _Base(__a, __n) { _M_default_initialize(); } /** * @brief Creates a %deque with copies of an exemplar element. * @param __n The number of elements to initially create. * @param __value An element to copy. * @param __a An allocator. * * This constructor fills the %deque with @a __n copies of @a __value. */ deque(size_type __n, const value_type& __value, const allocator_type& __a = allocator_type()) : _Base(__a, __n) { _M_fill_initialize(__value); } #else /** * @brief Creates a %deque with copies of an exemplar element. * @param __n The number of elements to initially create. * @param __value An element to copy. * @param __a An allocator. * * This constructor fills the %deque with @a __n copies of @a __value. */ explicit deque(size_type __n, const value_type& __value = value_type(), const allocator_type& __a = allocator_type()) : _Base(__a, __n) { _M_fill_initialize(__value); } #endif /** * @brief %Deque copy constructor. * @param __x A %deque of identical element and allocator types. * * The newly-created %deque uses a copy of the allocator object used * by @a __x (unless the allocator traits dictate a different object). */ deque(const deque& __x) : _Base(_Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()), __x.size()) { std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); } #if __cplusplus >= 201103L /** * @brief %Deque move constructor. * @param __x A %deque of identical element and allocator types. * * The newly-created %deque contains the exact contents of @a __x. * The contents of @a __x are a valid, but unspecified %deque. */ deque(deque&& __x) : _Base(std::move(__x)) { } /// Copy constructor with alternative allocator deque(const deque& __x, const allocator_type& __a) : _Base(__a, __x.size()) { std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); } /// Move constructor with alternative allocator deque(deque&& __x, const allocator_type& __a) : _Base(std::move(__x), __a, __x.size()) { if (__x.get_allocator() != __a) { std::__uninitialized_move_a(__x.begin(), __x.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); __x.clear(); } } /** * @brief Builds a %deque from an initializer list. * @param __l An initializer_list. * @param __a An allocator object. * * Create a %deque consisting of copies of the elements in the * initializer_list @a __l. * * This will call the element type's copy constructor N times * (where N is __l.size()) and do no memory reallocation. */ deque(initializer_list<value_type> __l, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_range_initialize(__l.begin(), __l.end(), random_access_iterator_tag()); } #endif /** * @brief Builds a %deque from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __a An allocator object. * * Create a %deque consisting of copies of the elements from [__first, * __last). * * If the iterators are forward, bidirectional, or random-access, then * this will call the elements' copy constructor N times (where N is * distance(__first,__last)) and do no memory reallocation. But if only * input iterators are used, then this will do at most 2N calls to the * copy constructor, and logN memory reallocations. */ #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> deque(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_initialize_dispatch(__first, __last, __false_type()); } #else template<typename _InputIterator> deque(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } #endif /** * The dtor only erases the elements, and note that if the elements * themselves are pointers, the pointed-to memory is not touched in any * way. Managing the pointer is the user's responsibility. */ ~deque() { _M_destroy_data(begin(), end(), _M_get_Tp_allocator()); } /** * @brief %Deque assignment operator. * @param __x A %deque of identical element and allocator types. * * All the elements of @a x are copied. * * The newly-created %deque uses a copy of the allocator object used * by @a __x (unless the allocator traits dictate a different object). */ deque& operator=(const deque& __x); #if __cplusplus >= 201103L /** * @brief %Deque move assignment operator. * @param __x A %deque of identical element and allocator types. * * The contents of @a __x are moved into this deque (without copying, * if the allocators permit it). * @a __x is a valid, but unspecified %deque. */ deque& operator=(deque&& __x) noexcept(_Alloc_traits::_S_always_equal()) { using __always_equal = typename _Alloc_traits::is_always_equal; _M_move_assign1(std::move(__x), __always_equal{}); return *this; } /** * @brief Assigns an initializer list to a %deque. * @param __l An initializer_list. * * This function fills a %deque with copies of the elements in the * initializer_list @a __l. * * Note that the assignment completely changes the %deque and that the * resulting %deque's size is the same as the number of elements * assigned. */ deque& operator=(initializer_list<value_type> __l) { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); return *this; } #endif /** * @brief Assigns a given value to a %deque. * @param __n Number of elements to be assigned. * @param __val Value to be assigned. * * This function fills a %deque with @a n copies of the given * value. Note that the assignment completely changes the * %deque and that the resulting %deque's size is the same as * the number of elements assigned. */ void assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); } /** * @brief Assigns a range to a %deque. * @param __first An input iterator. * @param __last An input iterator. * * This function fills a %deque with copies of the elements in the * range [__first,__last). * * Note that the assignment completely changes the %deque and that the * resulting %deque's size is the same as the number of elements * assigned. */ #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> void assign(_InputIterator __first, _InputIterator __last) { _M_assign_dispatch(__first, __last, __false_type()); } #else template<typename _InputIterator> void assign(_InputIterator __first, _InputIterator __last) { typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_assign_dispatch(__first, __last, _Integral()); } #endif #if __cplusplus >= 201103L /** * @brief Assigns an initializer list to a %deque. * @param __l An initializer_list. * * This function fills a %deque with copies of the elements in the * initializer_list @a __l. * * Note that the assignment completely changes the %deque and that the * resulting %deque's size is the same as the number of elements * assigned. */ void assign(initializer_list<value_type> __l) { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); } #endif /// Get a copy of the memory allocation object. allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return _Base::get_allocator(); } // iterators /** * Returns a read/write iterator that points to the first element in the * %deque. Iteration is done in ordinary element order. */ iterator begin() _GLIBCXX_NOEXCEPT { return this->_M_impl._M_start; } /** * Returns a read-only (constant) iterator that points to the first * element in the %deque. Iteration is done in ordinary element order. */ const_iterator begin() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_start; } /** * Returns a read/write iterator that points one past the last * element in the %deque. Iteration is done in ordinary * element order. */ iterator end() _GLIBCXX_NOEXCEPT { return this->_M_impl._M_finish; } /** * Returns a read-only (constant) iterator that points one past * the last element in the %deque. Iteration is done in * ordinary element order. */ const_iterator end() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_finish; } /** * Returns a read/write reverse iterator that points to the * last element in the %deque. Iteration is done in reverse * element order. */ reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return reverse_iterator(this->_M_impl._M_finish); } /** * Returns a read-only (constant) reverse iterator that points * to the last element in the %deque. Iteration is done in * reverse element order. */ const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(this->_M_impl._M_finish); } /** * Returns a read/write reverse iterator that points to one * before the first element in the %deque. Iteration is done * in reverse element order. */ reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(this->_M_impl._M_start); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first element in the %deque. Iteration is * done in reverse element order. */ const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(this->_M_impl._M_start); } #if __cplusplus >= 201103L /** * Returns a read-only (constant) iterator that points to the first * element in the %deque. Iteration is done in ordinary element order. */ const_iterator cbegin() const noexcept { return this->_M_impl._M_start; } /** * Returns a read-only (constant) iterator that points one past * the last element in the %deque. Iteration is done in * ordinary element order. */ const_iterator cend() const noexcept { return this->_M_impl._M_finish; } /** * Returns a read-only (constant) reverse iterator that points * to the last element in the %deque. Iteration is done in * reverse element order. */ const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(this->_M_impl._M_finish); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first element in the %deque. Iteration is * done in reverse element order. */ const_reverse_iterator crend() const noexcept { return const_reverse_iterator(this->_M_impl._M_start); } #endif // [23.2.1.2] capacity /** Returns the number of elements in the %deque. */ size_type size() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_finish - this->_M_impl._M_start; } /** Returns the size() of the largest possible %deque. */ size_type max_size() const _GLIBCXX_NOEXCEPT { return _Alloc_traits::max_size(_M_get_Tp_allocator()); } #if __cplusplus >= 201103L /** * @brief Resizes the %deque to the specified number of elements. * @param __new_size Number of elements the %deque should contain. * * This function will %resize the %deque to the specified * number of elements. If the number is smaller than the * %deque's current size the %deque is truncated, otherwise * default constructed elements are appended. */ void resize(size_type __new_size) { const size_type __len = size(); if (__new_size > __len) _M_default_append(__new_size - __len); else if (__new_size < __len) _M_erase_at_end(this->_M_impl._M_start + difference_type(__new_size)); } /** * @brief Resizes the %deque to the specified number of elements. * @param __new_size Number of elements the %deque should contain. * @param __x Data with which new elements should be populated. * * This function will %resize the %deque to the specified * number of elements. If the number is smaller than the * %deque's current size the %deque is truncated, otherwise the * %deque is extended and new elements are populated with given * data. */ void resize(size_type __new_size, const value_type& __x) { const size_type __len = size(); if (__new_size > __len) _M_fill_insert(this->_M_impl._M_finish, __new_size - __len, __x); else if (__new_size < __len) _M_erase_at_end(this->_M_impl._M_start + difference_type(__new_size)); } #else /** * @brief Resizes the %deque to the specified number of elements. * @param __new_size Number of elements the %deque should contain. * @param __x Data with which new elements should be populated. * * This function will %resize the %deque to the specified * number of elements. If the number is smaller than the * %deque's current size the %deque is truncated, otherwise the * %deque is extended and new elements are populated with given * data. */ void resize(size_type __new_size, value_type __x = value_type()) { const size_type __len = size(); if (__new_size > __len) _M_fill_insert(this->_M_impl._M_finish, __new_size - __len, __x); else if (__new_size < __len) _M_erase_at_end(this->_M_impl._M_start + difference_type(__new_size)); } #endif #if __cplusplus >= 201103L /** A non-binding request to reduce memory use. */ void shrink_to_fit() noexcept { _M_shrink_to_fit(); } #endif /** * Returns true if the %deque is empty. (Thus begin() would * equal end().) */ bool empty() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_finish == this->_M_impl._M_start; } // element access /** * @brief Subscript access to the data contained in the %deque. * @param __n The index of the element for which data should be * accessed. * @return Read/write reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ reference operator[](size_type __n) _GLIBCXX_NOEXCEPT { __glibcxx_requires_subscript(__n); return this->_M_impl._M_start[difference_type(__n)]; } /** * @brief Subscript access to the data contained in the %deque. * @param __n The index of the element for which data should be * accessed. * @return Read-only (constant) reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ const_reference operator[](size_type __n) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_subscript(__n); return this->_M_impl._M_start[difference_type(__n)]; } protected: /// Safety check used only from at(). void _M_range_check(size_type __n) const { if (__n >= this->size()) __throw_out_of_range_fmt(__N("deque::_M_range_check: __n " "(which is %zu)>= this->size() " "(which is %zu)"), __n, this->size()); } public: /** * @brief Provides access to the data contained in the %deque. * @param __n The index of the element for which data should be * accessed. * @return Read/write reference to data. * @throw std::out_of_range If @a __n is an invalid index. * * This function provides for safer data access. The parameter * is first checked that it is in the range of the deque. The * function throws out_of_range if the check fails. */ reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } /** * @brief Provides access to the data contained in the %deque. * @param __n The index of the element for which data should be * accessed. * @return Read-only (constant) reference to data. * @throw std::out_of_range If @a __n is an invalid index. * * This function provides for safer data access. The parameter is first * checked that it is in the range of the deque. The function throws * out_of_range if the check fails. */ const_reference at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } /** * Returns a read/write reference to the data at the first * element of the %deque. */ reference front() _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); return *begin(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %deque. */ const_reference front() const _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); return *begin(); } /** * Returns a read/write reference to the data at the last element of the * %deque. */ reference back() _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); iterator __tmp = end(); --__tmp; return *__tmp; } /** * Returns a read-only (constant) reference to the data at the last * element of the %deque. */ const_reference back() const _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); const_iterator __tmp = end(); --__tmp; return *__tmp; } // [23.2.1.2] modifiers /** * @brief Add data to the front of the %deque. * @param __x Data to be added. * * This is a typical stack operation. The function creates an * element at the front of the %deque and assigns the given * data to it. Due to the nature of a %deque this operation * can be done in constant time. */ void push_front(const value_type& __x) { if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first) { _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_start._M_cur - 1, __x); --this->_M_impl._M_start._M_cur; } else _M_push_front_aux(__x); } #if __cplusplus >= 201103L void push_front(value_type&& __x) { emplace_front(std::move(__x)); } template<typename... _Args> #if __cplusplus > 201402L reference #else void #endif emplace_front(_Args&&... __args); #endif /** * @brief Add data to the end of the %deque. * @param __x Data to be added. * * This is a typical stack operation. The function creates an * element at the end of the %deque and assigns the given data * to it. Due to the nature of a %deque this operation can be * done in constant time. */ void push_back(const value_type& __x) { if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_last - 1) { _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish._M_cur, __x); ++this->_M_impl._M_finish._M_cur; } else _M_push_back_aux(__x); } #if __cplusplus >= 201103L void push_back(value_type&& __x) { emplace_back(std::move(__x)); } template<typename... _Args> #if __cplusplus > 201402L reference #else void #endif emplace_back(_Args&&... __args); #endif /** * @brief Removes first element. * * This is a typical stack operation. It shrinks the %deque by one. * * Note that no data is returned, and if the first element's data is * needed, it should be retrieved before pop_front() is called. */ void pop_front() _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_last - 1) { _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_start._M_cur); ++this->_M_impl._M_start._M_cur; } else _M_pop_front_aux(); } /** * @brief Removes last element. * * This is a typical stack operation. It shrinks the %deque by one. * * Note that no data is returned, and if the last element's data is * needed, it should be retrieved before pop_back() is called. */ void pop_back() _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_first) { --this->_M_impl._M_finish._M_cur; _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish._M_cur); } else _M_pop_back_aux(); } #if __cplusplus >= 201103L /** * @brief Inserts an object in %deque before specified iterator. * @param __position A const_iterator into the %deque. * @param __args Arguments. * @return An iterator that points to the inserted data. * * This function will insert an object of type T constructed * with T(std::forward<Args>(args)...) before the specified location. */ template<typename... _Args> iterator emplace(const_iterator __position, _Args&&... __args); /** * @brief Inserts given value into %deque before specified iterator. * @param __position A const_iterator into the %deque. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given value before the * specified location. */ iterator insert(const_iterator __position, const value_type& __x); #else /** * @brief Inserts given value into %deque before specified iterator. * @param __position An iterator into the %deque. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given value before the * specified location. */ iterator insert(iterator __position, const value_type& __x); #endif #if __cplusplus >= 201103L /** * @brief Inserts given rvalue into %deque before specified iterator. * @param __position A const_iterator into the %deque. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given rvalue before the * specified location. */ iterator insert(const_iterator __position, value_type&& __x) { return emplace(__position, std::move(__x)); } /** * @brief Inserts an initializer list into the %deque. * @param __p An iterator into the %deque. * @param __l An initializer_list. * * This function will insert copies of the data in the * initializer_list @a __l into the %deque before the location * specified by @a __p. This is known as <em>list insert</em>. */ iterator insert(const_iterator __p, initializer_list<value_type> __l) { auto __offset = __p - cbegin(); _M_range_insert_aux(__p._M_const_cast(), __l.begin(), __l.end(), std::random_access_iterator_tag()); return begin() + __offset; } #endif #if __cplusplus >= 201103L /** * @brief Inserts a number of copies of given data into the %deque. * @param __position A const_iterator into the %deque. * @param __n Number of elements to be inserted. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a specified number of copies of the given * data before the location specified by @a __position. */ iterator insert(const_iterator __position, size_type __n, const value_type& __x) { difference_type __offset = __position - cbegin(); _M_fill_insert(__position._M_const_cast(), __n, __x); return begin() + __offset; } #else /** * @brief Inserts a number of copies of given data into the %deque. * @param __position An iterator into the %deque. * @param __n Number of elements to be inserted. * @param __x Data to be inserted. * * This function will insert a specified number of copies of the given * data before the location specified by @a __position. */ void insert(iterator __position, size_type __n, const value_type& __x) { _M_fill_insert(__position, __n, __x); } #endif #if __cplusplus >= 201103L /** * @brief Inserts a range into the %deque. * @param __position A const_iterator into the %deque. * @param __first An input iterator. * @param __last An input iterator. * @return An iterator that points to the inserted data. * * This function will insert copies of the data in the range * [__first,__last) into the %deque before the location specified * by @a __position. This is known as <em>range insert</em>. */ template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> iterator insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { difference_type __offset = __position - cbegin(); _M_insert_dispatch(__position._M_const_cast(), __first, __last, __false_type()); return begin() + __offset; } #else /** * @brief Inserts a range into the %deque. * @param __position An iterator into the %deque. * @param __first An input iterator. * @param __last An input iterator. * * This function will insert copies of the data in the range * [__first,__last) into the %deque before the location specified * by @a __position. This is known as <em>range insert</em>. */ template<typename _InputIterator> void insert(iterator __position, _InputIterator __first, _InputIterator __last) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); } #endif /** * @brief Remove element at given position. * @param __position Iterator pointing to element to be erased. * @return An iterator pointing to the next element (or end()). * * This function will erase the element at the given position and thus * shorten the %deque by one. * * The user is cautioned that * this function only erases the element, and that if the element is * itself a pointer, the pointed-to memory is not touched in any way. * Managing the pointer is the user's responsibility. */ iterator #if __cplusplus >= 201103L erase(const_iterator __position) #else erase(iterator __position) #endif { return _M_erase(__position._M_const_cast()); } /** * @brief Remove a range of elements. * @param __first Iterator pointing to the first element to be erased. * @param __last Iterator pointing to one past the last element to be * erased. * @return An iterator pointing to the element pointed to by @a last * prior to erasing (or end()). * * This function will erase the elements in the range * [__first,__last) and shorten the %deque accordingly. * * The user is cautioned that * this function only erases the elements, and that if the elements * themselves are pointers, the pointed-to memory is not touched in any * way. Managing the pointer is the user's responsibility. */ iterator #if __cplusplus >= 201103L erase(const_iterator __first, const_iterator __last) #else erase(iterator __first, iterator __last) #endif { return _M_erase(__first._M_const_cast(), __last._M_const_cast()); } /** * @brief Swaps data with another %deque. * @param __x A %deque of the same element and allocator types. * * This exchanges the elements between two deques in constant time. * (Four pointers, so it should be quite fast.) * Note that the global std::swap() function is specialized such that * std::swap(d1,d2) will feed to this function. * * Whether the allocators are swapped depends on the allocator traits. */ void swap(deque& __x) _GLIBCXX_NOEXCEPT { #if __cplusplus >= 201103L __glibcxx_assert(_Alloc_traits::propagate_on_container_swap::value || _M_get_Tp_allocator() == __x._M_get_Tp_allocator()); #endif _M_impl._M_swap_data(__x._M_impl); _Alloc_traits::_S_on_swap(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); } /** * Erases all the elements. Note that this function only erases the * elements, and that if the elements themselves are pointers, the * pointed-to memory is not touched in any way. Managing the pointer is * the user's responsibility. */ void clear() _GLIBCXX_NOEXCEPT { _M_erase_at_end(begin()); } protected: // Internal constructor functions follow. // called by the range constructor to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { _M_initialize_map(static_cast<size_type>(__n)); _M_fill_initialize(__x); } // called by the range constructor to implement [23.1.1]/9 template<typename _InputIterator> void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { _M_range_initialize(__first, __last, std::__iterator_category(__first)); } // called by the second initialize_dispatch above //@{ /** * @brief Fills the deque with whatever is in [first,last). * @param __first An input iterator. * @param __last An input iterator. * @return Nothing. * * If the iterators are actually forward iterators (or better), then the * memory layout can be done all at once. Else we move forward using * push_back on each value from the iterator. */ template<typename _InputIterator> void _M_range_initialize(_InputIterator __first, _InputIterator __last, std::input_iterator_tag); // called by the second initialize_dispatch above template<typename _ForwardIterator> void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag); //@} /** * @brief Fills the %deque with copies of value. * @param __value Initial value. * @return Nothing. * @pre _M_start and _M_finish have already been initialized, * but none of the %deque's elements have yet been constructed. * * This function is called only when the user provides an explicit size * (with or without an explicit exemplar value). */ void _M_fill_initialize(const value_type& __value); #if __cplusplus >= 201103L // called by deque(n). void _M_default_initialize(); #endif // Internal assign functions follow. The *_aux functions do the actual // assignment work for the range versions. // called by the range assign to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign(__n, __val); } // called by the range assign to implement [23.1.1]/9 template<typename _InputIterator> void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } // called by the second assign_dispatch above template<typename _InputIterator> void _M_assign_aux(_InputIterator __first, _InputIterator __last, std::input_iterator_tag); // called by the second assign_dispatch above template<typename _ForwardIterator> void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { const size_type __len = std::distance(__first, __last); if (__len > size()) { _ForwardIterator __mid = __first; std::advance(__mid, size()); std::copy(__first, __mid, begin()); _M_range_insert_aux(end(), __mid, __last, std::__iterator_category(__first)); } else _M_erase_at_end(std::copy(__first, __last, begin())); } // Called by assign(n,t), and the range assign when it turns out // to be the same thing. void _M_fill_assign(size_type __n, const value_type& __val) { if (__n > size()) { std::fill(begin(), end(), __val); _M_fill_insert(end(), __n - size(), __val); } else { _M_erase_at_end(begin() + difference_type(__n)); std::fill(begin(), end(), __val); } } //@{ /// Helper functions for push_* and pop_*. #if __cplusplus < 201103L void _M_push_back_aux(const value_type&); void _M_push_front_aux(const value_type&); #else template<typename... _Args> void _M_push_back_aux(_Args&&... __args); template<typename... _Args> void _M_push_front_aux(_Args&&... __args); #endif void _M_pop_back_aux(); void _M_pop_front_aux(); //@} // Internal insert functions follow. The *_aux functions do the actual // insertion work when all shortcuts fail. // called by the range insert to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type) { _M_fill_insert(__pos, __n, __x); } // called by the range insert to implement [23.1.1]/9 template<typename _InputIterator> void _M_insert_dispatch(iterator __pos, _InputIterator __first, _InputIterator __last, __false_type) { _M_range_insert_aux(__pos, __first, __last, std::__iterator_category(__first)); } // called by the second insert_dispatch above template<typename _InputIterator> void _M_range_insert_aux(iterator __pos, _InputIterator __first, _InputIterator __last, std::input_iterator_tag); // called by the second insert_dispatch above template<typename _ForwardIterator> void _M_range_insert_aux(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag); // Called by insert(p,n,x), and the range insert when it turns out to be // the same thing. Can use fill functions in optimal situations, // otherwise passes off to insert_aux(p,n,x). void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); // called by insert(p,x) #if __cplusplus < 201103L iterator _M_insert_aux(iterator __pos, const value_type& __x); #else template<typename... _Args> iterator _M_insert_aux(iterator __pos, _Args&&... __args); #endif // called by insert(p,n,x) via fill_insert void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); // called by range_insert_aux for forward iterators template<typename _ForwardIterator> void _M_insert_aux(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, size_type __n); // Internal erase functions follow. void _M_destroy_data_aux(iterator __first, iterator __last); // Called by ~deque(). // NB: Doesn't deallocate the nodes. template<typename _Alloc1> void _M_destroy_data(iterator __first, iterator __last, const _Alloc1&) { _M_destroy_data_aux(__first, __last); } void _M_destroy_data(iterator __first, iterator __last, const std::allocator<_Tp>&) { if (!__has_trivial_destructor(value_type)) _M_destroy_data_aux(__first, __last); } // Called by erase(q1, q2). void _M_erase_at_begin(iterator __pos) { _M_destroy_data(begin(), __pos, _M_get_Tp_allocator()); _M_destroy_nodes(this->_M_impl._M_start._M_node, __pos._M_node); this->_M_impl._M_start = __pos; } // Called by erase(q1, q2), resize(), clear(), _M_assign_aux, // _M_fill_assign, operator=. void _M_erase_at_end(iterator __pos) { _M_destroy_data(__pos, end(), _M_get_Tp_allocator()); _M_destroy_nodes(__pos._M_node + 1, this->_M_impl._M_finish._M_node + 1); this->_M_impl._M_finish = __pos; } iterator _M_erase(iterator __pos); iterator _M_erase(iterator __first, iterator __last); #if __cplusplus >= 201103L // Called by resize(sz). void _M_default_append(size_type __n); bool _M_shrink_to_fit(); #endif //@{ /// Memory-handling helpers for the previous internal insert functions. iterator _M_reserve_elements_at_front(size_type __n) { const size_type __vacancies = this->_M_impl._M_start._M_cur - this->_M_impl._M_start._M_first; if (__n > __vacancies) _M_new_elements_at_front(__n - __vacancies); return this->_M_impl._M_start - difference_type(__n); } iterator _M_reserve_elements_at_back(size_type __n) { const size_type __vacancies = (this->_M_impl._M_finish._M_last - this->_M_impl._M_finish._M_cur) - 1; if (__n > __vacancies) _M_new_elements_at_back(__n - __vacancies); return this->_M_impl._M_finish + difference_type(__n); } void _M_new_elements_at_front(size_type __new_elements); void _M_new_elements_at_back(size_type __new_elements); //@} //@{ /** * @brief Memory-handling helpers for the major %map. * * Makes sure the _M_map has space for new nodes. Does not * actually add the nodes. Can invalidate _M_map pointers. * (And consequently, %deque iterators.) */ void _M_reserve_map_at_back(size_type __nodes_to_add = 1) { if (__nodes_to_add + 1 > this->_M_impl._M_map_size - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map)) _M_reallocate_map(__nodes_to_add, false); } void _M_reserve_map_at_front(size_type __nodes_to_add = 1) { if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node - this->_M_impl._M_map)) _M_reallocate_map(__nodes_to_add, true); } void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); //@} #if __cplusplus >= 201103L // Constant-time, nothrow move assignment when source object's memory // can be moved because the allocators are equal. void _M_move_assign1(deque&& __x, /* always equal: */ true_type) noexcept { this->_M_impl._M_swap_data(__x._M_impl); __x.clear(); std::__alloc_on_move(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); } // When the allocators are not equal the operation could throw, because // we might need to allocate a new map for __x after moving from it // or we might need to allocate new elements for *this. void _M_move_assign1(deque&& __x, /* always equal: */ false_type) { constexpr bool __move_storage = _Alloc_traits::_S_propagate_on_move_assign(); _M_move_assign2(std::move(__x), __bool_constant<__move_storage>()); } // Destroy all elements and deallocate all memory, then replace // with elements created from __args. template<typename... _Args> void _M_replace_map(_Args&&... __args) { // Create new data first, so if allocation fails there are no effects. deque __newobj(std::forward<_Args>(__args)...); // Free existing storage using existing allocator. clear(); _M_deallocate_node(*begin()._M_node); // one node left after clear() _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size); this->_M_impl._M_map = nullptr; this->_M_impl._M_map_size = 0; // Take ownership of replacement memory. this->_M_impl._M_swap_data(__newobj._M_impl); } // Do move assignment when the allocator propagates. void _M_move_assign2(deque&& __x, /* propagate: */ true_type) { // Make a copy of the original allocator state. auto __alloc = __x._M_get_Tp_allocator(); // The allocator propagates so storage can be moved from __x, // leaving __x in a valid empty state with a moved-from allocator. _M_replace_map(std::move(__x)); // Move the corresponding allocator state too. _M_get_Tp_allocator() = std::move(__alloc); } // Do move assignment when it may not be possible to move source // object's memory, resulting in a linear-time operation. void _M_move_assign2(deque&& __x, /* propagate: */ false_type) { if (__x._M_get_Tp_allocator() == this->_M_get_Tp_allocator()) { // The allocators are equal so storage can be moved from __x, // leaving __x in a valid empty state with its current allocator. _M_replace_map(std::move(__x), __x.get_allocator()); } else { // The rvalue's allocator cannot be moved and is not equal, // so we need to individually move each element. _M_assign_aux(std::__make_move_if_noexcept_iterator(__x.begin()), std::__make_move_if_noexcept_iterator(__x.end()), std::random_access_iterator_tag()); __x.clear(); } } #endif }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _ValT = typename iterator_traits<_InputIterator>::value_type, typename _Allocator = allocator<_ValT>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> deque(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> deque<_ValT, _Allocator>; #endif /** * @brief Deque equality comparison. * @param __x A %deque. * @param __y A %deque of the same type as @a __x. * @return True iff the size and elements of the deques are equal. * * This is an equivalence relation. It is linear in the size of the * deques. Deques are considered equivalent if their sizes are equal, * and if corresponding elements compare equal. */ template<typename _Tp, typename _Alloc> inline bool operator==(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); } /** * @brief Deque ordering relation. * @param __x A %deque. * @param __y A %deque of the same type as @a __x. * @return True iff @a x is lexicographically less than @a __y. * * This is a total ordering relation. It is linear in the size of the * deques. The elements must be comparable with @c <. * * See std::lexicographical_compare() for how the determination is made. */ template<typename _Tp, typename _Alloc> inline bool operator<(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } /// Based on operator== template<typename _Tp, typename _Alloc> inline bool operator!=(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return !(__x == __y); } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return __y < __x; } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator<=(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return !(__y < __x); } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>=(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) { return !(__x < __y); } /// See std::deque::swap(). template<typename _Tp, typename _Alloc> inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { __x.swap(__y); } #undef _GLIBCXX_DEQUE_BUF_SIZE _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _STL_DEQUE_H */ c++/8/bits/codecvt.h 0000644 00000051451 15146341150 0010032 0 ustar 00 // Locale support (codecvt) -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/codecvt.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.2.1.5 Template class codecvt // // Written by Benjamin Kosnik <bkoz@redhat.com> #ifndef _CODECVT_H #define _CODECVT_H 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Empty base class for codecvt facet [22.2.1.5]. class codecvt_base { public: enum result { ok, partial, error, noconv }; }; /** * @brief Common base for codecvt functions. * * This template class provides implementations of the public functions * that forward to the protected virtual functions. * * This template also provides abstract stubs for the protected virtual * functions. */ template<typename _InternT, typename _ExternT, typename _StateT> class __codecvt_abstract_base : public locale::facet, public codecvt_base { public: // Types: typedef codecvt_base::result result; typedef _InternT intern_type; typedef _ExternT extern_type; typedef _StateT state_type; // 22.2.1.5.1 codecvt members /** * @brief Convert from internal to external character set. * * Converts input string of intern_type to output string of * extern_type. This is analogous to wcsrtombs. It does this by * calling codecvt::do_out. * * The source and destination character sets are determined by the * facet's locale, internal and external types. * * The characters in [from,from_end) are converted and written to * [to,to_end). from_next and to_next are set to point to the * character following the last successfully converted character, * respectively. If the result needed no conversion, from_next and * to_next are not affected. * * The @a state argument should be initialized if the input is at the * beginning and carried from a previous call if continuing * conversion. There are no guarantees about how @a state is used. * * The result returned is a member of codecvt_base::result. If * all the input is converted, returns codecvt_base::ok. If no * conversion is necessary, returns codecvt_base::noconv. If * the input ends early or there is insufficient space in the * output, returns codecvt_base::partial. Otherwise the * conversion failed and codecvt_base::error is returned. * * @param __state Persistent conversion state data. * @param __from Start of input. * @param __from_end End of input. * @param __from_next Returns start of unconverted data. * @param __to Start of output buffer. * @param __to_end End of output buffer. * @param __to_next Returns start of unused output area. * @return codecvt_base::result. */ result out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const { return this->do_out(__state, __from, __from_end, __from_next, __to, __to_end, __to_next); } /** * @brief Reset conversion state. * * Writes characters to output that would restore @a state to initial * conditions. The idea is that if a partial conversion occurs, then * the converting the characters written by this function would leave * the state in initial conditions, rather than partial conversion * state. It does this by calling codecvt::do_unshift(). * * For example, if 4 external characters always converted to 1 internal * character, and input to in() had 6 external characters with state * saved, this function would write two characters to the output and * set the state to initialized conditions. * * The source and destination character sets are determined by the * facet's locale, internal and external types. * * The result returned is a member of codecvt_base::result. If the * state could be reset and data written, returns codecvt_base::ok. If * no conversion is necessary, returns codecvt_base::noconv. If the * output has insufficient space, returns codecvt_base::partial. * Otherwise the reset failed and codecvt_base::error is returned. * * @param __state Persistent conversion state data. * @param __to Start of output buffer. * @param __to_end End of output buffer. * @param __to_next Returns start of unused output area. * @return codecvt_base::result. */ result unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const { return this->do_unshift(__state, __to,__to_end,__to_next); } /** * @brief Convert from external to internal character set. * * Converts input string of extern_type to output string of * intern_type. This is analogous to mbsrtowcs. It does this by * calling codecvt::do_in. * * The source and destination character sets are determined by the * facet's locale, internal and external types. * * The characters in [from,from_end) are converted and written to * [to,to_end). from_next and to_next are set to point to the * character following the last successfully converted character, * respectively. If the result needed no conversion, from_next and * to_next are not affected. * * The @a state argument should be initialized if the input is at the * beginning and carried from a previous call if continuing * conversion. There are no guarantees about how @a state is used. * * The result returned is a member of codecvt_base::result. If * all the input is converted, returns codecvt_base::ok. If no * conversion is necessary, returns codecvt_base::noconv. If * the input ends early or there is insufficient space in the * output, returns codecvt_base::partial. Otherwise the * conversion failed and codecvt_base::error is returned. * * @param __state Persistent conversion state data. * @param __from Start of input. * @param __from_end End of input. * @param __from_next Returns start of unconverted data. * @param __to Start of output buffer. * @param __to_end End of output buffer. * @param __to_next Returns start of unused output area. * @return codecvt_base::result. */ result in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const { return this->do_in(__state, __from, __from_end, __from_next, __to, __to_end, __to_next); } int encoding() const throw() { return this->do_encoding(); } bool always_noconv() const throw() { return this->do_always_noconv(); } int length(state_type& __state, const extern_type* __from, const extern_type* __end, size_t __max) const { return this->do_length(__state, __from, __end, __max); } int max_length() const throw() { return this->do_max_length(); } protected: explicit __codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { } virtual ~__codecvt_abstract_base() { } /** * @brief Convert from internal to external character set. * * Converts input string of intern_type to output string of * extern_type. This function is a hook for derived classes to change * the value returned. @see out for more information. */ virtual result do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const = 0; virtual result do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const = 0; virtual result do_in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const = 0; virtual int do_encoding() const throw() = 0; virtual bool do_always_noconv() const throw() = 0; virtual int do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const = 0; virtual int do_max_length() const throw() = 0; }; /** * @brief Primary class template codecvt. * @ingroup locales * * NB: Generic, mostly useless implementation. * */ template<typename _InternT, typename _ExternT, typename _StateT> class codecvt : public __codecvt_abstract_base<_InternT, _ExternT, _StateT> { public: // Types: typedef codecvt_base::result result; typedef _InternT intern_type; typedef _ExternT extern_type; typedef _StateT state_type; protected: __c_locale _M_c_locale_codecvt; public: static locale::id id; explicit codecvt(size_t __refs = 0) : __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs), _M_c_locale_codecvt(0) { } explicit codecvt(__c_locale __cloc, size_t __refs = 0); protected: virtual ~codecvt() { } virtual result do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result do_in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const; virtual int do_encoding() const throw(); virtual bool do_always_noconv() const throw(); virtual int do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int do_max_length() const throw(); }; template<typename _InternT, typename _ExternT, typename _StateT> locale::id codecvt<_InternT, _ExternT, _StateT>::id; /// class codecvt<char, char, mbstate_t> specialization. template<> class codecvt<char, char, mbstate_t> : public __codecvt_abstract_base<char, char, mbstate_t> { friend class messages<char>; public: // Types: typedef char intern_type; typedef char extern_type; typedef mbstate_t state_type; protected: __c_locale _M_c_locale_codecvt; public: static locale::id id; explicit codecvt(size_t __refs = 0); explicit codecvt(__c_locale __cloc, size_t __refs = 0); protected: virtual ~codecvt(); virtual result do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result do_in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const; virtual int do_encoding() const throw(); virtual bool do_always_noconv() const throw(); virtual int do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int do_max_length() const throw(); }; #ifdef _GLIBCXX_USE_WCHAR_T /** @brief Class codecvt<wchar_t, char, mbstate_t> specialization. * * Converts between narrow and wide characters in the native character set */ template<> class codecvt<wchar_t, char, mbstate_t> : public __codecvt_abstract_base<wchar_t, char, mbstate_t> { friend class messages<wchar_t>; public: // Types: typedef wchar_t intern_type; typedef char extern_type; typedef mbstate_t state_type; protected: __c_locale _M_c_locale_codecvt; public: static locale::id id; explicit codecvt(size_t __refs = 0); explicit codecvt(__c_locale __cloc, size_t __refs = 0); protected: virtual ~codecvt(); virtual result do_out(state_type& __state, const intern_type* __from, const intern_type* __from_end, const intern_type*& __from_next, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result do_unshift(state_type& __state, extern_type* __to, extern_type* __to_end, extern_type*& __to_next) const; virtual result do_in(state_type& __state, const extern_type* __from, const extern_type* __from_end, const extern_type*& __from_next, intern_type* __to, intern_type* __to_end, intern_type*& __to_next) const; virtual int do_encoding() const throw(); virtual bool do_always_noconv() const throw(); virtual int do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int do_max_length() const throw(); }; #endif //_GLIBCXX_USE_WCHAR_T #if __cplusplus >= 201103L #ifdef _GLIBCXX_USE_C99_STDINT_TR1 /** @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(); }; #endif // _GLIBCXX_USE_C99_STDINT_TR1 #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 && defined(_GLIBCXX_USE_C99_STDINT_TR1) 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() { } }; #endif // 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 && defined(_GLIBCXX_USE_C99_STDINT_TR1) extern template class codecvt_byname<char16_t, char, mbstate_t>; extern template class codecvt_byname<char32_t, char, mbstate_t>; #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _CODECVT_H c++/8/bits/basic_string.h 0000644 00000732011 15146341150 0011050 0 ustar 00 // Components for manipulating sequences of characters -*- C++ -*- // Copyright (C) 1997-2018 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_string.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{string} */ // // ISO C++ 14882: 21 Strings library // #ifndef _BASIC_STRING_H #define _BASIC_STRING_H 1 #pragma GCC system_header #include <ext/atomicity.h> #include <ext/alloc_traits.h> #include <debug/debug.h> #if __cplusplus >= 201103L #include <initializer_list> #endif #if __cplusplus > 201402L # include <string_view> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201703L // Support P0426R1 changes to char_traits in C++17. # define __cpp_lib_constexpr_string 201611L #endif #if _GLIBCXX_USE_CXX11_ABI _GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * @class basic_string basic_string.h <string> * @brief Managing sequences of characters and character-like objects. * * @ingroup strings * @ingroup sequences * * @tparam _CharT Type of character * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. * * 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>. Of the * <a href="tables.html#68">optional sequence requirements</a>, only * @c push_back, @c at, and @c %array access are supported. */ template<typename _CharT, typename _Traits, typename _Alloc> class basic_string { typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_CharT>::other _Char_alloc_type; typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits; // Types: public: typedef _Traits traits_type; typedef typename _Traits::char_type value_type; typedef _Char_alloc_type allocator_type; typedef typename _Alloc_traits::size_type size_type; typedef typename _Alloc_traits::difference_type difference_type; typedef typename _Alloc_traits::reference reference; typedef typename _Alloc_traits::const_reference const_reference; typedef typename _Alloc_traits::pointer pointer; typedef typename _Alloc_traits::const_pointer const_pointer; typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator; typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string> const_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; /// Value returned by various member functions when they fail. static const size_type npos = static_cast<size_type>(-1); private: // type used for positions in insert, erase etc. #if __cplusplus < 201103L typedef iterator __const_iterator; #else typedef const_iterator __const_iterator; #endif #if __cplusplus > 201402L // A helper type for avoiding boiler-plate. typedef basic_string_view<_CharT, _Traits> __sv_type; template<typename _Tp, typename _Res> using _If_sv = enable_if_t< __and_<is_convertible<const _Tp&, __sv_type>, __not_<is_convertible<const _Tp*, const basic_string*>>, __not_<is_convertible<const _Tp&, const _CharT*>>>::value, _Res>; // Allows an implicit conversion to __sv_type. static __sv_type _S_to_string_view(__sv_type __svt) noexcept { return __svt; } // Wraps a string_view by explicit conversion and thus // allows to add an internal constructor that does not // participate in overload resolution when a string_view // is provided. struct __sv_wrapper { explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { } __sv_type _M_sv; }; #endif // Use empty-base optimization: http://www.cantrip.org/emptyopt.html struct _Alloc_hider : allocator_type // TODO check __is_final { #if __cplusplus < 201103L _Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc()) : allocator_type(__a), _M_p(__dat) { } #else _Alloc_hider(pointer __dat, const _Alloc& __a) : allocator_type(__a), _M_p(__dat) { } _Alloc_hider(pointer __dat, _Alloc&& __a = _Alloc()) : allocator_type(std::move(__a)), _M_p(__dat) { } #endif pointer _M_p; // The actual data. }; _Alloc_hider _M_dataplus; size_type _M_string_length; enum { _S_local_capacity = 15 / sizeof(_CharT) }; union { _CharT _M_local_buf[_S_local_capacity + 1]; size_type _M_allocated_capacity; }; void _M_data(pointer __p) { _M_dataplus._M_p = __p; } void _M_length(size_type __length) { _M_string_length = __length; } pointer _M_data() const { return _M_dataplus._M_p; } pointer _M_local_data() { #if __cplusplus >= 201103L return std::pointer_traits<pointer>::pointer_to(*_M_local_buf); #else return pointer(_M_local_buf); #endif } const_pointer _M_local_data() const { #if __cplusplus >= 201103L return std::pointer_traits<const_pointer>::pointer_to(*_M_local_buf); #else return const_pointer(_M_local_buf); #endif } void _M_capacity(size_type __capacity) { _M_allocated_capacity = __capacity; } void _M_set_length(size_type __n) { _M_length(__n); traits_type::assign(_M_data()[__n], _CharT()); } bool _M_is_local() const { return _M_data() == _M_local_data(); } // Create & Destroy pointer _M_create(size_type&, size_type); void _M_dispose() { if (!_M_is_local()) _M_destroy(_M_allocated_capacity); } void _M_destroy(size_type __size) throw() { _Alloc_traits::deallocate(_M_get_allocator(), _M_data(), __size + 1); } // _M_construct_aux is used to implement the 21.3.1 para 15 which // requires special behaviour if _InIterator is an integral type template<typename _InIterator> void _M_construct_aux(_InIterator __beg, _InIterator __end, std::__false_type) { typedef typename iterator_traits<_InIterator>::iterator_category _Tag; _M_construct(__beg, __end, _Tag()); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_construct_aux(_Integer __beg, _Integer __end, std::__true_type) { _M_construct_aux_2(static_cast<size_type>(__beg), __end); } void _M_construct_aux_2(size_type __req, _CharT __c) { _M_construct(__req, __c); } template<typename _InIterator> void _M_construct(_InIterator __beg, _InIterator __end) { typedef typename std::__is_integer<_InIterator>::__type _Integral; _M_construct_aux(__beg, __end, _Integral()); } // For Input Iterators, used in istreambuf_iterators, etc. template<typename _InIterator> void _M_construct(_InIterator __beg, _InIterator __end, std::input_iterator_tag); // For forward_iterators up to random_access_iterators, used for // string::iterator, _CharT*, etc. template<typename _FwdIterator> void _M_construct(_FwdIterator __beg, _FwdIterator __end, std::forward_iterator_tag); void _M_construct(size_type __req, _CharT __c); allocator_type& _M_get_allocator() { return _M_dataplus; } const allocator_type& _M_get_allocator() const { return _M_dataplus; } private: #ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST // The explicit instantiations in misc-inst.cc require this due to // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64063 template<typename _Tp, bool _Requires = !__are_same<_Tp, _CharT*>::__value && !__are_same<_Tp, const _CharT*>::__value && !__are_same<_Tp, iterator>::__value && !__are_same<_Tp, const_iterator>::__value> struct __enable_if_not_native_iterator { typedef basic_string& __type; }; template<typename _Tp> struct __enable_if_not_native_iterator<_Tp, false> { }; #endif size_type _M_check(size_type __pos, const char* __s) const { if (__pos > this->size()) __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > " "this->size() (which is %zu)"), __s, __pos, this->size()); return __pos; } void _M_check_length(size_type __n1, size_type __n2, const char* __s) const { if (this->max_size() - (this->size() - __n1) < __n2) __throw_length_error(__N(__s)); } // NB: _M_limit doesn't check for a bad __pos value. size_type _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT { const bool __testoff = __off < this->size() - __pos; return __testoff ? __off : this->size() - __pos; } // True if _Rep and source do not overlap. bool _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT { return (less<const _CharT*>()(__s, _M_data()) || less<const _CharT*>()(_M_data() + this->size(), __s)); } // When __n = 1 way faster than the general multichar // traits_type::copy/move/assign. static void _S_copy(_CharT* __d, const _CharT* __s, size_type __n) { if (__n == 1) traits_type::assign(*__d, *__s); else traits_type::copy(__d, __s, __n); } static void _S_move(_CharT* __d, const _CharT* __s, size_type __n) { if (__n == 1) traits_type::assign(*__d, *__s); else traits_type::move(__d, __s, __n); } static void _S_assign(_CharT* __d, size_type __n, _CharT __c) { if (__n == 1) traits_type::assign(*__d, __c); else traits_type::assign(__d, __n, __c); } // _S_copy_chars is a separate template to permit specialization // to optimize for the common case of pointers as iterators. template<class _Iterator> static void _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) { for (; __k1 != __k2; ++__k1, (void)++__p) traits_type::assign(*__p, *__k1); // These types are off. } static void _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) _GLIBCXX_NOEXCEPT { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT { _S_copy(__p, __k1, __k2 - __k1); } static void _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) _GLIBCXX_NOEXCEPT { _S_copy(__p, __k1, __k2 - __k1); } static int _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT { const difference_type __d = difference_type(__n1 - __n2); if (__d > __gnu_cxx::__numeric_traits<int>::__max) return __gnu_cxx::__numeric_traits<int>::__max; else if (__d < __gnu_cxx::__numeric_traits<int>::__min) return __gnu_cxx::__numeric_traits<int>::__min; else return int(__d); } void _M_assign(const basic_string&); void _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, size_type __len2); void _M_erase(size_type __pos, size_type __n); public: // Construct/copy/destroy: // NB: We overload ctors in some cases instead of using default // arguments, per 17.4.4.4 para. 2 item 2. /** * @brief Default constructor creates an empty string. */ basic_string() _GLIBCXX_NOEXCEPT_IF(is_nothrow_default_constructible<_Alloc>::value) : _M_dataplus(_M_local_data()) { _M_set_length(0); } /** * @brief Construct an empty string using allocator @a a. */ explicit basic_string(const _Alloc& __a) _GLIBCXX_NOEXCEPT : _M_dataplus(_M_local_data(), __a) { _M_set_length(0); } /** * @brief Construct string with copy of value of @a __str. * @param __str Source string. */ basic_string(const basic_string& __str) : _M_dataplus(_M_local_data(), _Alloc_traits::_S_select_on_copy(__str._M_get_allocator())) { _M_construct(__str._M_data(), __str._M_data() + __str.length()); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2583. no way to supply an allocator for basic_string(str, pos) /** * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. * @param __a Allocator to use. */ basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a = _Alloc()) : _M_dataplus(_M_local_data(), __a) { const _CharT* __start = __str._M_data() + __str._M_check(__pos, "basic_string::basic_string"); _M_construct(__start, __start + __str._M_limit(__pos, npos)); } /** * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. * @param __n Number of characters to copy. */ basic_string(const basic_string& __str, size_type __pos, size_type __n) : _M_dataplus(_M_local_data()) { const _CharT* __start = __str._M_data() + __str._M_check(__pos, "basic_string::basic_string"); _M_construct(__start, __start + __str._M_limit(__pos, __n)); } /** * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. * @param __n Number of characters to copy. * @param __a Allocator to use. */ basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Alloc& __a) : _M_dataplus(_M_local_data(), __a) { const _CharT* __start = __str._M_data() + __str._M_check(__pos, "string::string"); _M_construct(__start, __start + __str._M_limit(__pos, __n)); } /** * @brief Construct string initialized by a character %array. * @param __s Source character %array. * @param __n Number of characters to copy. * @param __a Allocator to use (default is default allocator). * * NB: @a __s must have at least @a __n characters, '\\0' * has no special meaning. */ basic_string(const _CharT* __s, size_type __n, const _Alloc& __a = _Alloc()) : _M_dataplus(_M_local_data(), __a) { _M_construct(__s, __s + __n); } /** * @brief Construct string as copy of a C string. * @param __s Source C string. * @param __a Allocator to use (default is default allocator). */ #if __cpp_deduction_guides && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3076. basic_string CTAD ambiguity template<typename = _RequireAllocator<_Alloc>> #endif basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()) : _M_dataplus(_M_local_data(), __a) { _M_construct(__s, __s ? __s + traits_type::length(__s) : __s+npos); } /** * @brief Construct string as multiple characters. * @param __n Number of characters. * @param __c Character to use. * @param __a Allocator to use (default is default allocator). */ #if __cpp_deduction_guides && ! defined _GLIBCXX_DEFINING_STRING_INSTANTIATIONS // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3076. basic_string CTAD ambiguity template<typename = _RequireAllocator<_Alloc>> #endif basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()) : _M_dataplus(_M_local_data(), __a) { _M_construct(__n, __c); } #if __cplusplus >= 201103L /** * @brief Move construct string. * @param __str Source string. * * The newly-created string contains the exact contents of @a __str. * @a __str is a valid, but unspecified string. **/ basic_string(basic_string&& __str) noexcept : _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator())) { if (__str._M_is_local()) { traits_type::copy(_M_local_buf, __str._M_local_buf, _S_local_capacity + 1); } else { _M_data(__str._M_data()); _M_capacity(__str._M_allocated_capacity); } // Must use _M_length() here not _M_set_length() because // basic_stringbuf relies on writing into unallocated capacity so // we mess up the contents if we put a '\0' in the string. _M_length(__str.length()); __str._M_data(__str._M_local_data()); __str._M_set_length(0); } /** * @brief Construct string from an initializer %list. * @param __l std::initializer_list of characters. * @param __a Allocator to use (default is default allocator). */ basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc()) : _M_dataplus(_M_local_data(), __a) { _M_construct(__l.begin(), __l.end()); } basic_string(const basic_string& __str, const _Alloc& __a) : _M_dataplus(_M_local_data(), __a) { _M_construct(__str.begin(), __str.end()); } basic_string(basic_string&& __str, const _Alloc& __a) noexcept(_Alloc_traits::_S_always_equal()) : _M_dataplus(_M_local_data(), __a) { if (__str._M_is_local()) { traits_type::copy(_M_local_buf, __str._M_local_buf, _S_local_capacity + 1); _M_length(__str.length()); __str._M_set_length(0); } else if (_Alloc_traits::_S_always_equal() || __str.get_allocator() == __a) { _M_data(__str._M_data()); _M_length(__str.length()); _M_capacity(__str._M_allocated_capacity); __str._M_data(__str._M_local_buf); __str._M_set_length(0); } else _M_construct(__str.begin(), __str.end()); } #endif // C++11 /** * @brief Construct string as copy of a range. * @param __beg Start of range. * @param __end End of range. * @param __a Allocator to use (default is default allocator). */ #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> #else template<typename _InputIterator> #endif basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc()) : _M_dataplus(_M_local_data(), __a) { _M_construct(__beg, __end); } #if __cplusplus > 201402L /** * @brief Construct string from a substring of a string_view. * @param __t Source object convertible to string view. * @param __pos The index of the first character to copy from __t. * @param __n The number of characters to copy from __t. * @param __a Allocator to use. */ template<typename _Tp, typename = _If_sv<_Tp, void>> basic_string(const _Tp& __t, size_type __pos, size_type __n, const _Alloc& __a = _Alloc()) : basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { } /** * @brief Construct string from a string_view. * @param __t Source object convertible to string view. * @param __a Allocator to use (default is default allocator). */ template<typename _Tp, typename = _If_sv<_Tp, void>> explicit basic_string(const _Tp& __t, const _Alloc& __a = _Alloc()) : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { } /** * @brief Only internally used: Construct string from a string view * wrapper. * @param __svw string view wrapper. * @param __a Allocator to use. */ explicit basic_string(__sv_wrapper __svw, const _Alloc& __a) : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { } #endif // C++17 /** * @brief Destroy the string instance. */ ~basic_string() { _M_dispose(); } /** * @brief Assign the value of @a str to this string. * @param __str Source string. */ basic_string& operator=(const basic_string& __str) { #if __cplusplus >= 201103L if (_Alloc_traits::_S_propagate_on_copy_assign()) { if (!_Alloc_traits::_S_always_equal() && !_M_is_local() && _M_get_allocator() != __str._M_get_allocator()) { // Propagating allocator cannot free existing storage so must // deallocate it before replacing current allocator. if (__str.size() <= _S_local_capacity) { _M_destroy(_M_allocated_capacity); _M_data(_M_local_data()); _M_set_length(0); } else { const auto __len = __str.size(); auto __alloc = __str._M_get_allocator(); // If this allocation throws there are no effects: auto __ptr = _Alloc_traits::allocate(__alloc, __len + 1); _M_destroy(_M_allocated_capacity); _M_data(__ptr); _M_capacity(__len); _M_set_length(__len); } } std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator()); } #endif return this->assign(__str); } /** * @brief Copy contents of @a s into this string. * @param __s Source null-terminated string. */ basic_string& operator=(const _CharT* __s) { return this->assign(__s); } /** * @brief Set value to string of length 1. * @param __c Source character. * * Assigning to a character makes this string length 1 and * (*this)[0] == @a c. */ basic_string& operator=(_CharT __c) { this->assign(1, __c); return *this; } #if __cplusplus >= 201103L /** * @brief Move assign the value of @a str to this string. * @param __str Source string. * * The contents of @a str are moved into this string (without copying). * @a str is a valid, but unspecified string. **/ // PR 58265, this should be noexcept. // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2063. Contradictory requirements for string move assignment basic_string& operator=(basic_string&& __str) noexcept(_Alloc_traits::_S_nothrow_move()) { if (!_M_is_local() && _Alloc_traits::_S_propagate_on_move_assign() && !_Alloc_traits::_S_always_equal() && _M_get_allocator() != __str._M_get_allocator()) { // Destroy existing storage before replacing allocator. _M_destroy(_M_allocated_capacity); _M_data(_M_local_data()); _M_set_length(0); } // Replace allocator if POCMA is true. std::__alloc_on_move(_M_get_allocator(), __str._M_get_allocator()); if (__str._M_is_local()) { // We've always got room for a short string, just copy it. if (__str.size()) this->_S_copy(_M_data(), __str._M_data(), __str.size()); _M_set_length(__str.size()); } else if (_Alloc_traits::_S_propagate_on_move_assign() || _Alloc_traits::_S_always_equal() || _M_get_allocator() == __str._M_get_allocator()) { // Just move the allocated pointer, our allocator can free it. pointer __data = nullptr; size_type __capacity; if (!_M_is_local()) { if (_Alloc_traits::_S_always_equal()) { // __str can reuse our existing storage. __data = _M_data(); __capacity = _M_allocated_capacity; } else // __str can't use it, so free it. _M_destroy(_M_allocated_capacity); } _M_data(__str._M_data()); _M_length(__str.length()); _M_capacity(__str._M_allocated_capacity); if (__data) { __str._M_data(__data); __str._M_capacity(__capacity); } else __str._M_data(__str._M_local_buf); } else // Need to do a deep copy assign(__str); __str.clear(); return *this; } /** * @brief Set value to string constructed from initializer %list. * @param __l std::initializer_list. */ basic_string& operator=(initializer_list<_CharT> __l) { this->assign(__l.begin(), __l.size()); return *this; } #endif // C++11 #if __cplusplus > 201402L /** * @brief Set value to string constructed from a string_view. * @param __svt An object convertible to string_view. */ template<typename _Tp> _If_sv<_Tp, basic_string&> operator=(const _Tp& __svt) { return this->assign(__svt); } /** * @brief Convert to a string_view. * @return A string_view. */ operator __sv_type() const noexcept { return __sv_type(data(), size()); } #endif // C++17 // Iterators: /** * Returns a read/write iterator that points to the first character in * the %string. */ iterator begin() _GLIBCXX_NOEXCEPT { return iterator(_M_data()); } /** * Returns a read-only (constant) iterator that points to the first * character in the %string. */ const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_M_data()); } /** * Returns a read/write iterator that points one past the last * character in the %string. */ iterator end() _GLIBCXX_NOEXCEPT { return iterator(_M_data() + this->size()); } /** * Returns a read-only (constant) iterator that points one past the * last character in the %string. */ const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_M_data() + this->size()); } /** * Returns a read/write reverse iterator that points to the last * character in the %string. Iteration is done in reverse element * order. */ reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return reverse_iterator(this->end()); } /** * Returns a read-only (constant) reverse iterator that points * to the last character in the %string. Iteration is done in * reverse element order. */ const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(this->end()); } /** * Returns a read/write reverse iterator that points to one before the * first character in the %string. Iteration is done in reverse * element order. */ reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(this->begin()); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first character in the %string. Iteration * is done in reverse element order. */ const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(this->begin()); } #if __cplusplus >= 201103L /** * Returns a read-only (constant) iterator that points to the first * character in the %string. */ const_iterator cbegin() const noexcept { return const_iterator(this->_M_data()); } /** * Returns a read-only (constant) iterator that points one past the * last character in the %string. */ const_iterator cend() const noexcept { return const_iterator(this->_M_data() + this->size()); } /** * Returns a read-only (constant) reverse iterator that points * to the last character in the %string. Iteration is done in * reverse element order. */ const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(this->end()); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first character in the %string. Iteration * is done in reverse element order. */ const_reverse_iterator crend() const noexcept { return const_reverse_iterator(this->begin()); } #endif public: // Capacity: /// Returns the number of characters in the string, not including any /// null-termination. size_type size() const _GLIBCXX_NOEXCEPT { return _M_string_length; } /// Returns the number of characters in the string, not including any /// null-termination. size_type length() const _GLIBCXX_NOEXCEPT { return _M_string_length; } /// Returns the size() of the largest possible %string. size_type max_size() const _GLIBCXX_NOEXCEPT { return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; } /** * @brief Resizes the %string to the specified number of characters. * @param __n Number of characters the %string should contain. * @param __c Character to fill any new elements. * * This function will %resize the %string to the specified * number of characters. If the number is smaller than the * %string's current size the %string is truncated, otherwise * the %string is extended and new elements are %set to @a __c. */ void resize(size_type __n, _CharT __c); /** * @brief Resizes the %string to the specified number of characters. * @param __n Number of characters the %string should contain. * * This function will resize the %string to the specified length. If * the new size is smaller than the %string's current size the %string * is truncated, otherwise the %string is extended and new characters * are default-constructed. For basic types such as char, this means * setting them to 0. */ void resize(size_type __n) { this->resize(__n, _CharT()); } #if __cplusplus >= 201103L /// A non-binding request to reduce capacity() to size(). void shrink_to_fit() noexcept { #if __cpp_exceptions if (capacity() > size()) { try { reserve(0); } catch(...) { } } #endif } #endif /** * Returns the total number of characters that the %string can hold * before needing to allocate more memory. */ size_type capacity() const _GLIBCXX_NOEXCEPT { return _M_is_local() ? size_type(_S_local_capacity) : _M_allocated_capacity; } /** * @brief Attempt to preallocate enough memory for specified number of * characters. * @param __res_arg Number of characters required. * @throw std::length_error If @a __res_arg exceeds @c max_size(). * * This function attempts to reserve enough memory for the * %string to hold the specified number of characters. If the * number requested is more than max_size(), length_error is * thrown. * * The advantage of this function is that if optimal code is a * necessity and the user can determine the string length that will be * required, the user can reserve the memory in %advance, and thus * prevent a possible reallocation of memory and copying of %string * data. */ void reserve(size_type __res_arg = 0); /** * Erases the string, making it empty. */ void clear() _GLIBCXX_NOEXCEPT { _M_set_length(0); } /** * Returns true if the %string is empty. Equivalent to * <code>*this == ""</code>. */ bool empty() const _GLIBCXX_NOEXCEPT { return this->size() == 0; } // Element access: /** * @brief Subscript access to the data contained in the %string. * @param __pos The index of the character to access. * @return Read-only (constant) reference to the character. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ const_reference operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT { __glibcxx_assert(__pos <= size()); return _M_data()[__pos]; } /** * @brief Subscript access to the data contained in the %string. * @param __pos The index of the character to access. * @return Read/write reference to the character. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ reference operator[](size_type __pos) { // Allow pos == size() both in C++98 mode, as v3 extension, // and in C++11 mode. __glibcxx_assert(__pos <= size()); // In pedantic mode be strict in C++98 mode. _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size()); return _M_data()[__pos]; } /** * @brief Provides access to the data contained in the %string. * @param __n The index of the character to access. * @return Read-only (const) reference to the character. * @throw std::out_of_range If @a n is an invalid index. * * This function provides for safer data access. The parameter is * first checked that it is in the range of the string. The function * throws out_of_range if the check fails. */ const_reference at(size_type __n) const { if (__n >= this->size()) __throw_out_of_range_fmt(__N("basic_string::at: __n " "(which is %zu) >= this->size() " "(which is %zu)"), __n, this->size()); return _M_data()[__n]; } /** * @brief Provides access to the data contained in the %string. * @param __n The index of the character to access. * @return Read/write reference to the character. * @throw std::out_of_range If @a n is an invalid index. * * This function provides for safer data access. The parameter is * first checked that it is in the range of the string. The function * throws out_of_range if the check fails. */ reference at(size_type __n) { if (__n >= size()) __throw_out_of_range_fmt(__N("basic_string::at: __n " "(which is %zu) >= this->size() " "(which is %zu)"), __n, this->size()); return _M_data()[__n]; } #if __cplusplus >= 201103L /** * Returns a read/write reference to the data at the first * element of the %string. */ reference front() noexcept { __glibcxx_assert(!empty()); return operator[](0); } /** * Returns a read-only (constant) reference to the data at the first * element of the %string. */ const_reference front() const noexcept { __glibcxx_assert(!empty()); return operator[](0); } /** * Returns a read/write reference to the data at the last * element of the %string. */ reference back() noexcept { __glibcxx_assert(!empty()); return operator[](this->size() - 1); } /** * Returns a read-only (constant) reference to the data at the * last element of the %string. */ const_reference back() const noexcept { __glibcxx_assert(!empty()); return operator[](this->size() - 1); } #endif // Modifiers: /** * @brief Append a string to this string. * @param __str The string to append. * @return Reference to this string. */ basic_string& operator+=(const basic_string& __str) { return this->append(__str); } /** * @brief Append a C string. * @param __s The C string to append. * @return Reference to this string. */ basic_string& operator+=(const _CharT* __s) { return this->append(__s); } /** * @brief Append a character. * @param __c The character to append. * @return Reference to this string. */ basic_string& operator+=(_CharT __c) { this->push_back(__c); return *this; } #if __cplusplus >= 201103L /** * @brief Append an initializer_list of characters. * @param __l The initializer_list of characters to be appended. * @return Reference to this string. */ basic_string& operator+=(initializer_list<_CharT> __l) { return this->append(__l.begin(), __l.size()); } #endif // C++11 #if __cplusplus > 201402L /** * @brief Append a string_view. * @param __svt An object convertible to string_view to be appended. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> operator+=(const _Tp& __svt) { return this->append(__svt); } #endif // C++17 /** * @brief Append a string to this string. * @param __str The string to append. * @return Reference to this string. */ basic_string& append(const basic_string& __str) { return _M_append(__str._M_data(), __str.size()); } /** * @brief Append a substring. * @param __str The string to append. * @param __pos Index of the first character of str to append. * @param __n The number of characters to append. * @return Reference to this string. * @throw std::out_of_range if @a __pos is not a valid index. * * This function appends @a __n characters from @a __str * starting at @a __pos to this string. If @a __n is is larger * than the number of available characters in @a __str, the * remainder of @a __str is appended. */ basic_string& append(const basic_string& __str, size_type __pos, size_type __n = npos) { return _M_append(__str._M_data() + __str._M_check(__pos, "basic_string::append"), __str._M_limit(__pos, __n)); } /** * @brief Append a C substring. * @param __s The C string to append. * @param __n The number of characters to append. * @return Reference to this string. */ basic_string& append(const _CharT* __s, size_type __n) { __glibcxx_requires_string_len(__s, __n); _M_check_length(size_type(0), __n, "basic_string::append"); return _M_append(__s, __n); } /** * @brief Append a C string. * @param __s The C string to append. * @return Reference to this string. */ basic_string& append(const _CharT* __s) { __glibcxx_requires_string(__s); const size_type __n = traits_type::length(__s); _M_check_length(size_type(0), __n, "basic_string::append"); return _M_append(__s, __n); } /** * @brief Append multiple characters. * @param __n The number of characters to append. * @param __c The character to use. * @return Reference to this string. * * Appends __n copies of __c to this string. */ basic_string& append(size_type __n, _CharT __c) { return _M_replace_aux(this->size(), size_type(0), __n, __c); } #if __cplusplus >= 201103L /** * @brief Append an initializer_list of characters. * @param __l The initializer_list of characters to append. * @return Reference to this string. */ basic_string& append(initializer_list<_CharT> __l) { return this->append(__l.begin(), __l.size()); } #endif // C++11 /** * @brief Append a range of characters. * @param __first Iterator referencing the first character to append. * @param __last Iterator marking the end of the range. * @return Reference to this string. * * Appends characters in the range [__first,__last) to this string. */ #if __cplusplus >= 201103L template<class _InputIterator, typename = std::_RequireInputIter<_InputIterator>> #else template<class _InputIterator> #endif basic_string& append(_InputIterator __first, _InputIterator __last) { return this->replace(end(), end(), __first, __last); } #if __cplusplus > 201402L /** * @brief Append a string_view. * @param __svt An object convertible to string_view to be appended. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> append(const _Tp& __svt) { __sv_type __sv = __svt; return this->append(__sv.data(), __sv.size()); } /** * @brief Append a range of characters from a string_view. * @param __svt An object convertible to string_view to be appended from. * @param __pos The position in the string_view to append from. * @param __n The number of characters to append from the string_view. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> append(const _Tp& __svt, size_type __pos, size_type __n = npos) { __sv_type __sv = __svt; return _M_append(__sv.data() + __sv._M_check(__pos, "basic_string::append"), __sv._M_limit(__pos, __n)); } #endif // C++17 /** * @brief Append a single character. * @param __c Character to append. */ void push_back(_CharT __c) { const size_type __size = this->size(); if (__size + 1 > this->capacity()) this->_M_mutate(__size, size_type(0), 0, size_type(1)); traits_type::assign(this->_M_data()[__size], __c); this->_M_set_length(__size + 1); } /** * @brief Set value to contents of another string. * @param __str Source string to use. * @return Reference to this string. */ basic_string& assign(const basic_string& __str) { this->_M_assign(__str); return *this; } #if __cplusplus >= 201103L /** * @brief Set value to contents of another string. * @param __str Source string to use. * @return Reference to this string. * * This function sets this string to the exact contents of @a __str. * @a __str is a valid, but unspecified string. */ basic_string& assign(basic_string&& __str) noexcept(_Alloc_traits::_S_nothrow_move()) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2063. Contradictory requirements for string move assignment return *this = std::move(__str); } #endif // C++11 /** * @brief Set value to a substring of a string. * @param __str The string to use. * @param __pos Index of the first character of str. * @param __n Number of characters to use. * @return Reference to this string. * @throw std::out_of_range if @a pos is not a valid index. * * This function sets this string to the substring of @a __str * consisting of @a __n characters at @a __pos. If @a __n is * is larger than the number of available characters in @a * __str, the remainder of @a __str is used. */ basic_string& assign(const basic_string& __str, size_type __pos, size_type __n = npos) { return _M_replace(size_type(0), this->size(), __str._M_data() + __str._M_check(__pos, "basic_string::assign"), __str._M_limit(__pos, __n)); } /** * @brief Set value to a C substring. * @param __s The C string to use. * @param __n Number of characters to use. * @return Reference to this string. * * This function sets the value of this string to the first @a __n * characters of @a __s. If @a __n is is larger than the number of * available characters in @a __s, the remainder of @a __s is used. */ basic_string& assign(const _CharT* __s, size_type __n) { __glibcxx_requires_string_len(__s, __n); return _M_replace(size_type(0), this->size(), __s, __n); } /** * @brief Set value to contents of a C string. * @param __s The C string to use. * @return Reference to this string. * * This function sets the value of this string to the value of @a __s. * The data is copied, so there is no dependence on @a __s once the * function returns. */ basic_string& assign(const _CharT* __s) { __glibcxx_requires_string(__s); return _M_replace(size_type(0), this->size(), __s, traits_type::length(__s)); } /** * @brief Set value to multiple characters. * @param __n Length of the resulting string. * @param __c The character to use. * @return Reference to this string. * * This function sets the value of this string to @a __n copies of * character @a __c. */ basic_string& assign(size_type __n, _CharT __c) { return _M_replace_aux(size_type(0), this->size(), __n, __c); } /** * @brief Set value to a range of characters. * @param __first Iterator referencing the first character to append. * @param __last Iterator marking the end of the range. * @return Reference to this string. * * Sets value of string to characters in the range [__first,__last). */ #if __cplusplus >= 201103L template<class _InputIterator, typename = std::_RequireInputIter<_InputIterator>> #else template<class _InputIterator> #endif basic_string& assign(_InputIterator __first, _InputIterator __last) { return this->replace(begin(), end(), __first, __last); } #if __cplusplus >= 201103L /** * @brief Set value to an initializer_list of characters. * @param __l The initializer_list of characters to assign. * @return Reference to this string. */ basic_string& assign(initializer_list<_CharT> __l) { return this->assign(__l.begin(), __l.size()); } #endif // C++11 #if __cplusplus > 201402L /** * @brief Set value from a string_view. * @param __svt The source object convertible to string_view. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> assign(const _Tp& __svt) { __sv_type __sv = __svt; return this->assign(__sv.data(), __sv.size()); } /** * @brief Set value from a range of characters in a string_view. * @param __svt The source object convertible to string_view. * @param __pos The position in the string_view to assign from. * @param __n The number of characters to assign. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> assign(const _Tp& __svt, size_type __pos, size_type __n = npos) { __sv_type __sv = __svt; return _M_replace(size_type(0), this->size(), __sv.data() + __sv._M_check(__pos, "basic_string::assign"), __sv._M_limit(__pos, __n)); } #endif // C++17 #if __cplusplus >= 201103L /** * @brief Insert multiple characters. * @param __p Const_iterator referencing location in string to * insert at. * @param __n Number of characters to insert * @param __c The character to insert. * @return Iterator referencing the first inserted char. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts @a __n copies of character @a __c starting at the * position referenced by iterator @a __p. If adding * characters causes the length to exceed max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ iterator insert(const_iterator __p, size_type __n, _CharT __c) { _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); const size_type __pos = __p - begin(); this->replace(__p, __p, __n, __c); return iterator(this->_M_data() + __pos); } #else /** * @brief Insert multiple characters. * @param __p Iterator referencing location in string to insert at. * @param __n Number of characters to insert * @param __c The character to insert. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts @a __n copies of character @a __c starting at the * position referenced by iterator @a __p. If adding * characters causes the length to exceed max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ void insert(iterator __p, size_type __n, _CharT __c) { this->replace(__p, __p, __n, __c); } #endif #if __cplusplus >= 201103L /** * @brief Insert a range of characters. * @param __p Const_iterator referencing location in string to * insert at. * @param __beg Start of range. * @param __end End of range. * @return Iterator referencing the first inserted char. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts characters in range [beg,end). If adding characters * causes the length to exceed max_size(), length_error is * thrown. The value of the string doesn't change if an error * is thrown. */ template<class _InputIterator, typename = std::_RequireInputIter<_InputIterator>> iterator insert(const_iterator __p, _InputIterator __beg, _InputIterator __end) { _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); const size_type __pos = __p - begin(); this->replace(__p, __p, __beg, __end); return iterator(this->_M_data() + __pos); } #else /** * @brief Insert a range of characters. * @param __p Iterator referencing location in string to insert at. * @param __beg Start of range. * @param __end End of range. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts characters in range [__beg,__end). If adding * characters causes the length to exceed max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ template<class _InputIterator> void insert(iterator __p, _InputIterator __beg, _InputIterator __end) { this->replace(__p, __p, __beg, __end); } #endif #if __cplusplus >= 201103L /** * @brief Insert an initializer_list of characters. * @param __p Iterator referencing location in string to insert at. * @param __l The initializer_list of characters to insert. * @throw std::length_error If new length exceeds @c max_size(). */ void insert(iterator __p, initializer_list<_CharT> __l) { _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); this->insert(__p - begin(), __l.begin(), __l.size()); } #endif // C++11 /** * @brief Insert value of a string. * @param __pos1 Iterator referencing location in string to insert at. * @param __str The string to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts value of @a __str starting at @a __pos1. If adding * characters causes the length to exceed max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ basic_string& insert(size_type __pos1, const basic_string& __str) { return this->replace(__pos1, size_type(0), __str._M_data(), __str.size()); } /** * @brief Insert a substring. * @param __pos1 Iterator referencing location in string to insert at. * @param __str The string to insert. * @param __pos2 Start of characters in str to insert. * @param __n Number of characters to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a pos1 > size() or * @a __pos2 > @a str.size(). * * Starting at @a pos1, insert @a __n character of @a __str * beginning with @a __pos2. If adding characters causes the * length to exceed max_size(), length_error is thrown. If @a * __pos1 is beyond the end of this string or @a __pos2 is * beyond the end of @a __str, out_of_range is thrown. The * value of the string doesn't change if an error is thrown. */ basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos) { return this->replace(__pos1, size_type(0), __str._M_data() + __str._M_check(__pos2, "basic_string::insert"), __str._M_limit(__pos2, __n)); } /** * @brief Insert a C substring. * @param __pos Iterator referencing location in string to insert at. * @param __s The C string to insert. * @param __n The number of characters to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a __pos is beyond the end of this * string. * * Inserts the first @a __n characters of @a __s starting at @a * __pos. If adding characters causes the length to exceed * max_size(), length_error is thrown. If @a __pos is beyond * end(), out_of_range is thrown. The value of the string * doesn't change if an error is thrown. */ basic_string& insert(size_type __pos, const _CharT* __s, size_type __n) { return this->replace(__pos, size_type(0), __s, __n); } /** * @brief Insert a C string. * @param __pos Iterator referencing location in string to insert at. * @param __s The C string to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a pos is beyond the end of this * string. * * Inserts the first @a n characters of @a __s starting at @a __pos. If * adding characters causes the length to exceed max_size(), * length_error is thrown. If @a __pos is beyond end(), out_of_range is * thrown. The value of the string doesn't change if an error is * thrown. */ basic_string& insert(size_type __pos, const _CharT* __s) { __glibcxx_requires_string(__s); return this->replace(__pos, size_type(0), __s, traits_type::length(__s)); } /** * @brief Insert multiple characters. * @param __pos Index in string to insert at. * @param __n Number of characters to insert * @param __c The character to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a __pos is beyond the end of this * string. * * Inserts @a __n copies of character @a __c starting at index * @a __pos. If adding characters causes the length to exceed * max_size(), length_error is thrown. If @a __pos > length(), * out_of_range is thrown. The value of the string doesn't * change if an error is thrown. */ basic_string& insert(size_type __pos, size_type __n, _CharT __c) { return _M_replace_aux(_M_check(__pos, "basic_string::insert"), size_type(0), __n, __c); } /** * @brief Insert one character. * @param __p Iterator referencing position in string to insert at. * @param __c The character to insert. * @return Iterator referencing newly inserted char. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts character @a __c at position referenced by @a __p. * If adding character causes the length to exceed max_size(), * length_error is thrown. If @a __p is beyond end of string, * out_of_range is thrown. The value of the string doesn't * change if an error is thrown. */ iterator insert(__const_iterator __p, _CharT __c) { _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); const size_type __pos = __p - begin(); _M_replace_aux(__pos, size_type(0), size_type(1), __c); return iterator(_M_data() + __pos); } #if __cplusplus > 201402L /** * @brief Insert a string_view. * @param __pos Iterator referencing position in string to insert at. * @param __svt The object convertible to string_view to insert. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> insert(size_type __pos, const _Tp& __svt) { __sv_type __sv = __svt; return this->insert(__pos, __sv.data(), __sv.size()); } /** * @brief Insert a string_view. * @param __pos Iterator referencing position in string to insert at. * @param __svt The object convertible to string_view to insert from. * @param __pos Iterator referencing position in string_view to insert * from. * @param __n The number of characters to insert. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> insert(size_type __pos1, const _Tp& __svt, size_type __pos2, size_type __n = npos) { __sv_type __sv = __svt; return this->replace(__pos1, size_type(0), __sv.data() + __sv._M_check(__pos2, "basic_string::insert"), __sv._M_limit(__pos2, __n)); } #endif // C++17 /** * @brief Remove characters. * @param __pos Index of first character to remove (default 0). * @param __n Number of characters to remove (default remainder). * @return Reference to this string. * @throw std::out_of_range If @a pos is beyond the end of this * string. * * Removes @a __n characters from this string starting at @a * __pos. The length of the string is reduced by @a __n. If * there are < @a __n characters to remove, the remainder of * the string is truncated. If @a __p is beyond end of string, * out_of_range is thrown. The value of the string doesn't * change if an error is thrown. */ basic_string& erase(size_type __pos = 0, size_type __n = npos) { _M_check(__pos, "basic_string::erase"); if (__n == npos) this->_M_set_length(__pos); else if (__n != 0) this->_M_erase(__pos, _M_limit(__pos, __n)); return *this; } /** * @brief Remove one character. * @param __position Iterator referencing the character to remove. * @return iterator referencing same location after removal. * * Removes the character at @a __position from this string. The value * of the string doesn't change if an error is thrown. */ iterator erase(__const_iterator __position) { _GLIBCXX_DEBUG_PEDASSERT(__position >= begin() && __position < end()); const size_type __pos = __position - begin(); this->_M_erase(__pos, size_type(1)); return iterator(_M_data() + __pos); } /** * @brief Remove a range of characters. * @param __first Iterator referencing the first character to remove. * @param __last Iterator referencing the end of the range. * @return Iterator referencing location of first after removal. * * Removes the characters in the range [first,last) from this string. * The value of the string doesn't change if an error is thrown. */ iterator erase(__const_iterator __first, __const_iterator __last) { _GLIBCXX_DEBUG_PEDASSERT(__first >= begin() && __first <= __last && __last <= end()); const size_type __pos = __first - begin(); if (__last == end()) this->_M_set_length(__pos); else this->_M_erase(__pos, __last - __first); return iterator(this->_M_data() + __pos); } #if __cplusplus >= 201103L /** * @brief Remove the last character. * * The string must be non-empty. */ void pop_back() noexcept { __glibcxx_assert(!empty()); _M_erase(size() - 1, 1); } #endif // C++11 /** * @brief Replace characters with value from another string. * @param __pos Index of first character to replace. * @param __n Number of characters to be replaced. * @param __str String to insert. * @return Reference to this string. * @throw std::out_of_range If @a pos is beyond the end of this * string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__pos,__pos+__n) from * this string. In place, the value of @a __str is inserted. * If @a __pos is beyond end of string, out_of_range is thrown. * If the length of the result exceeds max_size(), length_error * is thrown. The value of the string doesn't change if an * error is thrown. */ basic_string& replace(size_type __pos, size_type __n, const basic_string& __str) { return this->replace(__pos, __n, __str._M_data(), __str.size()); } /** * @brief Replace characters with value from another string. * @param __pos1 Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __str String to insert. * @param __pos2 Index of first character of str to use. * @param __n2 Number of characters from str to use. * @return Reference to this string. * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 > * __str.size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__pos1,__pos1 + n) from this * string. In place, the value of @a __str is inserted. If @a __pos is * beyond end of string, out_of_range is thrown. If the length of the * result exceeds max_size(), length_error is thrown. The value of the * string doesn't change if an error is thrown. */ basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) { return this->replace(__pos1, __n1, __str._M_data() + __str._M_check(__pos2, "basic_string::replace"), __str._M_limit(__pos2, __n2)); } /** * @brief Replace characters with value of a C substring. * @param __pos Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __s C string to insert. * @param __n2 Number of characters from @a s to use. * @return Reference to this string. * @throw std::out_of_range If @a pos1 > size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__pos,__pos + __n1) * from this string. In place, the first @a __n2 characters of * @a __s are inserted, or all of @a __s if @a __n2 is too large. If * @a __pos is beyond end of string, out_of_range is thrown. If * the length of result exceeds max_size(), length_error is * thrown. The value of the string doesn't change if an error * is thrown. */ basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) { __glibcxx_requires_string_len(__s, __n2); return _M_replace(_M_check(__pos, "basic_string::replace"), _M_limit(__pos, __n1), __s, __n2); } /** * @brief Replace characters with value of a C string. * @param __pos Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __s C string to insert. * @return Reference to this string. * @throw std::out_of_range If @a pos > size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__pos,__pos + __n1) * from this string. In place, the characters of @a __s are * inserted. If @a __pos is beyond end of string, out_of_range * is thrown. If the length of result exceeds max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s) { __glibcxx_requires_string(__s); return this->replace(__pos, __n1, __s, traits_type::length(__s)); } /** * @brief Replace characters with multiple characters. * @param __pos Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __n2 Number of characters to insert. * @param __c Character to insert. * @return Reference to this string. * @throw std::out_of_range If @a __pos > size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [pos,pos + n1) from this * string. In place, @a __n2 copies of @a __c are inserted. * If @a __pos is beyond end of string, out_of_range is thrown. * If the length of result exceeds max_size(), length_error is * thrown. The value of the string doesn't change if an error * is thrown. */ basic_string& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) { return _M_replace_aux(_M_check(__pos, "basic_string::replace"), _M_limit(__pos, __n1), __n2, __c); } /** * @brief Replace range of characters with string. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __str String value to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * the value of @a __str is inserted. If the length of result * exceeds max_size(), length_error is thrown. The value of * the string doesn't change if an error is thrown. */ basic_string& replace(__const_iterator __i1, __const_iterator __i2, const basic_string& __str) { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } /** * @brief Replace range of characters with C substring. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __s C string value to insert. * @param __n Number of characters from s to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * the first @a __n characters of @a __s are inserted. If the * length of result exceeds max_size(), length_error is thrown. * The value of the string doesn't change if an error is * thrown. */ basic_string& replace(__const_iterator __i1, __const_iterator __i2, const _CharT* __s, size_type __n) { _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 && __i2 <= end()); return this->replace(__i1 - begin(), __i2 - __i1, __s, __n); } /** * @brief Replace range of characters with C string. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __s C string value to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * the characters of @a __s are inserted. If the length of * result exceeds max_size(), length_error is thrown. The * value of the string doesn't change if an error is thrown. */ basic_string& replace(__const_iterator __i1, __const_iterator __i2, const _CharT* __s) { __glibcxx_requires_string(__s); return this->replace(__i1, __i2, __s, traits_type::length(__s)); } /** * @brief Replace range of characters with multiple characters * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __n Number of characters to insert. * @param __c Character to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * @a __n copies of @a __c are inserted. If the length of * result exceeds max_size(), length_error is thrown. The * value of the string doesn't change if an error is thrown. */ basic_string& replace(__const_iterator __i1, __const_iterator __i2, size_type __n, _CharT __c) { _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 && __i2 <= end()); return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __c); } /** * @brief Replace range of characters with range. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __k1 Iterator referencing start of range to insert. * @param __k2 Iterator referencing end of range to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * characters in the range [__k1,__k2) are inserted. If the * length of result exceeds max_size(), length_error is thrown. * The value of the string doesn't change if an error is * thrown. */ #if __cplusplus >= 201103L template<class _InputIterator, typename = std::_RequireInputIter<_InputIterator>> basic_string& replace(const_iterator __i1, const_iterator __i2, _InputIterator __k1, _InputIterator __k2) { _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 && __i2 <= end()); __glibcxx_requires_valid_range(__k1, __k2); return this->_M_replace_dispatch(__i1, __i2, __k1, __k2, std::__false_type()); } #else template<class _InputIterator> #ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST typename __enable_if_not_native_iterator<_InputIterator>::__type #else basic_string& #endif replace(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2) { _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 && __i2 <= end()); __glibcxx_requires_valid_range(__k1, __k2); typedef typename std::__is_integer<_InputIterator>::__type _Integral; return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); } #endif // Specializations for the common case of pointer and iterator: // useful to avoid the overhead of temporary buffering in _M_replace. basic_string& replace(__const_iterator __i1, __const_iterator __i2, _CharT* __k1, _CharT* __k2) { _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 && __i2 <= end()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - begin(), __i2 - __i1, __k1, __k2 - __k1); } basic_string& replace(__const_iterator __i1, __const_iterator __i2, const _CharT* __k1, const _CharT* __k2) { _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 && __i2 <= end()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - begin(), __i2 - __i1, __k1, __k2 - __k1); } basic_string& replace(__const_iterator __i1, __const_iterator __i2, iterator __k1, iterator __k2) { _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 && __i2 <= end()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - begin(), __i2 - __i1, __k1.base(), __k2 - __k1); } basic_string& replace(__const_iterator __i1, __const_iterator __i2, const_iterator __k1, const_iterator __k2) { _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 && __i2 <= end()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - begin(), __i2 - __i1, __k1.base(), __k2 - __k1); } #if __cplusplus >= 201103L /** * @brief Replace range of characters with initializer_list. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __l The initializer_list of characters to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * characters in the range [__k1,__k2) are inserted. If the * length of result exceeds max_size(), length_error is thrown. * The value of the string doesn't change if an error is * thrown. */ basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<_CharT> __l) { return this->replace(__i1, __i2, __l.begin(), __l.size()); } #endif // C++11 #if __cplusplus > 201402L /** * @brief Replace range of characters with string_view. * @param __pos The position to replace at. * @param __n The number of characters to replace. * @param __svt The object convertible to string_view to insert. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> replace(size_type __pos, size_type __n, const _Tp& __svt) { __sv_type __sv = __svt; return this->replace(__pos, __n, __sv.data(), __sv.size()); } /** * @brief Replace range of characters with string_view. * @param __pos1 The position to replace at. * @param __n1 The number of characters to replace. * @param __svt The object convertible to string_view to insert from. * @param __pos2 The position in the string_view to insert from. * @param __n2 The number of characters to insert. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> replace(size_type __pos1, size_type __n1, const _Tp& __svt, size_type __pos2, size_type __n2 = npos) { __sv_type __sv = __svt; return this->replace(__pos1, __n1, __sv.data() + __sv._M_check(__pos2, "basic_string::replace"), __sv._M_limit(__pos2, __n2)); } /** * @brief Replace range of characters with string_view. * @param __i1 An iterator referencing the start position to replace at. * @param __i2 An iterator referencing the end position for the replace. * @param __svt The object convertible to string_view to insert from. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt) { __sv_type __sv = __svt; return this->replace(__i1 - begin(), __i2 - __i1, __sv); } #endif // C++17 private: template<class _Integer> basic_string& _M_replace_dispatch(const_iterator __i1, const_iterator __i2, _Integer __n, _Integer __val, __true_type) { return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __val); } template<class _InputIterator> basic_string& _M_replace_dispatch(const_iterator __i1, const_iterator __i2, _InputIterator __k1, _InputIterator __k2, __false_type); basic_string& _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, _CharT __c); basic_string& _M_replace(size_type __pos, size_type __len1, const _CharT* __s, const size_type __len2); basic_string& _M_append(const _CharT* __s, size_type __n); public: /** * @brief Copy substring into C string. * @param __s C string to copy value into. * @param __n Number of characters to copy. * @param __pos Index of first character to copy. * @return Number of characters actually copied * @throw std::out_of_range If __pos > size(). * * Copies up to @a __n characters starting at @a __pos into the * C string @a __s. If @a __pos is %greater than size(), * out_of_range is thrown. */ size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const; /** * @brief Swap contents with another string. * @param __s String to swap with. * * Exchanges the contents of this string with that of @a __s in constant * time. */ void swap(basic_string& __s) _GLIBCXX_NOEXCEPT; // String operations: /** * @brief Return const pointer to null-terminated contents. * * This is a handle to internal data. Do not modify or dire things may * happen. */ const _CharT* c_str() const _GLIBCXX_NOEXCEPT { return _M_data(); } /** * @brief Return const pointer to contents. * * This is a pointer to internal data. It is undefined to modify * the contents through the returned pointer. To get a pointer that * allows modifying the contents use @c &str[0] instead, * (or in C++17 the non-const @c str.data() overload). */ const _CharT* data() const _GLIBCXX_NOEXCEPT { return _M_data(); } #if __cplusplus > 201402L /** * @brief Return non-const pointer to contents. * * This is a pointer to the character sequence held by the string. * Modifying the characters in the sequence is allowed. */ _CharT* data() noexcept { return _M_data(); } #endif /** * @brief Return copy of allocator used to construct this string. */ allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return _M_get_allocator(); } /** * @brief Find position of a C substring. * @param __s C string to locate. * @param __pos Index of character to search from. * @param __n Number of characters from @a s to search for. * @return Index of start of first occurrence. * * Starting from @a __pos, searches forward for the first @a * __n characters in @a __s within this string. If found, * returns the index where it begins. If not found, returns * npos. */ size_type find(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find position of a string. * @param __str String to locate. * @param __pos Index of character to search from (default 0). * @return Index of start of first occurrence. * * Starting from @a __pos, searches forward for value of @a __str within * this string. If found, returns the index where it begins. If not * found, returns npos. */ size_type find(const basic_string& __str, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find(__str.data(), __pos, __str.size()); } #if __cplusplus > 201402L /** * @brief Find position of a string_view. * @param __svt The object convertible to string_view to locate. * @param __pos Index of character to search from (default 0). * @return Index of start of first occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> find(const _Tp& __svt, size_type __pos = 0) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->find(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find position of a C string. * @param __s C string to locate. * @param __pos Index of character to search from (default 0). * @return Index of start of first occurrence. * * Starting from @a __pos, searches forward for the value of @a * __s within this string. If found, returns the index where * it begins. If not found, returns npos. */ size_type find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->find(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a character. * @param __c Character to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for @a __c within * this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT; /** * @brief Find last position of a string. * @param __str String to locate. * @param __pos Index of character to search back from (default end). * @return Index of start of last occurrence. * * Starting from @a __pos, searches backward for value of @a * __str within this string. If found, returns the index where * it begins. If not found, returns npos. */ size_type rfind(const basic_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->rfind(__str.data(), __pos, __str.size()); } #if __cplusplus > 201402L /** * @brief Find last position of a string_view. * @param __svt The object convertible to string_view to locate. * @param __pos Index of character to search back from (default end). * @return Index of start of last occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> rfind(const _Tp& __svt, size_type __pos = npos) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->rfind(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find last position of a C substring. * @param __s C string to locate. * @param __pos Index of character to search back from. * @param __n Number of characters from s to search for. * @return Index of start of last occurrence. * * Starting from @a __pos, searches backward for the first @a * __n characters in @a __s within this string. If found, * returns the index where it begins. If not found, returns * npos. */ size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find last position of a C string. * @param __s C string to locate. * @param __pos Index of character to start search at (default end). * @return Index of start of last occurrence. * * Starting from @a __pos, searches backward for the value of * @a __s within this string. If found, returns the index * where it begins. If not found, returns npos. */ size_type rfind(const _CharT* __s, size_type __pos = npos) const { __glibcxx_requires_string(__s); return this->rfind(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a character. * @param __c Character to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for @a __c within * this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT; /** * @brief Find position of a character of string. * @param __str String containing characters to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for one of the * characters of @a __str within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find_first_of(__str.data(), __pos, __str.size()); } #if __cplusplus > 201402L /** * @brief Find position of a character of a string_view. * @param __svt An object convertible to string_view containing * characters to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> find_first_of(const _Tp& __svt, size_type __pos = 0) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->find_first_of(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find position of a character of C substring. * @param __s String containing characters to locate. * @param __pos Index of character to search from. * @param __n Number of characters from s to search for. * @return Index of first occurrence. * * Starting from @a __pos, searches forward for one of the * first @a __n characters of @a __s within this string. If * found, returns the index where it was found. If not found, * returns npos. */ size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find position of a character of C string. * @param __s String containing characters to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for one of the * characters of @a __s within this string. If found, returns * the index where it was found. If not found, returns npos. */ size_type find_first_of(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->find_first_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a character. * @param __c Character to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for the character * @a __c within this string. If found, returns the index * where it was found. If not found, returns npos. * * Note: equivalent to find(__c, __pos). */ size_type find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find(__c, __pos); } /** * @brief Find last position of a character of string. * @param __str String containing characters to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for one of the * characters of @a __str within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->find_last_of(__str.data(), __pos, __str.size()); } #if __cplusplus > 201402L /** * @brief Find last position of a character of string. * @param __svt An object convertible to string_view containing * characters to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> find_last_of(const _Tp& __svt, size_type __pos = npos) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->find_last_of(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find last position of a character of C substring. * @param __s C string containing characters to locate. * @param __pos Index of character to search back from. * @param __n Number of characters from s to search for. * @return Index of last occurrence. * * Starting from @a __pos, searches backward for one of the * first @a __n characters of @a __s within this string. If * found, returns the index where it was found. If not found, * returns npos. */ size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find last position of a character of C string. * @param __s C string containing characters to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for one of the * characters of @a __s within this string. If found, returns * the index where it was found. If not found, returns npos. */ size_type find_last_of(const _CharT* __s, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->find_last_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a character. * @param __c Character to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for @a __c within * this string. If found, returns the index where it was * found. If not found, returns npos. * * Note: equivalent to rfind(__c, __pos). */ size_type find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->rfind(__c, __pos); } /** * @brief Find position of a character not in string. * @param __str String containing characters to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character not contained * in @a __str within this string. If found, returns the index where it * was found. If not found, returns npos. */ size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find_first_not_of(__str.data(), __pos, __str.size()); } #if __cplusplus > 201402L /** * @brief Find position of a character not in a string_view. * @param __svt A object convertible to string_view containing * characters to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> find_first_not_of(const _Tp& __svt, size_type __pos = 0) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->find_first_not_of(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find position of a character not in C substring. * @param __s C string containing characters to avoid. * @param __pos Index of character to search from. * @param __n Number of characters from __s to consider. * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character not * contained in the first @a __n characters of @a __s within * this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find position of a character not in C string. * @param __s C string containing characters to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character not * contained in @a __s within this string. If found, returns * the index where it was found. If not found, returns npos. */ size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->find_first_not_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a different character. * @param __c Character to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character * other than @a __c within this string. If found, returns the * index where it was found. If not found, returns npos. */ size_type find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT; /** * @brief Find last position of a character not in string. * @param __str String containing characters to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character * not contained in @a __str within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->find_last_not_of(__str.data(), __pos, __str.size()); } #if __cplusplus > 201402L /** * @brief Find last position of a character not in a string_view. * @param __svt An object convertible to string_view containing * characters to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> find_last_not_of(const _Tp& __svt, size_type __pos = npos) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->find_last_not_of(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find last position of a character not in C substring. * @param __s C string containing characters to avoid. * @param __pos Index of character to search back from. * @param __n Number of characters from s to consider. * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character not * contained in the first @a __n characters of @a __s within this string. * If found, returns the index where it was found. If not found, * returns npos. */ size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find last position of a character not in C string. * @param __s C string containing characters to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character * not contained in @a __s within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->find_last_not_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a different character. * @param __c Character to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character other than * @a __c within this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type find_last_not_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT; /** * @brief Get a substring. * @param __pos Index of first character (default 0). * @param __n Number of characters in substring (default remainder). * @return The new string. * @throw std::out_of_range If __pos > size(). * * Construct and return a new string using the @a __n * characters starting at @a __pos. If the string is too * short, use the remainder of the characters. If @a __pos is * beyond the end of the string, out_of_range is thrown. */ basic_string substr(size_type __pos = 0, size_type __n = npos) const { return basic_string(*this, _M_check(__pos, "basic_string::substr"), __n); } /** * @brief Compare to a string. * @param __str String to compare against. * @return Integer < 0, 0, or > 0. * * Returns an integer < 0 if this string is ordered before @a * __str, 0 if their values are equivalent, or > 0 if this * string is ordered after @a __str. Determines the effective * length rlen of the strings to compare as the smallest of * size() and str.size(). The function then compares the two * strings by calling traits::compare(data(), str.data(),rlen). * If the result of the comparison is nonzero returns it, * otherwise the shorter one is ordered first. */ int compare(const basic_string& __str) const { const size_type __size = this->size(); const size_type __osize = __str.size(); const size_type __len = std::min(__size, __osize); int __r = traits_type::compare(_M_data(), __str.data(), __len); if (!__r) __r = _S_compare(__size, __osize); return __r; } #if __cplusplus > 201402L /** * @brief Compare to a string_view. * @param __svt An object convertible to string_view to compare against. * @return Integer < 0, 0, or > 0. */ template<typename _Tp> _If_sv<_Tp, int> compare(const _Tp& __svt) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; const size_type __size = this->size(); const size_type __osize = __sv.size(); const size_type __len = std::min(__size, __osize); int __r = traits_type::compare(_M_data(), __sv.data(), __len); if (!__r) __r = _S_compare(__size, __osize); return __r; } /** * @brief Compare to a string_view. * @param __pos A position in the string to start comparing from. * @param __n The number of characters to compare. * @param __svt An object convertible to string_view to compare * against. * @return Integer < 0, 0, or > 0. */ template<typename _Tp> _If_sv<_Tp, int> compare(size_type __pos, size_type __n, const _Tp& __svt) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return __sv_type(*this).substr(__pos, __n).compare(__sv); } /** * @brief Compare to a string_view. * @param __pos1 A position in the string to start comparing from. * @param __n1 The number of characters to compare. * @param __svt An object convertible to string_view to compare * against. * @param __pos2 A position in the string_view to start comparing from. * @param __n2 The number of characters to compare. * @return Integer < 0, 0, or > 0. */ template<typename _Tp> _If_sv<_Tp, int> compare(size_type __pos1, size_type __n1, const _Tp& __svt, size_type __pos2, size_type __n2 = npos) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return __sv_type(*this) .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); } #endif // C++17 /** * @brief Compare substring to a string. * @param __pos Index of first character of substring. * @param __n Number of characters in substring. * @param __str String to compare against. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n characters * starting at @a __pos. Returns an integer < 0 if the * substring is ordered before @a __str, 0 if their values are * equivalent, or > 0 if the substring is ordered after @a * __str. Determines the effective length rlen of the strings * to compare as the smallest of the length of the substring * and @a __str.size(). The function then compares the two * strings by calling * traits::compare(substring.data(),str.data(),rlen). If the * result of the comparison is nonzero returns it, otherwise * the shorter one is ordered first. */ int compare(size_type __pos, size_type __n, const basic_string& __str) const; /** * @brief Compare substring to a substring. * @param __pos1 Index of first character of substring. * @param __n1 Number of characters in substring. * @param __str String to compare against. * @param __pos2 Index of first character of substring of str. * @param __n2 Number of characters in substring of str. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n1 * characters starting at @a __pos1. Form the substring of @a * __str from the @a __n2 characters starting at @a __pos2. * Returns an integer < 0 if this substring is ordered before * the substring of @a __str, 0 if their values are equivalent, * or > 0 if this substring is ordered after the substring of * @a __str. Determines the effective length rlen of the * strings to compare as the smallest of the lengths of the * substrings. The function then compares the two strings by * calling * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). * If the result of the comparison is nonzero returns it, * otherwise the shorter one is ordered first. */ int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) const; /** * @brief Compare to a C string. * @param __s C string to compare against. * @return Integer < 0, 0, or > 0. * * Returns an integer < 0 if this string is ordered before @a __s, 0 if * their values are equivalent, or > 0 if this string is ordered after * @a __s. Determines the effective length rlen of the strings to * compare as the smallest of size() and the length of a string * constructed from @a __s. The function then compares the two strings * by calling traits::compare(data(),s,rlen). If the result of the * comparison is nonzero returns it, otherwise the shorter one is * ordered first. */ int compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 5 String::compare specification questionable /** * @brief Compare substring to a C string. * @param __pos Index of first character of substring. * @param __n1 Number of characters in substring. * @param __s C string to compare against. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n1 * characters starting at @a pos. Returns an integer < 0 if * the substring is ordered before @a __s, 0 if their values * are equivalent, or > 0 if the substring is ordered after @a * __s. Determines the effective length rlen of the strings to * compare as the smallest of the length of the substring and * the length of a string constructed from @a __s. The * function then compares the two string by calling * traits::compare(substring.data(),__s,rlen). If the result of * the comparison is nonzero returns it, otherwise the shorter * one is ordered first. */ int compare(size_type __pos, size_type __n1, const _CharT* __s) const; /** * @brief Compare substring against a character %array. * @param __pos Index of first character of substring. * @param __n1 Number of characters in substring. * @param __s character %array to compare against. * @param __n2 Number of characters of s. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n1 * characters starting at @a __pos. Form a string from the * first @a __n2 characters of @a __s. Returns an integer < 0 * if this substring is ordered before the string from @a __s, * 0 if their values are equivalent, or > 0 if this substring * is ordered after the string from @a __s. Determines the * effective length rlen of the strings to compare as the * smallest of the length of the substring and @a __n2. The * function then compares the two strings by calling * traits::compare(substring.data(),s,rlen). If the result of * the comparison is nonzero returns it, otherwise the shorter * one is ordered first. * * NB: s must have at least n2 characters, '\\0' has * no special meaning. */ int compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const; // Allow basic_stringbuf::__xfer_bufptrs to call _M_length: template<typename, typename, typename> friend class basic_stringbuf; }; _GLIBCXX_END_NAMESPACE_CXX11 #else // !_GLIBCXX_USE_CXX11_ABI // Reference-counted COW string implentation /** * @class basic_string basic_string.h <string> * @brief Managing sequences of characters and character-like objects. * * @ingroup strings * @ingroup sequences * * @tparam _CharT Type of character * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. * * 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>. Of the * <a href="tables.html#68">optional sequence requirements</a>, only * @c push_back, @c at, and @c %array access are supported. * * @doctodo * * * Documentation? What's that? * Nathan Myers <ncm@cantrip.org>. * * A string looks like this: * * @code * [_Rep] * _M_length * [basic_string<char_type>] _M_capacity * _M_dataplus _M_refcount * _M_p ----------------> unnamed array of char_type * @endcode * * Where the _M_p points to the first character in the string, and * you cast it to a pointer-to-_Rep and subtract 1 to get a * pointer to the header. * * This approach has the enormous advantage that a string object * requires only one allocation. All the ugliness is confined * within a single %pair of inline functions, which each compile to * a single @a add instruction: _Rep::_M_data(), and * string::_M_rep(); and the allocation function which gets a * block of raw bytes and with room enough and constructs a _Rep * object at the front. * * The reason you want _M_data pointing to the character %array and * not the _Rep is so that the debugger can see the string * contents. (Probably we should add a non-inline member to get * the _Rep for the debugger to use, so users can check the actual * string length.) * * Note that the _Rep object is a POD so that you can have a * static <em>empty string</em> _Rep object already @a constructed before * static constructors have run. The reference-count encoding is * chosen so that a 0 indicates one reference, so you never try to * destroy the empty-string _Rep object. * * All but the last paragraph is considered pretty conventional * for a C++ string implementation. */ // 21.3 Template class basic_string template<typename _CharT, typename _Traits, typename _Alloc> class basic_string { typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; // Types: public: typedef _Traits traits_type; typedef typename _Traits::char_type value_type; typedef _Alloc allocator_type; typedef typename _CharT_alloc_type::size_type size_type; typedef typename _CharT_alloc_type::difference_type difference_type; typedef typename _CharT_alloc_type::reference reference; typedef typename _CharT_alloc_type::const_reference const_reference; typedef typename _CharT_alloc_type::pointer pointer; typedef typename _CharT_alloc_type::const_pointer const_pointer; typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator; typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string> const_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; private: // _Rep: string representation // Invariants: // 1. String really contains _M_length + 1 characters: due to 21.3.4 // must be kept null-terminated. // 2. _M_capacity >= _M_length // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT). // 3. _M_refcount has three states: // -1: leaked, one reference, no ref-copies allowed, non-const. // 0: one reference, non-const. // n>0: n + 1 references, operations require a lock, const. // 4. All fields==0 is an empty string, given the extra storage // beyond-the-end for a null terminator; thus, the shared // empty string representation needs no constructor. struct _Rep_base { size_type _M_length; size_type _M_capacity; _Atomic_word _M_refcount; }; struct _Rep : _Rep_base { // Types: typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc; // (Public) Data members: // The maximum number of individual char_type elements of an // individual string is determined by _S_max_size. This is the // value that will be returned by max_size(). (Whereas npos // is the maximum number of bytes the allocator can allocate.) // If one was to divvy up the theoretical largest size string, // with a terminating character and m _CharT elements, it'd // look like this: // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) // Solving for m: // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1 // In addition, this implementation quarters this amount. static const size_type _S_max_size; static const _CharT _S_terminal; // The following storage is init'd to 0 by the linker, resulting // (carefully) in an empty string with one reference. static size_type _S_empty_rep_storage[]; static _Rep& _S_empty_rep() _GLIBCXX_NOEXCEPT { // NB: Mild hack to avoid strict-aliasing warnings. Note that // _S_empty_rep_storage is never modified and the punning should // be reasonably safe in this case. void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage); return *reinterpret_cast<_Rep*>(__p); } bool _M_is_leaked() const _GLIBCXX_NOEXCEPT { #if defined(__GTHREADS) // _M_refcount is mutated concurrently by _M_refcopy/_M_dispose, // so we need to use an atomic load. However, _M_is_leaked // predicate does not change concurrently (i.e. the string is either // leaked or not), so a relaxed load is enough. return __atomic_load_n(&this->_M_refcount, __ATOMIC_RELAXED) < 0; #else return this->_M_refcount < 0; #endif } bool _M_is_shared() const _GLIBCXX_NOEXCEPT { #if defined(__GTHREADS) // _M_refcount is mutated concurrently by _M_refcopy/_M_dispose, // so we need to use an atomic load. Another thread can drop last // but one reference concurrently with this check, so we need this // load to be acquire to synchronize with release fetch_and_add in // _M_dispose. return __atomic_load_n(&this->_M_refcount, __ATOMIC_ACQUIRE) > 0; #else return this->_M_refcount > 0; #endif } void _M_set_leaked() _GLIBCXX_NOEXCEPT { this->_M_refcount = -1; } void _M_set_sharable() _GLIBCXX_NOEXCEPT { this->_M_refcount = 0; } void _M_set_length_and_sharable(size_type __n) _GLIBCXX_NOEXCEPT { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (__builtin_expect(this != &_S_empty_rep(), false)) #endif { this->_M_set_sharable(); // One reference. this->_M_length = __n; traits_type::assign(this->_M_refdata()[__n], _S_terminal); // grrr. (per 21.3.4) // You cannot leave those LWG people alone for a second. } } _CharT* _M_refdata() throw() { return reinterpret_cast<_CharT*>(this + 1); } _CharT* _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) { return (!_M_is_leaked() && __alloc1 == __alloc2) ? _M_refcopy() : _M_clone(__alloc1); } // Create & Destroy static _Rep* _S_create(size_type, size_type, const _Alloc&); void _M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPT { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (__builtin_expect(this != &_S_empty_rep(), false)) #endif { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount); // Decrement of _M_refcount is acq_rel, because: // - all but last decrements need to release to synchronize with // the last decrement that will delete the object. // - the last decrement needs to acquire to synchronize with // all the previous decrements. // - last but one decrement needs to release to synchronize with // the acquire load in _M_is_shared that will conclude that // the object is not shared anymore. if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, -1) <= 0) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount); _M_destroy(__a); } } } // XXX MT void _M_destroy(const _Alloc&) throw(); _CharT* _M_refcopy() throw() { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (__builtin_expect(this != &_S_empty_rep(), false)) #endif __gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1); return _M_refdata(); } // XXX MT _CharT* _M_clone(const _Alloc&, size_type __res = 0); }; // Use empty-base optimization: http://www.cantrip.org/emptyopt.html struct _Alloc_hider : _Alloc { _Alloc_hider(_CharT* __dat, const _Alloc& __a) _GLIBCXX_NOEXCEPT : _Alloc(__a), _M_p(__dat) { } _CharT* _M_p; // The actual data. }; public: // Data Members (public): // NB: This is an unsigned type, and thus represents the maximum // size that the allocator can hold. /// Value returned by various member functions when they fail. static const size_type npos = static_cast<size_type>(-1); private: // Data Members (private): mutable _Alloc_hider _M_dataplus; _CharT* _M_data() const _GLIBCXX_NOEXCEPT { return _M_dataplus._M_p; } _CharT* _M_data(_CharT* __p) _GLIBCXX_NOEXCEPT { return (_M_dataplus._M_p = __p); } _Rep* _M_rep() const _GLIBCXX_NOEXCEPT { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } // For the internal use we have functions similar to `begin'/`end' // but they do not call _M_leak. iterator _M_ibegin() const _GLIBCXX_NOEXCEPT { return iterator(_M_data()); } iterator _M_iend() const _GLIBCXX_NOEXCEPT { return iterator(_M_data() + this->size()); } void _M_leak() // for use in begin() & non-const op[] { if (!_M_rep()->_M_is_leaked()) _M_leak_hard(); } size_type _M_check(size_type __pos, const char* __s) const { if (__pos > this->size()) __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > " "this->size() (which is %zu)"), __s, __pos, this->size()); return __pos; } void _M_check_length(size_type __n1, size_type __n2, const char* __s) const { if (this->max_size() - (this->size() - __n1) < __n2) __throw_length_error(__N(__s)); } // NB: _M_limit doesn't check for a bad __pos value. size_type _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT { const bool __testoff = __off < this->size() - __pos; return __testoff ? __off : this->size() - __pos; } // True if _Rep and source do not overlap. bool _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT { return (less<const _CharT*>()(__s, _M_data()) || less<const _CharT*>()(_M_data() + this->size(), __s)); } // When __n = 1 way faster than the general multichar // traits_type::copy/move/assign. static void _M_copy(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT { if (__n == 1) traits_type::assign(*__d, *__s); else traits_type::copy(__d, __s, __n); } static void _M_move(_CharT* __d, const _CharT* __s, size_type __n) _GLIBCXX_NOEXCEPT { if (__n == 1) traits_type::assign(*__d, *__s); else traits_type::move(__d, __s, __n); } static void _M_assign(_CharT* __d, size_type __n, _CharT __c) _GLIBCXX_NOEXCEPT { if (__n == 1) traits_type::assign(*__d, __c); else traits_type::assign(__d, __n, __c); } // _S_copy_chars is a separate template to permit specialization // to optimize for the common case of pointers as iterators. template<class _Iterator> static void _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) { for (; __k1 != __k2; ++__k1, (void)++__p) traits_type::assign(*__p, *__k1); // These types are off. } static void _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) _GLIBCXX_NOEXCEPT { _S_copy_chars(__p, __k1.base(), __k2.base()); } static void _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT { _M_copy(__p, __k1, __k2 - __k1); } static void _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) _GLIBCXX_NOEXCEPT { _M_copy(__p, __k1, __k2 - __k1); } static int _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT { const difference_type __d = difference_type(__n1 - __n2); if (__d > __gnu_cxx::__numeric_traits<int>::__max) return __gnu_cxx::__numeric_traits<int>::__max; else if (__d < __gnu_cxx::__numeric_traits<int>::__min) return __gnu_cxx::__numeric_traits<int>::__min; else return int(__d); } void _M_mutate(size_type __pos, size_type __len1, size_type __len2); void _M_leak_hard(); static _Rep& _S_empty_rep() _GLIBCXX_NOEXCEPT { return _Rep::_S_empty_rep(); } #if __cplusplus > 201402L // A helper type for avoiding boiler-plate. typedef basic_string_view<_CharT, _Traits> __sv_type; template<typename _Tp, typename _Res> using _If_sv = enable_if_t< __and_<is_convertible<const _Tp&, __sv_type>, __not_<is_convertible<const _Tp*, const basic_string*>>, __not_<is_convertible<const _Tp&, const _CharT*>>>::value, _Res>; // Allows an implicit conversion to __sv_type. static __sv_type _S_to_string_view(__sv_type __svt) noexcept { return __svt; } // Wraps a string_view by explicit conversion and thus // allows to add an internal constructor that does not // participate in overload resolution when a string_view // is provided. struct __sv_wrapper { explicit __sv_wrapper(__sv_type __sv) noexcept : _M_sv(__sv) { } __sv_type _M_sv; }; #endif public: // Construct/copy/destroy: // NB: We overload ctors in some cases instead of using default // arguments, per 17.4.4.4 para. 2 item 2. /** * @brief Default constructor creates an empty string. */ basic_string() #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { } #else : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()){ } #endif /** * @brief Construct an empty string using allocator @a a. */ explicit basic_string(const _Alloc& __a); // NB: per LWG issue 42, semantics different from IS: /** * @brief Construct string with copy of value of @a str. * @param __str Source string. */ basic_string(const basic_string& __str); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2583. no way to supply an allocator for basic_string(str, pos) /** * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. * @param __a Allocator to use. */ basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a = _Alloc()); /** * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. * @param __n Number of characters to copy. */ basic_string(const basic_string& __str, size_type __pos, size_type __n); /** * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. * @param __n Number of characters to copy. * @param __a Allocator to use. */ basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Alloc& __a); /** * @brief Construct string initialized by a character %array. * @param __s Source character %array. * @param __n Number of characters to copy. * @param __a Allocator to use (default is default allocator). * * NB: @a __s must have at least @a __n characters, '\\0' * has no special meaning. */ basic_string(const _CharT* __s, size_type __n, const _Alloc& __a = _Alloc()); /** * @brief Construct string as copy of a C string. * @param __s Source C string. * @param __a Allocator to use (default is default allocator). */ basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()); /** * @brief Construct string as multiple characters. * @param __n Number of characters. * @param __c Character to use. * @param __a Allocator to use (default is default allocator). */ basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()); #if __cplusplus >= 201103L /** * @brief Move construct string. * @param __str Source string. * * The newly-created string contains the exact contents of @a __str. * @a __str is a valid, but unspecified string. **/ basic_string(basic_string&& __str) #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 noexcept // FIXME C++11: should always be noexcept. #endif : _M_dataplus(__str._M_dataplus) { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 __str._M_data(_S_empty_rep()._M_refdata()); #else __str._M_data(_S_construct(size_type(), _CharT(), get_allocator())); #endif } /** * @brief Construct string from an initializer %list. * @param __l std::initializer_list of characters. * @param __a Allocator to use (default is default allocator). */ basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc()); #endif // C++11 /** * @brief Construct string as copy of a range. * @param __beg Start of range. * @param __end End of range. * @param __a Allocator to use (default is default allocator). */ template<class _InputIterator> basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc()); #if __cplusplus > 201402L /** * @brief Construct string from a substring of a string_view. * @param __t Source object convertible to string view. * @param __pos The index of the first character to copy from __t. * @param __n The number of characters to copy from __t. * @param __a Allocator to use. */ template<typename _Tp, typename = _If_sv<_Tp, void>> basic_string(const _Tp& __t, size_type __pos, size_type __n, const _Alloc& __a = _Alloc()) : basic_string(_S_to_string_view(__t).substr(__pos, __n), __a) { } /** * @brief Construct string from a string_view. * @param __t Source object convertible to string view. * @param __a Allocator to use (default is default allocator). */ template<typename _Tp, typename = _If_sv<_Tp, void>> explicit basic_string(const _Tp& __t, const _Alloc& __a = _Alloc()) : basic_string(__sv_wrapper(_S_to_string_view(__t)), __a) { } /** * @brief Only internally used: Construct string from a string view * wrapper. * @param __svw string view wrapper. * @param __a Allocator to use. */ explicit basic_string(__sv_wrapper __svw, const _Alloc& __a) : basic_string(__svw._M_sv.data(), __svw._M_sv.size(), __a) { } #endif // C++17 /** * @brief Destroy the string instance. */ ~basic_string() _GLIBCXX_NOEXCEPT { _M_rep()->_M_dispose(this->get_allocator()); } /** * @brief Assign the value of @a str to this string. * @param __str Source string. */ basic_string& operator=(const basic_string& __str) { return this->assign(__str); } /** * @brief Copy contents of @a s into this string. * @param __s Source null-terminated string. */ basic_string& operator=(const _CharT* __s) { return this->assign(__s); } /** * @brief Set value to string of length 1. * @param __c Source character. * * Assigning to a character makes this string length 1 and * (*this)[0] == @a c. */ basic_string& operator=(_CharT __c) { this->assign(1, __c); return *this; } #if __cplusplus >= 201103L /** * @brief Move assign the value of @a str to this string. * @param __str Source string. * * The contents of @a str are moved into this string (without copying). * @a str is a valid, but unspecified string. **/ // PR 58265, this should be noexcept. basic_string& operator=(basic_string&& __str) { // NB: DR 1204. this->swap(__str); return *this; } /** * @brief Set value to string constructed from initializer %list. * @param __l std::initializer_list. */ basic_string& operator=(initializer_list<_CharT> __l) { this->assign(__l.begin(), __l.size()); return *this; } #endif // C++11 #if __cplusplus > 201402L /** * @brief Set value to string constructed from a string_view. * @param __svt An object convertible to string_view. */ template<typename _Tp> _If_sv<_Tp, basic_string&> operator=(const _Tp& __svt) { return this->assign(__svt); } /** * @brief Convert to a string_view. * @return A string_view. */ operator __sv_type() const noexcept { return __sv_type(data(), size()); } #endif // C++17 // Iterators: /** * Returns a read/write iterator that points to the first character in * the %string. Unshares the string. */ iterator begin() // FIXME C++11: should be noexcept. { _M_leak(); return iterator(_M_data()); } /** * Returns a read-only (constant) iterator that points to the first * character in the %string. */ const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(_M_data()); } /** * Returns a read/write iterator that points one past the last * character in the %string. Unshares the string. */ iterator end() // FIXME C++11: should be noexcept. { _M_leak(); return iterator(_M_data() + this->size()); } /** * Returns a read-only (constant) iterator that points one past the * last character in the %string. */ const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(_M_data() + this->size()); } /** * Returns a read/write reverse iterator that points to the last * character in the %string. Iteration is done in reverse element * order. Unshares the string. */ reverse_iterator rbegin() // FIXME C++11: should be noexcept. { return reverse_iterator(this->end()); } /** * Returns a read-only (constant) reverse iterator that points * to the last character in the %string. Iteration is done in * reverse element order. */ const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(this->end()); } /** * Returns a read/write reverse iterator that points to one before the * first character in the %string. Iteration is done in reverse * element order. Unshares the string. */ reverse_iterator rend() // FIXME C++11: should be noexcept. { return reverse_iterator(this->begin()); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first character in the %string. Iteration * is done in reverse element order. */ const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(this->begin()); } #if __cplusplus >= 201103L /** * Returns a read-only (constant) iterator that points to the first * character in the %string. */ const_iterator cbegin() const noexcept { return const_iterator(this->_M_data()); } /** * Returns a read-only (constant) iterator that points one past the * last character in the %string. */ const_iterator cend() const noexcept { return const_iterator(this->_M_data() + this->size()); } /** * Returns a read-only (constant) reverse iterator that points * to the last character in the %string. Iteration is done in * reverse element order. */ const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(this->end()); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first character in the %string. Iteration * is done in reverse element order. */ const_reverse_iterator crend() const noexcept { return const_reverse_iterator(this->begin()); } #endif public: // Capacity: /// Returns the number of characters in the string, not including any /// null-termination. size_type size() const _GLIBCXX_NOEXCEPT { return _M_rep()->_M_length; } /// Returns the number of characters in the string, not including any /// null-termination. size_type length() const _GLIBCXX_NOEXCEPT { return _M_rep()->_M_length; } /// Returns the size() of the largest possible %string. size_type max_size() const _GLIBCXX_NOEXCEPT { return _Rep::_S_max_size; } /** * @brief Resizes the %string to the specified number of characters. * @param __n Number of characters the %string should contain. * @param __c Character to fill any new elements. * * This function will %resize the %string to the specified * number of characters. If the number is smaller than the * %string's current size the %string is truncated, otherwise * the %string is extended and new elements are %set to @a __c. */ void resize(size_type __n, _CharT __c); /** * @brief Resizes the %string to the specified number of characters. * @param __n Number of characters the %string should contain. * * This function will resize the %string to the specified length. If * the new size is smaller than the %string's current size the %string * is truncated, otherwise the %string is extended and new characters * are default-constructed. For basic types such as char, this means * setting them to 0. */ void resize(size_type __n) { this->resize(__n, _CharT()); } #if __cplusplus >= 201103L /// A non-binding request to reduce capacity() to size(). void shrink_to_fit() _GLIBCXX_NOEXCEPT { #if __cpp_exceptions if (capacity() > size()) { try { reserve(0); } catch(...) { } } #endif } #endif /** * Returns the total number of characters that the %string can hold * before needing to allocate more memory. */ size_type capacity() const _GLIBCXX_NOEXCEPT { return _M_rep()->_M_capacity; } /** * @brief Attempt to preallocate enough memory for specified number of * characters. * @param __res_arg Number of characters required. * @throw std::length_error If @a __res_arg exceeds @c max_size(). * * This function attempts to reserve enough memory for the * %string to hold the specified number of characters. If the * number requested is more than max_size(), length_error is * thrown. * * The advantage of this function is that if optimal code is a * necessity and the user can determine the string length that will be * required, the user can reserve the memory in %advance, and thus * prevent a possible reallocation of memory and copying of %string * data. */ void reserve(size_type __res_arg = 0); /** * Erases the string, making it empty. */ #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 void clear() _GLIBCXX_NOEXCEPT { if (_M_rep()->_M_is_shared()) { _M_rep()->_M_dispose(this->get_allocator()); _M_data(_S_empty_rep()._M_refdata()); } else _M_rep()->_M_set_length_and_sharable(0); } #else // PR 56166: this should not throw. void clear() { _M_mutate(0, this->size(), 0); } #endif /** * Returns true if the %string is empty. Equivalent to * <code>*this == ""</code>. */ bool empty() const _GLIBCXX_NOEXCEPT { return this->size() == 0; } // Element access: /** * @brief Subscript access to the data contained in the %string. * @param __pos The index of the character to access. * @return Read-only (constant) reference to the character. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ const_reference operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT { __glibcxx_assert(__pos <= size()); return _M_data()[__pos]; } /** * @brief Subscript access to the data contained in the %string. * @param __pos The index of the character to access. * @return Read/write reference to the character. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) Unshares the string. */ reference operator[](size_type __pos) { // Allow pos == size() both in C++98 mode, as v3 extension, // and in C++11 mode. __glibcxx_assert(__pos <= size()); // In pedantic mode be strict in C++98 mode. _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size()); _M_leak(); return _M_data()[__pos]; } /** * @brief Provides access to the data contained in the %string. * @param __n The index of the character to access. * @return Read-only (const) reference to the character. * @throw std::out_of_range If @a n is an invalid index. * * This function provides for safer data access. The parameter is * first checked that it is in the range of the string. The function * throws out_of_range if the check fails. */ const_reference at(size_type __n) const { if (__n >= this->size()) __throw_out_of_range_fmt(__N("basic_string::at: __n " "(which is %zu) >= this->size() " "(which is %zu)"), __n, this->size()); return _M_data()[__n]; } /** * @brief Provides access to the data contained in the %string. * @param __n The index of the character to access. * @return Read/write reference to the character. * @throw std::out_of_range If @a n is an invalid index. * * This function provides for safer data access. The parameter is * first checked that it is in the range of the string. The function * throws out_of_range if the check fails. Success results in * unsharing the string. */ reference at(size_type __n) { if (__n >= size()) __throw_out_of_range_fmt(__N("basic_string::at: __n " "(which is %zu) >= this->size() " "(which is %zu)"), __n, this->size()); _M_leak(); return _M_data()[__n]; } #if __cplusplus >= 201103L /** * Returns a read/write reference to the data at the first * element of the %string. */ reference front() { __glibcxx_assert(!empty()); return operator[](0); } /** * Returns a read-only (constant) reference to the data at the first * element of the %string. */ const_reference front() const noexcept { __glibcxx_assert(!empty()); return operator[](0); } /** * Returns a read/write reference to the data at the last * element of the %string. */ reference back() { __glibcxx_assert(!empty()); return operator[](this->size() - 1); } /** * Returns a read-only (constant) reference to the data at the * last element of the %string. */ const_reference back() const noexcept { __glibcxx_assert(!empty()); return operator[](this->size() - 1); } #endif // Modifiers: /** * @brief Append a string to this string. * @param __str The string to append. * @return Reference to this string. */ basic_string& operator+=(const basic_string& __str) { return this->append(__str); } /** * @brief Append a C string. * @param __s The C string to append. * @return Reference to this string. */ basic_string& operator+=(const _CharT* __s) { return this->append(__s); } /** * @brief Append a character. * @param __c The character to append. * @return Reference to this string. */ basic_string& operator+=(_CharT __c) { this->push_back(__c); return *this; } #if __cplusplus >= 201103L /** * @brief Append an initializer_list of characters. * @param __l The initializer_list of characters to be appended. * @return Reference to this string. */ basic_string& operator+=(initializer_list<_CharT> __l) { return this->append(__l.begin(), __l.size()); } #endif // C++11 #if __cplusplus > 201402L /** * @brief Append a string_view. * @param __svt The object convertible to string_view to be appended. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> operator+=(const _Tp& __svt) { return this->append(__svt); } #endif // C++17 /** * @brief Append a string to this string. * @param __str The string to append. * @return Reference to this string. */ basic_string& append(const basic_string& __str); /** * @brief Append a substring. * @param __str The string to append. * @param __pos Index of the first character of str to append. * @param __n The number of characters to append. * @return Reference to this string. * @throw std::out_of_range if @a __pos is not a valid index. * * This function appends @a __n characters from @a __str * starting at @a __pos to this string. If @a __n is is larger * than the number of available characters in @a __str, the * remainder of @a __str is appended. */ basic_string& append(const basic_string& __str, size_type __pos, size_type __n = npos); /** * @brief Append a C substring. * @param __s The C string to append. * @param __n The number of characters to append. * @return Reference to this string. */ basic_string& append(const _CharT* __s, size_type __n); /** * @brief Append a C string. * @param __s The C string to append. * @return Reference to this string. */ basic_string& append(const _CharT* __s) { __glibcxx_requires_string(__s); return this->append(__s, traits_type::length(__s)); } /** * @brief Append multiple characters. * @param __n The number of characters to append. * @param __c The character to use. * @return Reference to this string. * * Appends __n copies of __c to this string. */ basic_string& append(size_type __n, _CharT __c); #if __cplusplus >= 201103L /** * @brief Append an initializer_list of characters. * @param __l The initializer_list of characters to append. * @return Reference to this string. */ basic_string& append(initializer_list<_CharT> __l) { return this->append(__l.begin(), __l.size()); } #endif // C++11 /** * @brief Append a range of characters. * @param __first Iterator referencing the first character to append. * @param __last Iterator marking the end of the range. * @return Reference to this string. * * Appends characters in the range [__first,__last) to this string. */ template<class _InputIterator> basic_string& append(_InputIterator __first, _InputIterator __last) { return this->replace(_M_iend(), _M_iend(), __first, __last); } #if __cplusplus > 201402L /** * @brief Append a string_view. * @param __svt The object convertible to string_view to be appended. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> append(const _Tp& __svt) { __sv_type __sv = __svt; return this->append(__sv.data(), __sv.size()); } /** * @brief Append a range of characters from a string_view. * @param __svt The object convertible to string_view to be appended * from. * @param __pos The position in the string_view to append from. * @param __n The number of characters to append from the string_view. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> append(const _Tp& __svt, size_type __pos, size_type __n = npos) { __sv_type __sv = __svt; return append(__sv.data() + __sv._M_check(__pos, "basic_string::append"), __sv._M_limit(__pos, __n)); } #endif // C++17 /** * @brief Append a single character. * @param __c Character to append. */ void push_back(_CharT __c) { const size_type __len = 1 + this->size(); if (__len > this->capacity() || _M_rep()->_M_is_shared()) this->reserve(__len); traits_type::assign(_M_data()[this->size()], __c); _M_rep()->_M_set_length_and_sharable(__len); } /** * @brief Set value to contents of another string. * @param __str Source string to use. * @return Reference to this string. */ basic_string& assign(const basic_string& __str); #if __cplusplus >= 201103L /** * @brief Set value to contents of another string. * @param __str Source string to use. * @return Reference to this string. * * This function sets this string to the exact contents of @a __str. * @a __str is a valid, but unspecified string. */ // PR 58265, this should be noexcept. basic_string& assign(basic_string&& __str) { this->swap(__str); return *this; } #endif // C++11 /** * @brief Set value to a substring of a string. * @param __str The string to use. * @param __pos Index of the first character of str. * @param __n Number of characters to use. * @return Reference to this string. * @throw std::out_of_range if @a pos is not a valid index. * * This function sets this string to the substring of @a __str * consisting of @a __n characters at @a __pos. If @a __n is * is larger than the number of available characters in @a * __str, the remainder of @a __str is used. */ basic_string& assign(const basic_string& __str, size_type __pos, size_type __n = npos) { return this->assign(__str._M_data() + __str._M_check(__pos, "basic_string::assign"), __str._M_limit(__pos, __n)); } /** * @brief Set value to a C substring. * @param __s The C string to use. * @param __n Number of characters to use. * @return Reference to this string. * * This function sets the value of this string to the first @a __n * characters of @a __s. If @a __n is is larger than the number of * available characters in @a __s, the remainder of @a __s is used. */ basic_string& assign(const _CharT* __s, size_type __n); /** * @brief Set value to contents of a C string. * @param __s The C string to use. * @return Reference to this string. * * This function sets the value of this string to the value of @a __s. * The data is copied, so there is no dependence on @a __s once the * function returns. */ basic_string& assign(const _CharT* __s) { __glibcxx_requires_string(__s); return this->assign(__s, traits_type::length(__s)); } /** * @brief Set value to multiple characters. * @param __n Length of the resulting string. * @param __c The character to use. * @return Reference to this string. * * This function sets the value of this string to @a __n copies of * character @a __c. */ basic_string& assign(size_type __n, _CharT __c) { return _M_replace_aux(size_type(0), this->size(), __n, __c); } /** * @brief Set value to a range of characters. * @param __first Iterator referencing the first character to append. * @param __last Iterator marking the end of the range. * @return Reference to this string. * * Sets value of string to characters in the range [__first,__last). */ template<class _InputIterator> basic_string& assign(_InputIterator __first, _InputIterator __last) { return this->replace(_M_ibegin(), _M_iend(), __first, __last); } #if __cplusplus >= 201103L /** * @brief Set value to an initializer_list of characters. * @param __l The initializer_list of characters to assign. * @return Reference to this string. */ basic_string& assign(initializer_list<_CharT> __l) { return this->assign(__l.begin(), __l.size()); } #endif // C++11 #if __cplusplus > 201402L /** * @brief Set value from a string_view. * @param __svt The source object convertible to string_view. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> assign(const _Tp& __svt) { __sv_type __sv = __svt; return this->assign(__sv.data(), __sv.size()); } /** * @brief Set value from a range of characters in a string_view. * @param __svt The source object convertible to string_view. * @param __pos The position in the string_view to assign from. * @param __n The number of characters to assign. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> assign(const _Tp& __svt, size_type __pos, size_type __n = npos) { __sv_type __sv = __svt; return assign(__sv.data() + __sv._M_check(__pos, "basic_string::assign"), __sv._M_limit(__pos, __n)); } #endif // C++17 /** * @brief Insert multiple characters. * @param __p Iterator referencing location in string to insert at. * @param __n Number of characters to insert * @param __c The character to insert. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts @a __n copies of character @a __c starting at the * position referenced by iterator @a __p. If adding * characters causes the length to exceed max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ void insert(iterator __p, size_type __n, _CharT __c) { this->replace(__p, __p, __n, __c); } /** * @brief Insert a range of characters. * @param __p Iterator referencing location in string to insert at. * @param __beg Start of range. * @param __end End of range. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts characters in range [__beg,__end). If adding * characters causes the length to exceed max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ template<class _InputIterator> void insert(iterator __p, _InputIterator __beg, _InputIterator __end) { this->replace(__p, __p, __beg, __end); } #if __cplusplus >= 201103L /** * @brief Insert an initializer_list of characters. * @param __p Iterator referencing location in string to insert at. * @param __l The initializer_list of characters to insert. * @throw std::length_error If new length exceeds @c max_size(). */ void insert(iterator __p, initializer_list<_CharT> __l) { _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); this->insert(__p - _M_ibegin(), __l.begin(), __l.size()); } #endif // C++11 /** * @brief Insert value of a string. * @param __pos1 Iterator referencing location in string to insert at. * @param __str The string to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts value of @a __str starting at @a __pos1. If adding * characters causes the length to exceed max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ basic_string& insert(size_type __pos1, const basic_string& __str) { return this->insert(__pos1, __str, size_type(0), __str.size()); } /** * @brief Insert a substring. * @param __pos1 Iterator referencing location in string to insert at. * @param __str The string to insert. * @param __pos2 Start of characters in str to insert. * @param __n Number of characters to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a pos1 > size() or * @a __pos2 > @a str.size(). * * Starting at @a pos1, insert @a __n character of @a __str * beginning with @a __pos2. If adding characters causes the * length to exceed max_size(), length_error is thrown. If @a * __pos1 is beyond the end of this string or @a __pos2 is * beyond the end of @a __str, out_of_range is thrown. The * value of the string doesn't change if an error is thrown. */ basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos) { return this->insert(__pos1, __str._M_data() + __str._M_check(__pos2, "basic_string::insert"), __str._M_limit(__pos2, __n)); } /** * @brief Insert a C substring. * @param __pos Iterator referencing location in string to insert at. * @param __s The C string to insert. * @param __n The number of characters to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a __pos is beyond the end of this * string. * * Inserts the first @a __n characters of @a __s starting at @a * __pos. If adding characters causes the length to exceed * max_size(), length_error is thrown. If @a __pos is beyond * end(), out_of_range is thrown. The value of the string * doesn't change if an error is thrown. */ basic_string& insert(size_type __pos, const _CharT* __s, size_type __n); /** * @brief Insert a C string. * @param __pos Iterator referencing location in string to insert at. * @param __s The C string to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a pos is beyond the end of this * string. * * Inserts the first @a n characters of @a __s starting at @a __pos. If * adding characters causes the length to exceed max_size(), * length_error is thrown. If @a __pos is beyond end(), out_of_range is * thrown. The value of the string doesn't change if an error is * thrown. */ basic_string& insert(size_type __pos, const _CharT* __s) { __glibcxx_requires_string(__s); return this->insert(__pos, __s, traits_type::length(__s)); } /** * @brief Insert multiple characters. * @param __pos Index in string to insert at. * @param __n Number of characters to insert * @param __c The character to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * @throw std::out_of_range If @a __pos is beyond the end of this * string. * * Inserts @a __n copies of character @a __c starting at index * @a __pos. If adding characters causes the length to exceed * max_size(), length_error is thrown. If @a __pos > length(), * out_of_range is thrown. The value of the string doesn't * change if an error is thrown. */ basic_string& insert(size_type __pos, size_type __n, _CharT __c) { return _M_replace_aux(_M_check(__pos, "basic_string::insert"), size_type(0), __n, __c); } /** * @brief Insert one character. * @param __p Iterator referencing position in string to insert at. * @param __c The character to insert. * @return Iterator referencing newly inserted char. * @throw std::length_error If new length exceeds @c max_size(). * * Inserts character @a __c at position referenced by @a __p. * If adding character causes the length to exceed max_size(), * length_error is thrown. If @a __p is beyond end of string, * out_of_range is thrown. The value of the string doesn't * change if an error is thrown. */ iterator insert(iterator __p, _CharT __c) { _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); const size_type __pos = __p - _M_ibegin(); _M_replace_aux(__pos, size_type(0), size_type(1), __c); _M_rep()->_M_set_leaked(); return iterator(_M_data() + __pos); } #if __cplusplus > 201402L /** * @brief Insert a string_view. * @param __pos Iterator referencing position in string to insert at. * @param __svt The object convertible to string_view to insert. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> insert(size_type __pos, const _Tp& __svt) { __sv_type __sv = __svt; return this->insert(__pos, __sv.data(), __sv.size()); } /** * @brief Insert a string_view. * @param __pos Iterator referencing position in string to insert at. * @param __svt The object convertible to string_view to insert from. * @param __pos Iterator referencing position in string_view to insert * from. * @param __n The number of characters to insert. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> insert(size_type __pos1, const _Tp& __svt, size_type __pos2, size_type __n = npos) { __sv_type __sv = __svt; return this->replace(__pos1, size_type(0), __sv.data() + __sv._M_check(__pos2, "basic_string::insert"), __sv._M_limit(__pos2, __n)); } #endif // C++17 /** * @brief Remove characters. * @param __pos Index of first character to remove (default 0). * @param __n Number of characters to remove (default remainder). * @return Reference to this string. * @throw std::out_of_range If @a pos is beyond the end of this * string. * * Removes @a __n characters from this string starting at @a * __pos. The length of the string is reduced by @a __n. If * there are < @a __n characters to remove, the remainder of * the string is truncated. If @a __p is beyond end of string, * out_of_range is thrown. The value of the string doesn't * change if an error is thrown. */ basic_string& erase(size_type __pos = 0, size_type __n = npos) { _M_mutate(_M_check(__pos, "basic_string::erase"), _M_limit(__pos, __n), size_type(0)); return *this; } /** * @brief Remove one character. * @param __position Iterator referencing the character to remove. * @return iterator referencing same location after removal. * * Removes the character at @a __position from this string. The value * of the string doesn't change if an error is thrown. */ iterator erase(iterator __position) { _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() && __position < _M_iend()); const size_type __pos = __position - _M_ibegin(); _M_mutate(__pos, size_type(1), size_type(0)); _M_rep()->_M_set_leaked(); return iterator(_M_data() + __pos); } /** * @brief Remove a range of characters. * @param __first Iterator referencing the first character to remove. * @param __last Iterator referencing the end of the range. * @return Iterator referencing location of first after removal. * * Removes the characters in the range [first,last) from this string. * The value of the string doesn't change if an error is thrown. */ iterator erase(iterator __first, iterator __last); #if __cplusplus >= 201103L /** * @brief Remove the last character. * * The string must be non-empty. */ void pop_back() // FIXME C++11: should be noexcept. { __glibcxx_assert(!empty()); erase(size() - 1, 1); } #endif // C++11 /** * @brief Replace characters with value from another string. * @param __pos Index of first character to replace. * @param __n Number of characters to be replaced. * @param __str String to insert. * @return Reference to this string. * @throw std::out_of_range If @a pos is beyond the end of this * string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__pos,__pos+__n) from * this string. In place, the value of @a __str is inserted. * If @a __pos is beyond end of string, out_of_range is thrown. * If the length of the result exceeds max_size(), length_error * is thrown. The value of the string doesn't change if an * error is thrown. */ basic_string& replace(size_type __pos, size_type __n, const basic_string& __str) { return this->replace(__pos, __n, __str._M_data(), __str.size()); } /** * @brief Replace characters with value from another string. * @param __pos1 Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __str String to insert. * @param __pos2 Index of first character of str to use. * @param __n2 Number of characters from str to use. * @return Reference to this string. * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 > * __str.size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__pos1,__pos1 + n) from this * string. In place, the value of @a __str is inserted. If @a __pos is * beyond end of string, out_of_range is thrown. If the length of the * result exceeds max_size(), length_error is thrown. The value of the * string doesn't change if an error is thrown. */ basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) { return this->replace(__pos1, __n1, __str._M_data() + __str._M_check(__pos2, "basic_string::replace"), __str._M_limit(__pos2, __n2)); } /** * @brief Replace characters with value of a C substring. * @param __pos Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __s C string to insert. * @param __n2 Number of characters from @a s to use. * @return Reference to this string. * @throw std::out_of_range If @a pos1 > size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__pos,__pos + __n1) * from this string. In place, the first @a __n2 characters of * @a __s are inserted, or all of @a __s if @a __n2 is too large. If * @a __pos is beyond end of string, out_of_range is thrown. If * the length of result exceeds max_size(), length_error is * thrown. The value of the string doesn't change if an error * is thrown. */ basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2); /** * @brief Replace characters with value of a C string. * @param __pos Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __s C string to insert. * @return Reference to this string. * @throw std::out_of_range If @a pos > size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__pos,__pos + __n1) * from this string. In place, the characters of @a __s are * inserted. If @a __pos is beyond end of string, out_of_range * is thrown. If the length of result exceeds max_size(), * length_error is thrown. The value of the string doesn't * change if an error is thrown. */ basic_string& replace(size_type __pos, size_type __n1, const _CharT* __s) { __glibcxx_requires_string(__s); return this->replace(__pos, __n1, __s, traits_type::length(__s)); } /** * @brief Replace characters with multiple characters. * @param __pos Index of first character to replace. * @param __n1 Number of characters to be replaced. * @param __n2 Number of characters to insert. * @param __c Character to insert. * @return Reference to this string. * @throw std::out_of_range If @a __pos > size(). * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [pos,pos + n1) from this * string. In place, @a __n2 copies of @a __c are inserted. * If @a __pos is beyond end of string, out_of_range is thrown. * If the length of result exceeds max_size(), length_error is * thrown. The value of the string doesn't change if an error * is thrown. */ basic_string& replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) { return _M_replace_aux(_M_check(__pos, "basic_string::replace"), _M_limit(__pos, __n1), __n2, __c); } /** * @brief Replace range of characters with string. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __str String value to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * the value of @a __str is inserted. If the length of result * exceeds max_size(), length_error is thrown. The value of * the string doesn't change if an error is thrown. */ basic_string& replace(iterator __i1, iterator __i2, const basic_string& __str) { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } /** * @brief Replace range of characters with C substring. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __s C string value to insert. * @param __n Number of characters from s to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * the first @a __n characters of @a __s are inserted. If the * length of result exceeds max_size(), length_error is thrown. * The value of the string doesn't change if an error is * thrown. */ basic_string& replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n) { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); } /** * @brief Replace range of characters with C string. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __s C string value to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * the characters of @a __s are inserted. If the length of * result exceeds max_size(), length_error is thrown. The * value of the string doesn't change if an error is thrown. */ basic_string& replace(iterator __i1, iterator __i2, const _CharT* __s) { __glibcxx_requires_string(__s); return this->replace(__i1, __i2, __s, traits_type::length(__s)); } /** * @brief Replace range of characters with multiple characters * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __n Number of characters to insert. * @param __c Character to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * @a __n copies of @a __c are inserted. If the length of * result exceeds max_size(), length_error is thrown. The * value of the string doesn't change if an error is thrown. */ basic_string& replace(iterator __i1, iterator __i2, size_type __n, _CharT __c) { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c); } /** * @brief Replace range of characters with range. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __k1 Iterator referencing start of range to insert. * @param __k2 Iterator referencing end of range to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * characters in the range [__k1,__k2) are inserted. If the * length of result exceeds max_size(), length_error is thrown. * The value of the string doesn't change if an error is * thrown. */ template<class _InputIterator> basic_string& replace(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2) { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); typedef typename std::__is_integer<_InputIterator>::__type _Integral; return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); } // Specializations for the common case of pointer and iterator: // useful to avoid the overhead of temporary buffering in _M_replace. basic_string& replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2) { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1, __k2 - __k1); } basic_string& replace(iterator __i1, iterator __i2, const _CharT* __k1, const _CharT* __k2) { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1, __k2 - __k1); } basic_string& replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2) { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1.base(), __k2 - __k1); } basic_string& replace(iterator __i1, iterator __i2, const_iterator __k1, const_iterator __k2) { _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2 && __i2 <= _M_iend()); __glibcxx_requires_valid_range(__k1, __k2); return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1.base(), __k2 - __k1); } #if __cplusplus >= 201103L /** * @brief Replace range of characters with initializer_list. * @param __i1 Iterator referencing start of range to replace. * @param __i2 Iterator referencing end of range to replace. * @param __l The initializer_list of characters to insert. * @return Reference to this string. * @throw std::length_error If new length exceeds @c max_size(). * * Removes the characters in the range [__i1,__i2). In place, * characters in the range [__k1,__k2) are inserted. If the * length of result exceeds max_size(), length_error is thrown. * The value of the string doesn't change if an error is * thrown. */ basic_string& replace(iterator __i1, iterator __i2, initializer_list<_CharT> __l) { return this->replace(__i1, __i2, __l.begin(), __l.end()); } #endif // C++11 #if __cplusplus > 201402L /** * @brief Replace range of characters with string_view. * @param __pos The position to replace at. * @param __n The number of characters to replace. * @param __svt The object convertible to string_view to insert. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> replace(size_type __pos, size_type __n, const _Tp& __svt) { __sv_type __sv = __svt; return this->replace(__pos, __n, __sv.data(), __sv.size()); } /** * @brief Replace range of characters with string_view. * @param __pos1 The position to replace at. * @param __n1 The number of characters to replace. * @param __svt The object convertible to string_view to insert from. * @param __pos2 The position in the string_view to insert from. * @param __n2 The number of characters to insert. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> replace(size_type __pos1, size_type __n1, const _Tp& __svt, size_type __pos2, size_type __n2 = npos) { __sv_type __sv = __svt; return this->replace(__pos1, __n1, __sv.data() + __sv._M_check(__pos2, "basic_string::replace"), __sv._M_limit(__pos2, __n2)); } /** * @brief Replace range of characters with string_view. * @param __i1 An iterator referencing the start position to replace at. * @param __i2 An iterator referencing the end position for the replace. * @param __svt The object convertible to string_view to insert from. * @return Reference to this string. */ template<typename _Tp> _If_sv<_Tp, basic_string&> replace(const_iterator __i1, const_iterator __i2, const _Tp& __svt) { __sv_type __sv = __svt; return this->replace(__i1 - begin(), __i2 - __i1, __sv); } #endif // C++17 private: template<class _Integer> basic_string& _M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n, _Integer __val, __true_type) { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); } template<class _InputIterator> basic_string& _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2, __false_type); basic_string& _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, _CharT __c); basic_string& _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2); // _S_construct_aux is used to implement the 21.3.1 para 15 which // requires special behaviour if _InIter is an integral type template<class _InIterator> static _CharT* _S_construct_aux(_InIterator __beg, _InIterator __end, const _Alloc& __a, __false_type) { typedef typename iterator_traits<_InIterator>::iterator_category _Tag; return _S_construct(__beg, __end, __a, _Tag()); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<class _Integer> static _CharT* _S_construct_aux(_Integer __beg, _Integer __end, const _Alloc& __a, __true_type) { return _S_construct_aux_2(static_cast<size_type>(__beg), __end, __a); } static _CharT* _S_construct_aux_2(size_type __req, _CharT __c, const _Alloc& __a) { return _S_construct(__req, __c, __a); } template<class _InIterator> static _CharT* _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) { typedef typename std::__is_integer<_InIterator>::__type _Integral; return _S_construct_aux(__beg, __end, __a, _Integral()); } // For Input Iterators, used in istreambuf_iterators, etc. template<class _InIterator> static _CharT* _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, input_iterator_tag); // For forward_iterators up to random_access_iterators, used for // string::iterator, _CharT*, etc. template<class _FwdIterator> static _CharT* _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, forward_iterator_tag); static _CharT* _S_construct(size_type __req, _CharT __c, const _Alloc& __a); public: /** * @brief Copy substring into C string. * @param __s C string to copy value into. * @param __n Number of characters to copy. * @param __pos Index of first character to copy. * @return Number of characters actually copied * @throw std::out_of_range If __pos > size(). * * Copies up to @a __n characters starting at @a __pos into the * C string @a __s. If @a __pos is %greater than size(), * out_of_range is thrown. */ size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const; /** * @brief Swap contents with another string. * @param __s String to swap with. * * Exchanges the contents of this string with that of @a __s in constant * time. */ // PR 58265, this should be noexcept. void swap(basic_string& __s); // String operations: /** * @brief Return const pointer to null-terminated contents. * * This is a handle to internal data. Do not modify or dire things may * happen. */ const _CharT* c_str() const _GLIBCXX_NOEXCEPT { return _M_data(); } /** * @brief Return const pointer to contents. * * This is a pointer to internal data. It is undefined to modify * the contents through the returned pointer. To get a pointer that * allows modifying the contents use @c &str[0] instead, * (or in C++17 the non-const @c str.data() overload). */ const _CharT* data() const _GLIBCXX_NOEXCEPT { return _M_data(); } #if __cplusplus > 201402L /** * @brief Return non-const pointer to contents. * * This is a pointer to the character sequence held by the string. * Modifying the characters in the sequence is allowed. */ _CharT* data() noexcept { _M_leak(); return _M_data(); } #endif /** * @brief Return copy of allocator used to construct this string. */ allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return _M_dataplus; } /** * @brief Find position of a C substring. * @param __s C string to locate. * @param __pos Index of character to search from. * @param __n Number of characters from @a s to search for. * @return Index of start of first occurrence. * * Starting from @a __pos, searches forward for the first @a * __n characters in @a __s within this string. If found, * returns the index where it begins. If not found, returns * npos. */ size_type find(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find position of a string. * @param __str String to locate. * @param __pos Index of character to search from (default 0). * @return Index of start of first occurrence. * * Starting from @a __pos, searches forward for value of @a __str within * this string. If found, returns the index where it begins. If not * found, returns npos. */ size_type find(const basic_string& __str, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find(__str.data(), __pos, __str.size()); } /** * @brief Find position of a C string. * @param __s C string to locate. * @param __pos Index of character to search from (default 0). * @return Index of start of first occurrence. * * Starting from @a __pos, searches forward for the value of @a * __s within this string. If found, returns the index where * it begins. If not found, returns npos. */ size_type find(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->find(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a character. * @param __c Character to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for @a __c within * this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT; #if __cplusplus > 201402L /** * @brief Find position of a string_view. * @param __svt The object convertible to string_view to locate. * @param __pos Index of character to search from (default 0). * @return Index of start of first occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> find(const _Tp& __svt, size_type __pos = 0) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->find(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find last position of a string. * @param __str String to locate. * @param __pos Index of character to search back from (default end). * @return Index of start of last occurrence. * * Starting from @a __pos, searches backward for value of @a * __str within this string. If found, returns the index where * it begins. If not found, returns npos. */ size_type rfind(const basic_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->rfind(__str.data(), __pos, __str.size()); } /** * @brief Find last position of a C substring. * @param __s C string to locate. * @param __pos Index of character to search back from. * @param __n Number of characters from s to search for. * @return Index of start of last occurrence. * * Starting from @a __pos, searches backward for the first @a * __n characters in @a __s within this string. If found, * returns the index where it begins. If not found, returns * npos. */ size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find last position of a C string. * @param __s C string to locate. * @param __pos Index of character to start search at (default end). * @return Index of start of last occurrence. * * Starting from @a __pos, searches backward for the value of * @a __s within this string. If found, returns the index * where it begins. If not found, returns npos. */ size_type rfind(const _CharT* __s, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->rfind(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a character. * @param __c Character to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for @a __c within * this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT; #if __cplusplus > 201402L /** * @brief Find last position of a string_view. * @param __svt The object convertible to string_view to locate. * @param __pos Index of character to search back from (default end). * @return Index of start of last occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> rfind(const _Tp& __svt, size_type __pos = npos) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->rfind(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find position of a character of string. * @param __str String containing characters to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for one of the * characters of @a __str within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find_first_of(__str.data(), __pos, __str.size()); } /** * @brief Find position of a character of C substring. * @param __s String containing characters to locate. * @param __pos Index of character to search from. * @param __n Number of characters from s to search for. * @return Index of first occurrence. * * Starting from @a __pos, searches forward for one of the * first @a __n characters of @a __s within this string. If * found, returns the index where it was found. If not found, * returns npos. */ size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find position of a character of C string. * @param __s String containing characters to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for one of the * characters of @a __s within this string. If found, returns * the index where it was found. If not found, returns npos. */ size_type find_first_of(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->find_first_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a character. * @param __c Character to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for the character * @a __c within this string. If found, returns the index * where it was found. If not found, returns npos. * * Note: equivalent to find(__c, __pos). */ size_type find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find(__c, __pos); } #if __cplusplus > 201402L /** * @brief Find position of a character of a string_view. * @param __svt An object convertible to string_view containing * characters to locate. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> find_first_of(const _Tp& __svt, size_type __pos = 0) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->find_first_of(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find last position of a character of string. * @param __str String containing characters to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for one of the * characters of @a __str within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->find_last_of(__str.data(), __pos, __str.size()); } /** * @brief Find last position of a character of C substring. * @param __s C string containing characters to locate. * @param __pos Index of character to search back from. * @param __n Number of characters from s to search for. * @return Index of last occurrence. * * Starting from @a __pos, searches backward for one of the * first @a __n characters of @a __s within this string. If * found, returns the index where it was found. If not found, * returns npos. */ size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find last position of a character of C string. * @param __s C string containing characters to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for one of the * characters of @a __s within this string. If found, returns * the index where it was found. If not found, returns npos. */ size_type find_last_of(const _CharT* __s, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->find_last_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a character. * @param __c Character to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for @a __c within * this string. If found, returns the index where it was * found. If not found, returns npos. * * Note: equivalent to rfind(__c, __pos). */ size_type find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->rfind(__c, __pos); } #if __cplusplus > 201402L /** * @brief Find last position of a character of string. * @param __svt An object convertible to string_view containing * characters to locate. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> find_last_of(const _Tp& __svt, size_type __pos = npos) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->find_last_of(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find position of a character not in string. * @param __str String containing characters to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character not contained * in @a __str within this string. If found, returns the index where it * was found. If not found, returns npos. */ size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { return this->find_first_not_of(__str.data(), __pos, __str.size()); } /** * @brief Find position of a character not in C substring. * @param __s C string containing characters to avoid. * @param __pos Index of character to search from. * @param __n Number of characters from __s to consider. * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character not * contained in the first @a __n characters of @a __s within * this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find position of a character not in C string. * @param __s C string containing characters to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character not * contained in @a __s within this string. If found, returns * the index where it was found. If not found, returns npos. */ size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->find_first_not_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find position of a different character. * @param __c Character to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. * * Starting from @a __pos, searches forward for a character * other than @a __c within this string. If found, returns the * index where it was found. If not found, returns npos. */ size_type find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT; #if __cplusplus > 201402L /** * @brief Find position of a character not in a string_view. * @param __svt An object convertible to string_view containing * characters to avoid. * @param __pos Index of character to search from (default 0). * @return Index of first occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> find_first_not_of(const _Tp& __svt, size_type __pos = 0) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->find_first_not_of(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Find last position of a character not in string. * @param __str String containing characters to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character * not contained in @a __str within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { return this->find_last_not_of(__str.data(), __pos, __str.size()); } /** * @brief Find last position of a character not in C substring. * @param __s C string containing characters to avoid. * @param __pos Index of character to search back from. * @param __n Number of characters from s to consider. * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character not * contained in the first @a __n characters of @a __s within this string. * If found, returns the index where it was found. If not found, * returns npos. */ size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT; /** * @brief Find last position of a character not in C string. * @param __s C string containing characters to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character * not contained in @a __s within this string. If found, * returns the index where it was found. If not found, returns * npos. */ size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); return this->find_last_not_of(__s, __pos, traits_type::length(__s)); } /** * @brief Find last position of a different character. * @param __c Character to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. * * Starting from @a __pos, searches backward for a character other than * @a __c within this string. If found, returns the index where it was * found. If not found, returns npos. */ size_type find_last_not_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT; #if __cplusplus > 201402L /** * @brief Find last position of a character not in a string_view. * @param __svt An object convertible to string_view containing * characters to avoid. * @param __pos Index of character to search back from (default end). * @return Index of last occurrence. */ template<typename _Tp> _If_sv<_Tp, size_type> find_last_not_of(const _Tp& __svt, size_type __pos = npos) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return this->find_last_not_of(__sv.data(), __pos, __sv.size()); } #endif // C++17 /** * @brief Get a substring. * @param __pos Index of first character (default 0). * @param __n Number of characters in substring (default remainder). * @return The new string. * @throw std::out_of_range If __pos > size(). * * Construct and return a new string using the @a __n * characters starting at @a __pos. If the string is too * short, use the remainder of the characters. If @a __pos is * beyond the end of the string, out_of_range is thrown. */ basic_string substr(size_type __pos = 0, size_type __n = npos) const { return basic_string(*this, _M_check(__pos, "basic_string::substr"), __n); } /** * @brief Compare to a string. * @param __str String to compare against. * @return Integer < 0, 0, or > 0. * * Returns an integer < 0 if this string is ordered before @a * __str, 0 if their values are equivalent, or > 0 if this * string is ordered after @a __str. Determines the effective * length rlen of the strings to compare as the smallest of * size() and str.size(). The function then compares the two * strings by calling traits::compare(data(), str.data(),rlen). * If the result of the comparison is nonzero returns it, * otherwise the shorter one is ordered first. */ int compare(const basic_string& __str) const { const size_type __size = this->size(); const size_type __osize = __str.size(); const size_type __len = std::min(__size, __osize); int __r = traits_type::compare(_M_data(), __str.data(), __len); if (!__r) __r = _S_compare(__size, __osize); return __r; } #if __cplusplus > 201402L /** * @brief Compare to a string_view. * @param __svt An object convertible to string_view to compare against. * @return Integer < 0, 0, or > 0. */ template<typename _Tp> _If_sv<_Tp, int> compare(const _Tp& __svt) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; const size_type __size = this->size(); const size_type __osize = __sv.size(); const size_type __len = std::min(__size, __osize); int __r = traits_type::compare(_M_data(), __sv.data(), __len); if (!__r) __r = _S_compare(__size, __osize); return __r; } /** * @brief Compare to a string_view. * @param __pos A position in the string to start comparing from. * @param __n The number of characters to compare. * @param __svt An object convertible to string_view to compare * against. * @return Integer < 0, 0, or > 0. */ template<typename _Tp> _If_sv<_Tp, int> compare(size_type __pos, size_type __n, const _Tp& __svt) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return __sv_type(*this).substr(__pos, __n).compare(__sv); } /** * @brief Compare to a string_view. * @param __pos1 A position in the string to start comparing from. * @param __n1 The number of characters to compare. * @param __svt An object convertible to string_view to compare * against. * @param __pos2 A position in the string_view to start comparing from. * @param __n2 The number of characters to compare. * @return Integer < 0, 0, or > 0. */ template<typename _Tp> _If_sv<_Tp, int> compare(size_type __pos1, size_type __n1, const _Tp& __svt, size_type __pos2, size_type __n2 = npos) const noexcept(is_same<_Tp, __sv_type>::value) { __sv_type __sv = __svt; return __sv_type(*this) .substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); } #endif // C++17 /** * @brief Compare substring to a string. * @param __pos Index of first character of substring. * @param __n Number of characters in substring. * @param __str String to compare against. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n characters * starting at @a __pos. Returns an integer < 0 if the * substring is ordered before @a __str, 0 if their values are * equivalent, or > 0 if the substring is ordered after @a * __str. Determines the effective length rlen of the strings * to compare as the smallest of the length of the substring * and @a __str.size(). The function then compares the two * strings by calling * traits::compare(substring.data(),str.data(),rlen). If the * result of the comparison is nonzero returns it, otherwise * the shorter one is ordered first. */ int compare(size_type __pos, size_type __n, const basic_string& __str) const; /** * @brief Compare substring to a substring. * @param __pos1 Index of first character of substring. * @param __n1 Number of characters in substring. * @param __str String to compare against. * @param __pos2 Index of first character of substring of str. * @param __n2 Number of characters in substring of str. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n1 * characters starting at @a __pos1. Form the substring of @a * __str from the @a __n2 characters starting at @a __pos2. * Returns an integer < 0 if this substring is ordered before * the substring of @a __str, 0 if their values are equivalent, * or > 0 if this substring is ordered after the substring of * @a __str. Determines the effective length rlen of the * strings to compare as the smallest of the lengths of the * substrings. The function then compares the two strings by * calling * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). * If the result of the comparison is nonzero returns it, * otherwise the shorter one is ordered first. */ int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos) const; /** * @brief Compare to a C string. * @param __s C string to compare against. * @return Integer < 0, 0, or > 0. * * Returns an integer < 0 if this string is ordered before @a __s, 0 if * their values are equivalent, or > 0 if this string is ordered after * @a __s. Determines the effective length rlen of the strings to * compare as the smallest of size() and the length of a string * constructed from @a __s. The function then compares the two strings * by calling traits::compare(data(),s,rlen). If the result of the * comparison is nonzero returns it, otherwise the shorter one is * ordered first. */ int compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 5 String::compare specification questionable /** * @brief Compare substring to a C string. * @param __pos Index of first character of substring. * @param __n1 Number of characters in substring. * @param __s C string to compare against. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n1 * characters starting at @a pos. Returns an integer < 0 if * the substring is ordered before @a __s, 0 if their values * are equivalent, or > 0 if the substring is ordered after @a * __s. Determines the effective length rlen of the strings to * compare as the smallest of the length of the substring and * the length of a string constructed from @a __s. The * function then compares the two string by calling * traits::compare(substring.data(),__s,rlen). If the result of * the comparison is nonzero returns it, otherwise the shorter * one is ordered first. */ int compare(size_type __pos, size_type __n1, const _CharT* __s) const; /** * @brief Compare substring against a character %array. * @param __pos Index of first character of substring. * @param __n1 Number of characters in substring. * @param __s character %array to compare against. * @param __n2 Number of characters of s. * @return Integer < 0, 0, or > 0. * * Form the substring of this string from the @a __n1 * characters starting at @a __pos. Form a string from the * first @a __n2 characters of @a __s. Returns an integer < 0 * if this substring is ordered before the string from @a __s, * 0 if their values are equivalent, or > 0 if this substring * is ordered after the string from @a __s. Determines the * effective length rlen of the strings to compare as the * smallest of the length of the substring and @a __n2. The * function then compares the two strings by calling * traits::compare(substring.data(),s,rlen). If the result of * the comparison is nonzero returns it, otherwise the shorter * one is ordered first. * * NB: s must have at least n2 characters, '\\0' has * no special meaning. */ int compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const; # ifdef _GLIBCXX_TM_TS_INTERNAL friend void ::_txnal_cow_string_C1_for_exceptions(void* that, const char* s, void* exc); friend const char* ::_txnal_cow_string_c_str(const void *that); friend void ::_txnal_cow_string_D1(void *that); friend void ::_txnal_cow_string_D1_commit(void *that); # endif }; #endif // !_GLIBCXX_USE_CXX11_ABI #if __cpp_deduction_guides >= 201606 _GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _InputIterator, typename _CharT = typename iterator_traits<_InputIterator>::value_type, typename _Allocator = allocator<_CharT>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3075. basic_string needs deduction guides from basic_string_view template<typename _CharT, typename _Traits, typename _Allocator = allocator<_CharT>, typename = _RequireAllocator<_Allocator>> basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator()) -> basic_string<_CharT, _Traits, _Allocator>; template<typename _CharT, typename _Traits, typename _Allocator = allocator<_CharT>, typename = _RequireAllocator<_Allocator>> basic_string(basic_string_view<_CharT, _Traits>, typename basic_string<_CharT, _Traits, _Allocator>::size_type, typename basic_string<_CharT, _Traits, _Allocator>::size_type, const _Allocator& = _Allocator()) -> basic_string<_CharT, _Traits, _Allocator>; _GLIBCXX_END_NAMESPACE_CXX11 #endif // operator+ /** * @brief Concatenate two strings. * @param __lhs First string. * @param __rhs Last string. * @return New string with value of @a __lhs followed by @a __rhs. */ template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc> operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { basic_string<_CharT, _Traits, _Alloc> __str(__lhs); __str.append(__rhs); return __str; } /** * @brief Concatenate C string and string. * @param __lhs First string. * @param __rhs Last string. * @return New string with value of @a __lhs followed by @a __rhs. */ template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT,_Traits,_Alloc> operator+(const _CharT* __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); /** * @brief Concatenate character and string. * @param __lhs First string. * @param __rhs Last string. * @return New string with @a __lhs followed by @a __rhs. */ template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT,_Traits,_Alloc> operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs); /** * @brief Concatenate string and C string. * @param __lhs First string. * @param __rhs Last string. * @return New string with @a __lhs followed by @a __rhs. */ template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { basic_string<_CharT, _Traits, _Alloc> __str(__lhs); __str.append(__rhs); return __str; } /** * @brief Concatenate string and character. * @param __lhs First string. * @param __rhs Last string. * @return New string with @a __lhs followed by @a __rhs. */ template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs) { typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __string_type::size_type __size_type; __string_type __str(__lhs); __str.append(__size_type(1), __rhs); return __str; } #if __cplusplus >= 201103L template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return std::move(__lhs.append(__rhs)); } template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, basic_string<_CharT, _Traits, _Alloc>&& __rhs) { return std::move(__rhs.insert(0, __lhs)); } template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs, basic_string<_CharT, _Traits, _Alloc>&& __rhs) { const auto __size = __lhs.size() + __rhs.size(); const bool __cond = (__size > __lhs.capacity() && __size <= __rhs.capacity()); return __cond ? std::move(__rhs.insert(0, __lhs)) : std::move(__lhs.append(__rhs)); } template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(const _CharT* __lhs, basic_string<_CharT, _Traits, _Alloc>&& __rhs) { return std::move(__rhs.insert(0, __lhs)); } template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(_CharT __lhs, basic_string<_CharT, _Traits, _Alloc>&& __rhs) { return std::move(__rhs.insert(0, 1, __lhs)); } template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs, const _CharT* __rhs) { return std::move(__lhs.append(__rhs)); } template<typename _CharT, typename _Traits, typename _Alloc> inline basic_string<_CharT, _Traits, _Alloc> operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs, _CharT __rhs) { return std::move(__lhs.append(1, __rhs)); } #endif // operator == /** * @brief Test equivalence of two strings. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.compare(__rhs) == 0; } template<typename _CharT> inline typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type operator==(const basic_string<_CharT>& __lhs, const basic_string<_CharT>& __rhs) _GLIBCXX_NOEXCEPT { return (__lhs.size() == __rhs.size() && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(), __lhs.size())); } /** * @brief Test equivalence of C string and string. * @param __lhs C string. * @param __rhs String. * @return True if @a __rhs.compare(@a __lhs) == 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator==(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) == 0; } /** * @brief Test equivalence of string and C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs.compare(@a __rhs) == 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) == 0; } // operator != /** * @brief Test difference of two strings. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT { return !(__lhs == __rhs); } /** * @brief Test difference of C string and string. * @param __lhs C string. * @param __rhs String. * @return True if @a __rhs.compare(@a __lhs) != 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator!=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return !(__lhs == __rhs); } /** * @brief Test difference of string and C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs.compare(@a __rhs) != 0. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return !(__lhs == __rhs); } // operator < /** * @brief Test if string precedes string. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs precedes @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.compare(__rhs) < 0; } /** * @brief Test if string precedes C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs precedes @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) < 0; } /** * @brief Test if C string precedes string. * @param __lhs C string. * @param __rhs String. * @return True if @a __lhs precedes @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) > 0; } // operator > /** * @brief Test if string follows string. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs follows @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.compare(__rhs) > 0; } /** * @brief Test if string follows C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs follows @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) > 0; } /** * @brief Test if C string follows string. * @param __lhs C string. * @param __rhs String. * @return True if @a __lhs follows @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) < 0; } // operator <= /** * @brief Test if string doesn't follow string. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs doesn't follow @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.compare(__rhs) <= 0; } /** * @brief Test if string doesn't follow C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs doesn't follow @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) <= 0; } /** * @brief Test if C string doesn't follow string. * @param __lhs C string. * @param __rhs String. * @return True if @a __lhs doesn't follow @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator<=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) >= 0; } // operator >= /** * @brief Test if string doesn't precede string. * @param __lhs First string. * @param __rhs Second string. * @return True if @a __lhs doesn't precede @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT { return __lhs.compare(__rhs) >= 0; } /** * @brief Test if string doesn't precede C string. * @param __lhs String. * @param __rhs C string. * @return True if @a __lhs doesn't precede @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>=(const basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs) { return __lhs.compare(__rhs) >= 0; } /** * @brief Test if C string doesn't precede string. * @param __lhs C string. * @param __rhs String. * @return True if @a __lhs doesn't precede @a __rhs. False otherwise. */ template<typename _CharT, typename _Traits, typename _Alloc> inline bool operator>=(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { return __rhs.compare(__lhs) <= 0; } /** * @brief Swap contents of two strings. * @param __lhs First string. * @param __rhs Second string. * * Exchanges the contents of @a __lhs and @a __rhs in constant time. */ template<typename _CharT, typename _Traits, typename _Alloc> inline void swap(basic_string<_CharT, _Traits, _Alloc>& __lhs, basic_string<_CharT, _Traits, _Alloc>& __rhs) _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) { __lhs.swap(__rhs); } /** * @brief Read stream into a string. * @param __is Input stream. * @param __str Buffer to store into. * @return Reference to the input stream. * * Stores characters from @a __is into @a __str until whitespace is * found, the end of the stream is encountered, or str.max_size() * is reached. If is.width() is non-zero, that is the limit on the * number of characters stored into @a __str. Any previous * contents of @a __str are erased. */ template<typename _CharT, typename _Traits, typename _Alloc> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Alloc>& __str); template<> basic_istream<char>& operator>>(basic_istream<char>& __is, basic_string<char>& __str); /** * @brief Write string to a stream. * @param __os Output stream. * @param __str String to write out. * @return Reference to the output stream. * * Output characters of @a __str into os following the same rules as for * writing a C string. */ template<typename _CharT, typename _Traits, typename _Alloc> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const basic_string<_CharT, _Traits, _Alloc>& __str) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 586. string inserter not a formatted function return __ostream_insert(__os, __str.data(), __str.size()); } /** * @brief Read a line from stream into a string. * @param __is Input stream. * @param __str Buffer to store into. * @param __delim Character marking end of line. * @return Reference to the input stream. * * Stores characters from @a __is into @a __str until @a __delim is * found, the end of the stream is encountered, or str.max_size() * is reached. Any previous contents of @a __str are erased. If * @a __delim is encountered, it is extracted but not stored into * @a __str. */ template<typename _CharT, typename _Traits, typename _Alloc> basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim); /** * @brief Read a line from stream into a string. * @param __is Input stream. * @param __str Buffer to store into. * @return Reference to the input stream. * * Stores characters from is into @a __str until '\n' is * found, the end of the stream is encountered, or str.max_size() * is reached. Any previous contents of @a __str are erased. If * end of line is encountered, it is extracted but not stored into * @a __str. */ template<typename _CharT, typename _Traits, typename _Alloc> inline basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>& __is, basic_string<_CharT, _Traits, _Alloc>& __str) { return std::getline(__is, __str, __is.widen('\n')); } #if __cplusplus >= 201103L /// Read a line from an rvalue stream into a string. template<typename _CharT, typename _Traits, typename _Alloc> inline basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) { return std::getline(__is, __str, __delim); } /// Read a line from an rvalue stream into a string. template<typename _CharT, typename _Traits, typename _Alloc> inline basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>&& __is, basic_string<_CharT, _Traits, _Alloc>& __str) { return std::getline(__is, __str); } #endif template<> basic_istream<char>& getline(basic_istream<char>& __in, basic_string<char>& __str, char __delim); #ifdef _GLIBCXX_USE_WCHAR_T template<> basic_istream<wchar_t>& getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str, wchar_t __delim); #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if __cplusplus >= 201103L #include <ext/string_conversions.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CXX11 #if _GLIBCXX_USE_C99_STDLIB // 21.4 Numeric Conversions [string.conversions]. inline int stoi(const string& __str, size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(), __idx, __base); } inline long stol(const string& __str, size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(), __idx, __base); } inline unsigned long stoul(const string& __str, size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(), __idx, __base); } inline long long stoll(const string& __str, size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(), __idx, __base); } inline unsigned long long stoull(const string& __str, size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(), __idx, __base); } // NB: strtof vs strtod. inline float stof(const string& __str, size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); } inline double stod(const string& __str, size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); } inline long double stold(const string& __str, size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); } #endif // _GLIBCXX_USE_C99_STDLIB #if _GLIBCXX_USE_C99_STDIO // NB: (v)snprintf vs sprintf. // DR 1261. inline string to_string(int __val) { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(int), "%d", __val); } inline string to_string(unsigned __val) { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(unsigned), "%u", __val); } inline string to_string(long __val) { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(long), "%ld", __val); } inline string to_string(unsigned long __val) { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(unsigned long), "%lu", __val); } inline string to_string(long long __val) { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(long long), "%lld", __val); } inline string to_string(unsigned long long __val) { return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, 4 * sizeof(unsigned long long), "%llu", __val); } inline string to_string(float __val) { const int __n = __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n, "%f", __val); } inline string to_string(double __val) { const int __n = __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n, "%f", __val); } inline string to_string(long double __val) { const int __n = __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n, "%Lf", __val); } #endif // _GLIBCXX_USE_C99_STDIO #if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_WCHAR inline int stoi(const wstring& __str, size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa<long, int>(&std::wcstol, "stoi", __str.c_str(), __idx, __base); } inline long stol(const wstring& __str, size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::wcstol, "stol", __str.c_str(), __idx, __base); } inline unsigned long stoul(const wstring& __str, size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::wcstoul, "stoul", __str.c_str(), __idx, __base); } inline long long stoll(const wstring& __str, size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(), __idx, __base); } inline unsigned long long stoull(const wstring& __str, size_t* __idx = 0, int __base = 10) { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(), __idx, __base); } // NB: wcstof vs wcstod. inline float stof(const wstring& __str, size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); } inline double stod(const wstring& __str, size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::wcstod, "stod", __str.c_str(), __idx); } inline long double stold(const wstring& __str, size_t* __idx = 0) { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); } #ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF // DR 1261. inline wstring to_wstring(int __val) { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(int), L"%d", __val); } inline wstring to_wstring(unsigned __val) { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(unsigned), L"%u", __val); } inline wstring to_wstring(long __val) { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(long), L"%ld", __val); } inline wstring to_wstring(unsigned long __val) { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(unsigned long), L"%lu", __val); } inline wstring to_wstring(long long __val) { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(long long), L"%lld", __val); } inline wstring to_wstring(unsigned long long __val) { return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, 4 * sizeof(unsigned long long), L"%llu", __val); } inline wstring to_wstring(float __val) { const int __n = __gnu_cxx::__numeric_traits<float>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n, L"%f", __val); } inline wstring to_wstring(double __val) { const int __n = __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n, L"%f", __val); } inline wstring to_wstring(long double __val) { const int __n = __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 20; return __gnu_cxx::__to_xstring<wstring>(&std::vswprintf, __n, L"%Lf", __val); } #endif // _GLIBCXX_HAVE_BROKEN_VSWPRINTF #endif // _GLIBCXX_USE_WCHAR_T && _GLIBCXX_USE_C99_WCHAR _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* C++11 */ #if __cplusplus >= 201103L #include <bits/functional_hash.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // DR 1182. #ifndef _GLIBCXX_COMPATIBILITY_CXX0X /// std::hash specialization for string. template<> struct hash<string> : public __hash_base<size_t, string> { size_t operator()(const string& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length()); } }; template<> struct __is_fast_hash<hash<string>> : std::false_type { }; #ifdef _GLIBCXX_USE_WCHAR_T /// std::hash specialization for wstring. template<> struct hash<wstring> : public __hash_base<size_t, wstring> { size_t operator()(const wstring& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(wchar_t)); } }; template<> struct __is_fast_hash<hash<wstring>> : std::false_type { }; #endif #endif /* _GLIBCXX_COMPATIBILITY_CXX0X */ #ifdef _GLIBCXX_USE_C99_STDINT_TR1 /// std::hash specialization for u16string. template<> struct hash<u16string> : public __hash_base<size_t, u16string> { size_t operator()(const u16string& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(char16_t)); } }; template<> struct __is_fast_hash<hash<u16string>> : std::false_type { }; /// std::hash specialization for u32string. template<> struct hash<u32string> : public __hash_base<size_t, u32string> { size_t operator()(const u32string& __s) const noexcept { return std::_Hash_impl::hash(__s.data(), __s.length() * sizeof(char32_t)); } }; template<> struct __is_fast_hash<hash<u32string>> : std::false_type { }; #endif #if __cplusplus > 201103L #define __cpp_lib_string_udls 201304 inline namespace literals { inline namespace string_literals { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wliteral-suffix" _GLIBCXX_DEFAULT_ABI_TAG inline basic_string<char> operator""s(const char* __str, size_t __len) { return basic_string<char>{__str, __len}; } #ifdef _GLIBCXX_USE_WCHAR_T _GLIBCXX_DEFAULT_ABI_TAG inline basic_string<wchar_t> operator""s(const wchar_t* __str, size_t __len) { return basic_string<wchar_t>{__str, __len}; } #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 _GLIBCXX_DEFAULT_ABI_TAG inline basic_string<char16_t> operator""s(const char16_t* __str, size_t __len) { return basic_string<char16_t>{__str, __len}; } _GLIBCXX_DEFAULT_ABI_TAG inline basic_string<char32_t> operator""s(const char32_t* __str, size_t __len) { return basic_string<char32_t>{__str, __len}; } #endif #pragma GCC diagnostic pop } // inline namespace string_literals } // inline namespace literals #endif // __cplusplus > 201103L _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif /* _BASIC_STRING_H */ c++/8/bits/valarray_array.tcc 0000644 00000016126 15146341150 0011744 0 ustar 00 // The template and inlines for the -*- C++ -*- internal _Array helper class. // Copyright (C) 1997-2018 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/valarray_array.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{valarray} */ // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> #ifndef _VALARRAY_ARRAY_TCC #define _VALARRAY_ARRAY_TCC 1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> void __valarray_fill(_Array<_Tp> __a, size_t __n, _Array<bool> __m, const _Tp& __t) { _Tp* __p = __a._M_data; bool* __ok (__m._M_data); for (size_t __i=0; __i < __n; ++__i, ++__ok, ++__p) { while (!*__ok) { ++__ok; ++__p; } *__p = __t; } } // Copy n elements of a into consecutive elements of b. When m is // false, the corresponding element of a is skipped. m must contain // at least n true elements. a must contain at least n elements and // enough elements to match up with m through the nth true element // of m. I.e. if n is 10, m has 15 elements with 5 false followed // by 10 true, a must have 15 elements. template<typename _Tp> void __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b, size_t __n) { _Tp* __p (__a._M_data); bool* __ok (__m._M_data); for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__q, ++__ok, ++__p) { while (! *__ok) { ++__ok; ++__p; } *__q = *__p; } } // Copy n consecutive elements from a into elements of b. Elements // of b are skipped if the corresponding element of m is false. m // must contain at least n true elements. b must have at least as // many elements as the index of the nth true element of m. I.e. if // m has 15 elements with 5 false followed by 10 true, b must have // at least 15 elements. template<typename _Tp> void __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, _Array<bool> __m) { _Tp* __q (__b._M_data); bool* __ok (__m._M_data); for (_Tp* __p = __a._M_data; __p < __a._M_data+__n; ++__p, ++__ok, ++__q) { while (! *__ok) { ++__ok; ++__q; } *__q = *__p; } } // Copy n elements from a into elements of b. Elements of a are // skipped if the corresponding element of m is false. Elements of // b are skipped if the corresponding element of k is false. m and // k must contain at least n true elements. a and b must have at // least as many elements as the index of the nth true element of m. template<typename _Tp> void __valarray_copy(_Array<_Tp> __a, _Array<bool> __m, size_t __n, _Array<_Tp> __b, _Array<bool> __k) { _Tp* __p (__a._M_data); _Tp* __q (__b._M_data); bool* __srcok (__m._M_data); bool* __dstok (__k._M_data); for (size_t __i = 0; __i < __n; ++__srcok, ++__p, ++__dstok, ++__q, ++__i) { while (! *__srcok) { ++__srcok; ++__p; } while (! *__dstok) { ++__dstok; ++__q; } *__q = *__p; } } // Copy n consecutive elements of e into consecutive elements of a. // I.e. a[i] = e[i]. template<typename _Tp, class _Dom> void __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a) { _Tp* __p (__a._M_data); for (size_t __i = 0; __i < __n; ++__i, ++__p) *__p = __e[__i]; } // Copy n consecutive elements of e into elements of a using stride // s. I.e., a[0] = e[0], a[s] = e[1], a[2*s] = e[2]. template<typename _Tp, class _Dom> void __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a, size_t __s) { _Tp* __p (__a._M_data); for (size_t __i = 0; __i < __n; ++__i, __p += __s) *__p = __e[__i]; } // Copy n consecutive elements of e into elements of a indexed by // contents of i. I.e., a[i[0]] = e[0]. template<typename _Tp, class _Dom> void __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a, _Array<size_t> __i) { size_t* __j (__i._M_data); for (size_t __k = 0; __k < __n; ++__k, ++__j) __a._M_data[*__j] = __e[__k]; } // Copy n elements of e indexed by contents of f into elements of a // indexed by contents of i. I.e., a[i[0]] = e[f[0]]. template<typename _Tp> void __valarray_copy(_Array<_Tp> __e, _Array<size_t> __f, size_t __n, _Array<_Tp> __a, _Array<size_t> __i) { size_t* __g (__f._M_data); size_t* __j (__i._M_data); for (size_t __k = 0; __k < __n; ++__k, ++__j, ++__g) __a._M_data[*__j] = __e._M_data[*__g]; } // Copy n consecutive elements of e into elements of a. Elements of // a are skipped if the corresponding element of m is false. m must // have at least n true elements and a must have at least as many // elements as the index of the nth true element of m. I.e. if m // has 5 false followed by 10 true elements and n == 10, a must have // at least 15 elements. template<typename _Tp, class _Dom> void __valarray_copy(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a, _Array<bool> __m) { bool* __ok (__m._M_data); _Tp* __p (__a._M_data); for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) { while (! *__ok) { ++__ok; ++__p; } *__p = __e[__i]; } } template<typename _Tp, class _Dom> void __valarray_copy_construct(const _Expr<_Dom, _Tp>& __e, size_t __n, _Array<_Tp> __a) { _Tp* __p (__a._M_data); for (size_t __i = 0; __i < __n; ++__i, ++__p) new (__p) _Tp(__e[__i]); } template<typename _Tp> void __valarray_copy_construct(_Array<_Tp> __a, _Array<bool> __m, _Array<_Tp> __b, size_t __n) { _Tp* __p (__a._M_data); bool* __ok (__m._M_data); for (_Tp* __q = __b._M_data; __q < __b._M_data+__n; ++__q, ++__ok, ++__p) { while (! *__ok) { ++__ok; ++__p; } new (__q) _Tp(*__p); } } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _VALARRAY_ARRAY_TCC */ c++/8/bits/valarray_array.h 0000644 00000052457 15146341150 0011431 0 ustar 00 // The template and inlines for the -*- C++ -*- internal _Array helper class. // Copyright (C) 1997-2018 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/valarray_array.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{valarray} */ // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> #ifndef _VALARRAY_ARRAY_H #define _VALARRAY_ARRAY_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/cpp_type_traits.h> #include <cstdlib> #include <new> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // // Helper functions on raw pointers // // We get memory by the old fashion way inline void* __valarray_get_memory(size_t __n) { return operator new(__n); } template<typename _Tp> inline _Tp*__restrict__ __valarray_get_storage(size_t __n) { return static_cast<_Tp*__restrict__> (std::__valarray_get_memory(__n * sizeof(_Tp))); } // Return memory to the system inline void __valarray_release_memory(void* __p) { operator delete(__p); } // Turn a raw-memory into an array of _Tp filled with _Tp() // This is required in 'valarray<T> v(n);' template<typename _Tp, bool> struct _Array_default_ctor { // Please note that this isn't exception safe. But // valarrays aren't required to be exception safe. inline static void _S_do_it(_Tp* __b, _Tp* __e) { while (__b != __e) new(__b++) _Tp(); } }; template<typename _Tp> struct _Array_default_ctor<_Tp, true> { // For fundamental types, it suffices to say 'memset()' inline static void _S_do_it(_Tp* __b, _Tp* __e) { __builtin_memset(__b, 0, (__e - __b) * sizeof(_Tp)); } }; template<typename _Tp> inline void __valarray_default_construct(_Tp* __b, _Tp* __e) { _Array_default_ctor<_Tp, __is_scalar<_Tp>::__value>::_S_do_it(__b, __e); } // Turn a raw-memory into an array of _Tp filled with __t // This is the required in valarray<T> v(n, t). Also // used in valarray<>::resize(). template<typename _Tp, bool> struct _Array_init_ctor { // Please note that this isn't exception safe. But // valarrays aren't required to be exception safe. inline static void _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t) { while (__b != __e) new(__b++) _Tp(__t); } }; template<typename _Tp> struct _Array_init_ctor<_Tp, true> { inline static void _S_do_it(_Tp* __b, _Tp* __e, const _Tp __t) { while (__b != __e) *__b++ = __t; } }; template<typename _Tp> inline void __valarray_fill_construct(_Tp* __b, _Tp* __e, const _Tp __t) { _Array_init_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __t); } // // copy-construct raw array [__o, *) from plain array [__b, __e) // We can't just say 'memcpy()' // template<typename _Tp, bool> struct _Array_copy_ctor { // Please note that this isn't exception safe. But // valarrays aren't required to be exception safe. inline static void _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) { while (__b != __e) new(__o++) _Tp(*__b++); } }; template<typename _Tp> struct _Array_copy_ctor<_Tp, true> { inline static void _S_do_it(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) { if (__b) __builtin_memcpy(__o, __b, (__e - __b) * sizeof(_Tp)); } }; template<typename _Tp> inline void __valarray_copy_construct(const _Tp* __b, const _Tp* __e, _Tp* __restrict__ __o) { _Array_copy_ctor<_Tp, __is_trivial(_Tp)>::_S_do_it(__b, __e, __o); } // copy-construct raw array [__o, *) from strided array __a[<__n : __s>] template<typename _Tp> inline void __valarray_copy_construct (const _Tp* __restrict__ __a, size_t __n, size_t __s, _Tp* __restrict__ __o) { if (__is_trivial(_Tp)) while (__n--) { *__o++ = *__a; __a += __s; } else while (__n--) { new(__o++) _Tp(*__a); __a += __s; } } // copy-construct raw array [__o, *) from indexed array __a[__i[<__n>]] template<typename _Tp> inline void __valarray_copy_construct (const _Tp* __restrict__ __a, const size_t* __restrict__ __i, _Tp* __restrict__ __o, size_t __n) { if (__is_trivial(_Tp)) while (__n--) *__o++ = __a[*__i++]; else while (__n--) new (__o++) _Tp(__a[*__i++]); } // Do the necessary cleanup when we're done with arrays. template<typename _Tp> inline void __valarray_destroy_elements(_Tp* __b, _Tp* __e) { if (!__is_trivial(_Tp)) while (__b != __e) { __b->~_Tp(); ++__b; } } // Fill a plain array __a[<__n>] with __t template<typename _Tp> inline void __valarray_fill(_Tp* __restrict__ __a, size_t __n, const _Tp& __t) { while (__n--) *__a++ = __t; } // fill strided array __a[<__n-1 : __s>] with __t template<typename _Tp> inline void __valarray_fill(_Tp* __restrict__ __a, size_t __n, size_t __s, const _Tp& __t) { for (size_t __i = 0; __i < __n; ++__i, __a += __s) *__a = __t; } // fill indirect array __a[__i[<__n>]] with __i template<typename _Tp> inline void __valarray_fill(_Tp* __restrict__ __a, const size_t* __restrict__ __i, size_t __n, const _Tp& __t) { for (size_t __j = 0; __j < __n; ++__j, ++__i) __a[*__i] = __t; } // copy plain array __a[<__n>] in __b[<__n>] // For non-fundamental types, it is wrong to say 'memcpy()' template<typename _Tp, bool> struct _Array_copier { inline static void _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) { while(__n--) *__b++ = *__a++; } }; template<typename _Tp> struct _Array_copier<_Tp, true> { inline static void _S_do_it(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) { if (__n != 0) __builtin_memcpy(__b, __a, __n * sizeof (_Tp)); } }; // Copy a plain array __a[<__n>] into a play array __b[<>] template<typename _Tp> inline void __valarray_copy(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b) { _Array_copier<_Tp, __is_trivial(_Tp)>::_S_do_it(__a, __n, __b); } // Copy strided array __a[<__n : __s>] in plain __b[<__n>] template<typename _Tp> inline void __valarray_copy(const _Tp* __restrict__ __a, size_t __n, size_t __s, _Tp* __restrict__ __b) { for (size_t __i = 0; __i < __n; ++__i, ++__b, __a += __s) *__b = *__a; } // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] template<typename _Tp> inline void __valarray_copy(const _Tp* __restrict__ __a, _Tp* __restrict__ __b, size_t __n, size_t __s) { for (size_t __i = 0; __i < __n; ++__i, ++__a, __b += __s) *__b = *__a; } // Copy strided array __src[<__n : __s1>] into another // strided array __dst[< : __s2>]. Their sizes must match. template<typename _Tp> inline void __valarray_copy(const _Tp* __restrict__ __src, size_t __n, size_t __s1, _Tp* __restrict__ __dst, size_t __s2) { for (size_t __i = 0; __i < __n; ++__i) __dst[__i * __s2] = __src[__i * __s1]; } // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] template<typename _Tp> inline void __valarray_copy(const _Tp* __restrict__ __a, const size_t* __restrict__ __i, _Tp* __restrict__ __b, size_t __n) { for (size_t __j = 0; __j < __n; ++__j, ++__b, ++__i) *__b = __a[*__i]; } // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] template<typename _Tp> inline void __valarray_copy(const _Tp* __restrict__ __a, size_t __n, _Tp* __restrict__ __b, const size_t* __restrict__ __i) { for (size_t __j = 0; __j < __n; ++__j, ++__a, ++__i) __b[*__i] = *__a; } // Copy the __n first elements of an indexed array __src[<__i>] into // another indexed array __dst[<__j>]. template<typename _Tp> inline void __valarray_copy(const _Tp* __restrict__ __src, size_t __n, const size_t* __restrict__ __i, _Tp* __restrict__ __dst, const size_t* __restrict__ __j) { for (size_t __k = 0; __k < __n; ++__k) __dst[*__j++] = __src[*__i++]; } // // Compute the sum of elements in range [__f, __l) which must not be empty. // This is a naive algorithm. It suffers from cancelling. // In the future try to specialize for _Tp = float, double, long double // using a more accurate algorithm. // template<typename _Tp> inline _Tp __valarray_sum(const _Tp* __f, const _Tp* __l) { _Tp __r = *__f++; while (__f != __l) __r += *__f++; return __r; } // Compute the product of all elements in range [__f, __l) template<typename _Tp> inline _Tp __valarray_product(const _Tp* __f, const _Tp* __l) { _Tp __r = _Tp(1); while (__f != __l) __r = __r * *__f++; return __r; } // Compute the min/max of an array-expression template<typename _Ta> inline typename _Ta::value_type __valarray_min(const _Ta& __a) { size_t __s = __a.size(); typedef typename _Ta::value_type _Value_type; _Value_type __r = __s == 0 ? _Value_type() : __a[0]; for (size_t __i = 1; __i < __s; ++__i) { _Value_type __t = __a[__i]; if (__t < __r) __r = __t; } return __r; } template<typename _Ta> inline typename _Ta::value_type __valarray_max(const _Ta& __a) { size_t __s = __a.size(); typedef typename _Ta::value_type _Value_type; _Value_type __r = __s == 0 ? _Value_type() : __a[0]; for (size_t __i = 1; __i < __s; ++__i) { _Value_type __t = __a[__i]; if (__t > __r) __r = __t; } return __r; } // // Helper class _Array, first layer of valarray abstraction. // All operations on valarray should be forwarded to this class // whenever possible. -- gdr // template<typename _Tp> struct _Array { explicit _Array(size_t); explicit _Array(_Tp* const __restrict__); explicit _Array(const valarray<_Tp>&); _Array(const _Tp* __restrict__, size_t); _Tp* begin() const; _Tp* const __restrict__ _M_data; }; // Copy-construct plain array __b[<__n>] from indexed array __a[__i[<__n>]] template<typename _Tp> inline void __valarray_copy_construct(_Array<_Tp> __a, _Array<size_t> __i, _Array<_Tp> __b, size_t __n) { std::__valarray_copy_construct(__a._M_data, __i._M_data, __b._M_data, __n); } // Copy-construct plain array __b[<__n>] from strided array __a[<__n : __s>] template<typename _Tp> inline void __valarray_copy_construct(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) { std::__valarray_copy_construct(__a._M_data, __n, __s, __b._M_data); } template<typename _Tp> inline void __valarray_fill (_Array<_Tp> __a, size_t __n, const _Tp& __t) { std::__valarray_fill(__a._M_data, __n, __t); } template<typename _Tp> inline void __valarray_fill(_Array<_Tp> __a, size_t __n, size_t __s, const _Tp& __t) { std::__valarray_fill(__a._M_data, __n, __s, __t); } template<typename _Tp> inline void __valarray_fill(_Array<_Tp> __a, _Array<size_t> __i, size_t __n, const _Tp& __t) { std::__valarray_fill(__a._M_data, __i._M_data, __n, __t); } // Copy a plain array __a[<__n>] into a play array __b[<>] template<typename _Tp> inline void __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) { std::__valarray_copy(__a._M_data, __n, __b._M_data); } // Copy strided array __a[<__n : __s>] in plain __b[<__n>] template<typename _Tp> inline void __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s, _Array<_Tp> __b) { std::__valarray_copy(__a._M_data, __n, __s, __b._M_data); } // Copy a plain array __a[<__n>] into a strided array __b[<__n : __s>] template<typename _Tp> inline void __valarray_copy(_Array<_Tp> __a, _Array<_Tp> __b, size_t __n, size_t __s) { __valarray_copy(__a._M_data, __b._M_data, __n, __s); } // Copy strided array __src[<__n : __s1>] into another // strided array __dst[< : __s2>]. Their sizes must match. template<typename _Tp> inline void __valarray_copy(_Array<_Tp> __a, size_t __n, size_t __s1, _Array<_Tp> __b, size_t __s2) { std::__valarray_copy(__a._M_data, __n, __s1, __b._M_data, __s2); } // Copy an indexed array __a[__i[<__n>]] in plain array __b[<__n>] template<typename _Tp> inline void __valarray_copy(_Array<_Tp> __a, _Array<size_t> __i, _Array<_Tp> __b, size_t __n) { std::__valarray_copy(__a._M_data, __i._M_data, __b._M_data, __n); } // Copy a plain array __a[<__n>] in an indexed array __b[__i[<__n>]] template<typename _Tp> inline void __valarray_copy(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b, _Array<size_t> __i) { std::__valarray_copy(__a._M_data, __n, __b._M_data, __i._M_data); } // Copy the __n first elements of an indexed array __src[<__i>] into // another indexed array __dst[<__j>]. template<typename _Tp> inline void __valarray_copy(_Array<_Tp> __src, size_t __n, _Array<size_t> __i, _Array<_Tp> __dst, _Array<size_t> __j) { std::__valarray_copy(__src._M_data, __n, __i._M_data, __dst._M_data, __j._M_data); } template<typename _Tp> inline _Array<_Tp>::_Array(size_t __n) : _M_data(__valarray_get_storage<_Tp>(__n)) { std::__valarray_default_construct(_M_data, _M_data + __n); } template<typename _Tp> inline _Array<_Tp>::_Array(_Tp* const __restrict__ __p) : _M_data (__p) {} template<typename _Tp> inline _Array<_Tp>::_Array(const valarray<_Tp>& __v) : _M_data (__v._M_data) {} template<typename _Tp> inline _Array<_Tp>::_Array(const _Tp* __restrict__ __b, size_t __s) : _M_data(__valarray_get_storage<_Tp>(__s)) { std::__valarray_copy_construct(__b, __s, _M_data); } template<typename _Tp> inline _Tp* _Array<_Tp>::begin () const { return _M_data; } #define _DEFINE_ARRAY_FUNCTION(_Op, _Name) \ template<typename _Tp> \ inline void \ _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, const _Tp& __t) \ { \ for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; ++__p) \ *__p _Op##= __t; \ } \ \ template<typename _Tp> \ inline void \ _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, _Array<_Tp> __b) \ { \ _Tp* __p = __a._M_data; \ for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; ++__p, ++__q) \ *__p _Op##= *__q; \ } \ \ template<typename _Tp, class _Dom> \ void \ _Array_augmented_##_Name(_Array<_Tp> __a, \ const _Expr<_Dom, _Tp>& __e, size_t __n) \ { \ _Tp* __p(__a._M_data); \ for (size_t __i = 0; __i < __n; ++__i, ++__p) \ *__p _Op##= __e[__i]; \ } \ \ template<typename _Tp> \ inline void \ _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, size_t __s, \ _Array<_Tp> __b) \ { \ _Tp* __q(__b._M_data); \ for (_Tp* __p = __a._M_data; __p < __a._M_data + __s * __n; \ __p += __s, ++__q) \ *__p _Op##= *__q; \ } \ \ template<typename _Tp> \ inline void \ _Array_augmented_##_Name(_Array<_Tp> __a, _Array<_Tp> __b, \ size_t __n, size_t __s) \ { \ _Tp* __q(__b._M_data); \ for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ ++__p, __q += __s) \ *__p _Op##= *__q; \ } \ \ template<typename _Tp, class _Dom> \ void \ _Array_augmented_##_Name(_Array<_Tp> __a, size_t __s, \ const _Expr<_Dom, _Tp>& __e, size_t __n) \ { \ _Tp* __p(__a._M_data); \ for (size_t __i = 0; __i < __n; ++__i, __p += __s) \ *__p _Op##= __e[__i]; \ } \ \ template<typename _Tp> \ inline void \ _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ _Array<_Tp> __b, size_t __n) \ { \ _Tp* __q(__b._M_data); \ for (size_t* __j = __i._M_data; __j < __i._M_data + __n; \ ++__j, ++__q) \ __a._M_data[*__j] _Op##= *__q; \ } \ \ template<typename _Tp> \ inline void \ _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ _Array<_Tp> __b, _Array<size_t> __i) \ { \ _Tp* __p(__a._M_data); \ for (size_t* __j = __i._M_data; __j<__i._M_data + __n; \ ++__j, ++__p) \ *__p _Op##= __b._M_data[*__j]; \ } \ \ template<typename _Tp, class _Dom> \ void \ _Array_augmented_##_Name(_Array<_Tp> __a, _Array<size_t> __i, \ const _Expr<_Dom, _Tp>& __e, size_t __n) \ { \ size_t* __j(__i._M_data); \ for (size_t __k = 0; __k<__n; ++__k, ++__j) \ __a._M_data[*__j] _Op##= __e[__k]; \ } \ \ template<typename _Tp> \ void \ _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ _Array<_Tp> __b, size_t __n) \ { \ bool* __ok(__m._M_data); \ _Tp* __p(__a._M_data); \ for (_Tp* __q = __b._M_data; __q < __b._M_data + __n; \ ++__q, ++__ok, ++__p) \ { \ while (! *__ok) \ { \ ++__ok; \ ++__p; \ } \ *__p _Op##= *__q; \ } \ } \ \ template<typename _Tp> \ void \ _Array_augmented_##_Name(_Array<_Tp> __a, size_t __n, \ _Array<_Tp> __b, _Array<bool> __m) \ { \ bool* __ok(__m._M_data); \ _Tp* __q(__b._M_data); \ for (_Tp* __p = __a._M_data; __p < __a._M_data + __n; \ ++__p, ++__ok, ++__q) \ { \ while (! *__ok) \ { \ ++__ok; \ ++__q; \ } \ *__p _Op##= *__q; \ } \ } \ \ template<typename _Tp, class _Dom> \ void \ _Array_augmented_##_Name(_Array<_Tp> __a, _Array<bool> __m, \ const _Expr<_Dom, _Tp>& __e, size_t __n) \ { \ bool* __ok(__m._M_data); \ _Tp* __p(__a._M_data); \ for (size_t __i = 0; __i < __n; ++__i, ++__ok, ++__p) \ { \ while (! *__ok) \ { \ ++__ok; \ ++__p; \ } \ *__p _Op##= __e[__i]; \ } \ } _DEFINE_ARRAY_FUNCTION(+, __plus) _DEFINE_ARRAY_FUNCTION(-, __minus) _DEFINE_ARRAY_FUNCTION(*, __multiplies) _DEFINE_ARRAY_FUNCTION(/, __divides) _DEFINE_ARRAY_FUNCTION(%, __modulus) _DEFINE_ARRAY_FUNCTION(^, __bitwise_xor) _DEFINE_ARRAY_FUNCTION(|, __bitwise_or) _DEFINE_ARRAY_FUNCTION(&, __bitwise_and) _DEFINE_ARRAY_FUNCTION(<<, __shift_left) _DEFINE_ARRAY_FUNCTION(>>, __shift_right) #undef _DEFINE_ARRAY_FUNCTION _GLIBCXX_END_NAMESPACE_VERSION } // namespace # include <bits/valarray_array.tcc> #endif /* _ARRAY_H */ c++/8/bits/hash_bytes.h 0000644 00000004142 15146341150 0010527 0 ustar 00 // Declarations for hash functions. -*- C++ -*- // Copyright (C) 2010-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/hash_bytes.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{functional} */ #ifndef _HASH_BYTES_H #define _HASH_BYTES_H 1 #pragma GCC system_header #include <bits/c++config.h> namespace std { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Hash function implementation for the nontrivial specialization. // All of them are based on a primitive that hashes a pointer to a // byte array. The actual hash algorithm is not guaranteed to stay // the same from release to release -- it may be updated or tuned to // improve hash quality or speed. size_t _Hash_bytes(const void* __ptr, size_t __len, size_t __seed); // A similar hash primitive, using the FNV hash algorithm. This // algorithm is guaranteed to stay the same from release to release. // (although it might not produce the same values on different // machines.) size_t _Fnv_hash_bytes(const void* __ptr, size_t __len, size_t __seed); _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/bits/regex_scanner.h 0000644 00000015660 15146341150 0011230 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2013-2018 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/regex_scanner.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { /** * @addtogroup regex-detail * @{ */ struct _ScannerBase { public: /// Token types returned from the scanner. enum _TokenT : unsigned { _S_token_anychar, _S_token_ord_char, _S_token_oct_num, _S_token_hex_num, _S_token_backref, _S_token_subexpr_begin, _S_token_subexpr_no_group_begin, _S_token_subexpr_lookahead_begin, // neg if _M_value[0] == 'n' _S_token_subexpr_end, _S_token_bracket_begin, _S_token_bracket_neg_begin, _S_token_bracket_end, _S_token_interval_begin, _S_token_interval_end, _S_token_quoted_class, _S_token_char_class_name, _S_token_collsymbol, _S_token_equiv_class_name, _S_token_opt, _S_token_or, _S_token_closure0, _S_token_closure1, _S_token_line_begin, _S_token_line_end, _S_token_word_bound, // neg if _M_value[0] == 'n' _S_token_comma, _S_token_dup_count, _S_token_eof, _S_token_bracket_dash, _S_token_unknown = -1u }; protected: typedef regex_constants::syntax_option_type _FlagT; enum _StateT { _S_state_normal, _S_state_in_brace, _S_state_in_bracket, }; protected: _ScannerBase(_FlagT __flags) : _M_state(_S_state_normal), _M_flags(__flags), _M_escape_tbl(_M_is_ecma() ? _M_ecma_escape_tbl : _M_awk_escape_tbl), _M_spec_char(_M_is_ecma() ? _M_ecma_spec_char : _M_flags & regex_constants::basic ? _M_basic_spec_char : _M_flags & regex_constants::extended ? _M_extended_spec_char : _M_flags & regex_constants::grep ? ".[\\*^$\n" : _M_flags & regex_constants::egrep ? ".[\\()*+?{|^$\n" : _M_flags & regex_constants::awk ? _M_extended_spec_char : nullptr), _M_at_bracket_start(false) { __glibcxx_assert(_M_spec_char); } protected: const char* _M_find_escape(char __c) { auto __it = _M_escape_tbl; for (; __it->first != '\0'; ++__it) if (__it->first == __c) return &__it->second; return nullptr; } bool _M_is_ecma() const { return _M_flags & regex_constants::ECMAScript; } bool _M_is_basic() const { return _M_flags & (regex_constants::basic | regex_constants::grep); } bool _M_is_extended() const { return _M_flags & (regex_constants::extended | regex_constants::egrep | regex_constants::awk); } bool _M_is_grep() const { return _M_flags & (regex_constants::grep | regex_constants::egrep); } bool _M_is_awk() const { return _M_flags & regex_constants::awk; } protected: // TODO: Make them static in the next abi change. const std::pair<char, _TokenT> _M_token_tbl[9] = { {'^', _S_token_line_begin}, {'$', _S_token_line_end}, {'.', _S_token_anychar}, {'*', _S_token_closure0}, {'+', _S_token_closure1}, {'?', _S_token_opt}, {'|', _S_token_or}, {'\n', _S_token_or}, // grep and egrep {'\0', _S_token_or}, }; const std::pair<char, char> _M_ecma_escape_tbl[8] = { {'0', '\0'}, {'b', '\b'}, {'f', '\f'}, {'n', '\n'}, {'r', '\r'}, {'t', '\t'}, {'v', '\v'}, {'\0', '\0'}, }; const std::pair<char, char> _M_awk_escape_tbl[11] = { {'"', '"'}, {'/', '/'}, {'\\', '\\'}, {'a', '\a'}, {'b', '\b'}, {'f', '\f'}, {'n', '\n'}, {'r', '\r'}, {'t', '\t'}, {'v', '\v'}, {'\0', '\0'}, }; const char* _M_ecma_spec_char = "^$\\.*+?()[]{}|"; const char* _M_basic_spec_char = ".[\\*^$"; const char* _M_extended_spec_char = ".[\\()*+?{|^$"; _StateT _M_state; _FlagT _M_flags; _TokenT _M_token; const std::pair<char, char>* _M_escape_tbl; const char* _M_spec_char; bool _M_at_bracket_start; }; /** * @brief Scans an input range for regex tokens. * * The %_Scanner class interprets the regular expression pattern in * the input range passed to its constructor as a sequence of parse * tokens passed to the regular expression compiler. The sequence * of tokens provided depends on the flag settings passed to the * constructor: different regular expression grammars will interpret * the same input pattern in syntactically different ways. */ template<typename _CharT> class _Scanner : public _ScannerBase { public: typedef const _CharT* _IterT; typedef std::basic_string<_CharT> _StringT; typedef regex_constants::syntax_option_type _FlagT; typedef const std::ctype<_CharT> _CtypeT; _Scanner(_IterT __begin, _IterT __end, _FlagT __flags, std::locale __loc); void _M_advance(); _TokenT _M_get_token() const { return _M_token; } const _StringT& _M_get_value() const { return _M_value; } #ifdef _GLIBCXX_DEBUG std::ostream& _M_print(std::ostream&); #endif private: void _M_scan_normal(); void _M_scan_in_bracket(); void _M_scan_in_brace(); void _M_eat_escape_ecma(); void _M_eat_escape_posix(); void _M_eat_escape_awk(); void _M_eat_class(char); _IterT _M_current; _IterT _M_end; _CtypeT& _M_ctype; _StringT _M_value; void (_Scanner::* _M_eat_escape)(); }; //@} regex-detail } // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #include <bits/regex_scanner.tcc> c++/8/bits/concept_check.h 0000644 00000006537 15146341150 0011200 0 ustar 00 // Concept-checking control -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/concept_check.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iterator} */ #ifndef _CONCEPT_CHECK_H #define _CONCEPT_CHECK_H 1 #pragma GCC system_header #include <bits/c++config.h> // All places in libstdc++-v3 where these are used, or /might/ be used, or // don't need to be used, or perhaps /should/ be used, are commented with // "concept requirements" (and maybe some more text). So grep like crazy // if you're looking for additional places to use these. // Concept-checking code is off by default unless users turn it on via // configure options or editing c++config.h. // It is not supported for freestanding implementations. #if !defined(_GLIBCXX_CONCEPT_CHECKS) || !_GLIBCXX_HOSTED #define __glibcxx_function_requires(...) #define __glibcxx_class_requires(_a,_b) #define __glibcxx_class_requires2(_a,_b,_c) #define __glibcxx_class_requires3(_a,_b,_c,_d) #define __glibcxx_class_requires4(_a,_b,_c,_d,_e) #else // the checks are on #include <bits/boost_concept_check.h> // Note that the obvious and elegant approach of // //#define glibcxx_function_requires(C) debug::function_requires< debug::C >() // // won't work due to concept templates with more than one parameter, e.g., // BinaryPredicateConcept. The preprocessor tries to split things up on // the commas in the template argument list. We can't use an inner pair of // parenthesis to hide the commas, because "debug::(Temp<Foo,Bar>)" isn't // a valid instantiation pattern. Thus, we steal a feature from C99. #define __glibcxx_function_requires(...) \ __gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >(); #define __glibcxx_class_requires(_a,_C) \ _GLIBCXX_CLASS_REQUIRES(_a, __gnu_cxx, _C); #define __glibcxx_class_requires2(_a,_b,_C) \ _GLIBCXX_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C); #define __glibcxx_class_requires3(_a,_b,_c,_C) \ _GLIBCXX_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C); #define __glibcxx_class_requires4(_a,_b,_c,_d,_C) \ _GLIBCXX_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C); #endif // enable/disable #endif // _GLIBCXX_CONCEPT_CHECK c++/8/bits/sstream.tcc 0000644 00000023636 15146341150 0010407 0 ustar 00 // String based streams -*- C++ -*- // Copyright (C) 1997-2018 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/sstream.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{sstream} */ // // ISO C++ 14882: 27.7 String-based streams // #ifndef _SSTREAM_TCC #define _SSTREAM_TCC 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template <class _CharT, class _Traits, class _Alloc> typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type basic_stringbuf<_CharT, _Traits, _Alloc>:: pbackfail(int_type __c) { int_type __ret = traits_type::eof(); if (this->eback() < this->gptr()) { // Try to put back __c into input sequence in one of three ways. // Order these tests done in is unspecified by the standard. const bool __testeof = traits_type::eq_int_type(__c, __ret); if (!__testeof) { const bool __testeq = traits_type::eq(traits_type:: to_char_type(__c), this->gptr()[-1]); const bool __testout = this->_M_mode & ios_base::out; if (__testeq || __testout) { this->gbump(-1); if (!__testeq) *this->gptr() = traits_type::to_char_type(__c); __ret = __c; } } else { this->gbump(-1); __ret = traits_type::not_eof(__c); } } return __ret; } template <class _CharT, class _Traits, class _Alloc> typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type basic_stringbuf<_CharT, _Traits, _Alloc>:: overflow(int_type __c) { const bool __testout = this->_M_mode & ios_base::out; if (__builtin_expect(!__testout, false)) return traits_type::eof(); const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); if (__builtin_expect(__testeof, false)) return traits_type::not_eof(__c); const __size_type __capacity = _M_string.capacity(); #if _GLIBCXX_USE_CXX11_ABI if ((this->epptr() - this->pbase()) < __capacity) { // There is additional capacity in _M_string that can be used. char_type* __base = const_cast<char_type*>(_M_string.data()); _M_pbump(__base, __base + __capacity, this->pptr() - this->pbase()); if (_M_mode & ios_base::in) { const __size_type __nget = this->gptr() - this->eback(); const __size_type __eget = this->egptr() - this->eback(); this->setg(__base, __base + __nget, __base + __eget + 1); } *this->pptr() = traits_type::to_char_type(__c); this->pbump(1); return __c; } #endif const __size_type __max_size = _M_string.max_size(); const bool __testput = this->pptr() < this->epptr(); if (__builtin_expect(!__testput && __capacity == __max_size, false)) return traits_type::eof(); // Try to append __c into output sequence in one of two ways. // Order these tests done in is unspecified by the standard. const char_type __conv = traits_type::to_char_type(__c); if (!__testput) { // NB: Start ostringstream buffers at 512 chars. This is an // experimental value (pronounced "arbitrary" in some of the // hipper English-speaking countries), and can be changed to // suit particular needs. // // _GLIBCXX_RESOLVE_LIB_DEFECTS // 169. Bad efficiency of overflow() mandated // 432. stringbuf::overflow() makes only one write position // available const __size_type __opt_len = std::max(__size_type(2 * __capacity), __size_type(512)); const __size_type __len = std::min(__opt_len, __max_size); __string_type __tmp(_M_string.get_allocator()); __tmp.reserve(__len); if (this->pbase()) __tmp.assign(this->pbase(), this->epptr() - this->pbase()); __tmp.push_back(__conv); _M_string.swap(__tmp); _M_sync(const_cast<char_type*>(_M_string.data()), this->gptr() - this->eback(), this->pptr() - this->pbase()); } else *this->pptr() = __conv; this->pbump(1); return __c; } template <class _CharT, class _Traits, class _Alloc> typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type basic_stringbuf<_CharT, _Traits, _Alloc>:: underflow() { int_type __ret = traits_type::eof(); const bool __testin = this->_M_mode & ios_base::in; if (__testin) { // Update egptr() to match the actual string end. _M_update_egptr(); if (this->gptr() < this->egptr()) __ret = traits_type::to_int_type(*this->gptr()); } return __ret; } template <class _CharT, class _Traits, class _Alloc> typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type basic_stringbuf<_CharT, _Traits, _Alloc>:: seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) { pos_type __ret = pos_type(off_type(-1)); bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; const bool __testboth = __testin && __testout && __way != ios_base::cur; __testin &= !(__mode & ios_base::out); __testout &= !(__mode & ios_base::in); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 453. basic_stringbuf::seekoff need not always fail for an empty stream. const char_type* __beg = __testin ? this->eback() : this->pbase(); if ((__beg || !__off) && (__testin || __testout || __testboth)) { _M_update_egptr(); off_type __newoffi = __off; off_type __newoffo = __newoffi; if (__way == ios_base::cur) { __newoffi += this->gptr() - __beg; __newoffo += this->pptr() - __beg; } else if (__way == ios_base::end) __newoffo = __newoffi += this->egptr() - __beg; if ((__testin || __testboth) && __newoffi >= 0 && this->egptr() - __beg >= __newoffi) { this->setg(this->eback(), this->eback() + __newoffi, this->egptr()); __ret = pos_type(__newoffi); } if ((__testout || __testboth) && __newoffo >= 0 && this->egptr() - __beg >= __newoffo) { _M_pbump(this->pbase(), this->epptr(), __newoffo); __ret = pos_type(__newoffo); } } return __ret; } template <class _CharT, class _Traits, class _Alloc> typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type basic_stringbuf<_CharT, _Traits, _Alloc>:: seekpos(pos_type __sp, ios_base::openmode __mode) { pos_type __ret = pos_type(off_type(-1)); const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; const char_type* __beg = __testin ? this->eback() : this->pbase(); if ((__beg || !off_type(__sp)) && (__testin || __testout)) { _M_update_egptr(); const off_type __pos(__sp); const bool __testpos = (0 <= __pos && __pos <= this->egptr() - __beg); if (__testpos) { if (__testin) this->setg(this->eback(), this->eback() + __pos, this->egptr()); if (__testout) _M_pbump(this->pbase(), this->epptr(), __pos); __ret = __sp; } } return __ret; } template <class _CharT, class _Traits, class _Alloc> void basic_stringbuf<_CharT, _Traits, _Alloc>:: _M_sync(char_type* __base, __size_type __i, __size_type __o) { const bool __testin = _M_mode & ios_base::in; const bool __testout = _M_mode & ios_base::out; char_type* __endg = __base + _M_string.size(); char_type* __endp = __base + _M_string.capacity(); if (__base != _M_string.data()) { // setbuf: __i == size of buffer area (_M_string.size() == 0). __endg += __i; __i = 0; __endp = __endg; } if (__testin) this->setg(__base, __base + __i, __endg); if (__testout) { _M_pbump(__base, __endp, __o); // egptr() always tracks the string end. When !__testin, // for the correct functioning of the streambuf inlines // the other get area pointers are identical. if (!__testin) this->setg(__endg, __endg, __endg); } } template <class _CharT, class _Traits, class _Alloc> void basic_stringbuf<_CharT, _Traits, _Alloc>:: _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off) { this->setp(__pbeg, __pend); while (__off > __gnu_cxx::__numeric_traits<int>::__max) { this->pbump(__gnu_cxx::__numeric_traits<int>::__max); __off -= __gnu_cxx::__numeric_traits<int>::__max; } this->pbump(__off); } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_stringbuf<char>; extern template class basic_istringstream<char>; extern template class basic_ostringstream<char>; extern template class basic_stringstream<char>; #ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_stringbuf<wchar_t>; extern template class basic_istringstream<wchar_t>; extern template class basic_ostringstream<wchar_t>; extern template class basic_stringstream<wchar_t>; #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/ios_base.h 0000644 00000074457 15146341150 0010202 0 ustar 00 // Iostreams base classes -*- C++ -*- // Copyright (C) 1997-2018 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/ios_base.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ios} */ // // ISO C++ 14882: 27.4 Iostreams base classes // #ifndef _IOS_BASE_H #define _IOS_BASE_H 1 #pragma GCC system_header #include <ext/atomicity.h> #include <bits/localefwd.h> #include <bits/locale_classes.h> #if __cplusplus < 201103L # include <stdexcept> #else # include <system_error> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // The following definitions of bitmask types are enums, not ints, // as permitted (but not required) in the standard, in order to provide // better type safety in iostream calls. A side effect is that in C++98 // expressions involving them are not compile-time constants. enum _Ios_Fmtflags { _S_boolalpha = 1L << 0, _S_dec = 1L << 1, _S_fixed = 1L << 2, _S_hex = 1L << 3, _S_internal = 1L << 4, _S_left = 1L << 5, _S_oct = 1L << 6, _S_right = 1L << 7, _S_scientific = 1L << 8, _S_showbase = 1L << 9, _S_showpoint = 1L << 10, _S_showpos = 1L << 11, _S_skipws = 1L << 12, _S_unitbuf = 1L << 13, _S_uppercase = 1L << 14, _S_adjustfield = _S_left | _S_right | _S_internal, _S_basefield = _S_dec | _S_oct | _S_hex, _S_floatfield = _S_scientific | _S_fixed, _S_ios_fmtflags_end = 1L << 16, _S_ios_fmtflags_max = __INT_MAX__, _S_ios_fmtflags_min = ~__INT_MAX__ }; inline _GLIBCXX_CONSTEXPR _Ios_Fmtflags operator&(_Ios_Fmtflags __a, _Ios_Fmtflags __b) { return _Ios_Fmtflags(static_cast<int>(__a) & static_cast<int>(__b)); } inline _GLIBCXX_CONSTEXPR _Ios_Fmtflags operator|(_Ios_Fmtflags __a, _Ios_Fmtflags __b) { return _Ios_Fmtflags(static_cast<int>(__a) | static_cast<int>(__b)); } inline _GLIBCXX_CONSTEXPR _Ios_Fmtflags operator^(_Ios_Fmtflags __a, _Ios_Fmtflags __b) { return _Ios_Fmtflags(static_cast<int>(__a) ^ static_cast<int>(__b)); } inline _GLIBCXX_CONSTEXPR _Ios_Fmtflags operator~(_Ios_Fmtflags __a) { return _Ios_Fmtflags(~static_cast<int>(__a)); } inline const _Ios_Fmtflags& operator|=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) { return __a = __a | __b; } inline const _Ios_Fmtflags& operator&=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) { return __a = __a & __b; } inline const _Ios_Fmtflags& operator^=(_Ios_Fmtflags& __a, _Ios_Fmtflags __b) { return __a = __a ^ __b; } enum _Ios_Openmode { _S_app = 1L << 0, _S_ate = 1L << 1, _S_bin = 1L << 2, _S_in = 1L << 3, _S_out = 1L << 4, _S_trunc = 1L << 5, _S_ios_openmode_end = 1L << 16, _S_ios_openmode_max = __INT_MAX__, _S_ios_openmode_min = ~__INT_MAX__ }; inline _GLIBCXX_CONSTEXPR _Ios_Openmode operator&(_Ios_Openmode __a, _Ios_Openmode __b) { return _Ios_Openmode(static_cast<int>(__a) & static_cast<int>(__b)); } inline _GLIBCXX_CONSTEXPR _Ios_Openmode operator|(_Ios_Openmode __a, _Ios_Openmode __b) { return _Ios_Openmode(static_cast<int>(__a) | static_cast<int>(__b)); } inline _GLIBCXX_CONSTEXPR _Ios_Openmode operator^(_Ios_Openmode __a, _Ios_Openmode __b) { return _Ios_Openmode(static_cast<int>(__a) ^ static_cast<int>(__b)); } inline _GLIBCXX_CONSTEXPR _Ios_Openmode operator~(_Ios_Openmode __a) { return _Ios_Openmode(~static_cast<int>(__a)); } inline const _Ios_Openmode& operator|=(_Ios_Openmode& __a, _Ios_Openmode __b) { return __a = __a | __b; } inline const _Ios_Openmode& operator&=(_Ios_Openmode& __a, _Ios_Openmode __b) { return __a = __a & __b; } inline const _Ios_Openmode& operator^=(_Ios_Openmode& __a, _Ios_Openmode __b) { return __a = __a ^ __b; } enum _Ios_Iostate { _S_goodbit = 0, _S_badbit = 1L << 0, _S_eofbit = 1L << 1, _S_failbit = 1L << 2, _S_ios_iostate_end = 1L << 16, _S_ios_iostate_max = __INT_MAX__, _S_ios_iostate_min = ~__INT_MAX__ }; inline _GLIBCXX_CONSTEXPR _Ios_Iostate operator&(_Ios_Iostate __a, _Ios_Iostate __b) { return _Ios_Iostate(static_cast<int>(__a) & static_cast<int>(__b)); } inline _GLIBCXX_CONSTEXPR _Ios_Iostate operator|(_Ios_Iostate __a, _Ios_Iostate __b) { return _Ios_Iostate(static_cast<int>(__a) | static_cast<int>(__b)); } inline _GLIBCXX_CONSTEXPR _Ios_Iostate operator^(_Ios_Iostate __a, _Ios_Iostate __b) { return _Ios_Iostate(static_cast<int>(__a) ^ static_cast<int>(__b)); } inline _GLIBCXX_CONSTEXPR _Ios_Iostate operator~(_Ios_Iostate __a) { return _Ios_Iostate(~static_cast<int>(__a)); } inline const _Ios_Iostate& operator|=(_Ios_Iostate& __a, _Ios_Iostate __b) { return __a = __a | __b; } inline const _Ios_Iostate& operator&=(_Ios_Iostate& __a, _Ios_Iostate __b) { return __a = __a & __b; } inline const _Ios_Iostate& operator^=(_Ios_Iostate& __a, _Ios_Iostate __b) { return __a = __a ^ __b; } enum _Ios_Seekdir { _S_beg = 0, _S_cur = _GLIBCXX_STDIO_SEEK_CUR, _S_end = _GLIBCXX_STDIO_SEEK_END, _S_ios_seekdir_end = 1L << 16 }; #if __cplusplus >= 201103L /// I/O error code enum class io_errc { stream = 1 }; template <> struct is_error_code_enum<io_errc> : public true_type { }; const error_category& iostream_category() noexcept; inline error_code make_error_code(io_errc __e) noexcept { return error_code(static_cast<int>(__e), iostream_category()); } inline error_condition make_error_condition(io_errc __e) noexcept { return error_condition(static_cast<int>(__e), iostream_category()); } #endif // 27.4.2 Class ios_base /** * @brief The base of the I/O class hierarchy. * @ingroup io * * This class defines everything that can be defined about I/O that does * not depend on the type of characters being input or output. Most * people will only see @c ios_base when they need to specify the full * name of the various I/O flags (e.g., the openmodes). */ class ios_base { #if _GLIBCXX_USE_CXX11_ABI #if __cplusplus < 201103L // Type that is layout-compatible with std::system_error struct system_error : std::runtime_error { // Type that is layout-compatible with std::error_code struct error_code { error_code() { } private: int _M_value; const void* _M_cat; } _M_code; }; #endif #endif public: /** * @brief These are thrown to indicate problems with io. * @ingroup exceptions * * 27.4.2.1.1 Class ios_base::failure */ #if _GLIBCXX_USE_CXX11_ABI class _GLIBCXX_ABI_TAG_CXX11 failure : public system_error { public: explicit failure(const string& __str); #if __cplusplus >= 201103L explicit failure(const string&, const error_code&); explicit failure(const char*, const error_code& = io_errc::stream); #endif virtual ~failure() throw(); virtual const char* what() const throw(); }; #else class failure : public exception { public: // _GLIBCXX_RESOLVE_LIB_DEFECTS // 48. Use of non-existent exception constructor explicit failure(const string& __str) throw(); // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Vague-Linkage.html virtual ~failure() throw(); virtual const char* what() const throw(); private: string _M_msg; }; #endif // 27.4.2.1.2 Type ios_base::fmtflags /** * @brief This is a bitmask type. * * @c @a _Ios_Fmtflags is implementation-defined, but it is valid to * perform bitwise operations on these values and expect the Right * Thing to happen. Defined objects of type fmtflags are: * - boolalpha * - dec * - fixed * - hex * - internal * - left * - oct * - right * - scientific * - showbase * - showpoint * - showpos * - skipws * - unitbuf * - uppercase * - adjustfield * - basefield * - floatfield */ typedef _Ios_Fmtflags fmtflags; /// Insert/extract @c bool in alphabetic rather than numeric format. static const fmtflags boolalpha = _S_boolalpha; /// Converts integer input or generates integer output in decimal base. static const fmtflags dec = _S_dec; /// Generate floating-point output in fixed-point notation. static const fmtflags fixed = _S_fixed; /// Converts integer input or generates integer output in hexadecimal base. static const fmtflags hex = _S_hex; /// Adds fill characters at a designated internal point in certain /// generated output, or identical to @c right if no such point is /// designated. static const fmtflags internal = _S_internal; /// Adds fill characters on the right (final positions) of certain /// generated output. (I.e., the thing you print is flush left.) static const fmtflags left = _S_left; /// Converts integer input or generates integer output in octal base. static const fmtflags oct = _S_oct; /// Adds fill characters on the left (initial positions) of certain /// generated output. (I.e., the thing you print is flush right.) static const fmtflags right = _S_right; /// Generates floating-point output in scientific notation. static const fmtflags scientific = _S_scientific; /// Generates a prefix indicating the numeric base of generated integer /// output. static const fmtflags showbase = _S_showbase; /// Generates a decimal-point character unconditionally in generated /// floating-point output. static const fmtflags showpoint = _S_showpoint; /// Generates a + sign in non-negative generated numeric output. static const fmtflags showpos = _S_showpos; /// Skips leading white space before certain input operations. static const fmtflags skipws = _S_skipws; /// Flushes output after each output operation. static const fmtflags unitbuf = _S_unitbuf; /// Replaces certain lowercase letters with their uppercase equivalents /// in generated output. static const fmtflags uppercase = _S_uppercase; /// A mask of left|right|internal. Useful for the 2-arg form of @c setf. static const fmtflags adjustfield = _S_adjustfield; /// A mask of dec|oct|hex. Useful for the 2-arg form of @c setf. static const fmtflags basefield = _S_basefield; /// A mask of scientific|fixed. Useful for the 2-arg form of @c setf. static const fmtflags floatfield = _S_floatfield; // 27.4.2.1.3 Type ios_base::iostate /** * @brief This is a bitmask type. * * @c @a _Ios_Iostate is implementation-defined, but it is valid to * perform bitwise operations on these values and expect the Right * Thing to happen. Defined objects of type iostate are: * - badbit * - eofbit * - failbit * - goodbit */ typedef _Ios_Iostate iostate; /// Indicates a loss of integrity in an input or output sequence (such /// as an irrecoverable read error from a file). static const iostate badbit = _S_badbit; /// Indicates that an input operation reached the end of an input sequence. static const iostate eofbit = _S_eofbit; /// Indicates that an input operation failed to read the expected /// characters, or that an output operation failed to generate the /// desired characters. static const iostate failbit = _S_failbit; /// Indicates all is well. static const iostate goodbit = _S_goodbit; // 27.4.2.1.4 Type ios_base::openmode /** * @brief This is a bitmask type. * * @c @a _Ios_Openmode is implementation-defined, but it is valid to * perform bitwise operations on these values and expect the Right * Thing to happen. Defined objects of type openmode are: * - app * - ate * - binary * - in * - out * - trunc */ typedef _Ios_Openmode openmode; /// Seek to end before each write. static const openmode app = _S_app; /// Open and seek to end immediately after opening. static const openmode ate = _S_ate; /// Perform input and output in binary mode (as opposed to text mode). /// This is probably not what you think it is; see /// https://gcc.gnu.org/onlinedocs/libstdc++/manual/fstreams.html#std.io.filestreams.binary static const openmode binary = _S_bin; /// Open for input. Default for @c ifstream and fstream. static const openmode in = _S_in; /// Open for output. Default for @c ofstream and fstream. static const openmode out = _S_out; /// Truncate an existing stream when opening. Default for @c ofstream. static const openmode trunc = _S_trunc; // 27.4.2.1.5 Type ios_base::seekdir /** * @brief This is an enumerated type. * * @c @a _Ios_Seekdir is implementation-defined. Defined values * of type seekdir are: * - beg * - cur, equivalent to @c SEEK_CUR in the C standard library. * - end, equivalent to @c SEEK_END in the C standard library. */ typedef _Ios_Seekdir seekdir; /// Request a seek relative to the beginning of the stream. static const seekdir beg = _S_beg; /// Request a seek relative to the current position within the sequence. static const seekdir cur = _S_cur; /// Request a seek relative to the current end of the sequence. static const seekdir end = _S_end; #if __cplusplus <= 201402L // Annex D.6 (removed in C++17) typedef int io_state; typedef int open_mode; typedef int seek_dir; typedef std::streampos streampos; typedef std::streamoff streamoff; #endif // Callbacks; /** * @brief The set of events that may be passed to an event callback. * * erase_event is used during ~ios() and copyfmt(). imbue_event is used * during imbue(). copyfmt_event is used during copyfmt(). */ enum event { erase_event, imbue_event, copyfmt_event }; /** * @brief The type of an event callback function. * @param __e One of the members of the event enum. * @param __b Reference to the ios_base object. * @param __i The integer provided when the callback was registered. * * Event callbacks are user defined functions that get called during * several ios_base and basic_ios functions, specifically imbue(), * copyfmt(), and ~ios(). */ typedef void (*event_callback) (event __e, ios_base& __b, int __i); /** * @brief Add the callback __fn with parameter __index. * @param __fn The function to add. * @param __index The integer to pass to the function when invoked. * * Registers a function as an event callback with an integer parameter to * be passed to the function when invoked. Multiple copies of the * function are allowed. If there are multiple callbacks, they are * invoked in the order they were registered. */ void register_callback(event_callback __fn, int __index); protected: streamsize _M_precision; streamsize _M_width; fmtflags _M_flags; iostate _M_exception; iostate _M_streambuf_state; // 27.4.2.6 Members for callbacks // 27.4.2.6 ios_base callbacks struct _Callback_list { // Data Members _Callback_list* _M_next; ios_base::event_callback _M_fn; int _M_index; _Atomic_word _M_refcount; // 0 means one reference. _Callback_list(ios_base::event_callback __fn, int __index, _Callback_list* __cb) : _M_next(__cb), _M_fn(__fn), _M_index(__index), _M_refcount(0) { } void _M_add_reference() { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); } // 0 => OK to delete. int _M_remove_reference() { // Be race-detector-friendly. For more info see bits/c++config. _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount); int __res = __gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1); if (__res == 0) { _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount); } return __res; } }; _Callback_list* _M_callbacks; void _M_call_callbacks(event __ev) throw(); void _M_dispose_callbacks(void) throw(); // 27.4.2.5 Members for iword/pword storage struct _Words { void* _M_pword; long _M_iword; _Words() : _M_pword(0), _M_iword(0) { } }; // Only for failed iword/pword calls. _Words _M_word_zero; // Guaranteed storage. // The first 5 iword and pword slots are reserved for internal use. enum { _S_local_word_size = 8 }; _Words _M_local_word[_S_local_word_size]; // Allocated storage. int _M_word_size; _Words* _M_word; _Words& _M_grow_words(int __index, bool __iword); // Members for locale and locale caching. locale _M_ios_locale; void _M_init() throw(); public: // 27.4.2.1.6 Class ios_base::Init // Used to initialize standard streams. In theory, g++ could use // -finit-priority to order this stuff correctly without going // through these machinations. class Init { friend class ios_base; public: Init(); ~Init(); private: static _Atomic_word _S_refcount; static bool _S_synced_with_stdio; }; // [27.4.2.2] fmtflags state functions /** * @brief Access to format flags. * @return The format control flags for both input and output. */ fmtflags flags() const { return _M_flags; } /** * @brief Setting new format flags all at once. * @param __fmtfl The new flags to set. * @return The previous format control flags. * * This function overwrites all the format flags with @a __fmtfl. */ fmtflags flags(fmtflags __fmtfl) { fmtflags __old = _M_flags; _M_flags = __fmtfl; return __old; } /** * @brief Setting new format flags. * @param __fmtfl Additional flags to set. * @return The previous format control flags. * * This function sets additional flags in format control. Flags that * were previously set remain set. */ fmtflags setf(fmtflags __fmtfl) { fmtflags __old = _M_flags; _M_flags |= __fmtfl; return __old; } /** * @brief Setting new format flags. * @param __fmtfl Additional flags to set. * @param __mask The flags mask for @a fmtfl. * @return The previous format control flags. * * This function clears @a mask in the format flags, then sets * @a fmtfl @c & @a mask. An example mask is @c ios_base::adjustfield. */ fmtflags setf(fmtflags __fmtfl, fmtflags __mask) { fmtflags __old = _M_flags; _M_flags &= ~__mask; _M_flags |= (__fmtfl & __mask); return __old; } /** * @brief Clearing format flags. * @param __mask The flags to unset. * * This function clears @a __mask in the format flags. */ void unsetf(fmtflags __mask) { _M_flags &= ~__mask; } /** * @brief Flags access. * @return The precision to generate on certain output operations. * * Be careful if you try to give a definition of @a precision here; see * DR 189. */ streamsize precision() const { return _M_precision; } /** * @brief Changing flags. * @param __prec The new precision value. * @return The previous value of precision(). */ streamsize precision(streamsize __prec) { streamsize __old = _M_precision; _M_precision = __prec; return __old; } /** * @brief Flags access. * @return The minimum field width to generate on output operations. * * <em>Minimum field width</em> refers to the number of characters. */ streamsize width() const { return _M_width; } /** * @brief Changing flags. * @param __wide The new width value. * @return The previous value of width(). */ streamsize width(streamsize __wide) { streamsize __old = _M_width; _M_width = __wide; return __old; } // [27.4.2.4] ios_base static members /** * @brief Interaction with the standard C I/O objects. * @param __sync Whether to synchronize or not. * @return True if the standard streams were previously synchronized. * * The synchronization referred to is @e only that between the standard * C facilities (e.g., stdout) and the standard C++ objects (e.g., * cout). User-declared streams are unaffected. See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/fstreams.html#std.io.filestreams.binary */ static bool sync_with_stdio(bool __sync = true); // [27.4.2.3] ios_base locale functions /** * @brief Setting a new locale. * @param __loc The new locale. * @return The previous locale. * * Sets the new locale for this stream, and then invokes each callback * with imbue_event. */ locale imbue(const locale& __loc) throw(); /** * @brief Locale access * @return A copy of the current locale. * * If @c imbue(loc) has previously been called, then this function * returns @c loc. Otherwise, it returns a copy of @c std::locale(), * the global C++ locale. */ locale getloc() const { return _M_ios_locale; } /** * @brief Locale access * @return A reference to the current locale. * * Like getloc above, but returns a reference instead of * generating a copy. */ const locale& _M_getloc() const { return _M_ios_locale; } // [27.4.2.5] ios_base storage functions /** * @brief Access to unique indices. * @return An integer different from all previous calls. * * This function returns a unique integer every time it is called. It * can be used for any purpose, but is primarily intended to be a unique * index for the iword and pword functions. The expectation is that an * application calls xalloc in order to obtain an index in the iword and * pword arrays that can be used without fear of conflict. * * The implementation maintains a static variable that is incremented and * returned on each invocation. xalloc is guaranteed to return an index * that is safe to use in the iword and pword arrays. */ static int xalloc() throw(); /** * @brief Access to integer array. * @param __ix Index into the array. * @return A reference to an integer associated with the index. * * The iword function provides access to an array of integers that can be * used for any purpose. The array grows as required to hold the * supplied index. All integers in the array are initialized to 0. * * The implementation reserves several indices. You should use xalloc to * obtain an index that is safe to use. Also note that since the array * can grow dynamically, it is not safe to hold onto the reference. */ long& iword(int __ix) { _Words& __word = (__ix < _M_word_size) ? _M_word[__ix] : _M_grow_words(__ix, true); return __word._M_iword; } /** * @brief Access to void pointer array. * @param __ix Index into the array. * @return A reference to a void* associated with the index. * * The pword function provides access to an array of pointers that can be * used for any purpose. The array grows as required to hold the * supplied index. All pointers in the array are initialized to 0. * * The implementation reserves several indices. You should use xalloc to * obtain an index that is safe to use. Also note that since the array * can grow dynamically, it is not safe to hold onto the reference. */ void*& pword(int __ix) { _Words& __word = (__ix < _M_word_size) ? _M_word[__ix] : _M_grow_words(__ix, false); return __word._M_pword; } // Destructor /** * Invokes each callback with erase_event. Destroys local storage. * * Note that the ios_base object for the standard streams never gets * destroyed. As a result, any callbacks registered with the standard * streams will not get invoked with erase_event (unless copyfmt is * used). */ virtual ~ios_base(); protected: ios_base() throw (); #if __cplusplus < 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 50. Copy constructor and assignment operator of ios_base private: ios_base(const ios_base&); ios_base& operator=(const ios_base&); #else public: ios_base(const ios_base&) = delete; ios_base& operator=(const ios_base&) = delete; protected: void _M_move(ios_base&) noexcept; void _M_swap(ios_base& __rhs) noexcept; #endif }; // [27.4.5.1] fmtflags manipulators /// Calls base.setf(ios_base::boolalpha). inline ios_base& boolalpha(ios_base& __base) { __base.setf(ios_base::boolalpha); return __base; } /// Calls base.unsetf(ios_base::boolalpha). inline ios_base& noboolalpha(ios_base& __base) { __base.unsetf(ios_base::boolalpha); return __base; } /// Calls base.setf(ios_base::showbase). inline ios_base& showbase(ios_base& __base) { __base.setf(ios_base::showbase); return __base; } /// Calls base.unsetf(ios_base::showbase). inline ios_base& noshowbase(ios_base& __base) { __base.unsetf(ios_base::showbase); return __base; } /// Calls base.setf(ios_base::showpoint). inline ios_base& showpoint(ios_base& __base) { __base.setf(ios_base::showpoint); return __base; } /// Calls base.unsetf(ios_base::showpoint). inline ios_base& noshowpoint(ios_base& __base) { __base.unsetf(ios_base::showpoint); return __base; } /// Calls base.setf(ios_base::showpos). inline ios_base& showpos(ios_base& __base) { __base.setf(ios_base::showpos); return __base; } /// Calls base.unsetf(ios_base::showpos). inline ios_base& noshowpos(ios_base& __base) { __base.unsetf(ios_base::showpos); return __base; } /// Calls base.setf(ios_base::skipws). inline ios_base& skipws(ios_base& __base) { __base.setf(ios_base::skipws); return __base; } /// Calls base.unsetf(ios_base::skipws). inline ios_base& noskipws(ios_base& __base) { __base.unsetf(ios_base::skipws); return __base; } /// Calls base.setf(ios_base::uppercase). inline ios_base& uppercase(ios_base& __base) { __base.setf(ios_base::uppercase); return __base; } /// Calls base.unsetf(ios_base::uppercase). inline ios_base& nouppercase(ios_base& __base) { __base.unsetf(ios_base::uppercase); return __base; } /// Calls base.setf(ios_base::unitbuf). inline ios_base& unitbuf(ios_base& __base) { __base.setf(ios_base::unitbuf); return __base; } /// Calls base.unsetf(ios_base::unitbuf). inline ios_base& nounitbuf(ios_base& __base) { __base.unsetf(ios_base::unitbuf); return __base; } // [27.4.5.2] adjustfield manipulators /// Calls base.setf(ios_base::internal, ios_base::adjustfield). inline ios_base& internal(ios_base& __base) { __base.setf(ios_base::internal, ios_base::adjustfield); return __base; } /// Calls base.setf(ios_base::left, ios_base::adjustfield). inline ios_base& left(ios_base& __base) { __base.setf(ios_base::left, ios_base::adjustfield); return __base; } /// Calls base.setf(ios_base::right, ios_base::adjustfield). inline ios_base& right(ios_base& __base) { __base.setf(ios_base::right, ios_base::adjustfield); return __base; } // [27.4.5.3] basefield manipulators /// Calls base.setf(ios_base::dec, ios_base::basefield). inline ios_base& dec(ios_base& __base) { __base.setf(ios_base::dec, ios_base::basefield); return __base; } /// Calls base.setf(ios_base::hex, ios_base::basefield). inline ios_base& hex(ios_base& __base) { __base.setf(ios_base::hex, ios_base::basefield); return __base; } /// Calls base.setf(ios_base::oct, ios_base::basefield). inline ios_base& oct(ios_base& __base) { __base.setf(ios_base::oct, ios_base::basefield); return __base; } // [27.4.5.4] floatfield manipulators /// Calls base.setf(ios_base::fixed, ios_base::floatfield). inline ios_base& fixed(ios_base& __base) { __base.setf(ios_base::fixed, ios_base::floatfield); return __base; } /// Calls base.setf(ios_base::scientific, ios_base::floatfield). inline ios_base& scientific(ios_base& __base) { __base.setf(ios_base::scientific, ios_base::floatfield); return __base; } #if __cplusplus >= 201103L // New C++11 floatfield manipulators /// Calls /// base.setf(ios_base::fixed|ios_base::scientific, ios_base::floatfield) inline ios_base& hexfloat(ios_base& __base) { __base.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield); return __base; } /// Calls @c base.unsetf(ios_base::floatfield) inline ios_base& defaultfloat(ios_base& __base) { __base.unsetf(ios_base::floatfield); return __base; } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _IOS_BASE_H */ c++/8/bits/hashtable.h 0000644 00000220071 15146341150 0010332 0 ustar 00 // hashtable.h header -*- C++ -*- // Copyright (C) 2007-2018 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/hashtable.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{unordered_map, unordered_set} */ #ifndef _HASHTABLE_H #define _HASHTABLE_H 1 #pragma GCC system_header #include <bits/hashtable_policy.h> #if __cplusplus > 201402L # include <bits/node_handle.h> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp, typename _Hash> using __cache_default = __not_<__and_<// Do not cache for fast hasher. __is_fast_hash<_Hash>, // Mandatory to have erase not throwing. __is_nothrow_invocable<const _Hash&, const _Tp&>>>; /** * Primary class template _Hashtable. * * @ingroup hashtable-detail * * @tparam _Value CopyConstructible type. * * @tparam _Key CopyConstructible type. * * @tparam _Alloc An allocator type * ([lib.allocator.requirements]) whose _Alloc::value_type is * _Value. As a conforming extension, we allow for * _Alloc::value_type != _Value. * * @tparam _ExtractKey Function object that takes an object of type * _Value and returns a value of type _Key. * * @tparam _Equal Function object that takes two objects of type k * and returns a bool-like value that is true if the two objects * are considered equal. * * @tparam _H1 The hash function. A unary function object with * argument type _Key and result type size_t. Return values should * be distributed over the entire range [0, numeric_limits<size_t>:::max()]. * * @tparam _H2 The range-hashing function (in the terminology of * Tavori and Dreizin). A binary function object whose argument * types and result type are all size_t. Given arguments r and N, * the return value is in the range [0, N). * * @tparam _Hash The ranged hash function (Tavori and Dreizin). A * binary function whose argument types are _Key and size_t and * whose result type is size_t. Given arguments k and N, the * return value is in the range [0, N). Default: hash(k, N) = * h2(h1(k), N). If _Hash is anything other than the default, _H1 * and _H2 are ignored. * * @tparam _RehashPolicy Policy class with three members, all of * which govern the bucket count. _M_next_bkt(n) returns a bucket * count no smaller than n. _M_bkt_for_elements(n) returns a * bucket count appropriate for an element count of n. * _M_need_rehash(n_bkt, n_elt, n_ins) determines whether, if the * current bucket count is n_bkt and the current element count is * n_elt, we need to increase the bucket count. If so, returns * make_pair(true, n), where n is the new bucket count. If not, * returns make_pair(false, <anything>) * * @tparam _Traits Compile-time class with three boolean * std::integral_constant members: __cache_hash_code, __constant_iterators, * __unique_keys. * * Each _Hashtable data structure has: * * - _Bucket[] _M_buckets * - _Hash_node_base _M_before_begin * - size_type _M_bucket_count * - size_type _M_element_count * * with _Bucket being _Hash_node* and _Hash_node containing: * * - _Hash_node* _M_next * - Tp _M_value * - size_t _M_hash_code if cache_hash_code is true * * In terms of Standard containers the hashtable is like the aggregation of: * * - std::forward_list<_Node> containing the elements * - std::vector<std::forward_list<_Node>::iterator> representing the buckets * * The non-empty buckets contain the node before the first node in the * bucket. This design makes it possible to implement something like a * std::forward_list::insert_after on container insertion and * std::forward_list::erase_after on container erase * calls. _M_before_begin is equivalent to * std::forward_list::before_begin. Empty buckets contain * nullptr. Note that one of the non-empty buckets contains * &_M_before_begin which is not a dereferenceable node so the * node pointer in a bucket shall never be dereferenced, only its * next node can be. * * Walking through a bucket's nodes requires a check on the hash code to * see if each node is still in the bucket. Such a design assumes a * quite efficient hash functor and is one of the reasons it is * highly advisable to set __cache_hash_code to true. * * The container iterators are simply built from nodes. This way * incrementing the iterator is perfectly efficient independent of * how many empty buckets there are in the container. * * On insert we compute the element's hash code and use it to find the * bucket index. If the element must be inserted in an empty bucket * we add it at the beginning of the singly linked list and make the * bucket point to _M_before_begin. The bucket that used to point to * _M_before_begin, if any, is updated to point to its new before * begin node. * * On erase, the simple iterator design requires using the hash * functor to get the index of the bucket to update. For this * reason, when __cache_hash_code is set to false the hash functor must * not throw and this is enforced by a static assertion. * * Functionality is implemented by decomposition into base classes, * where the derived _Hashtable class is used in _Map_base, * _Insert, _Rehash_base, and _Equality base classes to access the * "this" pointer. _Hashtable_base is used in the base classes as a * non-recursive, fully-completed-type so that detailed nested type * information, such as iterator type and node type, can be * used. This is similar to the "Curiously Recurring Template * Pattern" (CRTP) technique, but uses a reconstructed, not * explicitly passed, template pattern. * * Base class templates are: * - __detail::_Hashtable_base * - __detail::_Map_base * - __detail::_Insert * - __detail::_Rehash_base * - __detail::_Equality */ template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> class _Hashtable : public __detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, _Hash, _Traits>, public __detail::_Map_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>, public __detail::_Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>, public __detail::_Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>, public __detail::_Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>, private __detail::_Hashtable_alloc< __alloc_rebind<_Alloc, __detail::_Hash_node<_Value, _Traits::__hash_cached::value>>> { static_assert(is_same<typename remove_cv<_Value>::type, _Value>::value, "unordered container must have a non-const, non-volatile value_type"); #ifdef __STRICT_ANSI__ static_assert(is_same<typename _Alloc::value_type, _Value>{}, "unordered container must have the same value_type as its allocator"); #endif using __traits_type = _Traits; using __hash_cached = typename __traits_type::__hash_cached; using __node_type = __detail::_Hash_node<_Value, __hash_cached::value>; using __node_alloc_type = __alloc_rebind<_Alloc, __node_type>; using __hashtable_alloc = __detail::_Hashtable_alloc<__node_alloc_type>; using __value_alloc_traits = typename __hashtable_alloc::__value_alloc_traits; using __node_alloc_traits = typename __hashtable_alloc::__node_alloc_traits; using __node_base = typename __hashtable_alloc::__node_base; using __bucket_type = typename __hashtable_alloc::__bucket_type; public: typedef _Key key_type; typedef _Value value_type; typedef _Alloc allocator_type; typedef _Equal key_equal; // mapped_type, if present, comes from _Map_base. // hasher, if present, comes from _Hash_code_base/_Hashtable_base. typedef typename __value_alloc_traits::pointer pointer; typedef typename __value_alloc_traits::const_pointer const_pointer; typedef value_type& reference; typedef const value_type& const_reference; private: using __rehash_type = _RehashPolicy; using __rehash_state = typename __rehash_type::_State; using __constant_iterators = typename __traits_type::__constant_iterators; using __unique_keys = typename __traits_type::__unique_keys; using __key_extract = typename std::conditional< __constant_iterators::value, __detail::_Identity, __detail::_Select1st>::type; using __hashtable_base = __detail:: _Hashtable_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, _Hash, _Traits>; using __hash_code_base = typename __hashtable_base::__hash_code_base; using __hash_code = typename __hashtable_base::__hash_code; using __ireturn_type = typename __hashtable_base::__ireturn_type; using __map_base = __detail::_Map_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; using __rehash_base = __detail::_Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; using __eq_base = __detail::_Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; using __reuse_or_alloc_node_type = __detail::_ReuseOrAllocNode<__node_alloc_type>; // Metaprogramming for picking apart hash caching. template<typename _Cond> using __if_hash_cached = __or_<__not_<__hash_cached>, _Cond>; template<typename _Cond> using __if_hash_not_cached = __or_<__hash_cached, _Cond>; // Compile-time diagnostics. // _Hash_code_base has everything protected, so use this derived type to // access it. struct __hash_code_base_access : __hash_code_base { using __hash_code_base::_M_bucket_index; }; // Getting a bucket index from a node shall not throw because it is used // in methods (erase, swap...) that shall not throw. static_assert(noexcept(declval<const __hash_code_base_access&>() ._M_bucket_index((const __node_type*)nullptr, (std::size_t)0)), "Cache the hash code or qualify your functors involved" " in hash code and bucket index computation with noexcept"); // Following two static assertions are necessary to guarantee // that local_iterator will be default constructible. // When hash codes are cached local iterator inherits from H2 functor // which must then be default constructible. static_assert(__if_hash_cached<is_default_constructible<_H2>>::value, "Functor used to map hash code to bucket index" " must be default constructible"); template<typename _Keya, typename _Valuea, typename _Alloca, typename _ExtractKeya, typename _Equala, typename _H1a, typename _H2a, typename _Hasha, typename _RehashPolicya, typename _Traitsa, bool _Unique_keysa> friend struct __detail::_Map_base; template<typename _Keya, typename _Valuea, typename _Alloca, typename _ExtractKeya, typename _Equala, typename _H1a, typename _H2a, typename _Hasha, typename _RehashPolicya, typename _Traitsa> friend struct __detail::_Insert_base; template<typename _Keya, typename _Valuea, typename _Alloca, typename _ExtractKeya, typename _Equala, typename _H1a, typename _H2a, typename _Hasha, typename _RehashPolicya, typename _Traitsa, bool _Constant_iteratorsa> friend struct __detail::_Insert; public: using size_type = typename __hashtable_base::size_type; using difference_type = typename __hashtable_base::difference_type; using iterator = typename __hashtable_base::iterator; using const_iterator = typename __hashtable_base::const_iterator; using local_iterator = typename __hashtable_base::local_iterator; using const_local_iterator = typename __hashtable_base:: const_local_iterator; #if __cplusplus > 201402L using node_type = _Node_handle<_Key, _Value, __node_alloc_type>; using insert_return_type = _Node_insert_return<iterator, node_type>; #endif private: __bucket_type* _M_buckets = &_M_single_bucket; size_type _M_bucket_count = 1; __node_base _M_before_begin; size_type _M_element_count = 0; _RehashPolicy _M_rehash_policy; // A single bucket used when only need for 1 bucket. Especially // interesting in move semantic to leave hashtable with only 1 buckets // which is not allocated so that we can have those operations noexcept // qualified. // Note that we can't leave hashtable with 0 bucket without adding // numerous checks in the code to avoid 0 modulus. __bucket_type _M_single_bucket = nullptr; bool _M_uses_single_bucket(__bucket_type* __bkts) const { return __builtin_expect(__bkts == &_M_single_bucket, false); } bool _M_uses_single_bucket() const { return _M_uses_single_bucket(_M_buckets); } __hashtable_alloc& _M_base_alloc() { return *this; } __bucket_type* _M_allocate_buckets(size_type __n) { if (__builtin_expect(__n == 1, false)) { _M_single_bucket = nullptr; return &_M_single_bucket; } return __hashtable_alloc::_M_allocate_buckets(__n); } void _M_deallocate_buckets(__bucket_type* __bkts, size_type __n) { if (_M_uses_single_bucket(__bkts)) return; __hashtable_alloc::_M_deallocate_buckets(__bkts, __n); } void _M_deallocate_buckets() { _M_deallocate_buckets(_M_buckets, _M_bucket_count); } // Gets bucket begin, deals with the fact that non-empty buckets contain // their before begin node. __node_type* _M_bucket_begin(size_type __bkt) const; __node_type* _M_begin() const { return static_cast<__node_type*>(_M_before_begin._M_nxt); } template<typename _NodeGenerator> void _M_assign(const _Hashtable&, const _NodeGenerator&); void _M_move_assign(_Hashtable&&, std::true_type); void _M_move_assign(_Hashtable&&, std::false_type); void _M_reset() noexcept; _Hashtable(const _H1& __h1, const _H2& __h2, const _Hash& __h, const _Equal& __eq, const _ExtractKey& __exk, const allocator_type& __a) : __hashtable_base(__exk, __h1, __h2, __h, __eq), __hashtable_alloc(__node_alloc_type(__a)) { } public: // Constructor, destructor, assignment, swap _Hashtable() = default; _Hashtable(size_type __bucket_hint, const _H1&, const _H2&, const _Hash&, const _Equal&, const _ExtractKey&, const allocator_type&); template<typename _InputIterator> _Hashtable(_InputIterator __first, _InputIterator __last, size_type __bucket_hint, const _H1&, const _H2&, const _Hash&, const _Equal&, const _ExtractKey&, const allocator_type&); _Hashtable(const _Hashtable&); _Hashtable(_Hashtable&&) noexcept; _Hashtable(const _Hashtable&, const allocator_type&); _Hashtable(_Hashtable&&, const allocator_type&); // Use delegating constructors. explicit _Hashtable(const allocator_type& __a) : __hashtable_alloc(__node_alloc_type(__a)) { } explicit _Hashtable(size_type __n, const _H1& __hf = _H1(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Hashtable(__n, __hf, _H2(), _Hash(), __eql, __key_extract(), __a) { } template<typename _InputIterator> _Hashtable(_InputIterator __f, _InputIterator __l, size_type __n = 0, const _H1& __hf = _H1(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Hashtable(__f, __l, __n, __hf, _H2(), _Hash(), __eql, __key_extract(), __a) { } _Hashtable(initializer_list<value_type> __l, size_type __n = 0, const _H1& __hf = _H1(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _Hashtable(__l.begin(), __l.end(), __n, __hf, _H2(), _Hash(), __eql, __key_extract(), __a) { } _Hashtable& operator=(const _Hashtable& __ht); _Hashtable& operator=(_Hashtable&& __ht) noexcept(__node_alloc_traits::_S_nothrow_move() && is_nothrow_move_assignable<_H1>::value && is_nothrow_move_assignable<_Equal>::value) { constexpr bool __move_storage = __node_alloc_traits::_S_propagate_on_move_assign() || __node_alloc_traits::_S_always_equal(); _M_move_assign(std::move(__ht), __bool_constant<__move_storage>()); return *this; } _Hashtable& operator=(initializer_list<value_type> __l) { __reuse_or_alloc_node_type __roan(_M_begin(), *this); _M_before_begin._M_nxt = nullptr; clear(); this->_M_insert_range(__l.begin(), __l.end(), __roan, __unique_keys()); return *this; } ~_Hashtable() noexcept; void swap(_Hashtable&) noexcept(__and_<__is_nothrow_swappable<_H1>, __is_nothrow_swappable<_Equal>>::value); // Basic container operations iterator begin() noexcept { return iterator(_M_begin()); } const_iterator begin() const noexcept { return const_iterator(_M_begin()); } iterator end() noexcept { return iterator(nullptr); } const_iterator end() const noexcept { return const_iterator(nullptr); } const_iterator cbegin() const noexcept { return const_iterator(_M_begin()); } const_iterator cend() const noexcept { return const_iterator(nullptr); } size_type size() const noexcept { return _M_element_count; } bool empty() const noexcept { return size() == 0; } allocator_type get_allocator() const noexcept { return allocator_type(this->_M_node_allocator()); } size_type max_size() const noexcept { return __node_alloc_traits::max_size(this->_M_node_allocator()); } // Observers key_equal key_eq() const { return this->_M_eq(); } // hash_function, if present, comes from _Hash_code_base. // Bucket operations size_type bucket_count() const noexcept { return _M_bucket_count; } size_type max_bucket_count() const noexcept { return max_size(); } size_type bucket_size(size_type __n) const { return std::distance(begin(__n), end(__n)); } size_type bucket(const key_type& __k) const { return _M_bucket_index(__k, this->_M_hash_code(__k)); } local_iterator begin(size_type __n) { return local_iterator(*this, _M_bucket_begin(__n), __n, _M_bucket_count); } local_iterator end(size_type __n) { return local_iterator(*this, nullptr, __n, _M_bucket_count); } const_local_iterator begin(size_type __n) const { return const_local_iterator(*this, _M_bucket_begin(__n), __n, _M_bucket_count); } const_local_iterator end(size_type __n) const { return const_local_iterator(*this, nullptr, __n, _M_bucket_count); } // DR 691. const_local_iterator cbegin(size_type __n) const { return const_local_iterator(*this, _M_bucket_begin(__n), __n, _M_bucket_count); } const_local_iterator cend(size_type __n) const { return const_local_iterator(*this, nullptr, __n, _M_bucket_count); } float load_factor() const noexcept { return static_cast<float>(size()) / static_cast<float>(bucket_count()); } // max_load_factor, if present, comes from _Rehash_base. // Generalization of max_load_factor. Extension, not found in // TR1. Only useful if _RehashPolicy is something other than // the default. const _RehashPolicy& __rehash_policy() const { return _M_rehash_policy; } void __rehash_policy(const _RehashPolicy& __pol) { _M_rehash_policy = __pol; } // Lookup. iterator find(const key_type& __k); const_iterator find(const key_type& __k) const; size_type count(const key_type& __k) const; std::pair<iterator, iterator> equal_range(const key_type& __k); std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const; protected: // Bucket index computation helpers. size_type _M_bucket_index(__node_type* __n) const noexcept { return __hash_code_base::_M_bucket_index(__n, _M_bucket_count); } size_type _M_bucket_index(const key_type& __k, __hash_code __c) const { return __hash_code_base::_M_bucket_index(__k, __c, _M_bucket_count); } // Find and insert helper functions and types // Find the node before the one matching the criteria. __node_base* _M_find_before_node(size_type, const key_type&, __hash_code) const; __node_type* _M_find_node(size_type __bkt, const key_type& __key, __hash_code __c) const { __node_base* __before_n = _M_find_before_node(__bkt, __key, __c); if (__before_n) return static_cast<__node_type*>(__before_n->_M_nxt); return nullptr; } // Insert a node at the beginning of a bucket. void _M_insert_bucket_begin(size_type, __node_type*); // Remove the bucket first node void _M_remove_bucket_begin(size_type __bkt, __node_type* __next_n, size_type __next_bkt); // Get the node before __n in the bucket __bkt __node_base* _M_get_previous_node(size_type __bkt, __node_base* __n); // Insert node with hash code __code, in bucket bkt if no rehash (assumes // no element with its key already present). Take ownership of the node, // deallocate it on exception. iterator _M_insert_unique_node(size_type __bkt, __hash_code __code, __node_type* __n, size_type __n_elt = 1); // Insert node with hash code __code. Take ownership of the node, // deallocate it on exception. iterator _M_insert_multi_node(__node_type* __hint, __hash_code __code, __node_type* __n); template<typename... _Args> std::pair<iterator, bool> _M_emplace(std::true_type, _Args&&... __args); template<typename... _Args> iterator _M_emplace(std::false_type __uk, _Args&&... __args) { return _M_emplace(cend(), __uk, std::forward<_Args>(__args)...); } // Emplace with hint, useless when keys are unique. template<typename... _Args> iterator _M_emplace(const_iterator, std::true_type __uk, _Args&&... __args) { return _M_emplace(__uk, std::forward<_Args>(__args)...).first; } template<typename... _Args> iterator _M_emplace(const_iterator, std::false_type, _Args&&... __args); template<typename _Arg, typename _NodeGenerator> std::pair<iterator, bool> _M_insert(_Arg&&, const _NodeGenerator&, true_type, size_type = 1); template<typename _Arg, typename _NodeGenerator> iterator _M_insert(_Arg&& __arg, const _NodeGenerator& __node_gen, false_type __uk) { return _M_insert(cend(), std::forward<_Arg>(__arg), __node_gen, __uk); } // Insert with hint, not used when keys are unique. template<typename _Arg, typename _NodeGenerator> iterator _M_insert(const_iterator, _Arg&& __arg, const _NodeGenerator& __node_gen, true_type __uk) { return _M_insert(std::forward<_Arg>(__arg), __node_gen, __uk).first; } // Insert with hint when keys are not unique. template<typename _Arg, typename _NodeGenerator> iterator _M_insert(const_iterator, _Arg&&, const _NodeGenerator&, false_type); size_type _M_erase(std::true_type, const key_type&); size_type _M_erase(std::false_type, const key_type&); iterator _M_erase(size_type __bkt, __node_base* __prev_n, __node_type* __n); public: // Emplace template<typename... _Args> __ireturn_type emplace(_Args&&... __args) { return _M_emplace(__unique_keys(), std::forward<_Args>(__args)...); } template<typename... _Args> iterator emplace_hint(const_iterator __hint, _Args&&... __args) { return _M_emplace(__hint, __unique_keys(), std::forward<_Args>(__args)...); } // Insert member functions via inheritance. // Erase iterator erase(const_iterator); // LWG 2059. iterator erase(iterator __it) { return erase(const_iterator(__it)); } size_type erase(const key_type& __k) { return _M_erase(__unique_keys(), __k); } iterator erase(const_iterator, const_iterator); void clear() noexcept; // Set number of buckets to be appropriate for container of n element. void rehash(size_type __n); // DR 1189. // reserve, if present, comes from _Rehash_base. #if __cplusplus > 201402L /// Re-insert an extracted node into a container with unique keys. insert_return_type _M_reinsert_node(node_type&& __nh) { insert_return_type __ret; if (__nh.empty()) __ret.position = end(); else { __glibcxx_assert(get_allocator() == __nh.get_allocator()); const key_type& __k = __nh._M_key(); __hash_code __code = this->_M_hash_code(__k); size_type __bkt = _M_bucket_index(__k, __code); if (__node_type* __n = _M_find_node(__bkt, __k, __code)) { __ret.node = std::move(__nh); __ret.position = iterator(__n); __ret.inserted = false; } else { __ret.position = _M_insert_unique_node(__bkt, __code, __nh._M_ptr); __nh._M_ptr = nullptr; __ret.inserted = true; } } return __ret; } /// Re-insert an extracted node into a container with equivalent keys. iterator _M_reinsert_node_multi(const_iterator __hint, node_type&& __nh) { iterator __ret; if (__nh.empty()) __ret = end(); else { __glibcxx_assert(get_allocator() == __nh.get_allocator()); auto __code = this->_M_hash_code(__nh._M_key()); auto __node = std::exchange(__nh._M_ptr, nullptr); // FIXME: this deallocates the node on exception. __ret = _M_insert_multi_node(__hint._M_cur, __code, __node); } return __ret; } /// Extract a node. node_type extract(const_iterator __pos) { __node_type* __n = __pos._M_cur; size_t __bkt = _M_bucket_index(__n); // Look for previous node to unlink it from the erased one, this // is why we need buckets to contain the before begin to make // this search fast. __node_base* __prev_n = _M_get_previous_node(__bkt, __n); if (__prev_n == _M_buckets[__bkt]) _M_remove_bucket_begin(__bkt, __n->_M_next(), __n->_M_nxt ? _M_bucket_index(__n->_M_next()) : 0); else if (__n->_M_nxt) { size_type __next_bkt = _M_bucket_index(__n->_M_next()); if (__next_bkt != __bkt) _M_buckets[__next_bkt] = __prev_n; } __prev_n->_M_nxt = __n->_M_nxt; __n->_M_nxt = nullptr; --_M_element_count; return { __n, this->_M_node_allocator() }; } /// Extract a node. node_type extract(const _Key& __k) { node_type __nh; auto __pos = find(__k); if (__pos != end()) __nh = extract(const_iterator(__pos)); return __nh; } /// Merge from a compatible container into one with unique keys. template<typename _Compatible_Hashtable> void _M_merge_unique(_Compatible_Hashtable& __src) noexcept { static_assert(is_same_v<typename _Compatible_Hashtable::node_type, node_type>, "Node types are compatible"); __glibcxx_assert(get_allocator() == __src.get_allocator()); auto __n_elt = __src.size(); for (auto __i = __src.begin(), __end = __src.end(); __i != __end;) { auto __pos = __i++; const key_type& __k = this->_M_extract()(__pos._M_cur->_M_v()); __hash_code __code = this->_M_hash_code(__k); size_type __bkt = _M_bucket_index(__k, __code); if (_M_find_node(__bkt, __k, __code) == nullptr) { auto __nh = __src.extract(__pos); _M_insert_unique_node(__bkt, __code, __nh._M_ptr, __n_elt); __nh._M_ptr = nullptr; __n_elt = 1; } else if (__n_elt != 1) --__n_elt; } } /// Merge from a compatible container into one with equivalent keys. template<typename _Compatible_Hashtable> void _M_merge_multi(_Compatible_Hashtable& __src) noexcept { static_assert(is_same_v<typename _Compatible_Hashtable::node_type, node_type>, "Node types are compatible"); __glibcxx_assert(get_allocator() == __src.get_allocator()); this->reserve(size() + __src.size()); for (auto __i = __src.begin(), __end = __src.end(); __i != __end;) _M_reinsert_node_multi(cend(), __src.extract(__i++)); } #endif // C++17 private: // Helper rehash method used when keys are unique. void _M_rehash_aux(size_type __n, std::true_type); // Helper rehash method used when keys can be non-unique. void _M_rehash_aux(size_type __n, std::false_type); // Unconditionally change size of bucket array to n, restore // hash policy state to __state on exception. void _M_rehash(size_type __n, const __rehash_state& __state); }; // Definitions of class template _Hashtable's out-of-line member functions. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_bucket_begin(size_type __bkt) const -> __node_type* { __node_base* __n = _M_buckets[__bkt]; return __n ? static_cast<__node_type*>(__n->_M_nxt) : nullptr; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _Hashtable(size_type __bucket_hint, const _H1& __h1, const _H2& __h2, const _Hash& __h, const _Equal& __eq, const _ExtractKey& __exk, const allocator_type& __a) : _Hashtable(__h1, __h2, __h, __eq, __exk, __a) { auto __bkt = _M_rehash_policy._M_next_bkt(__bucket_hint); if (__bkt > _M_bucket_count) { _M_buckets = _M_allocate_buckets(__bkt); _M_bucket_count = __bkt; } } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> template<typename _InputIterator> _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _Hashtable(_InputIterator __f, _InputIterator __l, size_type __bucket_hint, const _H1& __h1, const _H2& __h2, const _Hash& __h, const _Equal& __eq, const _ExtractKey& __exk, const allocator_type& __a) : _Hashtable(__h1, __h2, __h, __eq, __exk, __a) { auto __nb_elems = __detail::__distance_fw(__f, __l); auto __bkt_count = _M_rehash_policy._M_next_bkt( std::max(_M_rehash_policy._M_bkt_for_elements(__nb_elems), __bucket_hint)); if (__bkt_count > _M_bucket_count) { _M_buckets = _M_allocate_buckets(__bkt_count); _M_bucket_count = __bkt_count; } for (; __f != __l; ++__f) this->insert(*__f); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: operator=(const _Hashtable& __ht) -> _Hashtable& { if (&__ht == this) return *this; if (__node_alloc_traits::_S_propagate_on_copy_assign()) { auto& __this_alloc = this->_M_node_allocator(); auto& __that_alloc = __ht._M_node_allocator(); if (!__node_alloc_traits::_S_always_equal() && __this_alloc != __that_alloc) { // Replacement allocator cannot free existing storage. this->_M_deallocate_nodes(_M_begin()); _M_before_begin._M_nxt = nullptr; _M_deallocate_buckets(); _M_buckets = nullptr; std::__alloc_on_copy(__this_alloc, __that_alloc); __hashtable_base::operator=(__ht); _M_bucket_count = __ht._M_bucket_count; _M_element_count = __ht._M_element_count; _M_rehash_policy = __ht._M_rehash_policy; __try { _M_assign(__ht, [this](const __node_type* __n) { return this->_M_allocate_node(__n->_M_v()); }); } __catch(...) { // _M_assign took care of deallocating all memory. Now we // must make sure this instance remains in a usable state. _M_reset(); __throw_exception_again; } return *this; } std::__alloc_on_copy(__this_alloc, __that_alloc); } // Reuse allocated buckets and nodes. __bucket_type* __former_buckets = nullptr; std::size_t __former_bucket_count = _M_bucket_count; const __rehash_state& __former_state = _M_rehash_policy._M_state(); if (_M_bucket_count != __ht._M_bucket_count) { __former_buckets = _M_buckets; _M_buckets = _M_allocate_buckets(__ht._M_bucket_count); _M_bucket_count = __ht._M_bucket_count; } else __builtin_memset(_M_buckets, 0, _M_bucket_count * sizeof(__bucket_type)); __try { __hashtable_base::operator=(__ht); _M_element_count = __ht._M_element_count; _M_rehash_policy = __ht._M_rehash_policy; __reuse_or_alloc_node_type __roan(_M_begin(), *this); _M_before_begin._M_nxt = nullptr; _M_assign(__ht, [&__roan](const __node_type* __n) { return __roan(__n->_M_v()); }); if (__former_buckets) _M_deallocate_buckets(__former_buckets, __former_bucket_count); } __catch(...) { if (__former_buckets) { // Restore previous buckets. _M_deallocate_buckets(); _M_rehash_policy._M_reset(__former_state); _M_buckets = __former_buckets; _M_bucket_count = __former_bucket_count; } __builtin_memset(_M_buckets, 0, _M_bucket_count * sizeof(__bucket_type)); __throw_exception_again; } return *this; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> template<typename _NodeGenerator> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_assign(const _Hashtable& __ht, const _NodeGenerator& __node_gen) { __bucket_type* __buckets = nullptr; if (!_M_buckets) _M_buckets = __buckets = _M_allocate_buckets(_M_bucket_count); __try { if (!__ht._M_before_begin._M_nxt) return; // First deal with the special first node pointed to by // _M_before_begin. __node_type* __ht_n = __ht._M_begin(); __node_type* __this_n = __node_gen(__ht_n); this->_M_copy_code(__this_n, __ht_n); _M_before_begin._M_nxt = __this_n; _M_buckets[_M_bucket_index(__this_n)] = &_M_before_begin; // Then deal with other nodes. __node_base* __prev_n = __this_n; for (__ht_n = __ht_n->_M_next(); __ht_n; __ht_n = __ht_n->_M_next()) { __this_n = __node_gen(__ht_n); __prev_n->_M_nxt = __this_n; this->_M_copy_code(__this_n, __ht_n); size_type __bkt = _M_bucket_index(__this_n); if (!_M_buckets[__bkt]) _M_buckets[__bkt] = __prev_n; __prev_n = __this_n; } } __catch(...) { clear(); if (__buckets) _M_deallocate_buckets(); __throw_exception_again; } } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_reset() noexcept { _M_rehash_policy._M_reset(); _M_bucket_count = 1; _M_single_bucket = nullptr; _M_buckets = &_M_single_bucket; _M_before_begin._M_nxt = nullptr; _M_element_count = 0; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_move_assign(_Hashtable&& __ht, std::true_type) { this->_M_deallocate_nodes(_M_begin()); _M_deallocate_buckets(); __hashtable_base::operator=(std::move(__ht)); _M_rehash_policy = __ht._M_rehash_policy; if (!__ht._M_uses_single_bucket()) _M_buckets = __ht._M_buckets; else { _M_buckets = &_M_single_bucket; _M_single_bucket = __ht._M_single_bucket; } _M_bucket_count = __ht._M_bucket_count; _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt; _M_element_count = __ht._M_element_count; std::__alloc_on_move(this->_M_node_allocator(), __ht._M_node_allocator()); // Fix buckets containing the _M_before_begin pointers that can't be // moved. if (_M_begin()) _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin; __ht._M_reset(); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_move_assign(_Hashtable&& __ht, std::false_type) { if (__ht._M_node_allocator() == this->_M_node_allocator()) _M_move_assign(std::move(__ht), std::true_type()); else { // Can't move memory, move elements then. __bucket_type* __former_buckets = nullptr; size_type __former_bucket_count = _M_bucket_count; const __rehash_state& __former_state = _M_rehash_policy._M_state(); if (_M_bucket_count != __ht._M_bucket_count) { __former_buckets = _M_buckets; _M_buckets = _M_allocate_buckets(__ht._M_bucket_count); _M_bucket_count = __ht._M_bucket_count; } else __builtin_memset(_M_buckets, 0, _M_bucket_count * sizeof(__bucket_type)); __try { __hashtable_base::operator=(std::move(__ht)); _M_element_count = __ht._M_element_count; _M_rehash_policy = __ht._M_rehash_policy; __reuse_or_alloc_node_type __roan(_M_begin(), *this); _M_before_begin._M_nxt = nullptr; _M_assign(__ht, [&__roan](__node_type* __n) { return __roan(std::move_if_noexcept(__n->_M_v())); }); if (__former_buckets) _M_deallocate_buckets(__former_buckets, __former_bucket_count); __ht.clear(); } __catch(...) { if (__former_buckets) { _M_deallocate_buckets(); _M_rehash_policy._M_reset(__former_state); _M_buckets = __former_buckets; _M_bucket_count = __former_bucket_count; } __builtin_memset(_M_buckets, 0, _M_bucket_count * sizeof(__bucket_type)); __throw_exception_again; } } } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _Hashtable(const _Hashtable& __ht) : __hashtable_base(__ht), __map_base(__ht), __rehash_base(__ht), __hashtable_alloc( __node_alloc_traits::_S_select_on_copy(__ht._M_node_allocator())), _M_buckets(nullptr), _M_bucket_count(__ht._M_bucket_count), _M_element_count(__ht._M_element_count), _M_rehash_policy(__ht._M_rehash_policy) { _M_assign(__ht, [this](const __node_type* __n) { return this->_M_allocate_node(__n->_M_v()); }); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _Hashtable(_Hashtable&& __ht) noexcept : __hashtable_base(__ht), __map_base(__ht), __rehash_base(__ht), __hashtable_alloc(std::move(__ht._M_base_alloc())), _M_buckets(__ht._M_buckets), _M_bucket_count(__ht._M_bucket_count), _M_before_begin(__ht._M_before_begin._M_nxt), _M_element_count(__ht._M_element_count), _M_rehash_policy(__ht._M_rehash_policy) { // Update, if necessary, buckets if __ht is using its single bucket. if (__ht._M_uses_single_bucket()) { _M_buckets = &_M_single_bucket; _M_single_bucket = __ht._M_single_bucket; } // Update, if necessary, bucket pointing to before begin that hasn't // moved. if (_M_begin()) _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin; __ht._M_reset(); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _Hashtable(const _Hashtable& __ht, const allocator_type& __a) : __hashtable_base(__ht), __map_base(__ht), __rehash_base(__ht), __hashtable_alloc(__node_alloc_type(__a)), _M_buckets(), _M_bucket_count(__ht._M_bucket_count), _M_element_count(__ht._M_element_count), _M_rehash_policy(__ht._M_rehash_policy) { _M_assign(__ht, [this](const __node_type* __n) { return this->_M_allocate_node(__n->_M_v()); }); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _Hashtable(_Hashtable&& __ht, const allocator_type& __a) : __hashtable_base(__ht), __map_base(__ht), __rehash_base(__ht), __hashtable_alloc(__node_alloc_type(__a)), _M_buckets(nullptr), _M_bucket_count(__ht._M_bucket_count), _M_element_count(__ht._M_element_count), _M_rehash_policy(__ht._M_rehash_policy) { if (__ht._M_node_allocator() == this->_M_node_allocator()) { if (__ht._M_uses_single_bucket()) { _M_buckets = &_M_single_bucket; _M_single_bucket = __ht._M_single_bucket; } else _M_buckets = __ht._M_buckets; _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt; // Update, if necessary, bucket pointing to before begin that hasn't // moved. if (_M_begin()) _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin; __ht._M_reset(); } else { _M_assign(__ht, [this](__node_type* __n) { return this->_M_allocate_node( std::move_if_noexcept(__n->_M_v())); }); __ht.clear(); } } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: ~_Hashtable() noexcept { clear(); _M_deallocate_buckets(); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: swap(_Hashtable& __x) noexcept(__and_<__is_nothrow_swappable<_H1>, __is_nothrow_swappable<_Equal>>::value) { // The only base class with member variables is hash_code_base. // We define _Hash_code_base::_M_swap because different // specializations have different members. this->_M_swap(__x); std::__alloc_on_swap(this->_M_node_allocator(), __x._M_node_allocator()); std::swap(_M_rehash_policy, __x._M_rehash_policy); // Deal properly with potentially moved instances. if (this->_M_uses_single_bucket()) { if (!__x._M_uses_single_bucket()) { _M_buckets = __x._M_buckets; __x._M_buckets = &__x._M_single_bucket; } } else if (__x._M_uses_single_bucket()) { __x._M_buckets = _M_buckets; _M_buckets = &_M_single_bucket; } else std::swap(_M_buckets, __x._M_buckets); std::swap(_M_bucket_count, __x._M_bucket_count); std::swap(_M_before_begin._M_nxt, __x._M_before_begin._M_nxt); std::swap(_M_element_count, __x._M_element_count); std::swap(_M_single_bucket, __x._M_single_bucket); // Fix buckets containing the _M_before_begin pointers that can't be // swapped. if (_M_begin()) _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin; if (__x._M_begin()) __x._M_buckets[__x._M_bucket_index(__x._M_begin())] = &__x._M_before_begin; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: find(const key_type& __k) -> iterator { __hash_code __code = this->_M_hash_code(__k); std::size_t __n = _M_bucket_index(__k, __code); __node_type* __p = _M_find_node(__n, __k, __code); return __p ? iterator(__p) : end(); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: find(const key_type& __k) const -> const_iterator { __hash_code __code = this->_M_hash_code(__k); std::size_t __n = _M_bucket_index(__k, __code); __node_type* __p = _M_find_node(__n, __k, __code); return __p ? const_iterator(__p) : end(); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: count(const key_type& __k) const -> size_type { __hash_code __code = this->_M_hash_code(__k); std::size_t __n = _M_bucket_index(__k, __code); __node_type* __p = _M_bucket_begin(__n); if (!__p) return 0; std::size_t __result = 0; for (;; __p = __p->_M_next()) { if (this->_M_equals(__k, __code, __p)) ++__result; else if (__result) // All equivalent values are next to each other, if we // found a non-equivalent value after an equivalent one it // means that we won't find any new equivalent value. break; if (!__p->_M_nxt || _M_bucket_index(__p->_M_next()) != __n) break; } return __result; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: equal_range(const key_type& __k) -> pair<iterator, iterator> { __hash_code __code = this->_M_hash_code(__k); std::size_t __n = _M_bucket_index(__k, __code); __node_type* __p = _M_find_node(__n, __k, __code); if (__p) { __node_type* __p1 = __p->_M_next(); while (__p1 && _M_bucket_index(__p1) == __n && this->_M_equals(__k, __code, __p1)) __p1 = __p1->_M_next(); return std::make_pair(iterator(__p), iterator(__p1)); } else return std::make_pair(end(), end()); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: equal_range(const key_type& __k) const -> pair<const_iterator, const_iterator> { __hash_code __code = this->_M_hash_code(__k); std::size_t __n = _M_bucket_index(__k, __code); __node_type* __p = _M_find_node(__n, __k, __code); if (__p) { __node_type* __p1 = __p->_M_next(); while (__p1 && _M_bucket_index(__p1) == __n && this->_M_equals(__k, __code, __p1)) __p1 = __p1->_M_next(); return std::make_pair(const_iterator(__p), const_iterator(__p1)); } else return std::make_pair(end(), end()); } // Find the node whose key compares equal to k in the bucket n. // Return nullptr if no node is found. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_find_before_node(size_type __n, const key_type& __k, __hash_code __code) const -> __node_base* { __node_base* __prev_p = _M_buckets[__n]; if (!__prev_p) return nullptr; for (__node_type* __p = static_cast<__node_type*>(__prev_p->_M_nxt);; __p = __p->_M_next()) { if (this->_M_equals(__k, __code, __p)) return __prev_p; if (!__p->_M_nxt || _M_bucket_index(__p->_M_next()) != __n) break; __prev_p = __p; } return nullptr; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_insert_bucket_begin(size_type __bkt, __node_type* __node) { if (_M_buckets[__bkt]) { // Bucket is not empty, we just need to insert the new node // after the bucket before begin. __node->_M_nxt = _M_buckets[__bkt]->_M_nxt; _M_buckets[__bkt]->_M_nxt = __node; } else { // The bucket is empty, the new node is inserted at the // beginning of the singly-linked list and the bucket will // contain _M_before_begin pointer. __node->_M_nxt = _M_before_begin._M_nxt; _M_before_begin._M_nxt = __node; if (__node->_M_nxt) // We must update former begin bucket that is pointing to // _M_before_begin. _M_buckets[_M_bucket_index(__node->_M_next())] = __node; _M_buckets[__bkt] = &_M_before_begin; } } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_remove_bucket_begin(size_type __bkt, __node_type* __next, size_type __next_bkt) { if (!__next || __next_bkt != __bkt) { // Bucket is now empty // First update next bucket if any if (__next) _M_buckets[__next_bkt] = _M_buckets[__bkt]; // Second update before begin node if necessary if (&_M_before_begin == _M_buckets[__bkt]) _M_before_begin._M_nxt = __next; _M_buckets[__bkt] = nullptr; } } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_get_previous_node(size_type __bkt, __node_base* __n) -> __node_base* { __node_base* __prev_n = _M_buckets[__bkt]; while (__prev_n->_M_nxt != __n) __prev_n = __prev_n->_M_nxt; return __prev_n; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> template<typename... _Args> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_emplace(std::true_type, _Args&&... __args) -> pair<iterator, bool> { // First build the node to get access to the hash code __node_type* __node = this->_M_allocate_node(std::forward<_Args>(__args)...); const key_type& __k = this->_M_extract()(__node->_M_v()); __hash_code __code; __try { __code = this->_M_hash_code(__k); } __catch(...) { this->_M_deallocate_node(__node); __throw_exception_again; } size_type __bkt = _M_bucket_index(__k, __code); if (__node_type* __p = _M_find_node(__bkt, __k, __code)) { // There is already an equivalent node, no insertion this->_M_deallocate_node(__node); return std::make_pair(iterator(__p), false); } // Insert the node return std::make_pair(_M_insert_unique_node(__bkt, __code, __node), true); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> template<typename... _Args> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_emplace(const_iterator __hint, std::false_type, _Args&&... __args) -> iterator { // First build the node to get its hash code. __node_type* __node = this->_M_allocate_node(std::forward<_Args>(__args)...); __hash_code __code; __try { __code = this->_M_hash_code(this->_M_extract()(__node->_M_v())); } __catch(...) { this->_M_deallocate_node(__node); __throw_exception_again; } return _M_insert_multi_node(__hint._M_cur, __code, __node); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_insert_unique_node(size_type __bkt, __hash_code __code, __node_type* __node, size_type __n_elt) -> iterator { const __rehash_state& __saved_state = _M_rehash_policy._M_state(); std::pair<bool, std::size_t> __do_rehash = _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count, __n_elt); __try { if (__do_rehash.first) { _M_rehash(__do_rehash.second, __saved_state); __bkt = _M_bucket_index(this->_M_extract()(__node->_M_v()), __code); } this->_M_store_code(__node, __code); // Always insert at the beginning of the bucket. _M_insert_bucket_begin(__bkt, __node); ++_M_element_count; return iterator(__node); } __catch(...) { this->_M_deallocate_node(__node); __throw_exception_again; } } // Insert node, in bucket bkt if no rehash (assumes no element with its key // already present). Take ownership of the node, deallocate it on exception. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_insert_multi_node(__node_type* __hint, __hash_code __code, __node_type* __node) -> iterator { const __rehash_state& __saved_state = _M_rehash_policy._M_state(); std::pair<bool, std::size_t> __do_rehash = _M_rehash_policy._M_need_rehash(_M_bucket_count, _M_element_count, 1); __try { if (__do_rehash.first) _M_rehash(__do_rehash.second, __saved_state); this->_M_store_code(__node, __code); const key_type& __k = this->_M_extract()(__node->_M_v()); size_type __bkt = _M_bucket_index(__k, __code); // Find the node before an equivalent one or use hint if it exists and // if it is equivalent. __node_base* __prev = __builtin_expect(__hint != nullptr, false) && this->_M_equals(__k, __code, __hint) ? __hint : _M_find_before_node(__bkt, __k, __code); if (__prev) { // Insert after the node before the equivalent one. __node->_M_nxt = __prev->_M_nxt; __prev->_M_nxt = __node; if (__builtin_expect(__prev == __hint, false)) // hint might be the last bucket node, in this case we need to // update next bucket. if (__node->_M_nxt && !this->_M_equals(__k, __code, __node->_M_next())) { size_type __next_bkt = _M_bucket_index(__node->_M_next()); if (__next_bkt != __bkt) _M_buckets[__next_bkt] = __node; } } else // The inserted node has no equivalent in the // hashtable. We must insert the new node at the // beginning of the bucket to preserve equivalent // elements' relative positions. _M_insert_bucket_begin(__bkt, __node); ++_M_element_count; return iterator(__node); } __catch(...) { this->_M_deallocate_node(__node); __throw_exception_again; } } // Insert v if no element with its key is already present. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> template<typename _Arg, typename _NodeGenerator> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_insert(_Arg&& __v, const _NodeGenerator& __node_gen, true_type, size_type __n_elt) -> pair<iterator, bool> { const key_type& __k = this->_M_extract()(__v); __hash_code __code = this->_M_hash_code(__k); size_type __bkt = _M_bucket_index(__k, __code); __node_type* __n = _M_find_node(__bkt, __k, __code); if (__n) return std::make_pair(iterator(__n), false); __n = __node_gen(std::forward<_Arg>(__v)); return { _M_insert_unique_node(__bkt, __code, __n, __n_elt), true }; } // Insert v unconditionally. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> template<typename _Arg, typename _NodeGenerator> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_insert(const_iterator __hint, _Arg&& __v, const _NodeGenerator& __node_gen, false_type) -> iterator { // First compute the hash code so that we don't do anything if it // throws. __hash_code __code = this->_M_hash_code(this->_M_extract()(__v)); // Second allocate new node so that we don't rehash if it throws. __node_type* __node = __node_gen(std::forward<_Arg>(__v)); return _M_insert_multi_node(__hint._M_cur, __code, __node); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: erase(const_iterator __it) -> iterator { __node_type* __n = __it._M_cur; std::size_t __bkt = _M_bucket_index(__n); // Look for previous node to unlink it from the erased one, this // is why we need buckets to contain the before begin to make // this search fast. __node_base* __prev_n = _M_get_previous_node(__bkt, __n); return _M_erase(__bkt, __prev_n, __n); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_erase(size_type __bkt, __node_base* __prev_n, __node_type* __n) -> iterator { if (__prev_n == _M_buckets[__bkt]) _M_remove_bucket_begin(__bkt, __n->_M_next(), __n->_M_nxt ? _M_bucket_index(__n->_M_next()) : 0); else if (__n->_M_nxt) { size_type __next_bkt = _M_bucket_index(__n->_M_next()); if (__next_bkt != __bkt) _M_buckets[__next_bkt] = __prev_n; } __prev_n->_M_nxt = __n->_M_nxt; iterator __result(__n->_M_next()); this->_M_deallocate_node(__n); --_M_element_count; return __result; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_erase(std::true_type, const key_type& __k) -> size_type { __hash_code __code = this->_M_hash_code(__k); std::size_t __bkt = _M_bucket_index(__k, __code); // Look for the node before the first matching node. __node_base* __prev_n = _M_find_before_node(__bkt, __k, __code); if (!__prev_n) return 0; // We found a matching node, erase it. __node_type* __n = static_cast<__node_type*>(__prev_n->_M_nxt); _M_erase(__bkt, __prev_n, __n); return 1; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_erase(std::false_type, const key_type& __k) -> size_type { __hash_code __code = this->_M_hash_code(__k); std::size_t __bkt = _M_bucket_index(__k, __code); // Look for the node before the first matching node. __node_base* __prev_n = _M_find_before_node(__bkt, __k, __code); if (!__prev_n) return 0; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 526. Is it undefined if a function in the standard changes // in parameters? // We use one loop to find all matching nodes and another to deallocate // them so that the key stays valid during the first loop. It might be // invalidated indirectly when destroying nodes. __node_type* __n = static_cast<__node_type*>(__prev_n->_M_nxt); __node_type* __n_last = __n; std::size_t __n_last_bkt = __bkt; do { __n_last = __n_last->_M_next(); if (!__n_last) break; __n_last_bkt = _M_bucket_index(__n_last); } while (__n_last_bkt == __bkt && this->_M_equals(__k, __code, __n_last)); // Deallocate nodes. size_type __result = 0; do { __node_type* __p = __n->_M_next(); this->_M_deallocate_node(__n); __n = __p; ++__result; --_M_element_count; } while (__n != __n_last); if (__prev_n == _M_buckets[__bkt]) _M_remove_bucket_begin(__bkt, __n_last, __n_last_bkt); else if (__n_last && __n_last_bkt != __bkt) _M_buckets[__n_last_bkt] = __prev_n; __prev_n->_M_nxt = __n_last; return __result; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: erase(const_iterator __first, const_iterator __last) -> iterator { __node_type* __n = __first._M_cur; __node_type* __last_n = __last._M_cur; if (__n == __last_n) return iterator(__n); std::size_t __bkt = _M_bucket_index(__n); __node_base* __prev_n = _M_get_previous_node(__bkt, __n); bool __is_bucket_begin = __n == _M_bucket_begin(__bkt); std::size_t __n_bkt = __bkt; for (;;) { do { __node_type* __tmp = __n; __n = __n->_M_next(); this->_M_deallocate_node(__tmp); --_M_element_count; if (!__n) break; __n_bkt = _M_bucket_index(__n); } while (__n != __last_n && __n_bkt == __bkt); if (__is_bucket_begin) _M_remove_bucket_begin(__bkt, __n, __n_bkt); if (__n == __last_n) break; __is_bucket_begin = true; __bkt = __n_bkt; } if (__n && (__n_bkt != __bkt || __is_bucket_begin)) _M_buckets[__n_bkt] = __prev_n; __prev_n->_M_nxt = __n; return iterator(__n); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: clear() noexcept { this->_M_deallocate_nodes(_M_begin()); __builtin_memset(_M_buckets, 0, _M_bucket_count * sizeof(__bucket_type)); _M_element_count = 0; _M_before_begin._M_nxt = nullptr; } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: rehash(size_type __n) { const __rehash_state& __saved_state = _M_rehash_policy._M_state(); std::size_t __buckets = std::max(_M_rehash_policy._M_bkt_for_elements(_M_element_count + 1), __n); __buckets = _M_rehash_policy._M_next_bkt(__buckets); if (__buckets != _M_bucket_count) _M_rehash(__buckets, __saved_state); else // No rehash, restore previous state to keep a consistent state. _M_rehash_policy._M_reset(__saved_state); } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_rehash(size_type __n, const __rehash_state& __state) { __try { _M_rehash_aux(__n, __unique_keys()); } __catch(...) { // A failure here means that buckets allocation failed. We only // have to restore hash policy previous state. _M_rehash_policy._M_reset(__state); __throw_exception_again; } } // Rehash when there is no equivalent elements. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_rehash_aux(size_type __n, std::true_type) { __bucket_type* __new_buckets = _M_allocate_buckets(__n); __node_type* __p = _M_begin(); _M_before_begin._M_nxt = nullptr; std::size_t __bbegin_bkt = 0; while (__p) { __node_type* __next = __p->_M_next(); std::size_t __bkt = __hash_code_base::_M_bucket_index(__p, __n); if (!__new_buckets[__bkt]) { __p->_M_nxt = _M_before_begin._M_nxt; _M_before_begin._M_nxt = __p; __new_buckets[__bkt] = &_M_before_begin; if (__p->_M_nxt) __new_buckets[__bbegin_bkt] = __p; __bbegin_bkt = __bkt; } else { __p->_M_nxt = __new_buckets[__bkt]->_M_nxt; __new_buckets[__bkt]->_M_nxt = __p; } __p = __next; } _M_deallocate_buckets(); _M_bucket_count = __n; _M_buckets = __new_buckets; } // Rehash when there can be equivalent elements, preserve their relative // order. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> void _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_rehash_aux(size_type __n, std::false_type) { __bucket_type* __new_buckets = _M_allocate_buckets(__n); __node_type* __p = _M_begin(); _M_before_begin._M_nxt = nullptr; std::size_t __bbegin_bkt = 0; std::size_t __prev_bkt = 0; __node_type* __prev_p = nullptr; bool __check_bucket = false; while (__p) { __node_type* __next = __p->_M_next(); std::size_t __bkt = __hash_code_base::_M_bucket_index(__p, __n); if (__prev_p && __prev_bkt == __bkt) { // Previous insert was already in this bucket, we insert after // the previously inserted one to preserve equivalent elements // relative order. __p->_M_nxt = __prev_p->_M_nxt; __prev_p->_M_nxt = __p; // Inserting after a node in a bucket require to check that we // haven't change the bucket last node, in this case next // bucket containing its before begin node must be updated. We // schedule a check as soon as we move out of the sequence of // equivalent nodes to limit the number of checks. __check_bucket = true; } else { if (__check_bucket) { // Check if we shall update the next bucket because of // insertions into __prev_bkt bucket. if (__prev_p->_M_nxt) { std::size_t __next_bkt = __hash_code_base::_M_bucket_index(__prev_p->_M_next(), __n); if (__next_bkt != __prev_bkt) __new_buckets[__next_bkt] = __prev_p; } __check_bucket = false; } if (!__new_buckets[__bkt]) { __p->_M_nxt = _M_before_begin._M_nxt; _M_before_begin._M_nxt = __p; __new_buckets[__bkt] = &_M_before_begin; if (__p->_M_nxt) __new_buckets[__bbegin_bkt] = __p; __bbegin_bkt = __bkt; } else { __p->_M_nxt = __new_buckets[__bkt]->_M_nxt; __new_buckets[__bkt]->_M_nxt = __p; } } __prev_p = __p; __prev_bkt = __bkt; __p = __next; } if (__check_bucket && __prev_p->_M_nxt) { std::size_t __next_bkt = __hash_code_base::_M_bucket_index(__prev_p->_M_next(), __n); if (__next_bkt != __prev_bkt) __new_buckets[__next_bkt] = __prev_p; } _M_deallocate_buckets(); _M_bucket_count = __n; _M_buckets = __new_buckets; } #if __cplusplus > 201402L template<typename, typename, typename> class _Hash_merge_helper { }; #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _HASHTABLE_H c++/8/bits/stringfwd.h 0000644 00000005057 15146341150 0010413 0 ustar 00 // <string> Forward declarations -*- C++ -*- // Copyright (C) 2001-2018 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/stringfwd.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{string} */ // // ISO C++ 14882: 21 Strings library // #ifndef _STRINGFWD_H #define _STRINGFWD_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/memoryfwd.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup strings Strings * * @{ */ template<class _CharT> struct char_traits; template<> struct char_traits<char>; #ifdef _GLIBCXX_USE_WCHAR_T template<> struct char_traits<wchar_t>; #endif #if ((__cplusplus >= 201103L) \ && defined(_GLIBCXX_USE_C99_STDINT_TR1)) template<> struct char_traits<char16_t>; template<> struct char_traits<char32_t>; #endif _GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT> > class basic_string; /// A string of @c char typedef basic_string<char> string; #ifdef _GLIBCXX_USE_WCHAR_T /// A string of @c wchar_t typedef basic_string<wchar_t> wstring; #endif #if ((__cplusplus >= 201103L) \ && defined(_GLIBCXX_USE_C99_STDINT_TR1)) /// A string of @c char16_t typedef basic_string<char16_t> u16string; /// A string of @c char32_t typedef basic_string<char32_t> u32string; #endif _GLIBCXX_END_NAMESPACE_CXX11 /** @} */ _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _STRINGFWD_H c++/8/bits/range_access.h 0000644 00000023456 15146341150 0011024 0 ustar 00 // <range_access.h> -*- C++ -*- // Copyright (C) 2010-2018 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/range_access.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iterator} */ #ifndef _GLIBCXX_RANGE_ACCESS_H #define _GLIBCXX_RANGE_ACCESS_H 1 #pragma GCC system_header #if __cplusplus >= 201103L #include <initializer_list> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Return an iterator pointing to the first element of * the container. * @param __cont Container. */ template<typename _Container> inline _GLIBCXX17_CONSTEXPR auto begin(_Container& __cont) -> decltype(__cont.begin()) { return __cont.begin(); } /** * @brief Return an iterator pointing to the first element of * the const container. * @param __cont Container. */ template<typename _Container> inline _GLIBCXX17_CONSTEXPR auto begin(const _Container& __cont) -> decltype(__cont.begin()) { return __cont.begin(); } /** * @brief Return an iterator pointing to one past the last element of * the container. * @param __cont Container. */ template<typename _Container> inline _GLIBCXX17_CONSTEXPR auto end(_Container& __cont) -> decltype(__cont.end()) { return __cont.end(); } /** * @brief Return an iterator pointing to one past the last element of * the const container. * @param __cont Container. */ template<typename _Container> inline _GLIBCXX17_CONSTEXPR auto end(const _Container& __cont) -> decltype(__cont.end()) { return __cont.end(); } /** * @brief Return an iterator pointing to the first element of the array. * @param __arr Array. */ template<typename _Tp, size_t _Nm> inline _GLIBCXX14_CONSTEXPR _Tp* begin(_Tp (&__arr)[_Nm]) { return __arr; } /** * @brief Return an iterator pointing to one past the last element * of the array. * @param __arr Array. */ template<typename _Tp, size_t _Nm> inline _GLIBCXX14_CONSTEXPR _Tp* end(_Tp (&__arr)[_Nm]) { return __arr + _Nm; } #if __cplusplus >= 201402L template<typename _Tp> class valarray; // These overloads must be declared for cbegin and cend to use them. template<typename _Tp> _Tp* begin(valarray<_Tp>&); template<typename _Tp> const _Tp* begin(const valarray<_Tp>&); template<typename _Tp> _Tp* end(valarray<_Tp>&); template<typename _Tp> const _Tp* end(const valarray<_Tp>&); /** * @brief Return an iterator pointing to the first element of * the const container. * @param __cont Container. */ template<typename _Container> inline constexpr auto cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont))) -> decltype(std::begin(__cont)) { return std::begin(__cont); } /** * @brief Return an iterator pointing to one past the last element of * the const container. * @param __cont Container. */ template<typename _Container> inline constexpr auto cend(const _Container& __cont) noexcept(noexcept(std::end(__cont))) -> decltype(std::end(__cont)) { return std::end(__cont); } /** * @brief Return a reverse iterator pointing to the last element of * the container. * @param __cont Container. */ template<typename _Container> inline _GLIBCXX17_CONSTEXPR auto rbegin(_Container& __cont) -> decltype(__cont.rbegin()) { return __cont.rbegin(); } /** * @brief Return a reverse iterator pointing to the last element of * the const container. * @param __cont Container. */ template<typename _Container> inline _GLIBCXX17_CONSTEXPR auto rbegin(const _Container& __cont) -> decltype(__cont.rbegin()) { return __cont.rbegin(); } /** * @brief Return a reverse iterator pointing one past the first element of * the container. * @param __cont Container. */ template<typename _Container> inline _GLIBCXX17_CONSTEXPR auto rend(_Container& __cont) -> decltype(__cont.rend()) { return __cont.rend(); } /** * @brief Return a reverse iterator pointing one past the first element of * the const container. * @param __cont Container. */ template<typename _Container> inline _GLIBCXX17_CONSTEXPR auto rend(const _Container& __cont) -> decltype(__cont.rend()) { return __cont.rend(); } /** * @brief Return a reverse iterator pointing to the last element of * the array. * @param __arr Array. */ template<typename _Tp, size_t _Nm> inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*> rbegin(_Tp (&__arr)[_Nm]) { return reverse_iterator<_Tp*>(__arr + _Nm); } /** * @brief Return a reverse iterator pointing one past the first element of * the array. * @param __arr Array. */ template<typename _Tp, size_t _Nm> inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*> rend(_Tp (&__arr)[_Nm]) { return reverse_iterator<_Tp*>(__arr); } /** * @brief Return a reverse iterator pointing to the last element of * the initializer_list. * @param __il initializer_list. */ template<typename _Tp> inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*> rbegin(initializer_list<_Tp> __il) { return reverse_iterator<const _Tp*>(__il.end()); } /** * @brief Return a reverse iterator pointing one past the first element of * the initializer_list. * @param __il initializer_list. */ template<typename _Tp> inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*> rend(initializer_list<_Tp> __il) { return reverse_iterator<const _Tp*>(__il.begin()); } /** * @brief Return a reverse iterator pointing to the last element of * the const container. * @param __cont Container. */ template<typename _Container> inline _GLIBCXX17_CONSTEXPR auto crbegin(const _Container& __cont) -> decltype(std::rbegin(__cont)) { return std::rbegin(__cont); } /** * @brief Return a reverse iterator pointing one past the first element of * the const container. * @param __cont Container. */ template<typename _Container> inline _GLIBCXX17_CONSTEXPR auto crend(const _Container& __cont) -> decltype(std::rend(__cont)) { return std::rend(__cont); } #endif // C++14 #if __cplusplus >= 201703L #define __cpp_lib_nonmember_container_access 201411 /** * @brief Return the size of a container. * @param __cont Container. */ template <typename _Container> constexpr auto size(const _Container& __cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size()) { return __cont.size(); } /** * @brief Return the size of an array. * @param __array Array. */ template <typename _Tp, size_t _Nm> constexpr size_t size(const _Tp (&/*__array*/)[_Nm]) noexcept { return _Nm; } /** * @brief Return whether a container is empty. * @param __cont Container. */ template <typename _Container> [[nodiscard]] constexpr auto empty(const _Container& __cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty()) { return __cont.empty(); } /** * @brief Return whether an array is empty (always false). * @param __array Container. */ template <typename _Tp, size_t _Nm> [[nodiscard]] constexpr bool empty(const _Tp (&/*__array*/)[_Nm]) noexcept { return false; } /** * @brief Return whether an initializer_list is empty. * @param __il Initializer list. */ template <typename _Tp> [[nodiscard]] constexpr bool empty(initializer_list<_Tp> __il) noexcept { return __il.size() == 0;} /** * @brief Return the data pointer of a container. * @param __cont Container. */ template <typename _Container> constexpr auto data(_Container& __cont) noexcept(noexcept(__cont.data())) -> decltype(__cont.data()) { return __cont.data(); } /** * @brief Return the data pointer of a const container. * @param __cont Container. */ template <typename _Container> constexpr auto data(const _Container& __cont) noexcept(noexcept(__cont.data())) -> decltype(__cont.data()) { return __cont.data(); } /** * @brief Return the data pointer of an array. * @param __array Array. */ template <typename _Tp, size_t _Nm> constexpr _Tp* data(_Tp (&__array)[_Nm]) noexcept { return __array; } /** * @brief Return the data pointer of an initializer list. * @param __il Initializer list. */ template <typename _Tp> constexpr const _Tp* data(initializer_list<_Tp> __il) noexcept { return __il.begin(); } #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++11 #endif // _GLIBCXX_RANGE_ACCESS_H c++/8/bits/slice_array.h 0000644 00000022204 15146341150 0010672 0 ustar 00 // The template and inlines for the -*- C++ -*- slice_array class. // Copyright (C) 1997-2018 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/slice_array.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{valarray} */ // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> #ifndef _SLICE_ARRAY_H #define _SLICE_ARRAY_H 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup numeric_arrays * @{ */ /** * @brief Class defining one-dimensional subset of an array. * * The slice class represents a one-dimensional subset of an array, * specified by three parameters: start offset, size, and stride. The * start offset is the index of the first element of the array that is part * of the subset. The size is the total number of elements in the subset. * Stride is the distance between each successive array element to include * in the subset. * * For example, with an array of size 10, and a slice with offset 1, size 3 * and stride 2, the subset consists of array elements 1, 3, and 5. */ class slice { public: /// Construct an empty slice. slice(); /** * @brief Construct a slice. * * @param __o Offset in array of first element. * @param __d Number of elements in slice. * @param __s Stride between array elements. */ slice(size_t __o, size_t __d, size_t __s); /// Return array offset of first slice element. size_t start() const; /// Return size of slice. size_t size() const; /// Return array stride of slice. size_t stride() const; private: size_t _M_off; // offset size_t _M_sz; // size size_t _M_st; // stride unit }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 543. valarray slice default constructor inline slice::slice() : _M_off(0), _M_sz(0), _M_st(0) {} inline slice::slice(size_t __o, size_t __d, size_t __s) : _M_off(__o), _M_sz(__d), _M_st(__s) {} inline size_t slice::start() const { return _M_off; } inline size_t slice::size() const { return _M_sz; } inline size_t slice::stride() const { return _M_st; } /** * @brief Reference to one-dimensional subset of an array. * * A slice_array is a reference to the actual elements of an array * specified by a slice. The way to get a slice_array is to call * operator[](slice) on a valarray. The returned slice_array then permits * carrying operations out on the referenced subset of elements in the * original valarray. For example, operator+=(valarray) will add values * to the subset of elements in the underlying valarray this slice_array * refers to. * * @param Tp Element type. */ template<typename _Tp> class slice_array { public: typedef _Tp value_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 253. valarray helper functions are almost entirely useless /// Copy constructor. Both slices refer to the same underlying array. slice_array(const slice_array&); /// Assignment operator. Assigns slice elements to corresponding /// elements of @a a. slice_array& operator=(const slice_array&); /// Assign slice elements to corresponding elements of @a v. void operator=(const valarray<_Tp>&) const; /// Multiply slice elements by corresponding elements of @a v. void operator*=(const valarray<_Tp>&) const; /// Divide slice elements by corresponding elements of @a v. void operator/=(const valarray<_Tp>&) const; /// Modulo slice elements by corresponding elements of @a v. void operator%=(const valarray<_Tp>&) const; /// Add corresponding elements of @a v to slice elements. void operator+=(const valarray<_Tp>&) const; /// Subtract corresponding elements of @a v from slice elements. void operator-=(const valarray<_Tp>&) const; /// Logical xor slice elements with corresponding elements of @a v. void operator^=(const valarray<_Tp>&) const; /// Logical and slice elements with corresponding elements of @a v. void operator&=(const valarray<_Tp>&) const; /// Logical or slice elements with corresponding elements of @a v. void operator|=(const valarray<_Tp>&) const; /// Left shift slice elements by corresponding elements of @a v. void operator<<=(const valarray<_Tp>&) const; /// Right shift slice elements by corresponding elements of @a v. void operator>>=(const valarray<_Tp>&) const; /// Assign all slice elements to @a t. void operator=(const _Tp &) const; // ~slice_array (); template<class _Dom> void operator=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator*=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator/=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator%=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator+=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator-=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator^=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator&=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator|=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator<<=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator>>=(const _Expr<_Dom, _Tp>&) const; private: friend class valarray<_Tp>; slice_array(_Array<_Tp>, const slice&); const size_t _M_sz; const size_t _M_stride; const _Array<_Tp> _M_array; // not implemented slice_array(); }; template<typename _Tp> inline slice_array<_Tp>::slice_array(_Array<_Tp> __a, const slice& __s) : _M_sz(__s.size()), _M_stride(__s.stride()), _M_array(__a.begin() + __s.start()) {} template<typename _Tp> inline slice_array<_Tp>::slice_array(const slice_array<_Tp>& __a) : _M_sz(__a._M_sz), _M_stride(__a._M_stride), _M_array(__a._M_array) {} // template<typename _Tp> // inline slice_array<_Tp>::~slice_array () {} template<typename _Tp> inline slice_array<_Tp>& slice_array<_Tp>::operator=(const slice_array<_Tp>& __a) { std::__valarray_copy(__a._M_array, __a._M_sz, __a._M_stride, _M_array, _M_stride); return *this; } template<typename _Tp> inline void slice_array<_Tp>::operator=(const _Tp& __t) const { std::__valarray_fill(_M_array, _M_sz, _M_stride, __t); } template<typename _Tp> inline void slice_array<_Tp>::operator=(const valarray<_Tp>& __v) const { std::__valarray_copy(_Array<_Tp>(__v), _M_array, _M_sz, _M_stride); } template<typename _Tp> template<class _Dom> inline void slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const { std::__valarray_copy(__e, _M_sz, _M_array, _M_stride); } #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op,_Name) \ template<typename _Tp> \ inline void \ slice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ { \ _Array_augmented_##_Name(_M_array, _M_sz, _M_stride, _Array<_Tp>(__v));\ } \ \ template<typename _Tp> \ template<class _Dom> \ inline void \ slice_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\ { \ _Array_augmented_##_Name(_M_array, _M_stride, __e, _M_sz); \ } _DEFINE_VALARRAY_OPERATOR(*, __multiplies) _DEFINE_VALARRAY_OPERATOR(/, __divides) _DEFINE_VALARRAY_OPERATOR(%, __modulus) _DEFINE_VALARRAY_OPERATOR(+, __plus) _DEFINE_VALARRAY_OPERATOR(-, __minus) _DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) _DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) _DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) _DEFINE_VALARRAY_OPERATOR(<<, __shift_left) _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) #undef _DEFINE_VALARRAY_OPERATOR // @} group numeric_arrays _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _SLICE_ARRAY_H */ c++/8/bits/locale_conv.h 0000644 00000037341 15146341150 0010671 0 ustar 00 // wstring_convert implementation -*- C++ -*- // Copyright (C) 2015-2018 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/locale_conv.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ #ifndef _LOCALE_CONV_H #define _LOCALE_CONV_H 1 #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <streambuf> #include <bits/stringfwd.h> #include <bits/allocator.h> #include <bits/codecvt.h> #include <bits/unique_ptr.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup locales * @{ */ template<typename _OutStr, typename _InChar, typename _Codecvt, typename _State, typename _Fn> bool __do_str_codecvt(const _InChar* __first, const _InChar* __last, _OutStr& __outstr, const _Codecvt& __cvt, _State& __state, size_t& __count, _Fn __fn) { if (__first == __last) { __outstr.clear(); __count = 0; return true; } size_t __outchars = 0; auto __next = __first; const auto __maxlen = __cvt.max_length() + 1; codecvt_base::result __result; do { __outstr.resize(__outstr.size() + (__last - __next) * __maxlen); auto __outnext = &__outstr.front() + __outchars; auto const __outlast = &__outstr.back() + 1; __result = (__cvt.*__fn)(__state, __next, __last, __next, __outnext, __outlast, __outnext); __outchars = __outnext - &__outstr.front(); } while (__result == codecvt_base::partial && __next != __last && (__outstr.size() - __outchars) < __maxlen); if (__result == codecvt_base::error) { __count = __next - __first; return false; } if (__result == codecvt_base::noconv) { __outstr.assign(__first, __last); __count = __last - __first; } else { __outstr.resize(__outchars); __count = __next - __first; } return true; } // Convert narrow character string to wide. template<typename _CharT, typename _Traits, typename _Alloc, typename _State> inline bool __str_codecvt_in(const char* __first, const char* __last, basic_string<_CharT, _Traits, _Alloc>& __outstr, const codecvt<_CharT, char, _State>& __cvt, _State& __state, size_t& __count) { using _Codecvt = codecvt<_CharT, char, _State>; using _ConvFn = codecvt_base::result (_Codecvt::*)(_State&, const char*, const char*, const char*&, _CharT*, _CharT*, _CharT*&) const; _ConvFn __fn = &codecvt<_CharT, char, _State>::in; return __do_str_codecvt(__first, __last, __outstr, __cvt, __state, __count, __fn); } template<typename _CharT, typename _Traits, typename _Alloc, typename _State> inline bool __str_codecvt_in(const char* __first, const char* __last, basic_string<_CharT, _Traits, _Alloc>& __outstr, const codecvt<_CharT, char, _State>& __cvt) { _State __state = {}; size_t __n; return __str_codecvt_in(__first, __last, __outstr, __cvt, __state, __n); } // Convert wide character string to narrow. template<typename _CharT, typename _Traits, typename _Alloc, typename _State> inline bool __str_codecvt_out(const _CharT* __first, const _CharT* __last, basic_string<char, _Traits, _Alloc>& __outstr, const codecvt<_CharT, char, _State>& __cvt, _State& __state, size_t& __count) { using _Codecvt = codecvt<_CharT, char, _State>; using _ConvFn = codecvt_base::result (_Codecvt::*)(_State&, const _CharT*, const _CharT*, const _CharT*&, char*, char*, char*&) const; _ConvFn __fn = &codecvt<_CharT, char, _State>::out; return __do_str_codecvt(__first, __last, __outstr, __cvt, __state, __count, __fn); } template<typename _CharT, typename _Traits, typename _Alloc, typename _State> inline bool __str_codecvt_out(const _CharT* __first, const _CharT* __last, basic_string<char, _Traits, _Alloc>& __outstr, const codecvt<_CharT, char, _State>& __cvt) { _State __state = {}; size_t __n; return __str_codecvt_out(__first, __last, __outstr, __cvt, __state, __n); } #ifdef _GLIBCXX_USE_WCHAR_T _GLIBCXX_BEGIN_NAMESPACE_CXX11 /// String conversions template<typename _Codecvt, typename _Elem = wchar_t, typename _Wide_alloc = allocator<_Elem>, typename _Byte_alloc = allocator<char>> class wstring_convert { public: typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string; typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string; typedef typename _Codecvt::state_type state_type; typedef typename wide_string::traits_type::int_type int_type; /** Default constructor. * * @param __pcvt The facet to use for conversions. * * Takes ownership of @p __pcvt and will delete it in the destructor. */ explicit wstring_convert(_Codecvt* __pcvt = new _Codecvt()) : _M_cvt(__pcvt) { if (!_M_cvt) __throw_logic_error("wstring_convert"); } /** Construct with an initial converstion state. * * @param __pcvt The facet to use for conversions. * @param __state Initial conversion state. * * Takes ownership of @p __pcvt and will delete it in the destructor. * The object's conversion state will persist between conversions. */ wstring_convert(_Codecvt* __pcvt, state_type __state) : _M_cvt(__pcvt), _M_state(__state), _M_with_cvtstate(true) { if (!_M_cvt) __throw_logic_error("wstring_convert"); } /** Construct with error strings. * * @param __byte_err A string to return on failed conversions. * @param __wide_err A wide string to return on failed conversions. */ explicit wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err = wide_string()) : _M_cvt(new _Codecvt), _M_byte_err_string(__byte_err), _M_wide_err_string(__wide_err), _M_with_strings(true) { if (!_M_cvt) __throw_logic_error("wstring_convert"); } ~wstring_convert() = default; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2176. Special members for wstring_convert and wbuffer_convert wstring_convert(const wstring_convert&) = delete; wstring_convert& operator=(const wstring_convert&) = delete; /// @{ Convert from bytes. wide_string from_bytes(char __byte) { char __bytes[2] = { __byte }; return from_bytes(__bytes, __bytes+1); } wide_string from_bytes(const char* __ptr) { return from_bytes(__ptr, __ptr+char_traits<char>::length(__ptr)); } wide_string from_bytes(const byte_string& __str) { auto __ptr = __str.data(); return from_bytes(__ptr, __ptr + __str.size()); } wide_string from_bytes(const char* __first, const char* __last) { if (!_M_with_cvtstate) _M_state = state_type(); wide_string __out{ _M_wide_err_string.get_allocator() }; if (__str_codecvt_in(__first, __last, __out, *_M_cvt, _M_state, _M_count)) return __out; if (_M_with_strings) return _M_wide_err_string; __throw_range_error("wstring_convert::from_bytes"); } /// @} /// @{ Convert to bytes. byte_string to_bytes(_Elem __wchar) { _Elem __wchars[2] = { __wchar }; return to_bytes(__wchars, __wchars+1); } byte_string to_bytes(const _Elem* __ptr) { return to_bytes(__ptr, __ptr+wide_string::traits_type::length(__ptr)); } byte_string to_bytes(const wide_string& __wstr) { auto __ptr = __wstr.data(); return to_bytes(__ptr, __ptr + __wstr.size()); } byte_string to_bytes(const _Elem* __first, const _Elem* __last) { if (!_M_with_cvtstate) _M_state = state_type(); byte_string __out{ _M_byte_err_string.get_allocator() }; if (__str_codecvt_out(__first, __last, __out, *_M_cvt, _M_state, _M_count)) return __out; if (_M_with_strings) return _M_byte_err_string; __throw_range_error("wstring_convert::to_bytes"); } /// @} // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2174. wstring_convert::converted() should be noexcept /// The number of elements successfully converted in the last conversion. size_t converted() const noexcept { return _M_count; } /// The final conversion state of the last conversion. state_type state() const { return _M_state; } private: unique_ptr<_Codecvt> _M_cvt; byte_string _M_byte_err_string; wide_string _M_wide_err_string; state_type _M_state = state_type(); size_t _M_count = 0; bool _M_with_cvtstate = false; bool _M_with_strings = false; }; _GLIBCXX_END_NAMESPACE_CXX11 /// Buffer conversions template<typename _Codecvt, typename _Elem = wchar_t, typename _Tr = char_traits<_Elem>> class wbuffer_convert : public basic_streambuf<_Elem, _Tr> { typedef basic_streambuf<_Elem, _Tr> _Wide_streambuf; public: typedef typename _Codecvt::state_type state_type; /** Default constructor. * * @param __bytebuf The underlying byte stream buffer. * @param __pcvt The facet to use for conversions. * @param __state Initial conversion state. * * Takes ownership of @p __pcvt and will delete it in the destructor. */ explicit wbuffer_convert(streambuf* __bytebuf = 0, _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type()) : _M_buf(__bytebuf), _M_cvt(__pcvt), _M_state(__state) { if (!_M_cvt) __throw_logic_error("wbuffer_convert"); _M_always_noconv = _M_cvt->always_noconv(); if (_M_buf) { this->setp(_M_put_area, _M_put_area + _S_buffer_length); this->setg(_M_get_area + _S_putback_length, _M_get_area + _S_putback_length, _M_get_area + _S_putback_length); } } ~wbuffer_convert() = default; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2176. Special members for wstring_convert and wbuffer_convert wbuffer_convert(const wbuffer_convert&) = delete; wbuffer_convert& operator=(const wbuffer_convert&) = delete; streambuf* rdbuf() const noexcept { return _M_buf; } streambuf* rdbuf(streambuf *__bytebuf) noexcept { auto __prev = _M_buf; _M_buf = __bytebuf; return __prev; } /// The conversion state following the last conversion. state_type state() const noexcept { return _M_state; } protected: int sync() { return _M_buf && _M_conv_put() && !_M_buf->pubsync() ? 0 : -1; } typename _Wide_streambuf::int_type overflow(typename _Wide_streambuf::int_type __out) { if (!_M_buf || !_M_conv_put()) return _Tr::eof(); else if (!_Tr::eq_int_type(__out, _Tr::eof())) return this->sputc(__out); return _Tr::not_eof(__out); } typename _Wide_streambuf::int_type underflow() { if (!_M_buf) return _Tr::eof(); if (this->gptr() < this->egptr() || (_M_buf && _M_conv_get())) return _Tr::to_int_type(*this->gptr()); else return _Tr::eof(); } streamsize xsputn(const typename _Wide_streambuf::char_type* __s, streamsize __n) { if (!_M_buf || __n == 0) return 0; streamsize __done = 0; do { auto __nn = std::min<streamsize>(this->epptr() - this->pptr(), __n - __done); _Tr::copy(this->pptr(), __s + __done, __nn); this->pbump(__nn); __done += __nn; } while (__done < __n && _M_conv_put()); return __done; } private: // fill the get area from converted contents of the byte stream buffer bool _M_conv_get() { const streamsize __pb1 = this->gptr() - this->eback(); const streamsize __pb2 = _S_putback_length; const streamsize __npb = std::min(__pb1, __pb2); _Tr::move(_M_get_area + _S_putback_length - __npb, this->gptr() - __npb, __npb); streamsize __nbytes = sizeof(_M_get_buf) - _M_unconv; __nbytes = std::min(__nbytes, _M_buf->in_avail()); if (__nbytes < 1) __nbytes = 1; __nbytes = _M_buf->sgetn(_M_get_buf + _M_unconv, __nbytes); if (__nbytes < 1) return false; __nbytes += _M_unconv; // convert _M_get_buf into _M_get_area _Elem* __outbuf = _M_get_area + _S_putback_length; _Elem* __outnext = __outbuf; const char* __bnext = _M_get_buf; codecvt_base::result __result; if (_M_always_noconv) __result = codecvt_base::noconv; else { _Elem* __outend = _M_get_area + _S_buffer_length; __result = _M_cvt->in(_M_state, __bnext, __bnext + __nbytes, __bnext, __outbuf, __outend, __outnext); } if (__result == codecvt_base::noconv) { // cast is safe because noconv means _Elem is same type as char auto __get_buf = reinterpret_cast<const _Elem*>(_M_get_buf); _Tr::copy(__outbuf, __get_buf, __nbytes); _M_unconv = 0; return true; } if ((_M_unconv = _M_get_buf + __nbytes - __bnext)) char_traits<char>::move(_M_get_buf, __bnext, _M_unconv); this->setg(__outbuf, __outbuf, __outnext); return __result != codecvt_base::error; } // unused bool _M_put(...) { return false; } bool _M_put(const char* __p, streamsize __n) { if (_M_buf->sputn(__p, __n) < __n) return false; return true; } // convert the put area and write to the byte stream buffer bool _M_conv_put() { _Elem* const __first = this->pbase(); const _Elem* const __last = this->pptr(); const streamsize __pending = __last - __first; if (_M_always_noconv) return _M_put(__first, __pending); char __outbuf[2 * _S_buffer_length]; const _Elem* __next = __first; const _Elem* __start; do { __start = __next; char* __outnext = __outbuf; char* const __outlast = __outbuf + sizeof(__outbuf); auto __result = _M_cvt->out(_M_state, __next, __last, __next, __outnext, __outlast, __outnext); if (__result == codecvt_base::error) return false; else if (__result == codecvt_base::noconv) return _M_put(__next, __pending); if (!_M_put(__outbuf, __outnext - __outbuf)) return false; } while (__next != __last && __next != __start); if (__next != __last) _Tr::move(__first, __next, __last - __next); this->pbump(__first - __next); return __next != __first; } streambuf* _M_buf; unique_ptr<_Codecvt> _M_cvt; state_type _M_state; static const streamsize _S_buffer_length = 32; static const streamsize _S_putback_length = 3; _Elem _M_put_area[_S_buffer_length]; _Elem _M_get_area[_S_buffer_length]; streamsize _M_unconv = 0; char _M_get_buf[_S_buffer_length-_S_putback_length]; bool _M_always_noconv; }; #endif // _GLIBCXX_USE_WCHAR_T /// @} group locales _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // __cplusplus #endif /* _LOCALE_CONV_H */ c++/8/bits/basic_ios.h 0000644 00000037312 15146341150 0010336 0 ustar 00 // Iostreams base classes -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/basic_ios.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ios} */ #ifndef _BASIC_IOS_H #define _BASIC_IOS_H 1 #pragma GCC system_header #include <bits/localefwd.h> #include <bits/locale_classes.h> #include <bits/locale_facets.h> #include <bits/streambuf_iterator.h> #include <bits/move.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Facet> inline const _Facet& __check_facet(const _Facet* __f) { if (!__f) __throw_bad_cast(); return *__f; } /** * @brief Template class basic_ios, virtual base class for all * stream classes. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * Most of the member functions called dispatched on stream objects * (e.g., @c std::cout.foo(bar);) are consolidated in this class. */ template<typename _CharT, typename _Traits> class basic_ios : public ios_base { public: //@{ /** * These are standard types. They permit a standardized way of * referring to names of (or names dependent on) the template * parameters, which are specific to the implementation. */ typedef _CharT char_type; typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type; typedef _Traits traits_type; //@} //@{ /** * These are non-standard types. */ typedef ctype<_CharT> __ctype_type; typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > __num_put_type; typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> > __num_get_type; //@} // Data members: protected: basic_ostream<_CharT, _Traits>* _M_tie; mutable char_type _M_fill; mutable bool _M_fill_init; basic_streambuf<_CharT, _Traits>* _M_streambuf; // Cached use_facet<ctype>, which is based on the current locale info. const __ctype_type* _M_ctype; // For ostream. const __num_put_type* _M_num_put; // For istream. const __num_get_type* _M_num_get; public: //@{ /** * @brief The quick-and-easy status check. * * This allows you to write constructs such as * <code>if (!a_stream) ...</code> and <code>while (a_stream) ...</code> */ #if __cplusplus >= 201103L explicit operator bool() const { return !this->fail(); } #else operator void*() const { return this->fail() ? 0 : const_cast<basic_ios*>(this); } #endif bool operator!() const { return this->fail(); } //@} /** * @brief Returns the error state of the stream buffer. * @return A bit pattern (well, isn't everything?) * * See std::ios_base::iostate for the possible bit values. Most * users will call one of the interpreting wrappers, e.g., good(). */ iostate rdstate() const { return _M_streambuf_state; } /** * @brief [Re]sets the error state. * @param __state The new state flag(s) to set. * * See std::ios_base::iostate for the possible bit values. Most * users will not need to pass an argument. */ void clear(iostate __state = goodbit); /** * @brief Sets additional flags in the error state. * @param __state The additional state flag(s) to set. * * See std::ios_base::iostate for the possible bit values. */ void setstate(iostate __state) { this->clear(this->rdstate() | __state); } // Flip the internal state on for the proper state bits, then // rethrows the propagated exception if bit also set in // exceptions(). void _M_setstate(iostate __state) { // 27.6.1.2.1 Common requirements. // Turn this on without causing an ios::failure to be thrown. _M_streambuf_state |= __state; if (this->exceptions() & __state) __throw_exception_again; } /** * @brief Fast error checking. * @return True if no error flags are set. * * A wrapper around rdstate. */ bool good() const { return this->rdstate() == 0; } /** * @brief Fast error checking. * @return True if the eofbit is set. * * Note that other iostate flags may also be set. */ bool eof() const { return (this->rdstate() & eofbit) != 0; } /** * @brief Fast error checking. * @return True if either the badbit or the failbit is set. * * Checking the badbit in fail() is historical practice. * Note that other iostate flags may also be set. */ bool fail() const { return (this->rdstate() & (badbit | failbit)) != 0; } /** * @brief Fast error checking. * @return True if the badbit is set. * * Note that other iostate flags may also be set. */ bool bad() const { return (this->rdstate() & badbit) != 0; } /** * @brief Throwing exceptions on errors. * @return The current exceptions mask. * * This changes nothing in the stream. See the one-argument version * of exceptions(iostate) for the meaning of the return value. */ iostate exceptions() const { return _M_exception; } /** * @brief Throwing exceptions on errors. * @param __except The new exceptions mask. * * By default, error flags are set silently. You can set an * exceptions mask for each stream; if a bit in the mask becomes set * in the error flags, then an exception of type * std::ios_base::failure is thrown. * * If the error flag is already set when the exceptions mask is * added, the exception is immediately thrown. Try running the * following under GCC 3.1 or later: * @code * #include <iostream> * #include <fstream> * #include <exception> * * int main() * { * std::set_terminate (__gnu_cxx::__verbose_terminate_handler); * * std::ifstream f ("/etc/motd"); * * std::cerr << "Setting badbit\n"; * f.setstate (std::ios_base::badbit); * * std::cerr << "Setting exception mask\n"; * f.exceptions (std::ios_base::badbit); * } * @endcode */ void exceptions(iostate __except) { _M_exception = __except; this->clear(_M_streambuf_state); } // Constructor/destructor: /** * @brief Constructor performs initialization. * * The parameter is passed by derived streams. */ explicit basic_ios(basic_streambuf<_CharT, _Traits>* __sb) : ios_base(), _M_tie(0), _M_fill(), _M_fill_init(false), _M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0) { this->init(__sb); } /** * @brief Empty. * * The destructor does nothing. More specifically, it does not * destroy the streambuf held by rdbuf(). */ virtual ~basic_ios() { } // Members: /** * @brief Fetches the current @e tied stream. * @return A pointer to the tied stream, or NULL if the stream is * not tied. * * A stream may be @e tied (or synchronized) to a second output * stream. When this stream performs any I/O, the tied stream is * first flushed. For example, @c std::cin is tied to @c std::cout. */ basic_ostream<_CharT, _Traits>* tie() const { return _M_tie; } /** * @brief Ties this stream to an output stream. * @param __tiestr The output stream. * @return The previously tied output stream, or NULL if the stream * was not tied. * * This sets up a new tie; see tie() for more. */ basic_ostream<_CharT, _Traits>* tie(basic_ostream<_CharT, _Traits>* __tiestr) { basic_ostream<_CharT, _Traits>* __old = _M_tie; _M_tie = __tiestr; return __old; } /** * @brief Accessing the underlying buffer. * @return The current stream buffer. * * This does not change the state of the stream. */ basic_streambuf<_CharT, _Traits>* rdbuf() const { return _M_streambuf; } /** * @brief Changing the underlying buffer. * @param __sb The new stream buffer. * @return The previous stream buffer. * * Associates a new buffer with the current stream, and clears the * error state. * * Due to historical accidents which the LWG refuses to correct, the * I/O library suffers from a design error: this function is hidden * in derived classes by overrides of the zero-argument @c rdbuf(), * which is non-virtual for hysterical raisins. As a result, you * must use explicit qualifications to access this function via any * derived class. For example: * * @code * std::fstream foo; // or some other derived type * std::streambuf* p = .....; * * foo.ios::rdbuf(p); // ios == basic_ios<char> * @endcode */ basic_streambuf<_CharT, _Traits>* rdbuf(basic_streambuf<_CharT, _Traits>* __sb); /** * @brief Copies fields of __rhs into this. * @param __rhs The source values for the copies. * @return Reference to this object. * * All fields of __rhs are copied into this object except that rdbuf() * and rdstate() remain unchanged. All values in the pword and iword * arrays are copied. Before copying, each callback is invoked with * erase_event. After copying, each (new) callback is invoked with * copyfmt_event. The final step is to copy exceptions(). */ basic_ios& copyfmt(const basic_ios& __rhs); /** * @brief Retrieves the @a empty character. * @return The current fill character. * * It defaults to a space (' ') in the current locale. */ char_type fill() const { if (!_M_fill_init) { _M_fill = this->widen(' '); _M_fill_init = true; } return _M_fill; } /** * @brief Sets a new @a empty character. * @param __ch The new character. * @return The previous fill character. * * The fill character is used to fill out space when P+ characters * have been requested (e.g., via setw), Q characters are actually * used, and Q<P. It defaults to a space (' ') in the current locale. */ char_type fill(char_type __ch) { char_type __old = this->fill(); _M_fill = __ch; return __old; } // Locales: /** * @brief Moves to a new locale. * @param __loc The new locale. * @return The previous locale. * * Calls @c ios_base::imbue(loc), and if a stream buffer is associated * with this stream, calls that buffer's @c pubimbue(loc). * * Additional l10n notes are at * http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html */ locale imbue(const locale& __loc); /** * @brief Squeezes characters. * @param __c The character to narrow. * @param __dfault The character to narrow. * @return The narrowed character. * * Maps a character of @c char_type to a character of @c char, * if possible. * * Returns the result of * @code * std::use_facet<ctype<char_type> >(getloc()).narrow(c,dfault) * @endcode * * Additional l10n notes are at * http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html */ char narrow(char_type __c, char __dfault) const { return __check_facet(_M_ctype).narrow(__c, __dfault); } /** * @brief Widens characters. * @param __c The character to widen. * @return The widened character. * * Maps a character of @c char to a character of @c char_type. * * Returns the result of * @code * std::use_facet<ctype<char_type> >(getloc()).widen(c) * @endcode * * Additional l10n notes are at * http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html */ char_type widen(char __c) const { return __check_facet(_M_ctype).widen(__c); } protected: // 27.4.5.1 basic_ios constructors /** * @brief Empty. * * The default constructor does nothing and is not normally * accessible to users. */ basic_ios() : ios_base(), _M_tie(0), _M_fill(char_type()), _M_fill_init(false), _M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0) { } /** * @brief All setup is performed here. * * This is called from the public constructor. It is not virtual and * cannot be redefined. */ void init(basic_streambuf<_CharT, _Traits>* __sb); #if __cplusplus >= 201103L basic_ios(const basic_ios&) = delete; basic_ios& operator=(const basic_ios&) = delete; void move(basic_ios& __rhs) { ios_base::_M_move(__rhs); _M_cache_locale(_M_ios_locale); this->tie(__rhs.tie(nullptr)); _M_fill = __rhs._M_fill; _M_fill_init = __rhs._M_fill_init; _M_streambuf = nullptr; } void move(basic_ios&& __rhs) { this->move(__rhs); } void swap(basic_ios& __rhs) noexcept { ios_base::_M_swap(__rhs); _M_cache_locale(_M_ios_locale); __rhs._M_cache_locale(__rhs._M_ios_locale); std::swap(_M_tie, __rhs._M_tie); std::swap(_M_fill, __rhs._M_fill); std::swap(_M_fill_init, __rhs._M_fill_init); } void set_rdbuf(basic_streambuf<_CharT, _Traits>* __sb) { _M_streambuf = __sb; } #endif void _M_cache_locale(const locale& __loc); }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include <bits/basic_ios.tcc> #endif /* _BASIC_IOS_H */ c++/8/bits/regex_scanner.tcc 0000644 00000035241 15146341150 0011547 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2013-2018 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/regex_scanner.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ // FIXME make comments doxygen format. // N3376 specified 6 regex styles: ECMAScript, basic, extended, grep, egrep // and awk // 1) grep is basic except '\n' is treated as '|' // 2) egrep is extended except '\n' is treated as '|' // 3) awk is extended except special escaping rules, and there's no // back-reference. // // References: // // ECMAScript: ECMA-262 15.10 // // basic, extended: // http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html // // awk: http://pubs.opengroup.org/onlinepubs/000095399/utilities/awk.html namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { template<typename _CharT> _Scanner<_CharT>:: _Scanner(typename _Scanner::_IterT __begin, typename _Scanner::_IterT __end, _FlagT __flags, std::locale __loc) : _ScannerBase(__flags), _M_current(__begin), _M_end(__end), _M_ctype(std::use_facet<_CtypeT>(__loc)), _M_eat_escape(_M_is_ecma() ? &_Scanner::_M_eat_escape_ecma : &_Scanner::_M_eat_escape_posix) { _M_advance(); } template<typename _CharT> void _Scanner<_CharT>:: _M_advance() { if (_M_current == _M_end) { _M_token = _S_token_eof; return; } if (_M_state == _S_state_normal) _M_scan_normal(); else if (_M_state == _S_state_in_bracket) _M_scan_in_bracket(); else if (_M_state == _S_state_in_brace) _M_scan_in_brace(); else { __glibcxx_assert(false); } } // Differences between styles: // 1) "\(", "\)", "\{" in basic. It's not escaping. // 2) "(?:", "(?=", "(?!" in ECMAScript. template<typename _CharT> void _Scanner<_CharT>:: _M_scan_normal() { auto __c = *_M_current++; if (std::strchr(_M_spec_char, _M_ctype.narrow(__c, ' ')) == nullptr) { _M_token = _S_token_ord_char; _M_value.assign(1, __c); return; } if (__c == '\\') { if (_M_current == _M_end) __throw_regex_error( regex_constants::error_escape, "Unexpected end of regex when escaping."); if (!_M_is_basic() || (*_M_current != '(' && *_M_current != ')' && *_M_current != '{')) { (this->*_M_eat_escape)(); return; } __c = *_M_current++; } if (__c == '(') { if (_M_is_ecma() && *_M_current == '?') { if (++_M_current == _M_end) __throw_regex_error( regex_constants::error_paren, "Unexpected end of regex when in an open parenthesis."); if (*_M_current == ':') { ++_M_current; _M_token = _S_token_subexpr_no_group_begin; } else if (*_M_current == '=') { ++_M_current; _M_token = _S_token_subexpr_lookahead_begin; _M_value.assign(1, 'p'); } else if (*_M_current == '!') { ++_M_current; _M_token = _S_token_subexpr_lookahead_begin; _M_value.assign(1, 'n'); } else __throw_regex_error( regex_constants::error_paren, "Invalid special open parenthesis."); } else if (_M_flags & regex_constants::nosubs) _M_token = _S_token_subexpr_no_group_begin; else _M_token = _S_token_subexpr_begin; } else if (__c == ')') _M_token = _S_token_subexpr_end; else if (__c == '[') { _M_state = _S_state_in_bracket; _M_at_bracket_start = true; if (_M_current != _M_end && *_M_current == '^') { _M_token = _S_token_bracket_neg_begin; ++_M_current; } else _M_token = _S_token_bracket_begin; } else if (__c == '{') { _M_state = _S_state_in_brace; _M_token = _S_token_interval_begin; } else if (__c != ']' && __c != '}') { auto __it = _M_token_tbl; auto __narrowc = _M_ctype.narrow(__c, '\0'); for (; __it->first != '\0'; ++__it) if (__it->first == __narrowc) { _M_token = __it->second; return; } __glibcxx_assert(false); } else { _M_token = _S_token_ord_char; _M_value.assign(1, __c); } } // Differences between styles: // 1) different semantics of "[]" and "[^]". // 2) Escaping in bracket expr. template<typename _CharT> void _Scanner<_CharT>:: _M_scan_in_bracket() { if (_M_current == _M_end) __throw_regex_error( regex_constants::error_brack, "Unexpected end of regex when in bracket expression."); auto __c = *_M_current++; if (__c == '-') _M_token = _S_token_bracket_dash; else if (__c == '[') { if (_M_current == _M_end) __throw_regex_error(regex_constants::error_brack, "Unexpected character class open bracket."); if (*_M_current == '.') { _M_token = _S_token_collsymbol; _M_eat_class(*_M_current++); } else if (*_M_current == ':') { _M_token = _S_token_char_class_name; _M_eat_class(*_M_current++); } else if (*_M_current == '=') { _M_token = _S_token_equiv_class_name; _M_eat_class(*_M_current++); } else { _M_token = _S_token_ord_char; _M_value.assign(1, __c); } } // In POSIX, when encountering "[]" or "[^]", the ']' is interpreted // literally. So "[]]" and "[^]]" are valid regexes. See the testcases // `*/empty_range.cc`. else if (__c == ']' && (_M_is_ecma() || !_M_at_bracket_start)) { _M_token = _S_token_bracket_end; _M_state = _S_state_normal; } // ECMAScript and awk permits escaping in bracket. else if (__c == '\\' && (_M_is_ecma() || _M_is_awk())) (this->*_M_eat_escape)(); else { _M_token = _S_token_ord_char; _M_value.assign(1, __c); } _M_at_bracket_start = false; } // Differences between styles: // 1) "\}" in basic style. template<typename _CharT> void _Scanner<_CharT>:: _M_scan_in_brace() { if (_M_current == _M_end) __throw_regex_error( regex_constants::error_brace, "Unexpected end of regex when in brace expression."); auto __c = *_M_current++; if (_M_ctype.is(_CtypeT::digit, __c)) { _M_token = _S_token_dup_count; _M_value.assign(1, __c); while (_M_current != _M_end && _M_ctype.is(_CtypeT::digit, *_M_current)) _M_value += *_M_current++; } else if (__c == ',') _M_token = _S_token_comma; // basic use \}. else if (_M_is_basic()) { if (__c == '\\' && _M_current != _M_end && *_M_current == '}') { _M_state = _S_state_normal; _M_token = _S_token_interval_end; ++_M_current; } else __throw_regex_error(regex_constants::error_badbrace, "Unexpected character in brace expression."); } else if (__c == '}') { _M_state = _S_state_normal; _M_token = _S_token_interval_end; } else __throw_regex_error(regex_constants::error_badbrace, "Unexpected character in brace expression."); } template<typename _CharT> void _Scanner<_CharT>:: _M_eat_escape_ecma() { if (_M_current == _M_end) __throw_regex_error(regex_constants::error_escape, "Unexpected end of regex when escaping."); auto __c = *_M_current++; auto __pos = _M_find_escape(_M_ctype.narrow(__c, '\0')); if (__pos != nullptr && (__c != 'b' || _M_state == _S_state_in_bracket)) { _M_token = _S_token_ord_char; _M_value.assign(1, *__pos); } else if (__c == 'b') { _M_token = _S_token_word_bound; _M_value.assign(1, 'p'); } else if (__c == 'B') { _M_token = _S_token_word_bound; _M_value.assign(1, 'n'); } // N3376 28.13 else if (__c == 'd' || __c == 'D' || __c == 's' || __c == 'S' || __c == 'w' || __c == 'W') { _M_token = _S_token_quoted_class; _M_value.assign(1, __c); } else if (__c == 'c') { if (_M_current == _M_end) __throw_regex_error( regex_constants::error_escape, "Unexpected end of regex when reading control code."); _M_token = _S_token_ord_char; _M_value.assign(1, *_M_current++); } else if (__c == 'x' || __c == 'u') { _M_value.erase(); for (int __i = 0; __i < (__c == 'x' ? 2 : 4); __i++) { if (_M_current == _M_end || !_M_ctype.is(_CtypeT::xdigit, *_M_current)) __throw_regex_error( regex_constants::error_escape, "Unexpected end of regex when ascii character."); _M_value += *_M_current++; } _M_token = _S_token_hex_num; } // ECMAScript recognizes multi-digit back-references. else if (_M_ctype.is(_CtypeT::digit, __c)) { _M_value.assign(1, __c); while (_M_current != _M_end && _M_ctype.is(_CtypeT::digit, *_M_current)) _M_value += *_M_current++; _M_token = _S_token_backref; } else { _M_token = _S_token_ord_char; _M_value.assign(1, __c); } } // Differences between styles: // 1) Extended doesn't support backref, but basic does. template<typename _CharT> void _Scanner<_CharT>:: _M_eat_escape_posix() { if (_M_current == _M_end) __throw_regex_error(regex_constants::error_escape, "Unexpected end of regex when escaping."); auto __c = *_M_current; auto __pos = std::strchr(_M_spec_char, _M_ctype.narrow(__c, '\0')); if (__pos != nullptr && *__pos != '\0') { _M_token = _S_token_ord_char; _M_value.assign(1, __c); } // We MUST judge awk before handling backrefs. There's no backref in awk. else if (_M_is_awk()) { _M_eat_escape_awk(); return; } else if (_M_is_basic() && _M_ctype.is(_CtypeT::digit, __c) && __c != '0') { _M_token = _S_token_backref; _M_value.assign(1, __c); } else { #ifdef __STRICT_ANSI__ // POSIX says it is undefined to escape ordinary characters __throw_regex_error(regex_constants::error_escape, "Unexpected escape character."); #else _M_token = _S_token_ord_char; _M_value.assign(1, __c); #endif } ++_M_current; } template<typename _CharT> void _Scanner<_CharT>:: _M_eat_escape_awk() { auto __c = *_M_current++; auto __pos = _M_find_escape(_M_ctype.narrow(__c, '\0')); if (__pos != nullptr) { _M_token = _S_token_ord_char; _M_value.assign(1, *__pos); } // \ddd for oct representation else if (_M_ctype.is(_CtypeT::digit, __c) && __c != '8' && __c != '9') { _M_value.assign(1, __c); for (int __i = 0; __i < 2 && _M_current != _M_end && _M_ctype.is(_CtypeT::digit, *_M_current) && *_M_current != '8' && *_M_current != '9'; __i++) _M_value += *_M_current++; _M_token = _S_token_oct_num; return; } else __throw_regex_error(regex_constants::error_escape, "Unexpected escape character."); } // Eats a character class or throws an exception. // __ch could be ':', '.' or '=', _M_current is the char after ']' when // returning. template<typename _CharT> void _Scanner<_CharT>:: _M_eat_class(char __ch) { for (_M_value.clear(); _M_current != _M_end && *_M_current != __ch;) _M_value += *_M_current++; if (_M_current == _M_end || *_M_current++ != __ch || _M_current == _M_end // skip __ch || *_M_current++ != ']') // skip ']' { if (__ch == ':') __throw_regex_error(regex_constants::error_ctype, "Unexpected end of character class."); else __throw_regex_error(regex_constants::error_collate, "Unexpected end of character class."); } } #ifdef _GLIBCXX_DEBUG template<typename _CharT> std::ostream& _Scanner<_CharT>:: _M_print(std::ostream& ostr) { switch (_M_token) { case _S_token_anychar: ostr << "any-character\n"; break; case _S_token_backref: ostr << "backref\n"; break; case _S_token_bracket_begin: ostr << "bracket-begin\n"; break; case _S_token_bracket_neg_begin: ostr << "bracket-neg-begin\n"; break; case _S_token_bracket_end: ostr << "bracket-end\n"; break; case _S_token_char_class_name: ostr << "char-class-name \"" << _M_value << "\"\n"; break; case _S_token_closure0: ostr << "closure0\n"; break; case _S_token_closure1: ostr << "closure1\n"; break; case _S_token_collsymbol: ostr << "collsymbol \"" << _M_value << "\"\n"; break; case _S_token_comma: ostr << "comma\n"; break; case _S_token_dup_count: ostr << "dup count: " << _M_value << "\n"; break; case _S_token_eof: ostr << "EOF\n"; break; case _S_token_equiv_class_name: ostr << "equiv-class-name \"" << _M_value << "\"\n"; break; case _S_token_interval_begin: ostr << "interval begin\n"; break; case _S_token_interval_end: ostr << "interval end\n"; break; case _S_token_line_begin: ostr << "line begin\n"; break; case _S_token_line_end: ostr << "line end\n"; break; case _S_token_opt: ostr << "opt\n"; break; case _S_token_or: ostr << "or\n"; break; case _S_token_ord_char: ostr << "ordinary character: \"" << _M_value << "\"\n"; break; case _S_token_subexpr_begin: ostr << "subexpr begin\n"; break; case _S_token_subexpr_no_group_begin: ostr << "no grouping subexpr begin\n"; break; case _S_token_subexpr_lookahead_begin: ostr << "lookahead subexpr begin\n"; break; case _S_token_subexpr_end: ostr << "subexpr end\n"; break; case _S_token_unknown: ostr << "-- unknown token --\n"; break; case _S_token_oct_num: ostr << "oct number " << _M_value << "\n"; break; case _S_token_hex_num: ostr << "hex number " << _M_value << "\n"; break; case _S_token_quoted_class: ostr << "quoted class " << "\\" << _M_value << "\n"; break; default: _GLIBCXX_DEBUG_ASSERT(false); } return ostr; } #endif } // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/bits/stl_numeric.h 0000644 00000033010 15146341150 0010716 0 ustar 00 // Numeric functions implementation -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_numeric.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{numeric} */ #ifndef _STL_NUMERIC_H #define _STL_NUMERIC_H 1 #include <bits/concept_check.h> #include <debug/debug.h> #include <bits/move.h> // For _GLIBCXX_MOVE #if __cplusplus >= 201103L namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Create a range of sequentially increasing values. * * For each element in the range @p [first,last) assigns @p value and * increments @p value as if by @p ++value. * * @param __first Start of range. * @param __last End of range. * @param __value Starting value. * @return Nothing. */ template<typename _ForwardIterator, typename _Tp> void iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_function_requires(_ConvertibleConcept<_Tp, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first) { *__first = __value; ++__value; } } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_ALGO /** * @brief Accumulate values in a range. * * Accumulates the values in the range [first,last) using operator+(). The * initial value is @a init. The values are processed in order. * * @param __first Start of range. * @param __last End of range. * @param __init Starting value to add other values to. * @return The final sum. */ template<typename _InputIterator, typename _Tp> inline _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first) __init = __init + *__first; return __init; } /** * @brief Accumulate values in a range with operation. * * Accumulates the values in the range [first,last) using the function * object @p __binary_op. The initial value is @p __init. The values are * processed in order. * * @param __first Start of range. * @param __last End of range. * @param __init Starting value to add other values to. * @param __binary_op Function object to accumulate with. * @return The final sum. */ template<typename _InputIterator, typename _Tp, typename _BinaryOperation> inline _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first) __init = __binary_op(__init, *__first); return __init; } /** * @brief Compute inner product of two ranges. * * Starting with an initial value of @p __init, multiplies successive * elements from the two ranges and adds each product into the accumulated * value using operator+(). The values in the ranges are processed in * order. * * @param __first1 Start of range 1. * @param __last1 End of range 1. * @param __first2 Start of range 2. * @param __init Starting value to add other values to. * @return The final inner product. */ template<typename _InputIterator1, typename _InputIterator2, typename _Tp> inline _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_requires_valid_range(__first1, __last1); for (; __first1 != __last1; ++__first1, (void)++__first2) __init = __init + (*__first1 * *__first2); return __init; } /** * @brief Compute inner product of two ranges. * * Starting with an initial value of @p __init, applies @p __binary_op2 to * successive elements from the two ranges and accumulates each result into * the accumulated value using @p __binary_op1. The values in the ranges are * processed in order. * * @param __first1 Start of range 1. * @param __last1 End of range 1. * @param __first2 Start of range 2. * @param __init Starting value to add other values to. * @param __binary_op1 Function object to accumulate with. * @param __binary_op2 Function object to apply to pairs of input values. * @return The final inner product. */ template<typename _InputIterator1, typename _InputIterator2, typename _Tp, typename _BinaryOperation1, typename _BinaryOperation2> inline _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_requires_valid_range(__first1, __last1); for (; __first1 != __last1; ++__first1, (void)++__first2) __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); return __init; } /** * @brief Return list of partial sums * * Accumulates the values in the range [first,last) using the @c + operator. * As each successive input value is added into the total, that partial sum * is written to @p __result. Therefore, the first value in @p __result is * the first value of the input, the second value in @p __result is the sum * of the first and second input values, and so on. * * @param __first Start of input range. * @param __last End of input range. * @param __result Output sum. * @return Iterator pointing just beyond the values written to __result. */ template<typename _InputIterator, typename _OutputIterator> _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { typedef typename iterator_traits<_InputIterator>::value_type _ValueType; // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; _ValueType __value = *__first; *__result = __value; while (++__first != __last) { __value = __value + *__first; *++__result = __value; } return ++__result; } /** * @brief Return list of partial sums * * Accumulates the values in the range [first,last) using @p __binary_op. * As each successive input value is added into the total, that partial sum * is written to @p __result. Therefore, the first value in @p __result is * the first value of the input, the second value in @p __result is the sum * of the first and second input values, and so on. * * @param __first Start of input range. * @param __last End of input range. * @param __result Output sum. * @param __binary_op Function object. * @return Iterator pointing just beyond the values written to __result. */ template<typename _InputIterator, typename _OutputIterator, typename _BinaryOperation> _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOperation __binary_op) { typedef typename iterator_traits<_InputIterator>::value_type _ValueType; // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; _ValueType __value = *__first; *__result = __value; while (++__first != __last) { __value = __binary_op(__value, *__first); *++__result = __value; } return ++__result; } /** * @brief Return differences between adjacent values. * * Computes the difference between adjacent values in the range * [first,last) using operator-() and writes the result to @p __result. * * @param __first Start of input range. * @param __last End of input range. * @param __result Output sums. * @return Iterator pointing just beyond the values written to result. * * _GLIBCXX_RESOLVE_LIB_DEFECTS * DR 539. partial_sum and adjacent_difference should mention requirements */ template<typename _InputIterator, typename _OutputIterator> _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { typedef typename iterator_traits<_InputIterator>::value_type _ValueType; // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; _ValueType __value = *__first; *__result = __value; while (++__first != __last) { _ValueType __tmp = *__first; *++__result = __tmp - __value; __value = _GLIBCXX_MOVE(__tmp); } return ++__result; } /** * @brief Return differences between adjacent values. * * Computes the difference between adjacent values in the range * [__first,__last) using the function object @p __binary_op and writes the * result to @p __result. * * @param __first Start of input range. * @param __last End of input range. * @param __result Output sum. * @param __binary_op Function object. * @return Iterator pointing just beyond the values written to result. * * _GLIBCXX_RESOLVE_LIB_DEFECTS * DR 539. partial_sum and adjacent_difference should mention requirements */ template<typename _InputIterator, typename _OutputIterator, typename _BinaryOperation> _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOperation __binary_op) { typedef typename iterator_traits<_InputIterator>::value_type _ValueType; // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, _ValueType>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; _ValueType __value = *__first; *__result = __value; while (++__first != __last) { _ValueType __tmp = *__first; *++__result = __binary_op(__tmp, __value); __value = _GLIBCXX_MOVE(__tmp); } return ++__result; } _GLIBCXX_END_NAMESPACE_ALGO } // namespace std #endif /* _STL_NUMERIC_H */ c++/8/bits/nested_exception.h 0000644 00000011302 15146341150 0011732 0 ustar 00 // Nested Exception support header (nested_exception class) for -*- C++ -*- // Copyright (C) 2009-2018 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/nested_exception.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{exception} */ #ifndef _GLIBCXX_NESTED_EXCEPTION_H #define _GLIBCXX_NESTED_EXCEPTION_H 1 #pragma GCC visibility push(default) #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <bits/c++config.h> #include <bits/move.h> extern "C++" { namespace std { /** * @addtogroup exceptions * @{ */ /// Exception class with exception_ptr data member. class nested_exception { exception_ptr _M_ptr; public: nested_exception() noexcept : _M_ptr(current_exception()) { } nested_exception(const nested_exception&) noexcept = default; nested_exception& operator=(const nested_exception&) noexcept = default; virtual ~nested_exception() noexcept; [[noreturn]] void rethrow_nested() const { if (_M_ptr) rethrow_exception(_M_ptr); std::terminate(); } exception_ptr nested_ptr() const noexcept { return _M_ptr; } }; template<typename _Except> struct _Nested_exception : public _Except, public nested_exception { explicit _Nested_exception(const _Except& __ex) : _Except(__ex) { } explicit _Nested_exception(_Except&& __ex) : _Except(static_cast<_Except&&>(__ex)) { } }; // [except.nested]/8 // Throw an exception of unspecified type that is publicly derived from // both remove_reference_t<_Tp> and nested_exception. template<typename _Tp> [[noreturn]] inline void __throw_with_nested_impl(_Tp&& __t, true_type) { using _Up = typename remove_reference<_Tp>::type; throw _Nested_exception<_Up>{std::forward<_Tp>(__t)}; } template<typename _Tp> [[noreturn]] inline void __throw_with_nested_impl(_Tp&& __t, false_type) { throw std::forward<_Tp>(__t); } /// If @p __t is derived from nested_exception, throws @p __t. /// Else, throws an implementation-defined object derived from both. template<typename _Tp> [[noreturn]] inline void throw_with_nested(_Tp&& __t) { using _Up = typename decay<_Tp>::type; using _CopyConstructible = __and_<is_copy_constructible<_Up>, is_move_constructible<_Up>>; static_assert(_CopyConstructible::value, "throw_with_nested argument must be CopyConstructible"); using __nest = __and_<is_class<_Up>, __bool_constant<!__is_final(_Up)>, __not_<is_base_of<nested_exception, _Up>>>; std::__throw_with_nested_impl(std::forward<_Tp>(__t), __nest{}); } // Determine if dynamic_cast<const nested_exception&> would be well-formed. template<typename _Tp> using __rethrow_if_nested_cond = typename enable_if< __and_<is_polymorphic<_Tp>, __or_<__not_<is_base_of<nested_exception, _Tp>>, is_convertible<_Tp*, nested_exception*>>>::value >::type; // Attempt dynamic_cast to nested_exception and call rethrow_nested(). template<typename _Ex> inline __rethrow_if_nested_cond<_Ex> __rethrow_if_nested_impl(const _Ex* __ptr) { if (auto __ne_ptr = dynamic_cast<const nested_exception*>(__ptr)) __ne_ptr->rethrow_nested(); } // Otherwise, no effects. inline void __rethrow_if_nested_impl(const void*) { } /// If @p __ex is derived from nested_exception, @p __ex.rethrow_nested(). template<typename _Ex> inline void rethrow_if_nested(const _Ex& __ex) { std::__rethrow_if_nested_impl(std::__addressof(__ex)); } // @} group exceptions } // namespace std } // extern "C++" #endif // C++11 #pragma GCC visibility pop #endif // _GLIBCXX_NESTED_EXCEPTION_H c++/8/bits/functional_hash.h 0000644 00000020056 15146341150 0011545 0 ustar 00 // functional_hash.h header -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/functional_hash.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{functional} */ #ifndef _FUNCTIONAL_HASH_H #define _FUNCTIONAL_HASH_H 1 #pragma GCC system_header #include <bits/hash_bytes.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** @defgroup hashes Hashes * @ingroup functors * * Hashing functors taking a variable type and returning a @c std::size_t. * * @{ */ template<typename _Result, typename _Arg> struct __hash_base { typedef _Result result_type _GLIBCXX17_DEPRECATED; typedef _Arg argument_type _GLIBCXX17_DEPRECATED; }; /// Primary class template hash. template<typename _Tp> struct hash; template<typename _Tp, typename = void> struct __poison_hash { static constexpr bool __enable_hash_call = false; private: // Private rather than deleted to be non-trivially-copyable. __poison_hash(__poison_hash&&); ~__poison_hash(); }; template<typename _Tp> struct __poison_hash<_Tp, __void_t<decltype(hash<_Tp>()(declval<_Tp>()))>> { static constexpr bool __enable_hash_call = true; }; // Helper struct for SFINAE-poisoning non-enum types. template<typename _Tp, bool = is_enum<_Tp>::value> struct __hash_enum { private: // Private rather than deleted to be non-trivially-copyable. __hash_enum(__hash_enum&&); ~__hash_enum(); }; // Helper struct for hash with enum types. template<typename _Tp> struct __hash_enum<_Tp, true> : public __hash_base<size_t, _Tp> { size_t operator()(_Tp __val) const noexcept { using __type = typename underlying_type<_Tp>::type; return hash<__type>{}(static_cast<__type>(__val)); } }; /// Primary class template hash, usable for enum types only. // Use with non-enum types still SFINAES. template<typename _Tp> struct hash : __hash_enum<_Tp> { }; /// Partial specializations for pointer types. template<typename _Tp> struct hash<_Tp*> : public __hash_base<size_t, _Tp*> { size_t operator()(_Tp* __p) const noexcept { return reinterpret_cast<size_t>(__p); } }; // Explicit specializations for integer types. #define _Cxx_hashtable_define_trivial_hash(_Tp) \ template<> \ struct hash<_Tp> : public __hash_base<size_t, _Tp> \ { \ size_t \ operator()(_Tp __val) const noexcept \ { return static_cast<size_t>(__val); } \ }; /// Explicit specialization for bool. _Cxx_hashtable_define_trivial_hash(bool) /// Explicit specialization for char. _Cxx_hashtable_define_trivial_hash(char) /// Explicit specialization for signed char. _Cxx_hashtable_define_trivial_hash(signed char) /// Explicit specialization for unsigned char. _Cxx_hashtable_define_trivial_hash(unsigned char) /// Explicit specialization for wchar_t. _Cxx_hashtable_define_trivial_hash(wchar_t) /// Explicit specialization for char16_t. _Cxx_hashtable_define_trivial_hash(char16_t) /// Explicit specialization for char32_t. _Cxx_hashtable_define_trivial_hash(char32_t) /// Explicit specialization for short. _Cxx_hashtable_define_trivial_hash(short) /// Explicit specialization for int. _Cxx_hashtable_define_trivial_hash(int) /// Explicit specialization for long. _Cxx_hashtable_define_trivial_hash(long) /// Explicit specialization for long long. _Cxx_hashtable_define_trivial_hash(long long) /// Explicit specialization for unsigned short. _Cxx_hashtable_define_trivial_hash(unsigned short) /// Explicit specialization for unsigned int. _Cxx_hashtable_define_trivial_hash(unsigned int) /// Explicit specialization for unsigned long. _Cxx_hashtable_define_trivial_hash(unsigned long) /// Explicit specialization for unsigned long long. _Cxx_hashtable_define_trivial_hash(unsigned long long) #ifdef __GLIBCXX_TYPE_INT_N_0 _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_0) _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_0 unsigned) #endif #ifdef __GLIBCXX_TYPE_INT_N_1 _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_1) _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_1 unsigned) #endif #ifdef __GLIBCXX_TYPE_INT_N_2 _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_2) _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_2 unsigned) #endif #ifdef __GLIBCXX_TYPE_INT_N_3 _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3) _Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3 unsigned) #endif #undef _Cxx_hashtable_define_trivial_hash struct _Hash_impl { static size_t hash(const void* __ptr, size_t __clength, size_t __seed = static_cast<size_t>(0xc70f6907UL)) { return _Hash_bytes(__ptr, __clength, __seed); } template<typename _Tp> static size_t hash(const _Tp& __val) { return hash(&__val, sizeof(__val)); } template<typename _Tp> static size_t __hash_combine(const _Tp& __val, size_t __hash) { return hash(&__val, sizeof(__val), __hash); } }; // A hash function similar to FNV-1a (see PR59406 for how it differs). struct _Fnv_hash_impl { static size_t hash(const void* __ptr, size_t __clength, size_t __seed = static_cast<size_t>(2166136261UL)) { return _Fnv_hash_bytes(__ptr, __clength, __seed); } template<typename _Tp> static size_t hash(const _Tp& __val) { return hash(&__val, sizeof(__val)); } template<typename _Tp> static size_t __hash_combine(const _Tp& __val, size_t __hash) { return hash(&__val, sizeof(__val), __hash); } }; /// Specialization for float. template<> struct hash<float> : public __hash_base<size_t, float> { size_t operator()(float __val) const noexcept { // 0 and -0 both hash to zero. return __val != 0.0f ? std::_Hash_impl::hash(__val) : 0; } }; /// Specialization for double. template<> struct hash<double> : public __hash_base<size_t, double> { size_t operator()(double __val) const noexcept { // 0 and -0 both hash to zero. return __val != 0.0 ? std::_Hash_impl::hash(__val) : 0; } }; /// Specialization for long double. template<> struct hash<long double> : public __hash_base<size_t, long double> { _GLIBCXX_PURE size_t operator()(long double __val) const noexcept; }; // @} group hashes // Hint about performance of hash functor. If not fast the hash-based // containers will cache the hash code. // Default behavior is to consider that hashers are fast unless specified // otherwise. template<typename _Hash> struct __is_fast_hash : public std::true_type { }; template<> struct __is_fast_hash<hash<long double>> : public std::false_type { }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _FUNCTIONAL_HASH_H c++/8/bits/forward_list.h 0000644 00000137427 15146341150 0011112 0 ustar 00 // <forward_list.h> -*- C++ -*- // Copyright (C) 2008-2018 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.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{forward_list} */ #ifndef _FORWARD_LIST_H #define _FORWARD_LIST_H 1 #pragma GCC system_header #include <initializer_list> #include <bits/stl_iterator_base_types.h> #include <bits/stl_iterator.h> #include <bits/stl_algobase.h> #include <bits/stl_function.h> #include <bits/allocator.h> #include <ext/alloc_traits.h> #include <ext/aligned_buffer.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** * @brief A helper basic node class for %forward_list. * This is just a linked list with nothing inside it. * There are purely list shuffling utility methods here. */ struct _Fwd_list_node_base { _Fwd_list_node_base() = default; _Fwd_list_node_base(_Fwd_list_node_base&& __x) noexcept : _M_next(__x._M_next) { __x._M_next = nullptr; } _Fwd_list_node_base(const _Fwd_list_node_base&) = delete; _Fwd_list_node_base& operator=(const _Fwd_list_node_base&) = delete; _Fwd_list_node_base& operator=(_Fwd_list_node_base&& __x) noexcept { _M_next = __x._M_next; __x._M_next = nullptr; return *this; } _Fwd_list_node_base* _M_next = nullptr; _Fwd_list_node_base* _M_transfer_after(_Fwd_list_node_base* __begin, _Fwd_list_node_base* __end) noexcept { _Fwd_list_node_base* __keep = __begin->_M_next; if (__end) { __begin->_M_next = __end->_M_next; __end->_M_next = _M_next; } else __begin->_M_next = nullptr; _M_next = __keep; return __end; } void _M_reverse_after() noexcept { _Fwd_list_node_base* __tail = _M_next; if (!__tail) return; while (_Fwd_list_node_base* __temp = __tail->_M_next) { _Fwd_list_node_base* __keep = _M_next; _M_next = __temp; __tail->_M_next = __temp->_M_next; _M_next->_M_next = __keep; } } }; /** * @brief A helper node class for %forward_list. * This is just a linked list with uninitialized storage for a * data value in each node. * There is a sorting utility method. */ template<typename _Tp> struct _Fwd_list_node : public _Fwd_list_node_base { _Fwd_list_node() = default; __gnu_cxx::__aligned_buffer<_Tp> _M_storage; _Tp* _M_valptr() noexcept { return _M_storage._M_ptr(); } const _Tp* _M_valptr() const noexcept { return _M_storage._M_ptr(); } }; /** * @brief A forward_list::iterator. * * All the functions are op overloads. */ template<typename _Tp> struct _Fwd_list_iterator { typedef _Fwd_list_iterator<_Tp> _Self; typedef _Fwd_list_node<_Tp> _Node; typedef _Tp value_type; typedef _Tp* pointer; typedef _Tp& reference; typedef ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; _Fwd_list_iterator() noexcept : _M_node() { } explicit _Fwd_list_iterator(_Fwd_list_node_base* __n) noexcept : _M_node(__n) { } reference operator*() const noexcept { return *static_cast<_Node*>(this->_M_node)->_M_valptr(); } pointer operator->() const noexcept { return static_cast<_Node*>(this->_M_node)->_M_valptr(); } _Self& operator++() noexcept { _M_node = _M_node->_M_next; return *this; } _Self operator++(int) noexcept { _Self __tmp(*this); _M_node = _M_node->_M_next; return __tmp; } bool operator==(const _Self& __x) const noexcept { return _M_node == __x._M_node; } bool operator!=(const _Self& __x) const noexcept { return _M_node != __x._M_node; } _Self _M_next() const noexcept { if (_M_node) return _Fwd_list_iterator(_M_node->_M_next); else return _Fwd_list_iterator(nullptr); } _Fwd_list_node_base* _M_node; }; /** * @brief A forward_list::const_iterator. * * All the functions are op overloads. */ template<typename _Tp> struct _Fwd_list_const_iterator { typedef _Fwd_list_const_iterator<_Tp> _Self; typedef const _Fwd_list_node<_Tp> _Node; typedef _Fwd_list_iterator<_Tp> iterator; typedef _Tp value_type; typedef const _Tp* pointer; typedef const _Tp& reference; typedef ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; _Fwd_list_const_iterator() noexcept : _M_node() { } explicit _Fwd_list_const_iterator(const _Fwd_list_node_base* __n) noexcept : _M_node(__n) { } _Fwd_list_const_iterator(const iterator& __iter) noexcept : _M_node(__iter._M_node) { } reference operator*() const noexcept { return *static_cast<_Node*>(this->_M_node)->_M_valptr(); } pointer operator->() const noexcept { return static_cast<_Node*>(this->_M_node)->_M_valptr(); } _Self& operator++() noexcept { _M_node = _M_node->_M_next; return *this; } _Self operator++(int) noexcept { _Self __tmp(*this); _M_node = _M_node->_M_next; return __tmp; } bool operator==(const _Self& __x) const noexcept { return _M_node == __x._M_node; } bool operator!=(const _Self& __x) const noexcept { return _M_node != __x._M_node; } _Self _M_next() const noexcept { if (this->_M_node) return _Fwd_list_const_iterator(_M_node->_M_next); else return _Fwd_list_const_iterator(nullptr); } const _Fwd_list_node_base* _M_node; }; /** * @brief Forward list iterator equality comparison. */ template<typename _Tp> inline bool operator==(const _Fwd_list_iterator<_Tp>& __x, const _Fwd_list_const_iterator<_Tp>& __y) noexcept { return __x._M_node == __y._M_node; } /** * @brief Forward list iterator inequality comparison. */ template<typename _Tp> inline bool operator!=(const _Fwd_list_iterator<_Tp>& __x, const _Fwd_list_const_iterator<_Tp>& __y) noexcept { return __x._M_node != __y._M_node; } /** * @brief Base class for %forward_list. */ template<typename _Tp, typename _Alloc> struct _Fwd_list_base { protected: typedef __alloc_rebind<_Alloc, _Fwd_list_node<_Tp>> _Node_alloc_type; typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits; struct _Fwd_list_impl : public _Node_alloc_type { _Fwd_list_node_base _M_head; _Fwd_list_impl() noexcept(is_nothrow_default_constructible<_Node_alloc_type>::value) : _Node_alloc_type(), _M_head() { } _Fwd_list_impl(_Fwd_list_impl&&) = default; _Fwd_list_impl(_Fwd_list_impl&& __fl, _Node_alloc_type&& __a) : _Node_alloc_type(std::move(__a)), _M_head(std::move(__fl._M_head)) { } _Fwd_list_impl(_Node_alloc_type&& __a) : _Node_alloc_type(std::move(__a)), _M_head() { } }; _Fwd_list_impl _M_impl; public: typedef _Fwd_list_iterator<_Tp> iterator; typedef _Fwd_list_const_iterator<_Tp> const_iterator; typedef _Fwd_list_node<_Tp> _Node; _Node_alloc_type& _M_get_Node_allocator() noexcept { return this->_M_impl; } const _Node_alloc_type& _M_get_Node_allocator() const noexcept { return this->_M_impl; } _Fwd_list_base() = default; _Fwd_list_base(_Node_alloc_type&& __a) : _M_impl(std::move(__a)) { } // When allocators are always equal. _Fwd_list_base(_Fwd_list_base&& __lst, _Node_alloc_type&& __a, std::true_type) : _M_impl(std::move(__lst._M_impl), std::move(__a)) { } // When allocators are not always equal. _Fwd_list_base(_Fwd_list_base&& __lst, _Node_alloc_type&& __a); _Fwd_list_base(_Fwd_list_base&&) = default; ~_Fwd_list_base() { _M_erase_after(&_M_impl._M_head, nullptr); } protected: _Node* _M_get_node() { auto __ptr = _Node_alloc_traits::allocate(_M_get_Node_allocator(), 1); return std::__to_address(__ptr); } template<typename... _Args> _Node* _M_create_node(_Args&&... __args) { _Node* __node = this->_M_get_node(); __try { ::new ((void*)__node) _Node; _Node_alloc_traits::construct(_M_get_Node_allocator(), __node->_M_valptr(), std::forward<_Args>(__args)...); } __catch(...) { this->_M_put_node(__node); __throw_exception_again; } return __node; } template<typename... _Args> _Fwd_list_node_base* _M_insert_after(const_iterator __pos, _Args&&... __args); void _M_put_node(_Node* __p) { typedef typename _Node_alloc_traits::pointer _Ptr; auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__p); _Node_alloc_traits::deallocate(_M_get_Node_allocator(), __ptr, 1); } _Fwd_list_node_base* _M_erase_after(_Fwd_list_node_base* __pos); _Fwd_list_node_base* _M_erase_after(_Fwd_list_node_base* __pos, _Fwd_list_node_base* __last); }; /** * @brief A standard container with linear time access to elements, * and fixed time insertion/deletion at any point in the sequence. * * @ingroup sequences * * @tparam _Tp Type of element. * @tparam _Alloc Allocator type, defaults to allocator<_Tp>. * * Meets the requirements of a <a href="tables.html#65">container</a>, a * <a href="tables.html#67">sequence</a>, including the * <a href="tables.html#68">optional sequence requirements</a> with the * %exception of @c at and @c operator[]. * * This is a @e singly @e linked %list. Traversal up the * %list requires linear time, but adding and removing elements (or * @e nodes) is done in constant time, regardless of where the * change takes place. Unlike std::vector and std::deque, * random-access iterators are not provided, so subscripting ( @c * [] ) access is not allowed. For algorithms which only need * sequential access, this lack makes no difference. * * Also unlike the other standard containers, std::forward_list provides * specialized algorithms %unique to linked lists, such as * splicing, sorting, and in-place reversal. */ template<typename _Tp, typename _Alloc = allocator<_Tp>> class forward_list : private _Fwd_list_base<_Tp, _Alloc> { static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value, "std::forward_list must have a non-const, non-volatile value_type"); #ifdef __STRICT_ANSI__ static_assert(is_same<typename _Alloc::value_type, _Tp>::value, "std::forward_list must have the same value_type as its allocator"); #endif private: typedef _Fwd_list_base<_Tp, _Alloc> _Base; typedef _Fwd_list_node<_Tp> _Node; typedef _Fwd_list_node_base _Node_base; typedef typename _Base::_Node_alloc_type _Node_alloc_type; typedef typename _Base::_Node_alloc_traits _Node_alloc_traits; typedef allocator_traits<__alloc_rebind<_Alloc, _Tp>> _Alloc_traits; public: // types: typedef _Tp value_type; typedef typename _Alloc_traits::pointer pointer; typedef typename _Alloc_traits::const_pointer const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef _Fwd_list_iterator<_Tp> iterator; typedef _Fwd_list_const_iterator<_Tp> const_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef _Alloc allocator_type; // 23.3.4.2 construct/copy/destroy: /** * @brief Creates a %forward_list with no elements. */ forward_list() = default; /** * @brief Creates a %forward_list with no elements. * @param __al An allocator object. */ explicit forward_list(const _Alloc& __al) noexcept : _Base(_Node_alloc_type(__al)) { } /** * @brief Copy constructor with allocator argument. * @param __list Input list to copy. * @param __al An allocator object. */ forward_list(const forward_list& __list, const _Alloc& __al) : _Base(_Node_alloc_type(__al)) { _M_range_initialize(__list.begin(), __list.end()); } private: forward_list(forward_list&& __list, _Node_alloc_type&& __al, false_type) : _Base(std::move(__list), std::move(__al)) { // If __list is not empty it means its allocator is not equal to __a, // so we need to move from each element individually. insert_after(cbefore_begin(), std::__make_move_if_noexcept_iterator(__list.begin()), std::__make_move_if_noexcept_iterator(__list.end())); } forward_list(forward_list&& __list, _Node_alloc_type&& __al, true_type) noexcept : _Base(std::move(__list), _Node_alloc_type(__al), true_type{}) { } public: /** * @brief Move constructor with allocator argument. * @param __list Input list to move. * @param __al An allocator object. */ forward_list(forward_list&& __list, const _Alloc& __al) noexcept(_Node_alloc_traits::_S_always_equal()) : forward_list(std::move(__list), _Node_alloc_type(__al), typename _Node_alloc_traits::is_always_equal{}) { } /** * @brief Creates a %forward_list with default constructed elements. * @param __n The number of elements to initially create. * @param __al An allocator object. * * This constructor creates the %forward_list with @a __n default * constructed elements. */ explicit forward_list(size_type __n, const _Alloc& __al = _Alloc()) : _Base(_Node_alloc_type(__al)) { _M_default_initialize(__n); } /** * @brief Creates a %forward_list with copies of an exemplar element. * @param __n The number of elements to initially create. * @param __value An element to copy. * @param __al An allocator object. * * This constructor fills the %forward_list with @a __n copies of * @a __value. */ forward_list(size_type __n, const _Tp& __value, const _Alloc& __al = _Alloc()) : _Base(_Node_alloc_type(__al)) { _M_fill_initialize(__n, __value); } /** * @brief Builds a %forward_list from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __al An allocator object. * * Create a %forward_list consisting of copies of the elements from * [@a __first,@a __last). This is linear in N (where N is * distance(@a __first,@a __last)). */ template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> forward_list(_InputIterator __first, _InputIterator __last, const _Alloc& __al = _Alloc()) : _Base(_Node_alloc_type(__al)) { _M_range_initialize(__first, __last); } /** * @brief The %forward_list copy constructor. * @param __list A %forward_list of identical element and allocator * types. */ forward_list(const forward_list& __list) : _Base(_Node_alloc_traits::_S_select_on_copy( __list._M_get_Node_allocator())) { _M_range_initialize(__list.begin(), __list.end()); } /** * @brief The %forward_list move constructor. * @param __list A %forward_list of identical element and allocator * types. * * The newly-created %forward_list contains the exact contents of the * moved instance. The contents of the moved instance are a valid, but * unspecified %forward_list. */ forward_list(forward_list&&) = default; /** * @brief Builds a %forward_list from an initializer_list * @param __il An initializer_list of value_type. * @param __al An allocator object. * * Create a %forward_list consisting of copies of the elements * in the initializer_list @a __il. This is linear in __il.size(). */ forward_list(std::initializer_list<_Tp> __il, const _Alloc& __al = _Alloc()) : _Base(_Node_alloc_type(__al)) { _M_range_initialize(__il.begin(), __il.end()); } /** * @brief The forward_list dtor. */ ~forward_list() noexcept { } /** * @brief The %forward_list assignment operator. * @param __list A %forward_list of identical element and allocator * types. * * All the elements of @a __list are copied. * * Whether the allocator is copied depends on the allocator traits. */ forward_list& operator=(const forward_list& __list); /** * @brief The %forward_list move assignment operator. * @param __list A %forward_list of identical element and allocator * types. * * The contents of @a __list are moved into this %forward_list * (without copying, if the allocators permit it). * * Afterwards @a __list is a valid, but unspecified %forward_list * * Whether the allocator is moved depends on the allocator traits. */ forward_list& operator=(forward_list&& __list) noexcept(_Node_alloc_traits::_S_nothrow_move()) { constexpr bool __move_storage = _Node_alloc_traits::_S_propagate_on_move_assign() || _Node_alloc_traits::_S_always_equal(); _M_move_assign(std::move(__list), __bool_constant<__move_storage>()); return *this; } /** * @brief The %forward_list initializer list assignment operator. * @param __il An initializer_list of value_type. * * Replace the contents of the %forward_list with copies of the * elements in the initializer_list @a __il. This is linear in * __il.size(). */ forward_list& operator=(std::initializer_list<_Tp> __il) { assign(__il); return *this; } /** * @brief Assigns a range to a %forward_list. * @param __first An input iterator. * @param __last An input iterator. * * This function fills a %forward_list with copies of the elements * in the range [@a __first,@a __last). * * Note that the assignment completely changes the %forward_list and * that the number of elements of the resulting %forward_list is the * same as the number of elements assigned. */ template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> void assign(_InputIterator __first, _InputIterator __last) { typedef is_assignable<_Tp, decltype(*__first)> __assignable; _M_assign(__first, __last, __assignable()); } /** * @brief Assigns a given value to a %forward_list. * @param __n Number of elements to be assigned. * @param __val Value to be assigned. * * This function fills a %forward_list with @a __n copies of the * given value. Note that the assignment completely changes the * %forward_list, and that the resulting %forward_list has __n * elements. */ void assign(size_type __n, const _Tp& __val) { _M_assign_n(__n, __val, is_copy_assignable<_Tp>()); } /** * @brief Assigns an initializer_list to a %forward_list. * @param __il An initializer_list of value_type. * * Replace the contents of the %forward_list with copies of the * elements in the initializer_list @a __il. This is linear in * il.size(). */ void assign(std::initializer_list<_Tp> __il) { assign(__il.begin(), __il.end()); } /// Get a copy of the memory allocation object. allocator_type get_allocator() const noexcept { return allocator_type(this->_M_get_Node_allocator()); } // 23.3.4.3 iterators: /** * Returns a read/write iterator that points before the first element * in the %forward_list. Iteration is done in ordinary element order. */ iterator before_begin() noexcept { return iterator(&this->_M_impl._M_head); } /** * Returns a read-only (constant) iterator that points before the * first element in the %forward_list. Iteration is done in ordinary * element order. */ const_iterator before_begin() const noexcept { return const_iterator(&this->_M_impl._M_head); } /** * Returns a read/write iterator that points to the first element * in the %forward_list. Iteration is done in ordinary element order. */ iterator begin() noexcept { return iterator(this->_M_impl._M_head._M_next); } /** * Returns a read-only (constant) iterator that points to the first * element in the %forward_list. Iteration is done in ordinary * element order. */ const_iterator begin() const noexcept { return const_iterator(this->_M_impl._M_head._M_next); } /** * Returns a read/write iterator that points one past the last * element in the %forward_list. Iteration is done in ordinary * element order. */ iterator end() noexcept { return iterator(nullptr); } /** * Returns a read-only iterator that points one past the last * element in the %forward_list. Iteration is done in ordinary * element order. */ const_iterator end() const noexcept { return const_iterator(nullptr); } /** * Returns a read-only (constant) iterator that points to the * first element in the %forward_list. Iteration is done in ordinary * element order. */ const_iterator cbegin() const noexcept { return const_iterator(this->_M_impl._M_head._M_next); } /** * Returns a read-only (constant) iterator that points before the * first element in the %forward_list. Iteration is done in ordinary * element order. */ const_iterator cbefore_begin() const noexcept { return const_iterator(&this->_M_impl._M_head); } /** * Returns a read-only (constant) iterator that points one past * the last element in the %forward_list. Iteration is done in * ordinary element order. */ const_iterator cend() const noexcept { return const_iterator(nullptr); } /** * Returns true if the %forward_list is empty. (Thus begin() would * equal end().) */ bool empty() const noexcept { return this->_M_impl._M_head._M_next == nullptr; } /** * Returns the largest possible number of elements of %forward_list. */ size_type max_size() const noexcept { return _Node_alloc_traits::max_size(this->_M_get_Node_allocator()); } // 23.3.4.4 element access: /** * Returns a read/write reference to the data at the first * element of the %forward_list. */ reference front() { _Node* __front = static_cast<_Node*>(this->_M_impl._M_head._M_next); return *__front->_M_valptr(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %forward_list. */ const_reference front() const { _Node* __front = static_cast<_Node*>(this->_M_impl._M_head._M_next); return *__front->_M_valptr(); } // 23.3.4.5 modifiers: /** * @brief Constructs object in %forward_list at the front of the * list. * @param __args Arguments. * * This function will insert an object of type Tp constructed * with Tp(std::forward<Args>(args)...) at the front of the list * Due to the nature of a %forward_list this operation can * be done in constant time, and does not invalidate iterators * and references. */ template<typename... _Args> #if __cplusplus > 201402L reference #else void #endif emplace_front(_Args&&... __args) { this->_M_insert_after(cbefore_begin(), std::forward<_Args>(__args)...); #if __cplusplus > 201402L return front(); #endif } /** * @brief Add data to the front of the %forward_list. * @param __val Data to be added. * * This is a typical stack operation. The function creates an * element at the front of the %forward_list and assigns the given * data to it. Due to the nature of a %forward_list this operation * can be done in constant time, and does not invalidate iterators * and references. */ void push_front(const _Tp& __val) { this->_M_insert_after(cbefore_begin(), __val); } /** * */ void push_front(_Tp&& __val) { this->_M_insert_after(cbefore_begin(), std::move(__val)); } /** * @brief Removes first element. * * This is a typical stack operation. It shrinks the %forward_list * by one. Due to the nature of a %forward_list this operation can * be done in constant time, and only invalidates iterators/references * to the element being removed. * * Note that no data is returned, and if the first element's data * is needed, it should be retrieved before pop_front() is * called. */ void pop_front() { this->_M_erase_after(&this->_M_impl._M_head); } /** * @brief Constructs object in %forward_list after the specified * iterator. * @param __pos A const_iterator into the %forward_list. * @param __args Arguments. * @return An iterator that points to the inserted data. * * This function will insert an object of type T constructed * with T(std::forward<Args>(args)...) after the specified * location. Due to the nature of a %forward_list this operation can * be done in constant time, and does not invalidate iterators * and references. */ template<typename... _Args> iterator emplace_after(const_iterator __pos, _Args&&... __args) { return iterator(this->_M_insert_after(__pos, std::forward<_Args>(__args)...)); } /** * @brief Inserts given value into %forward_list after specified * iterator. * @param __pos An iterator into the %forward_list. * @param __val Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given value after * the specified location. Due to the nature of a %forward_list this * operation can be done in constant time, and does not * invalidate iterators and references. */ iterator insert_after(const_iterator __pos, const _Tp& __val) { return iterator(this->_M_insert_after(__pos, __val)); } /** * */ iterator insert_after(const_iterator __pos, _Tp&& __val) { return iterator(this->_M_insert_after(__pos, std::move(__val))); } /** * @brief Inserts a number of copies of given data into the * %forward_list. * @param __pos An iterator into the %forward_list. * @param __n Number of elements to be inserted. * @param __val Data to be inserted. * @return An iterator pointing to the last inserted copy of * @a val or @a pos if @a n == 0. * * This function will insert a specified number of copies of the * given data after the location specified by @a pos. * * This operation is linear in the number of elements inserted and * does not invalidate iterators and references. */ iterator insert_after(const_iterator __pos, size_type __n, const _Tp& __val); /** * @brief Inserts a range into the %forward_list. * @param __pos An iterator into the %forward_list. * @param __first An input iterator. * @param __last An input iterator. * @return An iterator pointing to the last inserted element or * @a __pos if @a __first == @a __last. * * This function will insert copies of the data in the range * [@a __first,@a __last) into the %forward_list after the * location specified by @a __pos. * * This operation is linear in the number of elements inserted and * does not invalidate iterators and references. */ template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> iterator insert_after(const_iterator __pos, _InputIterator __first, _InputIterator __last); /** * @brief Inserts the contents of an initializer_list into * %forward_list after the specified iterator. * @param __pos An iterator into the %forward_list. * @param __il An initializer_list of value_type. * @return An iterator pointing to the last inserted element * or @a __pos if @a __il is empty. * * This function will insert copies of the data in the * initializer_list @a __il into the %forward_list before the location * specified by @a __pos. * * This operation is linear in the number of elements inserted and * does not invalidate iterators and references. */ iterator insert_after(const_iterator __pos, std::initializer_list<_Tp> __il) { return insert_after(__pos, __il.begin(), __il.end()); } /** * @brief Removes the element pointed to by the iterator following * @c pos. * @param __pos Iterator pointing before element to be erased. * @return An iterator pointing to the element following the one * that was erased, or end() if no such element exists. * * This function will erase the element at the given position and * thus shorten the %forward_list by one. * * Due to the nature of a %forward_list this operation can be done * in constant time, and only invalidates iterators/references to * the element being removed. The user is also cautioned that * this function only erases the element, and that if the element * is itself a pointer, the pointed-to memory is not touched in * any way. Managing the pointer is the user's responsibility. */ iterator erase_after(const_iterator __pos) { return iterator(this->_M_erase_after(const_cast<_Node_base*> (__pos._M_node))); } /** * @brief Remove a range of elements. * @param __pos Iterator pointing before the first element to be * erased. * @param __last Iterator pointing to one past the last element to be * erased. * @return @ __last. * * This function will erase the elements in the range * @a (__pos,__last) and shorten the %forward_list accordingly. * * This operation is linear time in the size of the range and only * invalidates iterators/references to the element being removed. * The user is also cautioned that this function only erases the * elements, and that if the elements themselves are pointers, the * pointed-to memory is not touched in any way. Managing the pointer * is the user's responsibility. */ iterator erase_after(const_iterator __pos, const_iterator __last) { return iterator(this->_M_erase_after(const_cast<_Node_base*> (__pos._M_node), const_cast<_Node_base*> (__last._M_node))); } /** * @brief Swaps data with another %forward_list. * @param __list A %forward_list of the same element and allocator * types. * * This exchanges the elements between two lists in constant * time. Note that the global std::swap() function is * specialized such that std::swap(l1,l2) will feed to this * function. * * Whether the allocators are swapped depends on the allocator traits. */ void swap(forward_list& __list) noexcept { std::swap(this->_M_impl._M_head._M_next, __list._M_impl._M_head._M_next); _Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(), __list._M_get_Node_allocator()); } /** * @brief Resizes the %forward_list to the specified number of * elements. * @param __sz Number of elements the %forward_list should contain. * * This function will %resize the %forward_list to the specified * number of elements. If the number is smaller than the * %forward_list's current number of elements the %forward_list * is truncated, otherwise the %forward_list is extended and the * new elements are default constructed. */ void resize(size_type __sz); /** * @brief Resizes the %forward_list to the specified number of * elements. * @param __sz Number of elements the %forward_list should contain. * @param __val Data with which new elements should be populated. * * This function will %resize the %forward_list to the specified * number of elements. If the number is smaller than the * %forward_list's current number of elements the %forward_list * is truncated, otherwise the %forward_list is extended and new * elements are populated with given data. */ void resize(size_type __sz, const value_type& __val); /** * @brief Erases all the elements. * * Note that this function only erases * the elements, and that if the elements themselves are * pointers, the pointed-to memory is not touched in any way. * Managing the pointer is the user's responsibility. */ void clear() noexcept { this->_M_erase_after(&this->_M_impl._M_head, nullptr); } // 23.3.4.6 forward_list operations: /** * @brief Insert contents of another %forward_list. * @param __pos Iterator referencing the element to insert after. * @param __list Source list. * * The elements of @a list are inserted in constant time after * the element referenced by @a pos. @a list becomes an empty * list. * * Requires this != @a x. */ void splice_after(const_iterator __pos, forward_list&& __list) noexcept { if (!__list.empty()) _M_splice_after(__pos, __list.before_begin(), __list.end()); } void splice_after(const_iterator __pos, forward_list& __list) noexcept { splice_after(__pos, std::move(__list)); } /** * @brief Insert element from another %forward_list. * @param __pos Iterator referencing the element to insert after. * @param __list Source list. * @param __i Iterator referencing the element before the element * to move. * * Removes the element in list @a list referenced by @a i and * inserts it into the current list after @a pos. */ void splice_after(const_iterator __pos, forward_list&& __list, const_iterator __i) noexcept; void splice_after(const_iterator __pos, forward_list& __list, const_iterator __i) noexcept { splice_after(__pos, std::move(__list), __i); } /** * @brief Insert range from another %forward_list. * @param __pos Iterator referencing the element to insert after. * @param __list Source list. * @param __before Iterator referencing before the start of range * in list. * @param __last Iterator referencing the end of range in list. * * Removes elements in the range (__before,__last) and inserts them * after @a __pos in constant time. * * Undefined if @a __pos is in (__before,__last). * @{ */ void splice_after(const_iterator __pos, forward_list&&, const_iterator __before, const_iterator __last) noexcept { _M_splice_after(__pos, __before, __last); } void splice_after(const_iterator __pos, forward_list&, const_iterator __before, const_iterator __last) noexcept { _M_splice_after(__pos, __before, __last); } // @} /** * @brief Remove all elements equal to value. * @param __val The value to remove. * * Removes every element in the list equal to @a __val. * Remaining elements stay in list order. Note that this * function only erases the elements, and that if the elements * themselves are pointers, the pointed-to memory is not * touched in any way. Managing the pointer is the user's * responsibility. */ void remove(const _Tp& __val); /** * @brief Remove all elements satisfying a predicate. * @param __pred Unary predicate function or object. * * Removes every element in the list for which the predicate * returns true. Remaining elements stay in list order. Note * that this function only erases the elements, and that if the * elements themselves are pointers, the pointed-to memory is * not touched in any way. Managing the pointer is the user's * responsibility. */ template<typename _Pred> void remove_if(_Pred __pred); /** * @brief Remove consecutive duplicate elements. * * For each consecutive set of elements with the same value, * remove all but the first one. Remaining elements stay in * list order. Note that this function only erases the * elements, and that if the elements themselves are pointers, * the pointed-to memory is not touched in any way. Managing * the pointer is the user's responsibility. */ void unique() { unique(std::equal_to<_Tp>()); } /** * @brief Remove consecutive elements satisfying a predicate. * @param __binary_pred Binary predicate function or object. * * For each consecutive set of elements [first,last) that * satisfy predicate(first,i) where i is an iterator in * [first,last), remove all but the first one. Remaining * elements stay in list order. Note that this function only * erases the elements, and that if the elements themselves are * pointers, the pointed-to memory is not touched in any way. * Managing the pointer is the user's responsibility. */ template<typename _BinPred> void unique(_BinPred __binary_pred); /** * @brief Merge sorted lists. * @param __list Sorted list to merge. * * Assumes that both @a list and this list are sorted according to * operator<(). Merges elements of @a __list into this list in * sorted order, leaving @a __list empty when complete. Elements in * this list precede elements in @a __list that are equal. */ void merge(forward_list&& __list) { merge(std::move(__list), std::less<_Tp>()); } void merge(forward_list& __list) { merge(std::move(__list)); } /** * @brief Merge sorted lists according to comparison function. * @param __list Sorted list to merge. * @param __comp Comparison function defining sort order. * * Assumes that both @a __list and this list are sorted according to * comp. Merges elements of @a __list into this list * in sorted order, leaving @a __list empty when complete. Elements * in this list precede elements in @a __list that are equivalent * according to comp(). */ template<typename _Comp> void merge(forward_list&& __list, _Comp __comp); template<typename _Comp> void merge(forward_list& __list, _Comp __comp) { merge(std::move(__list), __comp); } /** * @brief Sort the elements of the list. * * Sorts the elements of this list in NlogN time. Equivalent * elements remain in list order. */ void sort() { sort(std::less<_Tp>()); } /** * @brief Sort the forward_list using a comparison function. * * Sorts the elements of this list in NlogN time. Equivalent * elements remain in list order. */ template<typename _Comp> void sort(_Comp __comp); /** * @brief Reverse the elements in list. * * Reverse the order of elements in the list in linear time. */ void reverse() noexcept { this->_M_impl._M_head._M_reverse_after(); } private: // Called by the range constructor to implement [23.3.4.2]/9 template<typename _InputIterator> void _M_range_initialize(_InputIterator __first, _InputIterator __last); // Called by forward_list(n,v,a), and the range constructor when it // turns out to be the same thing. void _M_fill_initialize(size_type __n, const value_type& __value); // Called by splice_after and insert_after. iterator _M_splice_after(const_iterator __pos, const_iterator __before, const_iterator __last); // Called by forward_list(n). void _M_default_initialize(size_type __n); // Called by resize(sz). void _M_default_insert_after(const_iterator __pos, size_type __n); // Called by operator=(forward_list&&) void _M_move_assign(forward_list&& __list, true_type) noexcept { clear(); this->_M_impl._M_head._M_next = __list._M_impl._M_head._M_next; __list._M_impl._M_head._M_next = nullptr; std::__alloc_on_move(this->_M_get_Node_allocator(), __list._M_get_Node_allocator()); } // Called by operator=(forward_list&&) void _M_move_assign(forward_list&& __list, false_type) { if (__list._M_get_Node_allocator() == this->_M_get_Node_allocator()) _M_move_assign(std::move(__list), true_type()); else // The rvalue's allocator cannot be moved, or is not equal, // so we need to individually move each element. this->assign(std::__make_move_if_noexcept_iterator(__list.begin()), std::__make_move_if_noexcept_iterator(__list.end())); } // Called by assign(_InputIterator, _InputIterator) if _Tp is // CopyAssignable. template<typename _InputIterator> void _M_assign(_InputIterator __first, _InputIterator __last, true_type) { auto __prev = before_begin(); auto __curr = begin(); auto __end = end(); while (__curr != __end && __first != __last) { *__curr = *__first; ++__prev; ++__curr; ++__first; } if (__first != __last) insert_after(__prev, __first, __last); else if (__curr != __end) erase_after(__prev, __end); } // Called by assign(_InputIterator, _InputIterator) if _Tp is not // CopyAssignable. template<typename _InputIterator> void _M_assign(_InputIterator __first, _InputIterator __last, false_type) { clear(); insert_after(cbefore_begin(), __first, __last); } // Called by assign(size_type, const _Tp&) if Tp is CopyAssignable void _M_assign_n(size_type __n, const _Tp& __val, true_type) { auto __prev = before_begin(); auto __curr = begin(); auto __end = end(); while (__curr != __end && __n > 0) { *__curr = __val; ++__prev; ++__curr; --__n; } if (__n > 0) insert_after(__prev, __n, __val); else if (__curr != __end) erase_after(__prev, __end); } // Called by assign(size_type, const _Tp&) if Tp is non-CopyAssignable void _M_assign_n(size_type __n, const _Tp& __val, false_type) { clear(); insert_after(cbefore_begin(), __n, __val); } }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _ValT = typename iterator_traits<_InputIterator>::value_type, typename _Allocator = allocator<_ValT>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> forward_list(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> forward_list<_ValT, _Allocator>; #endif /** * @brief Forward list equality comparison. * @param __lx A %forward_list * @param __ly A %forward_list of the same type as @a __lx. * @return True iff the elements of the forward lists are equal. * * This is an equivalence relation. It is linear in the number of * elements of the forward lists. Deques are considered equivalent * if corresponding elements compare equal. */ template<typename _Tp, typename _Alloc> bool operator==(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly); /** * @brief Forward list ordering relation. * @param __lx A %forward_list. * @param __ly A %forward_list of the same type as @a __lx. * @return True iff @a __lx is lexicographically less than @a __ly. * * This is a total ordering relation. It is linear in the number of * elements of the forward lists. The elements must be comparable * with @c <. * * See std::lexicographical_compare() for how the determination is made. */ template<typename _Tp, typename _Alloc> inline bool operator<(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return std::lexicographical_compare(__lx.cbegin(), __lx.cend(), __ly.cbegin(), __ly.cend()); } /// Based on operator== template<typename _Tp, typename _Alloc> inline bool operator!=(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return !(__lx == __ly); } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return (__ly < __lx); } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>=(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return !(__lx < __ly); } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator<=(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { return !(__ly < __lx); } /// See std::forward_list::swap(). template<typename _Tp, typename _Alloc> inline void swap(forward_list<_Tp, _Alloc>& __lx, forward_list<_Tp, _Alloc>& __ly) noexcept(noexcept(__lx.swap(__ly))) { __lx.swap(__ly); } _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _FORWARD_LIST_H c++/8/bits/stl_heap.h 0000644 00000047356 15146341150 0010213 0 ustar 00 // Heap implementation -*- C++ -*- // Copyright (C) 2001-2018 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) 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/stl_heap.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{queue} */ #ifndef _STL_HEAP_H #define _STL_HEAP_H 1 #include <debug/debug.h> #include <bits/move.h> #include <bits/predefined_ops.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup heap_algorithms Heap * @ingroup sorting_algorithms */ template<typename _RandomAccessIterator, typename _Distance, typename _Compare> _Distance __is_heap_until(_RandomAccessIterator __first, _Distance __n, _Compare& __comp) { _Distance __parent = 0; for (_Distance __child = 1; __child < __n; ++__child) { if (__comp(__first + __parent, __first + __child)) return __child; if ((__child & 1) == 0) ++__parent; } return __n; } // __is_heap, a predicate testing whether or not a range is a heap. // This function is an extension, not part of the C++ standard. template<typename _RandomAccessIterator, typename _Distance> inline bool __is_heap(_RandomAccessIterator __first, _Distance __n) { __gnu_cxx::__ops::_Iter_less_iter __comp; return std::__is_heap_until(__first, __n, __comp) == __n; } template<typename _RandomAccessIterator, typename _Compare, typename _Distance> inline bool __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n) { typedef __decltype(__comp) _Cmp; __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); return std::__is_heap_until(__first, __n, __cmp) == __n; } template<typename _RandomAccessIterator> inline bool __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { return std::__is_heap(__first, std::distance(__first, __last)); } template<typename _RandomAccessIterator, typename _Compare> inline bool __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { return std::__is_heap(__first, _GLIBCXX_MOVE(__comp), std::distance(__first, __last)); } // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap, // + is_heap and is_heap_until in C++0x. template<typename _RandomAccessIterator, typename _Distance, typename _Tp, typename _Compare> void __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, _Distance __topIndex, _Tp __value, _Compare& __comp) { _Distance __parent = (__holeIndex - 1) / 2; while (__holeIndex > __topIndex && __comp(__first + __parent, __value)) { *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent)); __holeIndex = __parent; __parent = (__holeIndex - 1) / 2; } *(__first + __holeIndex) = _GLIBCXX_MOVE(__value); } /** * @brief Push an element onto a heap. * @param __first Start of heap. * @param __last End of heap + element. * @ingroup heap_algorithms * * This operation pushes the element at last-1 onto the valid heap * over the range [__first,__last-1). After completion, * [__first,__last) is a valid heap. */ template<typename _RandomAccessIterator> inline void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; typedef typename iterator_traits<_RandomAccessIterator>::difference_type _DistanceType; // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); __glibcxx_requires_heap(__first, __last - 1); __gnu_cxx::__ops::_Iter_less_val __comp; _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); std::__push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), _GLIBCXX_MOVE(__value), __comp); } /** * @brief Push an element onto a heap using comparison functor. * @param __first Start of heap. * @param __last End of heap + element. * @param __comp Comparison functor. * @ingroup heap_algorithms * * This operation pushes the element at __last-1 onto the valid * heap over the range [__first,__last-1). After completion, * [__first,__last) is a valid heap. Compare operations are * performed using comp. */ template<typename _RandomAccessIterator, typename _Compare> inline void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; typedef typename iterator_traits<_RandomAccessIterator>::difference_type _DistanceType; // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); __glibcxx_requires_heap_pred(__first, __last - 1, __comp); __decltype(__gnu_cxx::__ops::__iter_comp_val(_GLIBCXX_MOVE(__comp))) __cmp(_GLIBCXX_MOVE(__comp)); _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); std::__push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), _GLIBCXX_MOVE(__value), __cmp); } template<typename _RandomAccessIterator, typename _Distance, typename _Tp, typename _Compare> void __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, _Distance __len, _Tp __value, _Compare __comp) { const _Distance __topIndex = __holeIndex; _Distance __secondChild = __holeIndex; while (__secondChild < (__len - 1) / 2) { __secondChild = 2 * (__secondChild + 1); if (__comp(__first + __secondChild, __first + (__secondChild - 1))) __secondChild--; *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild)); __holeIndex = __secondChild; } if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2) { __secondChild = 2 * (__secondChild + 1); *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + (__secondChild - 1))); __holeIndex = __secondChild - 1; } __decltype(__gnu_cxx::__ops::__iter_comp_val(_GLIBCXX_MOVE(__comp))) __cmp(_GLIBCXX_MOVE(__comp)); std::__push_heap(__first, __holeIndex, __topIndex, _GLIBCXX_MOVE(__value), __cmp); } template<typename _RandomAccessIterator, typename _Compare> inline void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __result, _Compare& __comp) { typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; typedef typename iterator_traits<_RandomAccessIterator>::difference_type _DistanceType; _ValueType __value = _GLIBCXX_MOVE(*__result); *__result = _GLIBCXX_MOVE(*__first); std::__adjust_heap(__first, _DistanceType(0), _DistanceType(__last - __first), _GLIBCXX_MOVE(__value), __comp); } /** * @brief Pop an element off a heap. * @param __first Start of heap. * @param __last End of heap. * @pre [__first, __last) is a valid, non-empty range. * @ingroup heap_algorithms * * This operation pops the top of the heap. The elements __first * and __last-1 are swapped and [__first,__last-1) is made into a * heap. */ template<typename _RandomAccessIterator> inline void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_non_empty_range(__first, __last); __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); __glibcxx_requires_heap(__first, __last); if (__last - __first > 1) { --__last; __gnu_cxx::__ops::_Iter_less_iter __comp; std::__pop_heap(__first, __last, __last, __comp); } } /** * @brief Pop an element off a heap using comparison functor. * @param __first Start of heap. * @param __last End of heap. * @param __comp Comparison functor to use. * @ingroup heap_algorithms * * This operation pops the top of the heap. The elements __first * and __last-1 are swapped and [__first,__last-1) is made into a * heap. Comparisons are made using comp. */ template<typename _RandomAccessIterator, typename _Compare> inline void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); __glibcxx_requires_non_empty_range(__first, __last); __glibcxx_requires_heap_pred(__first, __last, __comp); if (__last - __first > 1) { typedef __decltype(__comp) _Cmp; __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); --__last; std::__pop_heap(__first, __last, __last, __cmp); } } template<typename _RandomAccessIterator, typename _Compare> void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; typedef typename iterator_traits<_RandomAccessIterator>::difference_type _DistanceType; if (__last - __first < 2) return; const _DistanceType __len = __last - __first; _DistanceType __parent = (__len - 2) / 2; while (true) { _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value), __comp); if (__parent == 0) return; __parent--; } } /** * @brief Construct a heap over a range. * @param __first Start of heap. * @param __last End of heap. * @ingroup heap_algorithms * * This operation makes the elements in [__first,__last) into a heap. */ template<typename _RandomAccessIterator> inline void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); __gnu_cxx::__ops::_Iter_less_iter __comp; std::__make_heap(__first, __last, __comp); } /** * @brief Construct a heap over a range using comparison functor. * @param __first Start of heap. * @param __last End of heap. * @param __comp Comparison functor to use. * @ingroup heap_algorithms * * This operation makes the elements in [__first,__last) into a heap. * Comparisons are made using __comp. */ template<typename _RandomAccessIterator, typename _Compare> inline void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); typedef __decltype(__comp) _Cmp; __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); std::__make_heap(__first, __last, __cmp); } template<typename _RandomAccessIterator, typename _Compare> void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { while (__last - __first > 1) { --__last; std::__pop_heap(__first, __last, __last, __comp); } } /** * @brief Sort a heap. * @param __first Start of heap. * @param __last End of heap. * @ingroup heap_algorithms * * This operation sorts the valid heap in the range [__first,__last). */ template<typename _RandomAccessIterator> inline void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); __glibcxx_requires_heap(__first, __last); __gnu_cxx::__ops::_Iter_less_iter __comp; std::__sort_heap(__first, __last, __comp); } /** * @brief Sort a heap using comparison functor. * @param __first Start of heap. * @param __last End of heap. * @param __comp Comparison functor to use. * @ingroup heap_algorithms * * This operation sorts the valid heap in the range [__first,__last). * Comparisons are made using __comp. */ template<typename _RandomAccessIterator, typename _Compare> inline void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); __glibcxx_requires_heap_pred(__first, __last, __comp); typedef __decltype(__comp) _Cmp; __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); std::__sort_heap(__first, __last, __cmp); } #if __cplusplus >= 201103L /** * @brief Search the end of a heap. * @param __first Start of range. * @param __last End of range. * @return An iterator pointing to the first element not in the heap. * @ingroup heap_algorithms * * This operation returns the last iterator i in [__first, __last) for which * the range [__first, i) is a heap. */ template<typename _RandomAccessIterator> inline _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); __gnu_cxx::__ops::_Iter_less_iter __comp; return __first + std::__is_heap_until(__first, std::distance(__first, __last), __comp); } /** * @brief Search the end of a heap using comparison functor. * @param __first Start of range. * @param __last End of range. * @param __comp Comparison functor to use. * @return An iterator pointing to the first element not in the heap. * @ingroup heap_algorithms * * This operation returns the last iterator i in [__first, __last) for which * the range [__first, i) is a heap. Comparisons are made using __comp. */ template<typename _RandomAccessIterator, typename _Compare> inline _RandomAccessIterator is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); typedef __decltype(__comp) _Cmp; __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); return __first + std::__is_heap_until(__first, std::distance(__first, __last), __cmp); } /** * @brief Determines whether a range is a heap. * @param __first Start of range. * @param __last End of range. * @return True if range is a heap, false otherwise. * @ingroup heap_algorithms */ template<typename _RandomAccessIterator> inline bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { return std::is_heap_until(__first, __last) == __last; } /** * @brief Determines whether a range is a heap using comparison functor. * @param __first Start of range. * @param __last End of range. * @param __comp Comparison functor to use. * @return True if range is a heap, false otherwise. * @ingroup heap_algorithms */ template<typename _RandomAccessIterator, typename _Compare> inline bool is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); const auto __dist = std::distance(__first, __last); typedef __decltype(__comp) _Cmp; __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp)); return std::__is_heap_until(__first, __dist, __cmp) == __dist; } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _STL_HEAP_H */ c++/8/bits/regex.h 0000644 00000276172 15146341150 0007526 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2010-2018 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/regex.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename, typename> class basic_regex; template<typename, typename> class match_results; _GLIBCXX_END_NAMESPACE_CXX11 namespace __detail { enum class _RegexExecutorPolicy : int { _S_auto, _S_alternate }; template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT, _RegexExecutorPolicy __policy, bool __match_mode> bool __regex_algo_impl(_BiIter __s, _BiIter __e, match_results<_BiIter, _Alloc>& __m, const basic_regex<_CharT, _TraitsT>& __re, regex_constants::match_flag_type __flags); template<typename, typename, typename, bool> class _Executor; } _GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * @addtogroup regex * @{ */ /** * @brief Describes aspects of a regular expression. * * A regular expression traits class that satisfies the requirements of * section [28.7]. * * The class %regex is parameterized around a set of related types and * functions used to complete the definition of its semantics. This class * satisfies the requirements of such a traits class. */ template<typename _Ch_type> struct regex_traits { public: typedef _Ch_type char_type; typedef std::basic_string<char_type> string_type; typedef std::locale locale_type; private: struct _RegexMask { typedef std::ctype_base::mask _BaseType; _BaseType _M_base; unsigned char _M_extended; static constexpr unsigned char _S_under = 1 << 0; static constexpr unsigned char _S_valid_mask = 0x1; constexpr _RegexMask(_BaseType __base = 0, unsigned char __extended = 0) : _M_base(__base), _M_extended(__extended) { } constexpr _RegexMask operator&(_RegexMask __other) const { return _RegexMask(_M_base & __other._M_base, _M_extended & __other._M_extended); } constexpr _RegexMask operator|(_RegexMask __other) const { return _RegexMask(_M_base | __other._M_base, _M_extended | __other._M_extended); } constexpr _RegexMask operator^(_RegexMask __other) const { return _RegexMask(_M_base ^ __other._M_base, _M_extended ^ __other._M_extended); } constexpr _RegexMask operator~() const { return _RegexMask(~_M_base, ~_M_extended); } _RegexMask& operator&=(_RegexMask __other) { return *this = (*this) & __other; } _RegexMask& operator|=(_RegexMask __other) { return *this = (*this) | __other; } _RegexMask& operator^=(_RegexMask __other) { return *this = (*this) ^ __other; } constexpr bool operator==(_RegexMask __other) const { return (_M_extended & _S_valid_mask) == (__other._M_extended & _S_valid_mask) && _M_base == __other._M_base; } constexpr bool operator!=(_RegexMask __other) const { return !((*this) == __other); } }; public: typedef _RegexMask char_class_type; public: /** * @brief Constructs a default traits object. */ regex_traits() { } /** * @brief Gives the length of a C-style string starting at @p __p. * * @param __p a pointer to the start of a character sequence. * * @returns the number of characters between @p *__p and the first * default-initialized value of type @p char_type. In other words, uses * the C-string algorithm for determining the length of a sequence of * characters. */ static std::size_t length(const char_type* __p) { return string_type::traits_type::length(__p); } /** * @brief Performs the identity translation. * * @param __c A character to the locale-specific character set. * * @returns __c. */ char_type translate(char_type __c) const { return __c; } /** * @brief Translates a character into a case-insensitive equivalent. * * @param __c A character to the locale-specific character set. * * @returns the locale-specific lower-case equivalent of __c. * @throws std::bad_cast if the imbued locale does not support the ctype * facet. */ char_type translate_nocase(char_type __c) const { typedef std::ctype<char_type> __ctype_type; const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); return __fctyp.tolower(__c); } /** * @brief Gets a sort key for a character sequence. * * @param __first beginning of the character sequence. * @param __last one-past-the-end of the character sequence. * * Returns a sort key for the character sequence designated by the * iterator range [F1, F2) such that if the character sequence [G1, G2) * sorts before the character sequence [H1, H2) then * v.transform(G1, G2) < v.transform(H1, H2). * * What this really does is provide a more efficient way to compare a * string to multiple other strings in locales with fancy collation * rules and equivalence classes. * * @returns a locale-specific sort key equivalent to the input range. * * @throws std::bad_cast if the current locale does not have a collate * facet. */ template<typename _Fwd_iter> string_type transform(_Fwd_iter __first, _Fwd_iter __last) const { typedef std::collate<char_type> __collate_type; const __collate_type& __fclt(use_facet<__collate_type>(_M_locale)); string_type __s(__first, __last); return __fclt.transform(__s.data(), __s.data() + __s.size()); } /** * @brief Gets a sort key for a character sequence, independent of case. * * @param __first beginning of the character sequence. * @param __last one-past-the-end of the character sequence. * * Effects: if typeid(use_facet<collate<_Ch_type> >) == * typeid(collate_byname<_Ch_type>) and the form of the sort key * returned by collate_byname<_Ch_type>::transform(__first, __last) * is known and can be converted into a primary sort key * then returns that key, otherwise returns an empty string. * * @todo Implement this function correctly. */ template<typename _Fwd_iter> string_type transform_primary(_Fwd_iter __first, _Fwd_iter __last) const { // TODO : this is not entirely correct. // This function requires extra support from the platform. // // Read http://gcc.gnu.org/ml/libstdc++/2013-09/msg00117.html and // http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2003/n1429.htm // for details. typedef std::ctype<char_type> __ctype_type; const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); std::vector<char_type> __s(__first, __last); __fctyp.tolower(__s.data(), __s.data() + __s.size()); return this->transform(__s.data(), __s.data() + __s.size()); } /** * @brief Gets a collation element by name. * * @param __first beginning of the collation element name. * @param __last one-past-the-end of the collation element name. * * @returns a sequence of one or more characters that represents the * collating element consisting of the character sequence designated by * the iterator range [__first, __last). Returns an empty string if the * character sequence is not a valid collating element. */ template<typename _Fwd_iter> string_type lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const; /** * @brief Maps one or more characters to a named character * classification. * * @param __first beginning of the character sequence. * @param __last one-past-the-end of the character sequence. * @param __icase ignores the case of the classification name. * * @returns an unspecified value that represents the character * classification named by the character sequence designated by * the iterator range [__first, __last). If @p icase is true, * the returned mask identifies the classification regardless of * the case of the characters to be matched (for example, * [[:lower:]] is the same as [[:alpha:]]), otherwise a * case-dependent classification is returned. The value * returned shall be independent of the case of the characters * in the character sequence. If the name is not recognized then * returns a value that compares equal to 0. * * At least the following names (or their wide-character equivalent) are * supported. * - d * - w * - s * - alnum * - alpha * - blank * - cntrl * - digit * - graph * - lower * - print * - punct * - space * - upper * - xdigit */ template<typename _Fwd_iter> char_class_type lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase = false) const; /** * @brief Determines if @p c is a member of an identified class. * * @param __c a character. * @param __f a class type (as returned from lookup_classname). * * @returns true if the character @p __c is a member of the classification * represented by @p __f, false otherwise. * * @throws std::bad_cast if the current locale does not have a ctype * facet. */ bool isctype(_Ch_type __c, char_class_type __f) const; /** * @brief Converts a digit to an int. * * @param __ch a character representing a digit. * @param __radix the radix if the numeric conversion (limited to 8, 10, * or 16). * * @returns the value represented by the digit __ch in base radix if the * character __ch is a valid digit in base radix; otherwise returns -1. */ int value(_Ch_type __ch, int __radix) const; /** * @brief Imbues the regex_traits object with a copy of a new locale. * * @param __loc A locale. * * @returns a copy of the previous locale in use by the regex_traits * object. * * @note Calling imbue with a different locale than the one currently in * use invalidates all cached data held by *this. */ locale_type imbue(locale_type __loc) { std::swap(_M_locale, __loc); return __loc; } /** * @brief Gets a copy of the current locale in use by the regex_traits * object. */ locale_type getloc() const { return _M_locale; } protected: locale_type _M_locale; }; // [7.8] Class basic_regex /** * Objects of specializations of this class represent regular expressions * constructed from sequences of character type @p _Ch_type. * * Storage for the regular expression is allocated and deallocated as * necessary by the member functions of this class. */ template<typename _Ch_type, typename _Rx_traits = regex_traits<_Ch_type>> class basic_regex { public: static_assert(is_same<_Ch_type, typename _Rx_traits::char_type>::value, "regex traits class must have the same char_type"); // types: typedef _Ch_type value_type; typedef _Rx_traits traits_type; typedef typename traits_type::string_type string_type; typedef regex_constants::syntax_option_type flag_type; typedef typename traits_type::locale_type locale_type; /** * @name Constants * std [28.8.1](1) */ //@{ static constexpr flag_type icase = regex_constants::icase; static constexpr flag_type nosubs = regex_constants::nosubs; static constexpr flag_type optimize = regex_constants::optimize; static constexpr flag_type collate = regex_constants::collate; static constexpr flag_type ECMAScript = regex_constants::ECMAScript; static constexpr flag_type basic = regex_constants::basic; static constexpr flag_type extended = regex_constants::extended; static constexpr flag_type awk = regex_constants::awk; static constexpr flag_type grep = regex_constants::grep; static constexpr flag_type egrep = regex_constants::egrep; //@} // [7.8.2] construct/copy/destroy /** * Constructs a basic regular expression that does not match any * character sequence. */ basic_regex() : _M_flags(ECMAScript), _M_loc(), _M_automaton(nullptr) { } /** * @brief Constructs a basic regular expression from the * sequence [__p, __p + char_traits<_Ch_type>::length(__p)) * interpreted according to the flags in @p __f. * * @param __p A pointer to the start of a C-style null-terminated string * containing a regular expression. * @param __f Flags indicating the syntax rules and options. * * @throws regex_error if @p __p is not a valid regular expression. */ explicit basic_regex(const _Ch_type* __p, flag_type __f = ECMAScript) : basic_regex(__p, __p + char_traits<_Ch_type>::length(__p), __f) { } /** * @brief Constructs a basic regular expression from the sequence * [p, p + len) interpreted according to the flags in @p f. * * @param __p A pointer to the start of a string containing a regular * expression. * @param __len The length of the string containing the regular * expression. * @param __f Flags indicating the syntax rules and options. * * @throws regex_error if @p __p is not a valid regular expression. */ basic_regex(const _Ch_type* __p, std::size_t __len, flag_type __f = ECMAScript) : basic_regex(__p, __p + __len, __f) { } /** * @brief Copy-constructs a basic regular expression. * * @param __rhs A @p regex object. */ basic_regex(const basic_regex& __rhs) = default; /** * @brief Move-constructs a basic regular expression. * * @param __rhs A @p regex object. */ basic_regex(basic_regex&& __rhs) noexcept = default; /** * @brief Constructs a basic regular expression from the string * @p s interpreted according to the flags in @p f. * * @param __s A string containing a regular expression. * @param __f Flags indicating the syntax rules and options. * * @throws regex_error if @p __s is not a valid regular expression. */ template<typename _Ch_traits, typename _Ch_alloc> explicit basic_regex(const std::basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s, flag_type __f = ECMAScript) : basic_regex(__s.data(), __s.data() + __s.size(), __f) { } /** * @brief Constructs a basic regular expression from the range * [first, last) interpreted according to the flags in @p f. * * @param __first The start of a range containing a valid regular * expression. * @param __last The end of a range containing a valid regular * expression. * @param __f The format flags of the regular expression. * * @throws regex_error if @p [__first, __last) is not a valid regular * expression. */ template<typename _FwdIter> basic_regex(_FwdIter __first, _FwdIter __last, flag_type __f = ECMAScript) : basic_regex(std::move(__first), std::move(__last), locale_type(), __f) { } /** * @brief Constructs a basic regular expression from an initializer list. * * @param __l The initializer list. * @param __f The format flags of the regular expression. * * @throws regex_error if @p __l is not a valid regular expression. */ basic_regex(initializer_list<_Ch_type> __l, flag_type __f = ECMAScript) : basic_regex(__l.begin(), __l.end(), __f) { } /** * @brief Destroys a basic regular expression. */ ~basic_regex() { } /** * @brief Assigns one regular expression to another. */ basic_regex& operator=(const basic_regex& __rhs) { return this->assign(__rhs); } /** * @brief Move-assigns one regular expression to another. */ basic_regex& operator=(basic_regex&& __rhs) noexcept { return this->assign(std::move(__rhs)); } /** * @brief Replaces a regular expression with a new one constructed from * a C-style null-terminated string. * * @param __p A pointer to the start of a null-terminated C-style string * containing a regular expression. */ basic_regex& operator=(const _Ch_type* __p) { return this->assign(__p); } /** * @brief Replaces a regular expression with a new one constructed from * an initializer list. * * @param __l The initializer list. * * @throws regex_error if @p __l is not a valid regular expression. */ basic_regex& operator=(initializer_list<_Ch_type> __l) { return this->assign(__l.begin(), __l.end()); } /** * @brief Replaces a regular expression with a new one constructed from * a string. * * @param __s A pointer to a string containing a regular expression. */ template<typename _Ch_traits, typename _Alloc> basic_regex& operator=(const basic_string<_Ch_type, _Ch_traits, _Alloc>& __s) { return this->assign(__s); } // [7.8.3] assign /** * @brief the real assignment operator. * * @param __rhs Another regular expression object. */ basic_regex& assign(const basic_regex& __rhs) { basic_regex __tmp(__rhs); this->swap(__tmp); return *this; } /** * @brief The move-assignment operator. * * @param __rhs Another regular expression object. */ basic_regex& assign(basic_regex&& __rhs) noexcept { basic_regex __tmp(std::move(__rhs)); this->swap(__tmp); return *this; } /** * @brief Assigns a new regular expression to a regex object from a * C-style null-terminated string containing a regular expression * pattern. * * @param __p A pointer to a C-style null-terminated string containing * a regular expression pattern. * @param __flags Syntax option flags. * * @throws regex_error if __p does not contain a valid regular * expression pattern interpreted according to @p __flags. If * regex_error is thrown, *this remains unchanged. */ basic_regex& assign(const _Ch_type* __p, flag_type __flags = ECMAScript) { return this->assign(string_type(__p), __flags); } /** * @brief Assigns a new regular expression to a regex object from a * C-style string containing a regular expression pattern. * * @param __p A pointer to a C-style string containing a * regular expression pattern. * @param __len The length of the regular expression pattern string. * @param __flags Syntax option flags. * * @throws regex_error if p does not contain a valid regular * expression pattern interpreted according to @p __flags. If * regex_error is thrown, *this remains unchanged. */ basic_regex& assign(const _Ch_type* __p, std::size_t __len, flag_type __flags) { return this->assign(string_type(__p, __len), __flags); } /** * @brief Assigns a new regular expression to a regex object from a * string containing a regular expression pattern. * * @param __s A string containing a regular expression pattern. * @param __flags Syntax option flags. * * @throws regex_error if __s does not contain a valid regular * expression pattern interpreted according to @p __flags. If * regex_error is thrown, *this remains unchanged. */ template<typename _Ch_traits, typename _Alloc> basic_regex& assign(const basic_string<_Ch_type, _Ch_traits, _Alloc>& __s, flag_type __flags = ECMAScript) { return this->assign(basic_regex(__s.data(), __s.data() + __s.size(), _M_loc, __flags)); } /** * @brief Assigns a new regular expression to a regex object. * * @param __first The start of a range containing a valid regular * expression. * @param __last The end of a range containing a valid regular * expression. * @param __flags Syntax option flags. * * @throws regex_error if p does not contain a valid regular * expression pattern interpreted according to @p __flags. If * regex_error is thrown, the object remains unchanged. */ template<typename _InputIterator> basic_regex& assign(_InputIterator __first, _InputIterator __last, flag_type __flags = ECMAScript) { return this->assign(string_type(__first, __last), __flags); } /** * @brief Assigns a new regular expression to a regex object. * * @param __l An initializer list representing a regular expression. * @param __flags Syntax option flags. * * @throws regex_error if @p __l does not contain a valid * regular expression pattern interpreted according to @p * __flags. If regex_error is thrown, the object remains * unchanged. */ basic_regex& assign(initializer_list<_Ch_type> __l, flag_type __flags = ECMAScript) { return this->assign(__l.begin(), __l.end(), __flags); } // [7.8.4] const operations /** * @brief Gets the number of marked subexpressions within the regular * expression. */ unsigned int mark_count() const { if (_M_automaton) return _M_automaton->_M_sub_count() - 1; return 0; } /** * @brief Gets the flags used to construct the regular expression * or in the last call to assign(). */ flag_type flags() const { return _M_flags; } // [7.8.5] locale /** * @brief Imbues the regular expression object with the given locale. * * @param __loc A locale. */ locale_type imbue(locale_type __loc) { std::swap(__loc, _M_loc); _M_automaton.reset(); return __loc; } /** * @brief Gets the locale currently imbued in the regular expression * object. */ locale_type getloc() const { return _M_loc; } // [7.8.6] swap /** * @brief Swaps the contents of two regular expression objects. * * @param __rhs Another regular expression object. */ void swap(basic_regex& __rhs) { std::swap(_M_flags, __rhs._M_flags); std::swap(_M_loc, __rhs._M_loc); std::swap(_M_automaton, __rhs._M_automaton); } #ifdef _GLIBCXX_DEBUG void _M_dot(std::ostream& __ostr) { _M_automaton->_M_dot(__ostr); } #endif private: typedef std::shared_ptr<const __detail::_NFA<_Rx_traits>> _AutomatonPtr; template<typename _FwdIter> basic_regex(_FwdIter __first, _FwdIter __last, locale_type __loc, flag_type __f) : _M_flags(__f), _M_loc(std::move(__loc)), _M_automaton(__detail::__compile_nfa<_Rx_traits>( std::move(__first), std::move(__last), _M_loc, _M_flags)) { } template<typename _Bp, typename _Ap, typename _Cp, typename _Rp, __detail::_RegexExecutorPolicy, bool> friend bool __detail::__regex_algo_impl(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Rp>&, regex_constants::match_flag_type); template<typename, typename, typename, bool> friend class __detail::_Executor; flag_type _M_flags; locale_type _M_loc; _AutomatonPtr _M_automaton; }; #if __cplusplus < 201703L template<typename _Ch, typename _Tr> constexpr regex_constants::syntax_option_type basic_regex<_Ch, _Tr>::icase; template<typename _Ch, typename _Tr> constexpr regex_constants::syntax_option_type basic_regex<_Ch, _Tr>::nosubs; template<typename _Ch, typename _Tr> constexpr regex_constants::syntax_option_type basic_regex<_Ch, _Tr>::optimize; template<typename _Ch, typename _Tr> constexpr regex_constants::syntax_option_type basic_regex<_Ch, _Tr>::collate; template<typename _Ch, typename _Tr> constexpr regex_constants::syntax_option_type basic_regex<_Ch, _Tr>::ECMAScript; template<typename _Ch, typename _Tr> constexpr regex_constants::syntax_option_type basic_regex<_Ch, _Tr>::basic; template<typename _Ch, typename _Tr> constexpr regex_constants::syntax_option_type basic_regex<_Ch, _Tr>::extended; template<typename _Ch, typename _Tr> constexpr regex_constants::syntax_option_type basic_regex<_Ch, _Tr>::awk; template<typename _Ch, typename _Tr> constexpr regex_constants::syntax_option_type basic_regex<_Ch, _Tr>::grep; template<typename _Ch, typename _Tr> constexpr regex_constants::syntax_option_type basic_regex<_Ch, _Tr>::egrep; #endif // ! C++17 #if __cpp_deduction_guides >= 201606 template<typename _ForwardIterator> basic_regex(_ForwardIterator, _ForwardIterator, regex_constants::syntax_option_type = {}) -> basic_regex<typename iterator_traits<_ForwardIterator>::value_type>; #endif /** @brief Standard regular expressions. */ typedef basic_regex<char> regex; #ifdef _GLIBCXX_USE_WCHAR_T /** @brief Standard wide-character regular expressions. */ typedef basic_regex<wchar_t> wregex; #endif // [7.8.6] basic_regex swap /** * @brief Swaps the contents of two regular expression objects. * @param __lhs First regular expression. * @param __rhs Second regular expression. */ template<typename _Ch_type, typename _Rx_traits> inline void swap(basic_regex<_Ch_type, _Rx_traits>& __lhs, basic_regex<_Ch_type, _Rx_traits>& __rhs) { __lhs.swap(__rhs); } // [7.9] Class template sub_match /** * A sequence of characters matched by a particular marked sub-expression. * * An object of this class is essentially a pair of iterators marking a * matched subexpression within a regular expression pattern match. Such * objects can be converted to and compared with std::basic_string objects * of a similar base character type as the pattern matched by the regular * expression. * * The iterators that make up the pair are the usual half-open interval * referencing the actual original pattern matched. */ template<typename _BiIter> class sub_match : public std::pair<_BiIter, _BiIter> { typedef iterator_traits<_BiIter> __iter_traits; public: typedef typename __iter_traits::value_type value_type; typedef typename __iter_traits::difference_type difference_type; typedef _BiIter iterator; typedef std::basic_string<value_type> string_type; bool matched; constexpr sub_match() : matched() { } /** * Gets the length of the matching sequence. */ difference_type length() const { return this->matched ? std::distance(this->first, this->second) : 0; } /** * @brief Gets the matching sequence as a string. * * @returns the matching sequence as a string. * * This is the implicit conversion operator. It is identical to the * str() member function except that it will want to pop up in * unexpected places and cause a great deal of confusion and cursing * from the unwary. */ operator string_type() const { return this->matched ? string_type(this->first, this->second) : string_type(); } /** * @brief Gets the matching sequence as a string. * * @returns the matching sequence as a string. */ string_type str() const { return this->matched ? string_type(this->first, this->second) : string_type(); } /** * @brief Compares this and another matched sequence. * * @param __s Another matched sequence to compare to this one. * * @retval <0 this matched sequence will collate before @p __s. * @retval =0 this matched sequence is equivalent to @p __s. * @retval <0 this matched sequence will collate after @p __s. */ int compare(const sub_match& __s) const { return this->str().compare(__s.str()); } /** * @brief Compares this sub_match to a string. * * @param __s A string to compare to this sub_match. * * @retval <0 this matched sequence will collate before @p __s. * @retval =0 this matched sequence is equivalent to @p __s. * @retval <0 this matched sequence will collate after @p __s. */ int compare(const string_type& __s) const { return this->str().compare(__s); } /** * @brief Compares this sub_match to a C-style string. * * @param __s A C-style string to compare to this sub_match. * * @retval <0 this matched sequence will collate before @p __s. * @retval =0 this matched sequence is equivalent to @p __s. * @retval <0 this matched sequence will collate after @p __s. */ int compare(const value_type* __s) const { return this->str().compare(__s); } }; /** @brief Standard regex submatch over a C-style null-terminated string. */ typedef sub_match<const char*> csub_match; /** @brief Standard regex submatch over a standard string. */ typedef sub_match<string::const_iterator> ssub_match; #ifdef _GLIBCXX_USE_WCHAR_T /** @brief Regex submatch over a C-style null-terminated wide string. */ typedef sub_match<const wchar_t*> wcsub_match; /** @brief Regex submatch over a standard wide string. */ typedef sub_match<wstring::const_iterator> wssub_match; #endif // [7.9.2] sub_match non-member operators /** * @brief Tests the equivalence of two regular expression submatches. * @param __lhs First regular expression submatch. * @param __rhs Second regular expression submatch. * @returns true if @a __lhs is equivalent to @a __rhs, false otherwise. */ template<typename _BiIter> inline bool operator==(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs) { return __lhs.compare(__rhs) == 0; } /** * @brief Tests the inequivalence of two regular expression submatches. * @param __lhs First regular expression submatch. * @param __rhs Second regular expression submatch. * @returns true if @a __lhs is not equivalent to @a __rhs, false otherwise. */ template<typename _BiIter> inline bool operator!=(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs) { return __lhs.compare(__rhs) != 0; } /** * @brief Tests the ordering of two regular expression submatches. * @param __lhs First regular expression submatch. * @param __rhs Second regular expression submatch. * @returns true if @a __lhs precedes @a __rhs, false otherwise. */ template<typename _BiIter> inline bool operator<(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs) { return __lhs.compare(__rhs) < 0; } /** * @brief Tests the ordering of two regular expression submatches. * @param __lhs First regular expression submatch. * @param __rhs Second regular expression submatch. * @returns true if @a __lhs does not succeed @a __rhs, false otherwise. */ template<typename _BiIter> inline bool operator<=(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs) { return __lhs.compare(__rhs) <= 0; } /** * @brief Tests the ordering of two regular expression submatches. * @param __lhs First regular expression submatch. * @param __rhs Second regular expression submatch. * @returns true if @a __lhs does not precede @a __rhs, false otherwise. */ template<typename _BiIter> inline bool operator>=(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs) { return __lhs.compare(__rhs) >= 0; } /** * @brief Tests the ordering of two regular expression submatches. * @param __lhs First regular expression submatch. * @param __rhs Second regular expression submatch. * @returns true if @a __lhs succeeds @a __rhs, false otherwise. */ template<typename _BiIter> inline bool operator>(const sub_match<_BiIter>& __lhs, const sub_match<_BiIter>& __rhs) { return __lhs.compare(__rhs) > 0; } // Alias for sub_match'd string. template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> using __sub_match_string = basic_string< typename iterator_traits<_Bi_iter>::value_type, _Ch_traits, _Ch_alloc>; /** * @brief Tests the equivalence of a string and a regular expression * submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs is equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> inline bool operator==(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) { typedef typename sub_match<_Bi_iter>::string_type string_type; return __rhs.compare(string_type(__lhs.data(), __lhs.size())) == 0; } /** * @brief Tests the inequivalence of a string and a regular expression * submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs is not equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> inline bool operator!=(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) { return !(__lhs == __rhs); } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs precedes @a __rhs, false otherwise. */ template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> inline bool operator<(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) { typedef typename sub_match<_Bi_iter>::string_type string_type; return __rhs.compare(string_type(__lhs.data(), __lhs.size())) > 0; } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs succeeds @a __rhs, false otherwise. */ template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> inline bool operator>(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) { return __rhs < __lhs; } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs does not precede @a __rhs, false otherwise. */ template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> inline bool operator>=(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) { return !(__lhs < __rhs); } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs does not succeed @a __rhs, false otherwise. */ template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> inline bool operator<=(const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) { return !(__rhs < __lhs); } /** * @brief Tests the equivalence of a regular expression submatch and a * string. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs is equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> inline bool operator==(const sub_match<_Bi_iter>& __lhs, const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __rhs) { typedef typename sub_match<_Bi_iter>::string_type string_type; return __lhs.compare(string_type(__rhs.data(), __rhs.size())) == 0; } /** * @brief Tests the inequivalence of a regular expression submatch and a * string. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs is not equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> inline bool operator!=(const sub_match<_Bi_iter>& __lhs, const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __rhs) { return !(__lhs == __rhs); } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs precedes @a __rhs, false otherwise. */ template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> inline bool operator<(const sub_match<_Bi_iter>& __lhs, const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __rhs) { typedef typename sub_match<_Bi_iter>::string_type string_type; return __lhs.compare(string_type(__rhs.data(), __rhs.size())) < 0; } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs succeeds @a __rhs, false otherwise. */ template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> inline bool operator>(const sub_match<_Bi_iter>& __lhs, const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __rhs) { return __rhs < __lhs; } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs does not precede @a __rhs, false otherwise. */ template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> inline bool operator>=(const sub_match<_Bi_iter>& __lhs, const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __rhs) { return !(__lhs < __rhs); } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs does not succeed @a __rhs, false otherwise. */ template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> inline bool operator<=(const sub_match<_Bi_iter>& __lhs, const __sub_match_string<_Bi_iter, _Ch_traits, _Ch_alloc>& __rhs) { return !(__rhs < __lhs); } /** * @brief Tests the equivalence of a C string and a regular expression * submatch. * @param __lhs A C string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs is equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator==(typename iterator_traits<_Bi_iter>::value_type const* __lhs, const sub_match<_Bi_iter>& __rhs) { return __rhs.compare(__lhs) == 0; } /** * @brief Tests the inequivalence of an iterator value and a regular * expression submatch. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs is not equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator!=(typename iterator_traits<_Bi_iter>::value_type const* __lhs, const sub_match<_Bi_iter>& __rhs) { return !(__lhs == __rhs); } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs precedes @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator<(typename iterator_traits<_Bi_iter>::value_type const* __lhs, const sub_match<_Bi_iter>& __rhs) { return __rhs.compare(__lhs) > 0; } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs succeeds @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator>(typename iterator_traits<_Bi_iter>::value_type const* __lhs, const sub_match<_Bi_iter>& __rhs) { return __rhs < __lhs; } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs does not precede @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator>=(typename iterator_traits<_Bi_iter>::value_type const* __lhs, const sub_match<_Bi_iter>& __rhs) { return !(__lhs < __rhs); } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs does not succeed @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator<=(typename iterator_traits<_Bi_iter>::value_type const* __lhs, const sub_match<_Bi_iter>& __rhs) { return !(__rhs < __lhs); } /** * @brief Tests the equivalence of a regular expression submatch and a * string. * @param __lhs A regular expression submatch. * @param __rhs A pointer to a string? * @returns true if @a __lhs is equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator==(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const* __rhs) { return __lhs.compare(__rhs) == 0; } /** * @brief Tests the inequivalence of a regular expression submatch and a * string. * @param __lhs A regular expression submatch. * @param __rhs A pointer to a string. * @returns true if @a __lhs is not equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator!=(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const* __rhs) { return !(__lhs == __rhs); } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs precedes @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator<(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const* __rhs) { return __lhs.compare(__rhs) < 0; } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs succeeds @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator>(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const* __rhs) { return __rhs < __lhs; } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs does not precede @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator>=(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const* __rhs) { return !(__lhs < __rhs); } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A string. * @returns true if @a __lhs does not succeed @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator<=(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const* __rhs) { return !(__rhs < __lhs); } /** * @brief Tests the equivalence of a string and a regular expression * submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs is equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator==(typename iterator_traits<_Bi_iter>::value_type const& __lhs, const sub_match<_Bi_iter>& __rhs) { typedef typename sub_match<_Bi_iter>::string_type string_type; return __rhs.compare(string_type(1, __lhs)) == 0; } /** * @brief Tests the inequivalence of a string and a regular expression * submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs is not equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator!=(typename iterator_traits<_Bi_iter>::value_type const& __lhs, const sub_match<_Bi_iter>& __rhs) { return !(__lhs == __rhs); } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs precedes @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator<(typename iterator_traits<_Bi_iter>::value_type const& __lhs, const sub_match<_Bi_iter>& __rhs) { typedef typename sub_match<_Bi_iter>::string_type string_type; return __rhs.compare(string_type(1, __lhs)) > 0; } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs succeeds @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator>(typename iterator_traits<_Bi_iter>::value_type const& __lhs, const sub_match<_Bi_iter>& __rhs) { return __rhs < __lhs; } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs does not precede @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator>=(typename iterator_traits<_Bi_iter>::value_type const& __lhs, const sub_match<_Bi_iter>& __rhs) { return !(__lhs < __rhs); } /** * @brief Tests the ordering of a string and a regular expression submatch. * @param __lhs A string. * @param __rhs A regular expression submatch. * @returns true if @a __lhs does not succeed @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator<=(typename iterator_traits<_Bi_iter>::value_type const& __lhs, const sub_match<_Bi_iter>& __rhs) { return !(__rhs < __lhs); } /** * @brief Tests the equivalence of a regular expression submatch and a * string. * @param __lhs A regular expression submatch. * @param __rhs A const string reference. * @returns true if @a __lhs is equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator==(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const& __rhs) { typedef typename sub_match<_Bi_iter>::string_type string_type; return __lhs.compare(string_type(1, __rhs)) == 0; } /** * @brief Tests the inequivalence of a regular expression submatch and a * string. * @param __lhs A regular expression submatch. * @param __rhs A const string reference. * @returns true if @a __lhs is not equivalent to @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator!=(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const& __rhs) { return !(__lhs == __rhs); } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A const string reference. * @returns true if @a __lhs precedes @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator<(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const& __rhs) { typedef typename sub_match<_Bi_iter>::string_type string_type; return __lhs.compare(string_type(1, __rhs)) < 0; } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A const string reference. * @returns true if @a __lhs succeeds @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator>(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const& __rhs) { return __rhs < __lhs; } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A const string reference. * @returns true if @a __lhs does not precede @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator>=(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const& __rhs) { return !(__lhs < __rhs); } /** * @brief Tests the ordering of a regular expression submatch and a string. * @param __lhs A regular expression submatch. * @param __rhs A const string reference. * @returns true if @a __lhs does not succeed @a __rhs, false otherwise. */ template<typename _Bi_iter> inline bool operator<=(const sub_match<_Bi_iter>& __lhs, typename iterator_traits<_Bi_iter>::value_type const& __rhs) { return !(__rhs < __lhs); } /** * @brief Inserts a matched string into an output stream. * * @param __os The output stream. * @param __m A submatch string. * * @returns the output stream with the submatch string inserted. */ template<typename _Ch_type, typename _Ch_traits, typename _Bi_iter> inline basic_ostream<_Ch_type, _Ch_traits>& operator<<(basic_ostream<_Ch_type, _Ch_traits>& __os, const sub_match<_Bi_iter>& __m) { return __os << __m.str(); } // [7.10] Class template match_results /** * @brief The results of a match or search operation. * * A collection of character sequences representing the result of a regular * expression match. Storage for the collection is allocated and freed as * necessary by the member functions of class template match_results. * * This class satisfies the Sequence requirements, with the exception that * only the operations defined for a const-qualified Sequence are supported. * * The sub_match object stored at index 0 represents sub-expression 0, i.e. * the whole match. In this case the %sub_match member matched is always true. * The sub_match object stored at index n denotes what matched the marked * sub-expression n within the matched expression. If the sub-expression n * participated in a regular expression match then the %sub_match member * matched evaluates to true, and members first and second denote the range * of characters [first, second) which formed that match. Otherwise matched * is false, and members first and second point to the end of the sequence * that was searched. * * @nosubgrouping */ template<typename _Bi_iter, typename _Alloc = allocator<sub_match<_Bi_iter> > > class match_results : private std::vector<sub_match<_Bi_iter>, _Alloc> { private: /* * The vector base is empty if this does not represent a match (!ready()); * Otherwise if it's a match failure, it contains 3 elements: * [0] unmatched * [1] prefix * [2] suffix * Otherwise it contains n+4 elements where n is the number of marked * sub-expressions: * [0] entire match * [1] 1st marked subexpression * ... * [n] nth marked subexpression * [n+1] unmatched * [n+2] prefix * [n+3] suffix */ typedef std::vector<sub_match<_Bi_iter>, _Alloc> _Base_type; typedef std::iterator_traits<_Bi_iter> __iter_traits; typedef regex_constants::match_flag_type match_flag_type; public: /** * @name 10.? Public Types */ //@{ typedef sub_match<_Bi_iter> value_type; typedef const value_type& const_reference; typedef value_type& reference; typedef typename _Base_type::const_iterator const_iterator; typedef const_iterator iterator; typedef typename __iter_traits::difference_type difference_type; typedef typename allocator_traits<_Alloc>::size_type size_type; typedef _Alloc allocator_type; typedef typename __iter_traits::value_type char_type; typedef std::basic_string<char_type> string_type; //@} public: /** * @name 28.10.1 Construction, Copying, and Destruction */ //@{ /** * @brief Constructs a default %match_results container. * @post size() returns 0 and str() returns an empty string. */ explicit match_results(const _Alloc& __a = _Alloc()) : _Base_type(__a) { } /** * @brief Copy constructs a %match_results. */ match_results(const match_results& __rhs) = default; /** * @brief Move constructs a %match_results. */ match_results(match_results&& __rhs) noexcept = default; /** * @brief Assigns rhs to *this. */ match_results& operator=(const match_results& __rhs) = default; /** * @brief Move-assigns rhs to *this. */ match_results& operator=(match_results&& __rhs) = default; /** * @brief Destroys a %match_results object. */ ~match_results() { } //@} // 28.10.2, state: /** * @brief Indicates if the %match_results is ready. * @retval true The object has a fully-established result state. * @retval false The object is not ready. */ bool ready() const { return !_Base_type::empty(); } /** * @name 28.10.2 Size */ //@{ /** * @brief Gets the number of matches and submatches. * * The number of matches for a given regular expression will be either 0 * if there was no match or mark_count() + 1 if a match was successful. * Some matches may be empty. * * @returns the number of matches found. */ size_type size() const { return _Base_type::empty() ? 0 : _Base_type::size() - 3; } size_type max_size() const { return _Base_type::max_size(); } /** * @brief Indicates if the %match_results contains no results. * @retval true The %match_results object is empty. * @retval false The %match_results object is not empty. */ bool empty() const { return size() == 0; } //@} /** * @name 10.3 Element Access */ //@{ /** * @brief Gets the length of the indicated submatch. * @param __sub indicates the submatch. * @pre ready() == true * * This function returns the length of the indicated submatch, or the * length of the entire match if @p __sub is zero (the default). */ difference_type length(size_type __sub = 0) const { return (*this)[__sub].length(); } /** * @brief Gets the offset of the beginning of the indicated submatch. * @param __sub indicates the submatch. * @pre ready() == true * * This function returns the offset from the beginning of the target * sequence to the beginning of the submatch, unless the value of @p __sub * is zero (the default), in which case this function returns the offset * from the beginning of the target sequence to the beginning of the * match. */ difference_type position(size_type __sub = 0) const { return std::distance(_M_begin, (*this)[__sub].first); } /** * @brief Gets the match or submatch converted to a string type. * @param __sub indicates the submatch. * @pre ready() == true * * This function gets the submatch (or match, if @p __sub is * zero) extracted from the target range and converted to the * associated string type. */ string_type str(size_type __sub = 0) const { return string_type((*this)[__sub]); } /** * @brief Gets a %sub_match reference for the match or submatch. * @param __sub indicates the submatch. * @pre ready() == true * * This function gets a reference to the indicated submatch, or * the entire match if @p __sub is zero. * * If @p __sub >= size() then this function returns a %sub_match with a * special value indicating no submatch. */ const_reference operator[](size_type __sub) const { __glibcxx_assert( ready() ); return __sub < size() ? _Base_type::operator[](__sub) : _M_unmatched_sub(); } /** * @brief Gets a %sub_match representing the match prefix. * @pre ready() == true * * This function gets a reference to a %sub_match object representing the * part of the target range between the start of the target range and the * start of the match. */ const_reference prefix() const { __glibcxx_assert( ready() ); return !empty() ? _M_prefix() : _M_unmatched_sub(); } /** * @brief Gets a %sub_match representing the match suffix. * @pre ready() == true * * This function gets a reference to a %sub_match object representing the * part of the target range between the end of the match and the end of * the target range. */ const_reference suffix() const { __glibcxx_assert( ready() ); return !empty() ? _M_suffix() : _M_unmatched_sub(); } /** * @brief Gets an iterator to the start of the %sub_match collection. */ const_iterator begin() const { return _Base_type::begin(); } /** * @brief Gets an iterator to the start of the %sub_match collection. */ const_iterator cbegin() const { return this->begin(); } /** * @brief Gets an iterator to one-past-the-end of the collection. */ const_iterator end() const { return _Base_type::end() - (empty() ? 0 : 3); } /** * @brief Gets an iterator to one-past-the-end of the collection. */ const_iterator cend() const { return this->end(); } //@} /** * @name 10.4 Formatting * * These functions perform formatted substitution of the matched * character sequences into their target. The format specifiers and * escape sequences accepted by these functions are determined by * their @p flags parameter as documented above. */ //@{ /** * @pre ready() == true */ template<typename _Out_iter> _Out_iter format(_Out_iter __out, const char_type* __fmt_first, const char_type* __fmt_last, match_flag_type __flags = regex_constants::format_default) const; /** * @pre ready() == true */ template<typename _Out_iter, typename _St, typename _Sa> _Out_iter format(_Out_iter __out, const basic_string<char_type, _St, _Sa>& __fmt, match_flag_type __flags = regex_constants::format_default) const { return format(__out, __fmt.data(), __fmt.data() + __fmt.size(), __flags); } /** * @pre ready() == true */ template<typename _St, typename _Sa> basic_string<char_type, _St, _Sa> format(const basic_string<char_type, _St, _Sa>& __fmt, match_flag_type __flags = regex_constants::format_default) const { basic_string<char_type, _St, _Sa> __result; format(std::back_inserter(__result), __fmt, __flags); return __result; } /** * @pre ready() == true */ string_type format(const char_type* __fmt, match_flag_type __flags = regex_constants::format_default) const { string_type __result; format(std::back_inserter(__result), __fmt, __fmt + char_traits<char_type>::length(__fmt), __flags); return __result; } //@} /** * @name 10.5 Allocator */ //@{ /** * @brief Gets a copy of the allocator. */ allocator_type get_allocator() const { return _Base_type::get_allocator(); } //@} /** * @name 10.6 Swap */ //@{ /** * @brief Swaps the contents of two match_results. */ void swap(match_results& __that) { using std::swap; _Base_type::swap(__that); swap(_M_begin, __that._M_begin); } //@} private: template<typename, typename, typename, bool> friend class __detail::_Executor; template<typename, typename, typename> friend class regex_iterator; template<typename _Bp, typename _Ap, typename _Cp, typename _Rp, __detail::_RegexExecutorPolicy, bool> friend bool __detail::__regex_algo_impl(_Bp, _Bp, match_results<_Bp, _Ap>&, const basic_regex<_Cp, _Rp>&, regex_constants::match_flag_type); void _M_resize(unsigned int __size) { _Base_type::resize(__size + 3); } const_reference _M_unmatched_sub() const { return _Base_type::operator[](_Base_type::size() - 3); } sub_match<_Bi_iter>& _M_unmatched_sub() { return _Base_type::operator[](_Base_type::size() - 3); } const_reference _M_prefix() const { return _Base_type::operator[](_Base_type::size() - 2); } sub_match<_Bi_iter>& _M_prefix() { return _Base_type::operator[](_Base_type::size() - 2); } const_reference _M_suffix() const { return _Base_type::operator[](_Base_type::size() - 1); } sub_match<_Bi_iter>& _M_suffix() { return _Base_type::operator[](_Base_type::size() - 1); } _Bi_iter _M_begin; }; typedef match_results<const char*> cmatch; typedef match_results<string::const_iterator> smatch; #ifdef _GLIBCXX_USE_WCHAR_T typedef match_results<const wchar_t*> wcmatch; typedef match_results<wstring::const_iterator> wsmatch; #endif // match_results comparisons /** * @brief Compares two match_results for equality. * @returns true if the two objects refer to the same match, * false otherwise. */ template<typename _Bi_iter, typename _Alloc> inline bool operator==(const match_results<_Bi_iter, _Alloc>& __m1, const match_results<_Bi_iter, _Alloc>& __m2) { if (__m1.ready() != __m2.ready()) return false; if (!__m1.ready()) // both are not ready return true; if (__m1.empty() != __m2.empty()) return false; if (__m1.empty()) // both are empty return true; return __m1.prefix() == __m2.prefix() && __m1.size() == __m2.size() && std::equal(__m1.begin(), __m1.end(), __m2.begin()) && __m1.suffix() == __m2.suffix(); } /** * @brief Compares two match_results for inequality. * @returns true if the two objects do not refer to the same match, * false otherwise. */ template<typename _Bi_iter, class _Alloc> inline bool operator!=(const match_results<_Bi_iter, _Alloc>& __m1, const match_results<_Bi_iter, _Alloc>& __m2) { return !(__m1 == __m2); } // [7.10.6] match_results swap /** * @brief Swaps two match results. * @param __lhs A match result. * @param __rhs A match result. * * The contents of the two match_results objects are swapped. */ template<typename _Bi_iter, typename _Alloc> inline void swap(match_results<_Bi_iter, _Alloc>& __lhs, match_results<_Bi_iter, _Alloc>& __rhs) { __lhs.swap(__rhs); } _GLIBCXX_END_NAMESPACE_CXX11 // [7.11.2] Function template regex_match /** * @name Matching, Searching, and Replacing */ //@{ /** * @brief Determines if there is a match between the regular expression @p e * and all of the character sequence [first, last). * * @param __s Start of the character sequence to match. * @param __e One-past-the-end of the character sequence to match. * @param __m The match results. * @param __re The regular expression. * @param __flags Controls how the regular expression is matched. * * @retval true A match exists. * @retval false Otherwise. * * @throws an exception of type regex_error. */ template<typename _Bi_iter, typename _Alloc, typename _Ch_type, typename _Rx_traits> inline bool regex_match(_Bi_iter __s, _Bi_iter __e, match_results<_Bi_iter, _Alloc>& __m, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags = regex_constants::match_default) { return __detail::__regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, __detail::_RegexExecutorPolicy::_S_auto, true> (__s, __e, __m, __re, __flags); } /** * @brief Indicates if there is a match between the regular expression @p e * and all of the character sequence [first, last). * * @param __first Beginning of the character sequence to match. * @param __last One-past-the-end of the character sequence to match. * @param __re The regular expression. * @param __flags Controls how the regular expression is matched. * * @retval true A match exists. * @retval false Otherwise. * * @throws an exception of type regex_error. */ template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> inline bool regex_match(_Bi_iter __first, _Bi_iter __last, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags = regex_constants::match_default) { match_results<_Bi_iter> __what; return regex_match(__first, __last, __what, __re, __flags); } /** * @brief Determines if there is a match between the regular expression @p e * and a C-style null-terminated string. * * @param __s The C-style null-terminated string to match. * @param __m The match results. * @param __re The regular expression. * @param __f Controls how the regular expression is matched. * * @retval true A match exists. * @retval false Otherwise. * * @throws an exception of type regex_error. */ template<typename _Ch_type, typename _Alloc, typename _Rx_traits> inline bool regex_match(const _Ch_type* __s, match_results<const _Ch_type*, _Alloc>& __m, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __f = regex_constants::match_default) { return regex_match(__s, __s + _Rx_traits::length(__s), __m, __re, __f); } /** * @brief Determines if there is a match between the regular expression @p e * and a string. * * @param __s The string to match. * @param __m The match results. * @param __re The regular expression. * @param __flags Controls how the regular expression is matched. * * @retval true A match exists. * @retval false Otherwise. * * @throws an exception of type regex_error. */ template<typename _Ch_traits, typename _Ch_alloc, typename _Alloc, typename _Ch_type, typename _Rx_traits> inline bool regex_match(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s, match_results<typename basic_string<_Ch_type, _Ch_traits, _Ch_alloc>::const_iterator, _Alloc>& __m, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags = regex_constants::match_default) { return regex_match(__s.begin(), __s.end(), __m, __re, __flags); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2329. regex_match() with match_results should forbid temporary strings /// Prevent unsafe attempts to get match_results from a temporary string. template<typename _Ch_traits, typename _Ch_alloc, typename _Alloc, typename _Ch_type, typename _Rx_traits> bool regex_match(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>&&, match_results<typename basic_string<_Ch_type, _Ch_traits, _Ch_alloc>::const_iterator, _Alloc>&, const basic_regex<_Ch_type, _Rx_traits>&, regex_constants::match_flag_type = regex_constants::match_default) = delete; /** * @brief Indicates if there is a match between the regular expression @p e * and a C-style null-terminated string. * * @param __s The C-style null-terminated string to match. * @param __re The regular expression. * @param __f Controls how the regular expression is matched. * * @retval true A match exists. * @retval false Otherwise. * * @throws an exception of type regex_error. */ template<typename _Ch_type, class _Rx_traits> inline bool regex_match(const _Ch_type* __s, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __f = regex_constants::match_default) { return regex_match(__s, __s + _Rx_traits::length(__s), __re, __f); } /** * @brief Indicates if there is a match between the regular expression @p e * and a string. * * @param __s [IN] The string to match. * @param __re [IN] The regular expression. * @param __flags [IN] Controls how the regular expression is matched. * * @retval true A match exists. * @retval false Otherwise. * * @throws an exception of type regex_error. */ template<typename _Ch_traits, typename _Str_allocator, typename _Ch_type, typename _Rx_traits> inline bool regex_match(const basic_string<_Ch_type, _Ch_traits, _Str_allocator>& __s, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags = regex_constants::match_default) { return regex_match(__s.begin(), __s.end(), __re, __flags); } // [7.11.3] Function template regex_search /** * Searches for a regular expression within a range. * @param __s [IN] The start of the string to search. * @param __e [IN] One-past-the-end of the string to search. * @param __m [OUT] The match results. * @param __re [IN] The regular expression to search for. * @param __flags [IN] Search policy flags. * @retval true A match was found within the string. * @retval false No match was found within the string, the content of %m is * undefined. * * @throws an exception of type regex_error. */ template<typename _Bi_iter, typename _Alloc, typename _Ch_type, typename _Rx_traits> inline bool regex_search(_Bi_iter __s, _Bi_iter __e, match_results<_Bi_iter, _Alloc>& __m, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags = regex_constants::match_default) { return __detail::__regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, __detail::_RegexExecutorPolicy::_S_auto, false> (__s, __e, __m, __re, __flags); } /** * Searches for a regular expression within a range. * @param __first [IN] The start of the string to search. * @param __last [IN] One-past-the-end of the string to search. * @param __re [IN] The regular expression to search for. * @param __flags [IN] Search policy flags. * @retval true A match was found within the string. * @retval false No match was found within the string. * * @throws an exception of type regex_error. */ template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> inline bool regex_search(_Bi_iter __first, _Bi_iter __last, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags = regex_constants::match_default) { match_results<_Bi_iter> __what; return regex_search(__first, __last, __what, __re, __flags); } /** * @brief Searches for a regular expression within a C-string. * @param __s [IN] A C-string to search for the regex. * @param __m [OUT] The set of regex matches. * @param __e [IN] The regex to search for in @p s. * @param __f [IN] The search flags. * @retval true A match was found within the string. * @retval false No match was found within the string, the content of %m is * undefined. * * @throws an exception of type regex_error. */ template<typename _Ch_type, class _Alloc, class _Rx_traits> inline bool regex_search(const _Ch_type* __s, match_results<const _Ch_type*, _Alloc>& __m, const basic_regex<_Ch_type, _Rx_traits>& __e, regex_constants::match_flag_type __f = regex_constants::match_default) { return regex_search(__s, __s + _Rx_traits::length(__s), __m, __e, __f); } /** * @brief Searches for a regular expression within a C-string. * @param __s [IN] The C-string to search. * @param __e [IN] The regular expression to search for. * @param __f [IN] Search policy flags. * @retval true A match was found within the string. * @retval false No match was found within the string. * * @throws an exception of type regex_error. */ template<typename _Ch_type, typename _Rx_traits> inline bool regex_search(const _Ch_type* __s, const basic_regex<_Ch_type, _Rx_traits>& __e, regex_constants::match_flag_type __f = regex_constants::match_default) { return regex_search(__s, __s + _Rx_traits::length(__s), __e, __f); } /** * @brief Searches for a regular expression within a string. * @param __s [IN] The string to search. * @param __e [IN] The regular expression to search for. * @param __flags [IN] Search policy flags. * @retval true A match was found within the string. * @retval false No match was found within the string. * * @throws an exception of type regex_error. */ template<typename _Ch_traits, typename _String_allocator, typename _Ch_type, typename _Rx_traits> inline bool regex_search(const basic_string<_Ch_type, _Ch_traits, _String_allocator>& __s, const basic_regex<_Ch_type, _Rx_traits>& __e, regex_constants::match_flag_type __flags = regex_constants::match_default) { return regex_search(__s.begin(), __s.end(), __e, __flags); } /** * @brief Searches for a regular expression within a string. * @param __s [IN] A C++ string to search for the regex. * @param __m [OUT] The set of regex matches. * @param __e [IN] The regex to search for in @p s. * @param __f [IN] The search flags. * @retval true A match was found within the string. * @retval false No match was found within the string, the content of %m is * undefined. * * @throws an exception of type regex_error. */ template<typename _Ch_traits, typename _Ch_alloc, typename _Alloc, typename _Ch_type, typename _Rx_traits> inline bool regex_search(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s, match_results<typename basic_string<_Ch_type, _Ch_traits, _Ch_alloc>::const_iterator, _Alloc>& __m, const basic_regex<_Ch_type, _Rx_traits>& __e, regex_constants::match_flag_type __f = regex_constants::match_default) { return regex_search(__s.begin(), __s.end(), __m, __e, __f); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2329. regex_search() with match_results should forbid temporary strings /// Prevent unsafe attempts to get match_results from a temporary string. template<typename _Ch_traits, typename _Ch_alloc, typename _Alloc, typename _Ch_type, typename _Rx_traits> bool regex_search(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>&&, match_results<typename basic_string<_Ch_type, _Ch_traits, _Ch_alloc>::const_iterator, _Alloc>&, const basic_regex<_Ch_type, _Rx_traits>&, regex_constants::match_flag_type = regex_constants::match_default) = delete; // std [28.11.4] Function template regex_replace /** * @brief Search for a regular expression within a range for multiple times, and replace the matched parts through filling a format string. * @param __out [OUT] The output iterator. * @param __first [IN] The start of the string to search. * @param __last [IN] One-past-the-end of the string to search. * @param __e [IN] The regular expression to search for. * @param __fmt [IN] The format string. * @param __flags [IN] Search and replace policy flags. * * @returns __out * @throws an exception of type regex_error. */ template<typename _Out_iter, typename _Bi_iter, typename _Rx_traits, typename _Ch_type, typename _St, typename _Sa> inline _Out_iter regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last, const basic_regex<_Ch_type, _Rx_traits>& __e, const basic_string<_Ch_type, _St, _Sa>& __fmt, regex_constants::match_flag_type __flags = regex_constants::match_default) { return regex_replace(__out, __first, __last, __e, __fmt.c_str(), __flags); } /** * @brief Search for a regular expression within a range for multiple times, and replace the matched parts through filling a format C-string. * @param __out [OUT] The output iterator. * @param __first [IN] The start of the string to search. * @param __last [IN] One-past-the-end of the string to search. * @param __e [IN] The regular expression to search for. * @param __fmt [IN] The format C-string. * @param __flags [IN] Search and replace policy flags. * * @returns __out * @throws an exception of type regex_error. */ template<typename _Out_iter, typename _Bi_iter, typename _Rx_traits, typename _Ch_type> _Out_iter regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last, const basic_regex<_Ch_type, _Rx_traits>& __e, const _Ch_type* __fmt, regex_constants::match_flag_type __flags = regex_constants::match_default); /** * @brief Search for a regular expression within a string for multiple times, and replace the matched parts through filling a format string. * @param __s [IN] The string to search and replace. * @param __e [IN] The regular expression to search for. * @param __fmt [IN] The format string. * @param __flags [IN] Search and replace policy flags. * * @returns The string after replacing. * @throws an exception of type regex_error. */ template<typename _Rx_traits, typename _Ch_type, typename _St, typename _Sa, typename _Fst, typename _Fsa> inline basic_string<_Ch_type, _St, _Sa> regex_replace(const basic_string<_Ch_type, _St, _Sa>& __s, const basic_regex<_Ch_type, _Rx_traits>& __e, const basic_string<_Ch_type, _Fst, _Fsa>& __fmt, regex_constants::match_flag_type __flags = regex_constants::match_default) { basic_string<_Ch_type, _St, _Sa> __result; regex_replace(std::back_inserter(__result), __s.begin(), __s.end(), __e, __fmt, __flags); return __result; } /** * @brief Search for a regular expression within a string for multiple times, and replace the matched parts through filling a format C-string. * @param __s [IN] The string to search and replace. * @param __e [IN] The regular expression to search for. * @param __fmt [IN] The format C-string. * @param __flags [IN] Search and replace policy flags. * * @returns The string after replacing. * @throws an exception of type regex_error. */ template<typename _Rx_traits, typename _Ch_type, typename _St, typename _Sa> inline basic_string<_Ch_type, _St, _Sa> regex_replace(const basic_string<_Ch_type, _St, _Sa>& __s, const basic_regex<_Ch_type, _Rx_traits>& __e, const _Ch_type* __fmt, regex_constants::match_flag_type __flags = regex_constants::match_default) { basic_string<_Ch_type, _St, _Sa> __result; regex_replace(std::back_inserter(__result), __s.begin(), __s.end(), __e, __fmt, __flags); return __result; } /** * @brief Search for a regular expression within a C-string for multiple times, and replace the matched parts through filling a format string. * @param __s [IN] The C-string to search and replace. * @param __e [IN] The regular expression to search for. * @param __fmt [IN] The format string. * @param __flags [IN] Search and replace policy flags. * * @returns The string after replacing. * @throws an exception of type regex_error. */ template<typename _Rx_traits, typename _Ch_type, typename _St, typename _Sa> inline basic_string<_Ch_type> regex_replace(const _Ch_type* __s, const basic_regex<_Ch_type, _Rx_traits>& __e, const basic_string<_Ch_type, _St, _Sa>& __fmt, regex_constants::match_flag_type __flags = regex_constants::match_default) { basic_string<_Ch_type> __result; regex_replace(std::back_inserter(__result), __s, __s + char_traits<_Ch_type>::length(__s), __e, __fmt, __flags); return __result; } /** * @brief Search for a regular expression within a C-string for multiple times, and replace the matched parts through filling a format C-string. * @param __s [IN] The C-string to search and replace. * @param __e [IN] The regular expression to search for. * @param __fmt [IN] The format C-string. * @param __flags [IN] Search and replace policy flags. * * @returns The string after replacing. * @throws an exception of type regex_error. */ template<typename _Rx_traits, typename _Ch_type> inline basic_string<_Ch_type> regex_replace(const _Ch_type* __s, const basic_regex<_Ch_type, _Rx_traits>& __e, const _Ch_type* __fmt, regex_constants::match_flag_type __flags = regex_constants::match_default) { basic_string<_Ch_type> __result; regex_replace(std::back_inserter(__result), __s, __s + char_traits<_Ch_type>::length(__s), __e, __fmt, __flags); return __result; } //@} _GLIBCXX_BEGIN_NAMESPACE_CXX11 // std [28.12] Class template regex_iterator /** * An iterator adaptor that will provide repeated calls of regex_search over * a range until no more matches remain. */ template<typename _Bi_iter, typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type, typename _Rx_traits = regex_traits<_Ch_type> > class regex_iterator { public: typedef basic_regex<_Ch_type, _Rx_traits> regex_type; typedef match_results<_Bi_iter> value_type; typedef std::ptrdiff_t difference_type; typedef const value_type* pointer; typedef const value_type& reference; typedef std::forward_iterator_tag iterator_category; /** * @brief Provides a singular iterator, useful for indicating * one-past-the-end of a range. */ regex_iterator() : _M_pregex() { } /** * Constructs a %regex_iterator... * @param __a [IN] The start of a text range to search. * @param __b [IN] One-past-the-end of the text range to search. * @param __re [IN] The regular expression to match. * @param __m [IN] Policy flags for match rules. */ regex_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re, regex_constants::match_flag_type __m = regex_constants::match_default) : _M_begin(__a), _M_end(__b), _M_pregex(&__re), _M_flags(__m), _M_match() { if (!regex_search(_M_begin, _M_end, _M_match, *_M_pregex, _M_flags)) *this = regex_iterator(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2332. regex_iterator should forbid temporary regexes regex_iterator(_Bi_iter, _Bi_iter, const regex_type&&, regex_constants::match_flag_type = regex_constants::match_default) = delete; /** * Copy constructs a %regex_iterator. */ regex_iterator(const regex_iterator& __rhs) = default; /** * @brief Assigns one %regex_iterator to another. */ regex_iterator& operator=(const regex_iterator& __rhs) = default; /** * @brief Tests the equivalence of two regex iterators. */ bool operator==(const regex_iterator& __rhs) const; /** * @brief Tests the inequivalence of two regex iterators. */ bool operator!=(const regex_iterator& __rhs) const { return !(*this == __rhs); } /** * @brief Dereferences a %regex_iterator. */ const value_type& operator*() const { return _M_match; } /** * @brief Selects a %regex_iterator member. */ const value_type* operator->() const { return &_M_match; } /** * @brief Increments a %regex_iterator. */ regex_iterator& operator++(); /** * @brief Postincrements a %regex_iterator. */ regex_iterator operator++(int) { auto __tmp = *this; ++(*this); return __tmp; } private: _Bi_iter _M_begin; _Bi_iter _M_end; const regex_type* _M_pregex; regex_constants::match_flag_type _M_flags; match_results<_Bi_iter> _M_match; }; typedef regex_iterator<const char*> cregex_iterator; typedef regex_iterator<string::const_iterator> sregex_iterator; #ifdef _GLIBCXX_USE_WCHAR_T typedef regex_iterator<const wchar_t*> wcregex_iterator; typedef regex_iterator<wstring::const_iterator> wsregex_iterator; #endif // [7.12.2] Class template regex_token_iterator /** * Iterates over submatches in a range (or @a splits a text string). * * The purpose of this iterator is to enumerate all, or all specified, * matches of a regular expression within a text range. The dereferenced * value of an iterator of this class is a std::sub_match object. */ template<typename _Bi_iter, typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type, typename _Rx_traits = regex_traits<_Ch_type> > class regex_token_iterator { public: typedef basic_regex<_Ch_type, _Rx_traits> regex_type; typedef sub_match<_Bi_iter> value_type; typedef std::ptrdiff_t difference_type; typedef const value_type* pointer; typedef const value_type& reference; typedef std::forward_iterator_tag iterator_category; public: /** * @brief Default constructs a %regex_token_iterator. * * A default-constructed %regex_token_iterator is a singular iterator * that will compare equal to the one-past-the-end value for any * iterator of the same type. */ regex_token_iterator() : _M_position(), _M_subs(), _M_suffix(), _M_n(0), _M_result(nullptr), _M_has_m1(false) { } /** * Constructs a %regex_token_iterator... * @param __a [IN] The start of the text to search. * @param __b [IN] One-past-the-end of the text to search. * @param __re [IN] The regular expression to search for. * @param __submatch [IN] Which submatch to return. There are some * special values for this parameter: * - -1 each enumerated subexpression does NOT * match the regular expression (aka field * splitting) * - 0 the entire string matching the * subexpression is returned for each match * within the text. * - >0 enumerates only the indicated * subexpression from a match within the text. * @param __m [IN] Policy flags for match rules. */ regex_token_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re, int __submatch = 0, regex_constants::match_flag_type __m = regex_constants::match_default) : _M_position(__a, __b, __re, __m), _M_subs(1, __submatch), _M_n(0) { _M_init(__a, __b); } /** * Constructs a %regex_token_iterator... * @param __a [IN] The start of the text to search. * @param __b [IN] One-past-the-end of the text to search. * @param __re [IN] The regular expression to search for. * @param __submatches [IN] A list of subexpressions to return for each * regular expression match within the text. * @param __m [IN] Policy flags for match rules. */ regex_token_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re, const std::vector<int>& __submatches, regex_constants::match_flag_type __m = regex_constants::match_default) : _M_position(__a, __b, __re, __m), _M_subs(__submatches), _M_n(0) { _M_init(__a, __b); } /** * Constructs a %regex_token_iterator... * @param __a [IN] The start of the text to search. * @param __b [IN] One-past-the-end of the text to search. * @param __re [IN] The regular expression to search for. * @param __submatches [IN] A list of subexpressions to return for each * regular expression match within the text. * @param __m [IN] Policy flags for match rules. */ regex_token_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re, initializer_list<int> __submatches, regex_constants::match_flag_type __m = regex_constants::match_default) : _M_position(__a, __b, __re, __m), _M_subs(__submatches), _M_n(0) { _M_init(__a, __b); } /** * Constructs a %regex_token_iterator... * @param __a [IN] The start of the text to search. * @param __b [IN] One-past-the-end of the text to search. * @param __re [IN] The regular expression to search for. * @param __submatches [IN] A list of subexpressions to return for each * regular expression match within the text. * @param __m [IN] Policy flags for match rules. */ template<std::size_t _Nm> regex_token_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re, const int (&__submatches)[_Nm], regex_constants::match_flag_type __m = regex_constants::match_default) : _M_position(__a, __b, __re, __m), _M_subs(__submatches, __submatches + _Nm), _M_n(0) { _M_init(__a, __b); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2332. regex_token_iterator should forbid temporary regexes regex_token_iterator(_Bi_iter, _Bi_iter, const regex_type&&, int = 0, regex_constants::match_flag_type = regex_constants::match_default) = delete; regex_token_iterator(_Bi_iter, _Bi_iter, const regex_type&&, const std::vector<int>&, regex_constants::match_flag_type = regex_constants::match_default) = delete; regex_token_iterator(_Bi_iter, _Bi_iter, const regex_type&&, initializer_list<int>, regex_constants::match_flag_type = regex_constants::match_default) = delete; template <std::size_t _Nm> regex_token_iterator(_Bi_iter, _Bi_iter, const regex_type&&, const int (&)[_Nm], regex_constants::match_flag_type = regex_constants::match_default) = delete; /** * @brief Copy constructs a %regex_token_iterator. * @param __rhs [IN] A %regex_token_iterator to copy. */ regex_token_iterator(const regex_token_iterator& __rhs) : _M_position(__rhs._M_position), _M_subs(__rhs._M_subs), _M_suffix(__rhs._M_suffix), _M_n(__rhs._M_n), _M_has_m1(__rhs._M_has_m1) { _M_normalize_result(); } /** * @brief Assigns a %regex_token_iterator to another. * @param __rhs [IN] A %regex_token_iterator to copy. */ regex_token_iterator& operator=(const regex_token_iterator& __rhs); /** * @brief Compares a %regex_token_iterator to another for equality. */ bool operator==(const regex_token_iterator& __rhs) const; /** * @brief Compares a %regex_token_iterator to another for inequality. */ bool operator!=(const regex_token_iterator& __rhs) const { return !(*this == __rhs); } /** * @brief Dereferences a %regex_token_iterator. */ const value_type& operator*() const { return *_M_result; } /** * @brief Selects a %regex_token_iterator member. */ const value_type* operator->() const { return _M_result; } /** * @brief Increments a %regex_token_iterator. */ regex_token_iterator& operator++(); /** * @brief Postincrements a %regex_token_iterator. */ regex_token_iterator operator++(int) { auto __tmp = *this; ++(*this); return __tmp; } private: typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> _Position; void _M_init(_Bi_iter __a, _Bi_iter __b); const value_type& _M_current_match() const { if (_M_subs[_M_n] == -1) return (*_M_position).prefix(); else return (*_M_position)[_M_subs[_M_n]]; } constexpr bool _M_end_of_seq() const { return _M_result == nullptr; } // [28.12.2.2.4] void _M_normalize_result() { if (_M_position != _Position()) _M_result = &_M_current_match(); else if (_M_has_m1) _M_result = &_M_suffix; else _M_result = nullptr; } _Position _M_position; std::vector<int> _M_subs; value_type _M_suffix; std::size_t _M_n; const value_type* _M_result; // Show whether _M_subs contains -1 bool _M_has_m1; }; /** @brief Token iterator for C-style NULL-terminated strings. */ typedef regex_token_iterator<const char*> cregex_token_iterator; /** @brief Token iterator for standard strings. */ typedef regex_token_iterator<string::const_iterator> sregex_token_iterator; #ifdef _GLIBCXX_USE_WCHAR_T /** @brief Token iterator for C-style NULL-terminated wide strings. */ typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator; /** @brief Token iterator for standard wide-character strings. */ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator; #endif //@} // group regex _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include <bits/regex.tcc> c++/8/bits/regex_executor.h 0000644 00000016500 15146341150 0011427 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2013-2018 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/regex_executor.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ // FIXME convert comments to doxygen format. namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { /** * @addtogroup regex-detail * @{ */ /** * @brief Takes a regex and an input string and does the matching. * * The %_Executor class has two modes: DFS mode and BFS mode, controlled * by the template parameter %__dfs_mode. */ template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> class _Executor { using __search_mode = integral_constant<bool, __dfs_mode>; using __dfs = true_type; using __bfs = false_type; enum class _Match_mode : unsigned char { _Exact, _Prefix }; public: typedef typename iterator_traits<_BiIter>::value_type _CharT; typedef basic_regex<_CharT, _TraitsT> _RegexT; typedef std::vector<sub_match<_BiIter>, _Alloc> _ResultsVec; typedef regex_constants::match_flag_type _FlagT; typedef typename _TraitsT::char_class_type _ClassT; typedef _NFA<_TraitsT> _NFAT; public: _Executor(_BiIter __begin, _BiIter __end, _ResultsVec& __results, const _RegexT& __re, _FlagT __flags) : _M_begin(__begin), _M_end(__end), _M_re(__re), _M_nfa(*__re._M_automaton), _M_results(__results), _M_rep_count(_M_nfa.size()), _M_states(_M_nfa._M_start(), _M_nfa.size()), _M_flags((__flags & regex_constants::match_prev_avail) ? (__flags & ~regex_constants::match_not_bol & ~regex_constants::match_not_bow) : __flags) { } // Set matched when string exactly matches the pattern. bool _M_match() { _M_current = _M_begin; return _M_main(_Match_mode::_Exact); } // Set matched when some prefix of the string matches the pattern. bool _M_search_from_first() { _M_current = _M_begin; return _M_main(_Match_mode::_Prefix); } bool _M_search(); private: void _M_rep_once_more(_Match_mode __match_mode, _StateIdT); void _M_handle_repeat(_Match_mode, _StateIdT); void _M_handle_subexpr_begin(_Match_mode, _StateIdT); void _M_handle_subexpr_end(_Match_mode, _StateIdT); void _M_handle_line_begin_assertion(_Match_mode, _StateIdT); void _M_handle_line_end_assertion(_Match_mode, _StateIdT); void _M_handle_word_boundary(_Match_mode, _StateIdT); void _M_handle_subexpr_lookahead(_Match_mode, _StateIdT); void _M_handle_match(_Match_mode, _StateIdT); void _M_handle_backref(_Match_mode, _StateIdT); void _M_handle_accept(_Match_mode, _StateIdT); void _M_handle_alternative(_Match_mode, _StateIdT); void _M_dfs(_Match_mode __match_mode, _StateIdT __start); bool _M_main(_Match_mode __match_mode) { return _M_main_dispatch(__match_mode, __search_mode{}); } bool _M_main_dispatch(_Match_mode __match_mode, __dfs); bool _M_main_dispatch(_Match_mode __match_mode, __bfs); bool _M_is_word(_CharT __ch) const { static const _CharT __s[2] = { 'w' }; return _M_re._M_automaton->_M_traits.isctype (__ch, _M_re._M_automaton->_M_traits.lookup_classname(__s, __s+1)); } bool _M_at_begin() const { return _M_current == _M_begin && !(_M_flags & (regex_constants::match_not_bol | regex_constants::match_prev_avail)); } bool _M_at_end() const { return _M_current == _M_end && !(_M_flags & regex_constants::match_not_eol); } bool _M_word_boundary() const; bool _M_lookahead(_StateIdT __next); // Holds additional information used in BFS-mode. template<typename _SearchMode, typename _ResultsVec> struct _State_info; template<typename _ResultsVec> struct _State_info<__bfs, _ResultsVec> { explicit _State_info(_StateIdT __start, size_t __n) : _M_visited_states(new bool[__n]()), _M_start(__start) { } bool _M_visited(_StateIdT __i) { if (_M_visited_states[__i]) return true; _M_visited_states[__i] = true; return false; } void _M_queue(_StateIdT __i, const _ResultsVec& __res) { _M_match_queue.emplace_back(__i, __res); } // Dummy implementations for BFS mode. _BiIter* _M_get_sol_pos() { return nullptr; } // Saves states that need to be considered for the next character. vector<pair<_StateIdT, _ResultsVec>> _M_match_queue; // Indicates which states are already visited. unique_ptr<bool[]> _M_visited_states; // To record current solution. _StateIdT _M_start; }; template<typename _ResultsVec> struct _State_info<__dfs, _ResultsVec> { explicit _State_info(_StateIdT __start, size_t) : _M_start(__start) { } // Dummy implementations for DFS mode. bool _M_visited(_StateIdT) const { return false; } void _M_queue(_StateIdT, const _ResultsVec&) { } _BiIter* _M_get_sol_pos() { return &_M_sol_pos; } // To record current solution. _StateIdT _M_start; _BiIter _M_sol_pos; }; public: _ResultsVec _M_cur_results; _BiIter _M_current; _BiIter _M_begin; const _BiIter _M_end; const _RegexT& _M_re; const _NFAT& _M_nfa; _ResultsVec& _M_results; vector<pair<_BiIter, int>> _M_rep_count; _State_info<__search_mode, _ResultsVec> _M_states; _FlagT _M_flags; // Do we have a solution so far? bool _M_has_sol; }; //@} regex-detail } // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #include <bits/regex_executor.tcc> c++/8/bits/random.h 0000644 00000526222 15146341150 0007666 0 ustar 00 // random number generation -*- C++ -*- // Copyright (C) 2009-2018 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/random.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{random} */ #ifndef _RANDOM_H #define _RANDOM_H 1 #include <vector> #include <bits/uniform_int_dist.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // [26.4] Random number generation /** * @defgroup random Random Number Generation * @ingroup numerics * * A facility for generating random numbers on selected distributions. * @{ */ /** * @brief A function template for converting the output of a (integral) * uniform random number generator to a floatng point result in the range * [0-1). */ template<typename _RealType, size_t __bits, typename _UniformRandomNumberGenerator> _RealType generate_canonical(_UniformRandomNumberGenerator& __g); /* * Implementation-space details. */ namespace __detail { template<typename _UIntType, size_t __w, bool = __w < static_cast<size_t> (std::numeric_limits<_UIntType>::digits)> struct _Shift { static const _UIntType __value = 0; }; template<typename _UIntType, size_t __w> struct _Shift<_UIntType, __w, true> { static const _UIntType __value = _UIntType(1) << __w; }; template<int __s, int __which = ((__s <= __CHAR_BIT__ * sizeof (int)) + (__s <= __CHAR_BIT__ * sizeof (long)) + (__s <= __CHAR_BIT__ * sizeof (long long)) /* assume long long no bigger than __int128 */ + (__s <= 128))> struct _Select_uint_least_t { static_assert(__which < 0, /* needs to be dependent */ "sorry, would be too much trouble for a slow result"); }; template<int __s> struct _Select_uint_least_t<__s, 4> { typedef unsigned int type; }; template<int __s> struct _Select_uint_least_t<__s, 3> { typedef unsigned long type; }; template<int __s> struct _Select_uint_least_t<__s, 2> { typedef unsigned long long type; }; #ifdef _GLIBCXX_USE_INT128 template<int __s> struct _Select_uint_least_t<__s, 1> { typedef unsigned __int128 type; }; #endif // Assume a != 0, a < m, c < m, x < m. template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool __big_enough = (!(__m & (__m - 1)) || (_Tp(-1) - __c) / __a >= __m - 1), bool __schrage_ok = __m % __a < __m / __a> struct _Mod { typedef typename _Select_uint_least_t<std::__lg(__a) + std::__lg(__m) + 2>::type _Tp2; static _Tp __calc(_Tp __x) { return static_cast<_Tp>((_Tp2(__a) * __x + __c) % __m); } }; // Schrage. template<typename _Tp, _Tp __m, _Tp __a, _Tp __c> struct _Mod<_Tp, __m, __a, __c, false, true> { static _Tp __calc(_Tp __x); }; // Special cases: // - for m == 2^n or m == 0, unsigned integer overflow is safe. // - a * (m - 1) + c fits in _Tp, there is no overflow. template<typename _Tp, _Tp __m, _Tp __a, _Tp __c, bool __s> struct _Mod<_Tp, __m, __a, __c, true, __s> { static _Tp __calc(_Tp __x) { _Tp __res = __a * __x + __c; if (__m) __res %= __m; return __res; } }; template<typename _Tp, _Tp __m, _Tp __a = 1, _Tp __c = 0> inline _Tp __mod(_Tp __x) { return _Mod<_Tp, __m, __a, __c>::__calc(__x); } /* * An adaptor class for converting the output of any Generator into * the input for a specific Distribution. */ template<typename _Engine, typename _DInputType> struct _Adaptor { static_assert(std::is_floating_point<_DInputType>::value, "template argument must be a floating point type"); public: _Adaptor(_Engine& __g) : _M_g(__g) { } _DInputType min() const { return _DInputType(0); } _DInputType max() const { return _DInputType(1); } /* * Converts a value generated by the adapted random number generator * into a value in the input domain for the dependent random number * distribution. */ _DInputType operator()() { return std::generate_canonical<_DInputType, std::numeric_limits<_DInputType>::digits, _Engine>(_M_g); } private: _Engine& _M_g; }; } // namespace __detail /** * @addtogroup random_generators Random Number Generators * @ingroup random * * These classes define objects which provide random or pseudorandom * numbers, either from a discrete or a continuous interval. The * random number generator supplied as a part of this library are * all uniform random number generators which provide a sequence of * random number uniformly distributed over their range. * * A number generator is a function object with an operator() that * takes zero arguments and returns a number. * * A compliant random number generator must satisfy the following * requirements. <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Random Number Generator Requirements</caption> * <tr><td>To be documented.</td></tr> </table> * * @{ */ /** * @brief A model of a linear congruential random number generator. * * A random number generator that produces pseudorandom numbers via * linear function: * @f[ * x_{i+1}\leftarrow(ax_{i} + c) \bmod m * @f] * * The template parameter @p _UIntType must be an unsigned integral type * large enough to store values up to (__m-1). If the template parameter * @p __m is 0, the modulus @p __m used is * std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template * parameters @p __a and @p __c must be less than @p __m. * * The size of the state is @f$1@f$. */ template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> class linear_congruential_engine { static_assert(std::is_unsigned<_UIntType>::value, "result_type must be an unsigned integral type"); static_assert(__m == 0u || (__a < __m && __c < __m), "template argument substituting __m out of bounds"); public: /** The type of the generated random value. */ typedef _UIntType result_type; /** The multiplier. */ static constexpr result_type multiplier = __a; /** An increment. */ static constexpr result_type increment = __c; /** The modulus. */ static constexpr result_type modulus = __m; static constexpr result_type default_seed = 1u; /** * @brief Constructs a %linear_congruential_engine random number * generator engine with seed @p __s. The default seed value * is 1. * * @param __s The initial seed value. */ explicit linear_congruential_engine(result_type __s = default_seed) { seed(__s); } /** * @brief Constructs a %linear_congruential_engine random number * generator engine seeded from the seed sequence @p __q. * * @param __q the seed sequence. */ template<typename _Sseq, typename = typename std::enable_if<!std::is_same<_Sseq, linear_congruential_engine>::value> ::type> explicit linear_congruential_engine(_Sseq& __q) { seed(__q); } /** * @brief Reseeds the %linear_congruential_engine random number generator * engine sequence to the seed @p __s. * * @param __s The new seed. */ void seed(result_type __s = default_seed); /** * @brief Reseeds the %linear_congruential_engine random number generator * engine * sequence using values from the seed sequence @p __q. * * @param __q the seed sequence. */ template<typename _Sseq> typename std::enable_if<std::is_class<_Sseq>::value>::type seed(_Sseq& __q); /** * @brief Gets the smallest possible value in the output range. * * The minimum depends on the @p __c parameter: if it is zero, the * minimum generated must be > 0, otherwise 0 is allowed. */ static constexpr result_type min() { return __c == 0u ? 1u : 0u; } /** * @brief Gets the largest possible value in the output range. */ static constexpr result_type max() { return __m - 1u; } /** * @brief Discard a sequence of random numbers. */ void discard(unsigned long long __z) { for (; __z != 0ULL; --__z) (*this)(); } /** * @brief Gets the next random number in the sequence. */ result_type operator()() { _M_x = __detail::__mod<_UIntType, __m, __a, __c>(_M_x); return _M_x; } /** * @brief Compares two linear congruential random number generator * objects of the same type for equality. * * @param __lhs A linear congruential random number generator object. * @param __rhs Another linear congruential random number generator * object. * * @returns true if the infinite sequences of generated values * would be equal, false otherwise. */ friend bool operator==(const linear_congruential_engine& __lhs, const linear_congruential_engine& __rhs) { return __lhs._M_x == __rhs._M_x; } /** * @brief Writes the textual representation of the state x(i) of x to * @p __os. * * @param __os The output stream. * @param __lcr A % linear_congruential_engine random number generator. * @returns __os. */ template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1, _UIntType1 __m1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::linear_congruential_engine<_UIntType1, __a1, __c1, __m1>& __lcr); /** * @brief Sets the state of the engine by reading its textual * representation from @p __is. * * The textual representation must have been previously written using * an output stream whose imbued locale and whose type's template * specialization arguments _CharT and _Traits were the same as those * of @p __is. * * @param __is The input stream. * @param __lcr A % linear_congruential_engine random number generator. * @returns __is. */ template<typename _UIntType1, _UIntType1 __a1, _UIntType1 __c1, _UIntType1 __m1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::linear_congruential_engine<_UIntType1, __a1, __c1, __m1>& __lcr); private: _UIntType _M_x; }; /** * @brief Compares two linear congruential random number generator * objects of the same type for inequality. * * @param __lhs A linear congruential random number generator object. * @param __rhs Another linear congruential random number generator * object. * * @returns true if the infinite sequences of generated values * would be different, false otherwise. */ template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> inline bool operator!=(const std::linear_congruential_engine<_UIntType, __a, __c, __m>& __lhs, const std::linear_congruential_engine<_UIntType, __a, __c, __m>& __rhs) { return !(__lhs == __rhs); } /** * A generalized feedback shift register discrete random number generator. * * This algorithm avoids multiplication and division and is designed to be * friendly to a pipelined architecture. If the parameters are chosen * correctly, this generator will produce numbers with a very long period and * fairly good apparent entropy, although still not cryptographically strong. * * The best way to use this generator is with the predefined mt19937 class. * * This algorithm was originally invented by Makoto Matsumoto and * Takuji Nishimura. * * @tparam __w Word size, the number of bits in each element of * the state vector. * @tparam __n The degree of recursion. * @tparam __m The period parameter. * @tparam __r The separation point bit index. * @tparam __a The last row of the twist matrix. * @tparam __u The first right-shift tempering matrix parameter. * @tparam __d The first right-shift tempering matrix mask. * @tparam __s The first left-shift tempering matrix parameter. * @tparam __b The first left-shift tempering matrix mask. * @tparam __t The second left-shift tempering matrix parameter. * @tparam __c The second left-shift tempering matrix mask. * @tparam __l The second right-shift tempering matrix parameter. * @tparam __f Initialization multiplier. */ template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> class mersenne_twister_engine { static_assert(std::is_unsigned<_UIntType>::value, "result_type must be an unsigned integral type"); static_assert(1u <= __m && __m <= __n, "template argument substituting __m out of bounds"); static_assert(__r <= __w, "template argument substituting " "__r out of bound"); static_assert(__u <= __w, "template argument substituting " "__u out of bound"); static_assert(__s <= __w, "template argument substituting " "__s out of bound"); static_assert(__t <= __w, "template argument substituting " "__t out of bound"); static_assert(__l <= __w, "template argument substituting " "__l out of bound"); static_assert(__w <= std::numeric_limits<_UIntType>::digits, "template argument substituting __w out of bound"); static_assert(__a <= (__detail::_Shift<_UIntType, __w>::__value - 1), "template argument substituting __a out of bound"); static_assert(__b <= (__detail::_Shift<_UIntType, __w>::__value - 1), "template argument substituting __b out of bound"); static_assert(__c <= (__detail::_Shift<_UIntType, __w>::__value - 1), "template argument substituting __c out of bound"); static_assert(__d <= (__detail::_Shift<_UIntType, __w>::__value - 1), "template argument substituting __d out of bound"); static_assert(__f <= (__detail::_Shift<_UIntType, __w>::__value - 1), "template argument substituting __f out of bound"); public: /** The type of the generated random value. */ typedef _UIntType result_type; // parameter values static constexpr size_t word_size = __w; static constexpr size_t state_size = __n; static constexpr size_t shift_size = __m; static constexpr size_t mask_bits = __r; static constexpr result_type xor_mask = __a; static constexpr size_t tempering_u = __u; static constexpr result_type tempering_d = __d; static constexpr size_t tempering_s = __s; static constexpr result_type tempering_b = __b; static constexpr size_t tempering_t = __t; static constexpr result_type tempering_c = __c; static constexpr size_t tempering_l = __l; static constexpr result_type initialization_multiplier = __f; static constexpr result_type default_seed = 5489u; // constructors and member function explicit mersenne_twister_engine(result_type __sd = default_seed) { seed(__sd); } /** * @brief Constructs a %mersenne_twister_engine random number generator * engine seeded from the seed sequence @p __q. * * @param __q the seed sequence. */ template<typename _Sseq, typename = typename std::enable_if<!std::is_same<_Sseq, mersenne_twister_engine>::value> ::type> explicit mersenne_twister_engine(_Sseq& __q) { seed(__q); } void seed(result_type __sd = default_seed); template<typename _Sseq> typename std::enable_if<std::is_class<_Sseq>::value>::type seed(_Sseq& __q); /** * @brief Gets the smallest possible value in the output range. */ static constexpr result_type min() { return 0; } /** * @brief Gets the largest possible value in the output range. */ static constexpr result_type max() { return __detail::_Shift<_UIntType, __w>::__value - 1; } /** * @brief Discard a sequence of random numbers. */ void discard(unsigned long long __z); result_type operator()(); /** * @brief Compares two % mersenne_twister_engine random number generator * objects of the same type for equality. * * @param __lhs A % mersenne_twister_engine random number generator * object. * @param __rhs Another % mersenne_twister_engine random number * generator object. * * @returns true if the infinite sequences of generated values * would be equal, false otherwise. */ friend bool operator==(const mersenne_twister_engine& __lhs, const mersenne_twister_engine& __rhs) { return (std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x) && __lhs._M_p == __rhs._M_p); } /** * @brief Inserts the current state of a % mersenne_twister_engine * random number generator engine @p __x into the output stream * @p __os. * * @param __os An output stream. * @param __x A % mersenne_twister_engine random number generator * engine. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _UIntType1, size_t __w1, size_t __n1, size_t __m1, size_t __r1, _UIntType1 __a1, size_t __u1, _UIntType1 __d1, size_t __s1, _UIntType1 __b1, size_t __t1, _UIntType1 __c1, size_t __l1, _UIntType1 __f1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::mersenne_twister_engine<_UIntType1, __w1, __n1, __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1, __l1, __f1>& __x); /** * @brief Extracts the current state of a % mersenne_twister_engine * random number generator engine @p __x from the input stream * @p __is. * * @param __is An input stream. * @param __x A % mersenne_twister_engine random number generator * engine. * * @returns The input stream with the state of @p __x extracted or in * an error state. */ template<typename _UIntType1, size_t __w1, size_t __n1, size_t __m1, size_t __r1, _UIntType1 __a1, size_t __u1, _UIntType1 __d1, size_t __s1, _UIntType1 __b1, size_t __t1, _UIntType1 __c1, size_t __l1, _UIntType1 __f1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::mersenne_twister_engine<_UIntType1, __w1, __n1, __m1, __r1, __a1, __u1, __d1, __s1, __b1, __t1, __c1, __l1, __f1>& __x); private: void _M_gen_rand(); _UIntType _M_x[state_size]; size_t _M_p; }; /** * @brief Compares two % mersenne_twister_engine random number generator * objects of the same type for inequality. * * @param __lhs A % mersenne_twister_engine random number generator * object. * @param __rhs Another % mersenne_twister_engine random number * generator object. * * @returns true if the infinite sequences of generated values * would be different, false otherwise. */ template<typename _UIntType, size_t __w, size_t __n, size_t __m, size_t __r, _UIntType __a, size_t __u, _UIntType __d, size_t __s, _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f> inline bool operator!=(const std::mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __lhs, const std::mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>& __rhs) { return !(__lhs == __rhs); } /** * @brief The Marsaglia-Zaman generator. * * This is a model of a Generalized Fibonacci discrete random number * generator, sometimes referred to as the SWC generator. * * A discrete random number generator that produces pseudorandom * numbers using: * @f[ * x_{i}\leftarrow(x_{i - s} - x_{i - r} - carry_{i-1}) \bmod m * @f] * * The size of the state is @f$r@f$ * and the maximum period of the generator is @f$(m^r - m^s - 1)@f$. */ template<typename _UIntType, size_t __w, size_t __s, size_t __r> class subtract_with_carry_engine { static_assert(std::is_unsigned<_UIntType>::value, "result_type must be an unsigned integral type"); static_assert(0u < __s && __s < __r, "0 < s < r"); static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits, "template argument substituting __w out of bounds"); public: /** The type of the generated random value. */ typedef _UIntType result_type; // parameter values static constexpr size_t word_size = __w; static constexpr size_t short_lag = __s; static constexpr size_t long_lag = __r; static constexpr result_type default_seed = 19780503u; /** * @brief Constructs an explicitly seeded % subtract_with_carry_engine * random number generator. */ explicit subtract_with_carry_engine(result_type __sd = default_seed) { seed(__sd); } /** * @brief Constructs a %subtract_with_carry_engine random number engine * seeded from the seed sequence @p __q. * * @param __q the seed sequence. */ template<typename _Sseq, typename = typename std::enable_if<!std::is_same<_Sseq, subtract_with_carry_engine>::value> ::type> explicit subtract_with_carry_engine(_Sseq& __q) { seed(__q); } /** * @brief Seeds the initial state @f$x_0@f$ of the random number * generator. * * N1688[4.19] modifies this as follows. If @p __value == 0, * sets value to 19780503. In any case, with a linear * congruential generator lcg(i) having parameters @f$ m_{lcg} = * 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value * @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m * \dots lcg(r) \bmod m @f$ respectively. If @f$ x_{-1} = 0 @f$ * set carry to 1, otherwise sets carry to 0. */ void seed(result_type __sd = default_seed); /** * @brief Seeds the initial state @f$x_0@f$ of the * % subtract_with_carry_engine random number generator. */ template<typename _Sseq> typename std::enable_if<std::is_class<_Sseq>::value>::type seed(_Sseq& __q); /** * @brief Gets the inclusive minimum value of the range of random * integers returned by this generator. */ static constexpr result_type min() { return 0; } /** * @brief Gets the inclusive maximum value of the range of random * integers returned by this generator. */ static constexpr result_type max() { return __detail::_Shift<_UIntType, __w>::__value - 1; } /** * @brief Discard a sequence of random numbers. */ void discard(unsigned long long __z) { for (; __z != 0ULL; --__z) (*this)(); } /** * @brief Gets the next random number in the sequence. */ result_type operator()(); /** * @brief Compares two % subtract_with_carry_engine random number * generator objects of the same type for equality. * * @param __lhs A % subtract_with_carry_engine random number generator * object. * @param __rhs Another % subtract_with_carry_engine random number * generator object. * * @returns true if the infinite sequences of generated values * would be equal, false otherwise. */ friend bool operator==(const subtract_with_carry_engine& __lhs, const subtract_with_carry_engine& __rhs) { return (std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x) && __lhs._M_carry == __rhs._M_carry && __lhs._M_p == __rhs._M_p); } /** * @brief Inserts the current state of a % subtract_with_carry_engine * random number generator engine @p __x into the output stream * @p __os. * * @param __os An output stream. * @param __x A % subtract_with_carry_engine random number generator * engine. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::subtract_with_carry_engine<_UIntType1, __w1, __s1, __r1>& __x); /** * @brief Extracts the current state of a % subtract_with_carry_engine * random number generator engine @p __x from the input stream * @p __is. * * @param __is An input stream. * @param __x A % subtract_with_carry_engine random number generator * engine. * * @returns The input stream with the state of @p __x extracted or in * an error state. */ template<typename _UIntType1, size_t __w1, size_t __s1, size_t __r1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::subtract_with_carry_engine<_UIntType1, __w1, __s1, __r1>& __x); private: /// The state of the generator. This is a ring buffer. _UIntType _M_x[long_lag]; _UIntType _M_carry; ///< The carry size_t _M_p; ///< Current index of x(i - r). }; /** * @brief Compares two % subtract_with_carry_engine random number * generator objects of the same type for inequality. * * @param __lhs A % subtract_with_carry_engine random number generator * object. * @param __rhs Another % subtract_with_carry_engine random number * generator object. * * @returns true if the infinite sequences of generated values * would be different, false otherwise. */ template<typename _UIntType, size_t __w, size_t __s, size_t __r> inline bool operator!=(const std::subtract_with_carry_engine<_UIntType, __w, __s, __r>& __lhs, const std::subtract_with_carry_engine<_UIntType, __w, __s, __r>& __rhs) { return !(__lhs == __rhs); } /** * Produces random numbers from some base engine by discarding blocks of * data. * * 0 <= @p __r <= @p __p */ template<typename _RandomNumberEngine, size_t __p, size_t __r> class discard_block_engine { static_assert(1 <= __r && __r <= __p, "template argument substituting __r out of bounds"); public: /** The type of the generated random value. */ typedef typename _RandomNumberEngine::result_type result_type; // parameter values static constexpr size_t block_size = __p; static constexpr size_t used_block = __r; /** * @brief Constructs a default %discard_block_engine engine. * * The underlying engine is default constructed as well. */ discard_block_engine() : _M_b(), _M_n(0) { } /** * @brief Copy constructs a %discard_block_engine engine. * * Copies an existing base class random number generator. * @param __rng An existing (base class) engine object. */ explicit discard_block_engine(const _RandomNumberEngine& __rng) : _M_b(__rng), _M_n(0) { } /** * @brief Move constructs a %discard_block_engine engine. * * Copies an existing base class random number generator. * @param __rng An existing (base class) engine object. */ explicit discard_block_engine(_RandomNumberEngine&& __rng) : _M_b(std::move(__rng)), _M_n(0) { } /** * @brief Seed constructs a %discard_block_engine engine. * * Constructs the underlying generator engine seeded with @p __s. * @param __s A seed value for the base class engine. */ explicit discard_block_engine(result_type __s) : _M_b(__s), _M_n(0) { } /** * @brief Generator construct a %discard_block_engine engine. * * @param __q A seed sequence. */ template<typename _Sseq, typename = typename std::enable_if<!std::is_same<_Sseq, discard_block_engine>::value && !std::is_same<_Sseq, _RandomNumberEngine>::value> ::type> explicit discard_block_engine(_Sseq& __q) : _M_b(__q), _M_n(0) { } /** * @brief Reseeds the %discard_block_engine object with the default * seed for the underlying base class generator engine. */ void seed() { _M_b.seed(); _M_n = 0; } /** * @brief Reseeds the %discard_block_engine object with the default * seed for the underlying base class generator engine. */ void seed(result_type __s) { _M_b.seed(__s); _M_n = 0; } /** * @brief Reseeds the %discard_block_engine object with the given seed * sequence. * @param __q A seed generator function. */ template<typename _Sseq> void seed(_Sseq& __q) { _M_b.seed(__q); _M_n = 0; } /** * @brief Gets a const reference to the underlying generator engine * object. */ const _RandomNumberEngine& base() const noexcept { return _M_b; } /** * @brief Gets the minimum value in the generated random number range. */ static constexpr result_type min() { return _RandomNumberEngine::min(); } /** * @brief Gets the maximum value in the generated random number range. */ static constexpr result_type max() { return _RandomNumberEngine::max(); } /** * @brief Discard a sequence of random numbers. */ void discard(unsigned long long __z) { for (; __z != 0ULL; --__z) (*this)(); } /** * @brief Gets the next value in the generated random number sequence. */ result_type operator()(); /** * @brief Compares two %discard_block_engine random number generator * objects of the same type for equality. * * @param __lhs A %discard_block_engine random number generator object. * @param __rhs Another %discard_block_engine random number generator * object. * * @returns true if the infinite sequences of generated values * would be equal, false otherwise. */ friend bool operator==(const discard_block_engine& __lhs, const discard_block_engine& __rhs) { return __lhs._M_b == __rhs._M_b && __lhs._M_n == __rhs._M_n; } /** * @brief Inserts the current state of a %discard_block_engine random * number generator engine @p __x into the output stream * @p __os. * * @param __os An output stream. * @param __x A %discard_block_engine random number generator engine. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RandomNumberEngine1, size_t __p1, size_t __r1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::discard_block_engine<_RandomNumberEngine1, __p1, __r1>& __x); /** * @brief Extracts the current state of a % subtract_with_carry_engine * random number generator engine @p __x from the input stream * @p __is. * * @param __is An input stream. * @param __x A %discard_block_engine random number generator engine. * * @returns The input stream with the state of @p __x extracted or in * an error state. */ template<typename _RandomNumberEngine1, size_t __p1, size_t __r1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::discard_block_engine<_RandomNumberEngine1, __p1, __r1>& __x); private: _RandomNumberEngine _M_b; size_t _M_n; }; /** * @brief Compares two %discard_block_engine random number generator * objects of the same type for inequality. * * @param __lhs A %discard_block_engine random number generator object. * @param __rhs Another %discard_block_engine random number generator * object. * * @returns true if the infinite sequences of generated values * would be different, false otherwise. */ template<typename _RandomNumberEngine, size_t __p, size_t __r> inline bool operator!=(const std::discard_block_engine<_RandomNumberEngine, __p, __r>& __lhs, const std::discard_block_engine<_RandomNumberEngine, __p, __r>& __rhs) { return !(__lhs == __rhs); } /** * Produces random numbers by combining random numbers from some base * engine to produce random numbers with a specifies number of bits @p __w. */ template<typename _RandomNumberEngine, size_t __w, typename _UIntType> class independent_bits_engine { static_assert(std::is_unsigned<_UIntType>::value, "result_type must be an unsigned integral type"); static_assert(0u < __w && __w <= std::numeric_limits<_UIntType>::digits, "template argument substituting __w out of bounds"); public: /** The type of the generated random value. */ typedef _UIntType result_type; /** * @brief Constructs a default %independent_bits_engine engine. * * The underlying engine is default constructed as well. */ independent_bits_engine() : _M_b() { } /** * @brief Copy constructs a %independent_bits_engine engine. * * Copies an existing base class random number generator. * @param __rng An existing (base class) engine object. */ explicit independent_bits_engine(const _RandomNumberEngine& __rng) : _M_b(__rng) { } /** * @brief Move constructs a %independent_bits_engine engine. * * Copies an existing base class random number generator. * @param __rng An existing (base class) engine object. */ explicit independent_bits_engine(_RandomNumberEngine&& __rng) : _M_b(std::move(__rng)) { } /** * @brief Seed constructs a %independent_bits_engine engine. * * Constructs the underlying generator engine seeded with @p __s. * @param __s A seed value for the base class engine. */ explicit independent_bits_engine(result_type __s) : _M_b(__s) { } /** * @brief Generator construct a %independent_bits_engine engine. * * @param __q A seed sequence. */ template<typename _Sseq, typename = typename std::enable_if<!std::is_same<_Sseq, independent_bits_engine>::value && !std::is_same<_Sseq, _RandomNumberEngine>::value> ::type> explicit independent_bits_engine(_Sseq& __q) : _M_b(__q) { } /** * @brief Reseeds the %independent_bits_engine object with the default * seed for the underlying base class generator engine. */ void seed() { _M_b.seed(); } /** * @brief Reseeds the %independent_bits_engine object with the default * seed for the underlying base class generator engine. */ void seed(result_type __s) { _M_b.seed(__s); } /** * @brief Reseeds the %independent_bits_engine object with the given * seed sequence. * @param __q A seed generator function. */ template<typename _Sseq> void seed(_Sseq& __q) { _M_b.seed(__q); } /** * @brief Gets a const reference to the underlying generator engine * object. */ const _RandomNumberEngine& base() const noexcept { return _M_b; } /** * @brief Gets the minimum value in the generated random number range. */ static constexpr result_type min() { return 0U; } /** * @brief Gets the maximum value in the generated random number range. */ static constexpr result_type max() { return __detail::_Shift<_UIntType, __w>::__value - 1; } /** * @brief Discard a sequence of random numbers. */ void discard(unsigned long long __z) { for (; __z != 0ULL; --__z) (*this)(); } /** * @brief Gets the next value in the generated random number sequence. */ result_type operator()(); /** * @brief Compares two %independent_bits_engine random number generator * objects of the same type for equality. * * @param __lhs A %independent_bits_engine random number generator * object. * @param __rhs Another %independent_bits_engine random number generator * object. * * @returns true if the infinite sequences of generated values * would be equal, false otherwise. */ friend bool operator==(const independent_bits_engine& __lhs, const independent_bits_engine& __rhs) { return __lhs._M_b == __rhs._M_b; } /** * @brief Extracts the current state of a % subtract_with_carry_engine * random number generator engine @p __x from the input stream * @p __is. * * @param __is An input stream. * @param __x A %independent_bits_engine random number generator * engine. * * @returns The input stream with the state of @p __x extracted or in * an error state. */ template<typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::independent_bits_engine<_RandomNumberEngine, __w, _UIntType>& __x) { __is >> __x._M_b; return __is; } private: _RandomNumberEngine _M_b; }; /** * @brief Compares two %independent_bits_engine random number generator * objects of the same type for inequality. * * @param __lhs A %independent_bits_engine random number generator * object. * @param __rhs Another %independent_bits_engine random number generator * object. * * @returns true if the infinite sequences of generated values * would be different, false otherwise. */ template<typename _RandomNumberEngine, size_t __w, typename _UIntType> inline bool operator!=(const std::independent_bits_engine<_RandomNumberEngine, __w, _UIntType>& __lhs, const std::independent_bits_engine<_RandomNumberEngine, __w, _UIntType>& __rhs) { return !(__lhs == __rhs); } /** * @brief Inserts the current state of a %independent_bits_engine random * number generator engine @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %independent_bits_engine random number generator engine. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RandomNumberEngine, size_t __w, typename _UIntType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::independent_bits_engine<_RandomNumberEngine, __w, _UIntType>& __x) { __os << __x.base(); return __os; } /** * @brief Produces random numbers by combining random numbers from some * base engine to produce random numbers with a specifies number of bits * @p __k. */ template<typename _RandomNumberEngine, size_t __k> class shuffle_order_engine { static_assert(1u <= __k, "template argument substituting " "__k out of bound"); public: /** The type of the generated random value. */ typedef typename _RandomNumberEngine::result_type result_type; static constexpr size_t table_size = __k; /** * @brief Constructs a default %shuffle_order_engine engine. * * The underlying engine is default constructed as well. */ shuffle_order_engine() : _M_b() { _M_initialize(); } /** * @brief Copy constructs a %shuffle_order_engine engine. * * Copies an existing base class random number generator. * @param __rng An existing (base class) engine object. */ explicit shuffle_order_engine(const _RandomNumberEngine& __rng) : _M_b(__rng) { _M_initialize(); } /** * @brief Move constructs a %shuffle_order_engine engine. * * Copies an existing base class random number generator. * @param __rng An existing (base class) engine object. */ explicit shuffle_order_engine(_RandomNumberEngine&& __rng) : _M_b(std::move(__rng)) { _M_initialize(); } /** * @brief Seed constructs a %shuffle_order_engine engine. * * Constructs the underlying generator engine seeded with @p __s. * @param __s A seed value for the base class engine. */ explicit shuffle_order_engine(result_type __s) : _M_b(__s) { _M_initialize(); } /** * @brief Generator construct a %shuffle_order_engine engine. * * @param __q A seed sequence. */ template<typename _Sseq, typename = typename std::enable_if<!std::is_same<_Sseq, shuffle_order_engine>::value && !std::is_same<_Sseq, _RandomNumberEngine>::value> ::type> explicit shuffle_order_engine(_Sseq& __q) : _M_b(__q) { _M_initialize(); } /** * @brief Reseeds the %shuffle_order_engine object with the default seed for the underlying base class generator engine. */ void seed() { _M_b.seed(); _M_initialize(); } /** * @brief Reseeds the %shuffle_order_engine object with the default seed * for the underlying base class generator engine. */ void seed(result_type __s) { _M_b.seed(__s); _M_initialize(); } /** * @brief Reseeds the %shuffle_order_engine object with the given seed * sequence. * @param __q A seed generator function. */ template<typename _Sseq> void seed(_Sseq& __q) { _M_b.seed(__q); _M_initialize(); } /** * Gets a const reference to the underlying generator engine object. */ const _RandomNumberEngine& base() const noexcept { return _M_b; } /** * Gets the minimum value in the generated random number range. */ static constexpr result_type min() { return _RandomNumberEngine::min(); } /** * Gets the maximum value in the generated random number range. */ static constexpr result_type max() { return _RandomNumberEngine::max(); } /** * Discard a sequence of random numbers. */ void discard(unsigned long long __z) { for (; __z != 0ULL; --__z) (*this)(); } /** * Gets the next value in the generated random number sequence. */ result_type operator()(); /** * Compares two %shuffle_order_engine random number generator objects * of the same type for equality. * * @param __lhs A %shuffle_order_engine random number generator object. * @param __rhs Another %shuffle_order_engine random number generator * object. * * @returns true if the infinite sequences of generated values * would be equal, false otherwise. */ friend bool operator==(const shuffle_order_engine& __lhs, const shuffle_order_engine& __rhs) { return (__lhs._M_b == __rhs._M_b && std::equal(__lhs._M_v, __lhs._M_v + __k, __rhs._M_v) && __lhs._M_y == __rhs._M_y); } /** * @brief Inserts the current state of a %shuffle_order_engine random * number generator engine @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %shuffle_order_engine random number generator engine. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RandomNumberEngine1, size_t __k1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::shuffle_order_engine<_RandomNumberEngine1, __k1>& __x); /** * @brief Extracts the current state of a % subtract_with_carry_engine * random number generator engine @p __x from the input stream * @p __is. * * @param __is An input stream. * @param __x A %shuffle_order_engine random number generator engine. * * @returns The input stream with the state of @p __x extracted or in * an error state. */ template<typename _RandomNumberEngine1, size_t __k1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::shuffle_order_engine<_RandomNumberEngine1, __k1>& __x); private: void _M_initialize() { for (size_t __i = 0; __i < __k; ++__i) _M_v[__i] = _M_b(); _M_y = _M_b(); } _RandomNumberEngine _M_b; result_type _M_v[__k]; result_type _M_y; }; /** * Compares two %shuffle_order_engine random number generator objects * of the same type for inequality. * * @param __lhs A %shuffle_order_engine random number generator object. * @param __rhs Another %shuffle_order_engine random number generator * object. * * @returns true if the infinite sequences of generated values * would be different, false otherwise. */ template<typename _RandomNumberEngine, size_t __k> inline bool operator!=(const std::shuffle_order_engine<_RandomNumberEngine, __k>& __lhs, const std::shuffle_order_engine<_RandomNumberEngine, __k>& __rhs) { return !(__lhs == __rhs); } /** * The classic Minimum Standard rand0 of Lewis, Goodman, and Miller. */ typedef linear_congruential_engine<uint_fast32_t, 16807UL, 0UL, 2147483647UL> minstd_rand0; /** * An alternative LCR (Lehmer Generator function). */ typedef linear_congruential_engine<uint_fast32_t, 48271UL, 0UL, 2147483647UL> minstd_rand; /** * The classic Mersenne Twister. * * Reference: * M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally * Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions * on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30. */ typedef mersenne_twister_engine< uint_fast32_t, 32, 624, 397, 31, 0x9908b0dfUL, 11, 0xffffffffUL, 7, 0x9d2c5680UL, 15, 0xefc60000UL, 18, 1812433253UL> mt19937; /** * An alternative Mersenne Twister. */ typedef mersenne_twister_engine< uint_fast64_t, 64, 312, 156, 31, 0xb5026f5aa96619e9ULL, 29, 0x5555555555555555ULL, 17, 0x71d67fffeda60000ULL, 37, 0xfff7eee000000000ULL, 43, 6364136223846793005ULL> mt19937_64; typedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24> ranlux24_base; typedef subtract_with_carry_engine<uint_fast64_t, 48, 5, 12> ranlux48_base; typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24; typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48; typedef shuffle_order_engine<minstd_rand0, 256> knuth_b; typedef minstd_rand0 default_random_engine; /** * A standard interface to a platform-specific non-deterministic * random number generator (if any are available). */ class random_device { public: /** The type of the generated random value. */ typedef unsigned int result_type; // constructors, destructors and member functions #ifdef _GLIBCXX_USE_RANDOM_TR1 explicit random_device(const std::string& __token = "default") { _M_init(__token); } ~random_device() { _M_fini(); } #else explicit random_device(const std::string& __token = "mt19937") { _M_init_pretr1(__token); } public: #endif static constexpr result_type min() { return std::numeric_limits<result_type>::min(); } static constexpr result_type max() { return std::numeric_limits<result_type>::max(); } double entropy() const noexcept { #ifdef _GLIBCXX_USE_RANDOM_TR1 return this->_M_getentropy(); #else return 0.0; #endif } result_type operator()() { #ifdef _GLIBCXX_USE_RANDOM_TR1 return this->_M_getval(); #else return this->_M_getval_pretr1(); #endif } // No copy functions. random_device(const random_device&) = delete; void operator=(const random_device&) = delete; private: void _M_init(const std::string& __token); void _M_init_pretr1(const std::string& __token); void _M_fini(); result_type _M_getval(); result_type _M_getval_pretr1(); double _M_getentropy() const noexcept; union { void* _M_file; mt19937 _M_mt; }; }; /* @} */ // group random_generators /** * @addtogroup random_distributions Random Number Distributions * @ingroup random * @{ */ /** * @addtogroup random_distributions_uniform Uniform Distributions * @ingroup random_distributions * @{ */ // std::uniform_int_distribution is defined in <bits/uniform_int_dist.h> /** * @brief Return true if two uniform integer distributions have * different parameters. */ template<typename _IntType> inline bool operator!=(const std::uniform_int_distribution<_IntType>& __d1, const std::uniform_int_distribution<_IntType>& __d2) { return !(__d1 == __d2); } /** * @brief Inserts a %uniform_int_distribution random number * distribution @p __x into the output stream @p os. * * @param __os An output stream. * @param __x A %uniform_int_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _IntType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const std::uniform_int_distribution<_IntType>&); /** * @brief Extracts a %uniform_int_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %uniform_int_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _IntType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, std::uniform_int_distribution<_IntType>&); /** * @brief Uniform continuous distribution for random numbers. * * A continuous random distribution on the range [min, max) with equal * probability throughout the range. The URNG should be real-valued and * deliver number in the range [0, 1). */ template<typename _RealType = double> class uniform_real_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef uniform_real_distribution<_RealType> distribution_type; explicit param_type(_RealType __a = _RealType(0), _RealType __b = _RealType(1)) : _M_a(__a), _M_b(__b) { __glibcxx_assert(_M_a <= _M_b); } result_type a() const { return _M_a; } result_type b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_a; _RealType _M_b; }; public: /** * @brief Constructs a uniform_real_distribution object. * * @param __a [IN] The lower bound of the distribution. * @param __b [IN] The upper bound of the distribution. */ explicit uniform_real_distribution(_RealType __a = _RealType(0), _RealType __b = _RealType(1)) : _M_param(__a, __b) { } explicit uniform_real_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. * * Does nothing for the uniform real distribution. */ void reset() { } result_type a() const { return _M_param.a(); } result_type b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the inclusive lower bound of the distribution range. */ result_type min() const { return this->a(); } /** * @brief Returns the inclusive upper bound of the distribution range. */ result_type max() const { return this->b(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); return (__aurng() * (__p.b() - __p.a())) + __p.a(); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two uniform real distributions have * the same parameters. */ friend bool operator==(const uniform_real_distribution& __d1, const uniform_real_distribution& __d2) { return __d1._M_param == __d2._M_param; } private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two uniform real distributions have * different parameters. */ template<typename _IntType> inline bool operator!=(const std::uniform_real_distribution<_IntType>& __d1, const std::uniform_real_distribution<_IntType>& __d2) { return !(__d1 == __d2); } /** * @brief Inserts a %uniform_real_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %uniform_real_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>&, const std::uniform_real_distribution<_RealType>&); /** * @brief Extracts a %uniform_real_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %uniform_real_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>&, std::uniform_real_distribution<_RealType>&); /* @} */ // group random_distributions_uniform /** * @addtogroup random_distributions_normal Normal Distributions * @ingroup random_distributions * @{ */ /** * @brief A normal continuous distribution for random numbers. * * The formula for the normal probability density function is * @f[ * p(x|\mu,\sigma) = \frac{1}{\sigma \sqrt{2 \pi}} * e^{- \frac{{x - \mu}^ {2}}{2 \sigma ^ {2}} } * @f] */ template<typename _RealType = double> class normal_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef normal_distribution<_RealType> distribution_type; explicit param_type(_RealType __mean = _RealType(0), _RealType __stddev = _RealType(1)) : _M_mean(__mean), _M_stddev(__stddev) { __glibcxx_assert(_M_stddev > _RealType(0)); } _RealType mean() const { return _M_mean; } _RealType stddev() const { return _M_stddev; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_mean == __p2._M_mean && __p1._M_stddev == __p2._M_stddev); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_mean; _RealType _M_stddev; }; public: /** * Constructs a normal distribution with parameters @f$mean@f$ and * standard deviation. */ explicit normal_distribution(result_type __mean = result_type(0), result_type __stddev = result_type(1)) : _M_param(__mean, __stddev) { } explicit normal_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { _M_saved_available = false; } /** * @brief Returns the mean of the distribution. */ _RealType mean() const { return _M_param.mean(); } /** * @brief Returns the standard deviation of the distribution. */ _RealType stddev() const { return _M_param.stddev(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return std::numeric_limits<result_type>::lowest(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two normal distributions have * the same parameters and the sequences that would * be generated are equal. */ template<typename _RealType1> friend bool operator==(const std::normal_distribution<_RealType1>& __d1, const std::normal_distribution<_RealType1>& __d2); /** * @brief Inserts a %normal_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %normal_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::normal_distribution<_RealType1>& __x); /** * @brief Extracts a %normal_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %normal_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error * state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::normal_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; result_type _M_saved = 0; bool _M_saved_available = false; }; /** * @brief Return true if two normal distributions are different. */ template<typename _RealType> inline bool operator!=(const std::normal_distribution<_RealType>& __d1, const std::normal_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A lognormal_distribution random number distribution. * * The formula for the normal probability mass function is * @f[ * p(x|m,s) = \frac{1}{sx\sqrt{2\pi}} * \exp{-\frac{(\ln{x} - m)^2}{2s^2}} * @f] */ template<typename _RealType = double> class lognormal_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef lognormal_distribution<_RealType> distribution_type; explicit param_type(_RealType __m = _RealType(0), _RealType __s = _RealType(1)) : _M_m(__m), _M_s(__s) { } _RealType m() const { return _M_m; } _RealType s() const { return _M_s; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_m == __p2._M_m && __p1._M_s == __p2._M_s; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_m; _RealType _M_s; }; explicit lognormal_distribution(_RealType __m = _RealType(0), _RealType __s = _RealType(1)) : _M_param(__m, __s), _M_nd() { } explicit lognormal_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * */ _RealType m() const { return _M_param.m(); } _RealType s() const { return _M_param.s(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two lognormal distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const lognormal_distribution& __d1, const lognormal_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd); } /** * @brief Inserts a %lognormal_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %lognormal_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::lognormal_distribution<_RealType1>& __x); /** * @brief Extracts a %lognormal_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %lognormal_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::lognormal_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<result_type> _M_nd; }; /** * @brief Return true if two lognormal distributions are different. */ template<typename _RealType> inline bool operator!=(const std::lognormal_distribution<_RealType>& __d1, const std::lognormal_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A gamma continuous distribution for random numbers. * * The formula for the gamma probability density function is: * @f[ * p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)} * (x/\beta)^{\alpha - 1} e^{-x/\beta} * @f] */ template<typename _RealType = double> class gamma_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef gamma_distribution<_RealType> distribution_type; friend class gamma_distribution<_RealType>; explicit param_type(_RealType __alpha_val = _RealType(1), _RealType __beta_val = _RealType(1)) : _M_alpha(__alpha_val), _M_beta(__beta_val) { __glibcxx_assert(_M_alpha > _RealType(0)); _M_initialize(); } _RealType alpha() const { return _M_alpha; } _RealType beta() const { return _M_beta; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return (__p1._M_alpha == __p2._M_alpha && __p1._M_beta == __p2._M_beta); } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); _RealType _M_alpha; _RealType _M_beta; _RealType _M_malpha, _M_a2; }; public: /** * @brief Constructs a gamma distribution with parameters * @f$\alpha@f$ and @f$\beta@f$. */ explicit gamma_distribution(_RealType __alpha_val = _RealType(1), _RealType __beta_val = _RealType(1)) : _M_param(__alpha_val, __beta_val), _M_nd() { } explicit gamma_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * @brief Returns the @f$\alpha@f$ of the distribution. */ _RealType alpha() const { return _M_param.alpha(); } /** * @brief Returns the @f$\beta@f$ of the distribution. */ _RealType beta() const { return _M_param.beta(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two gamma distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const gamma_distribution& __d1, const gamma_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd); } /** * @brief Inserts a %gamma_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %gamma_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::gamma_distribution<_RealType1>& __x); /** * @brief Extracts a %gamma_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %gamma_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::gamma_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<result_type> _M_nd; }; /** * @brief Return true if two gamma distributions are different. */ template<typename _RealType> inline bool operator!=(const std::gamma_distribution<_RealType>& __d1, const std::gamma_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A chi_squared_distribution random number distribution. * * The formula for the normal probability mass function is * @f$p(x|n) = \frac{x^{(n/2) - 1}e^{-x/2}}{\Gamma(n/2) 2^{n/2}}@f$ */ template<typename _RealType = double> class chi_squared_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef chi_squared_distribution<_RealType> distribution_type; explicit param_type(_RealType __n = _RealType(1)) : _M_n(__n) { } _RealType n() const { return _M_n; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_n == __p2._M_n; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_n; }; explicit chi_squared_distribution(_RealType __n = _RealType(1)) : _M_param(__n), _M_gd(__n / 2) { } explicit chi_squared_distribution(const param_type& __p) : _M_param(__p), _M_gd(__p.n() / 2) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd.reset(); } /** * */ _RealType n() const { return _M_param.n(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; typedef typename std::gamma_distribution<result_type>::param_type param_type; _M_gd.param(param_type{__param.n() / 2}); } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return 2 * _M_gd(__urng); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typedef typename std::gamma_distribution<result_type>::param_type param_type; return 2 * _M_gd(__urng, param_type(__p.n() / 2)); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate_impl(__f, __t, __urng); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::gamma_distribution<result_type>::param_type __p2(__p.n() / 2); this->__generate_impl(__f, __t, __urng, __p2); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng) { this->__generate_impl(__f, __t, __urng); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { typename std::gamma_distribution<result_type>::param_type __p2(__p.n() / 2); this->__generate_impl(__f, __t, __urng, __p2); } /** * @brief Return true if two Chi-squared distributions have * the same parameters and the sequences that would be * generated are equal. */ friend bool operator==(const chi_squared_distribution& __d1, const chi_squared_distribution& __d2) { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; } /** * @brief Inserts a %chi_squared_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %chi_squared_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::chi_squared_distribution<_RealType1>& __x); /** * @brief Extracts a %chi_squared_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %chi_squared_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::chi_squared_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const typename std::gamma_distribution<result_type>::param_type& __p); param_type _M_param; std::gamma_distribution<result_type> _M_gd; }; /** * @brief Return true if two Chi-squared distributions are different. */ template<typename _RealType> inline bool operator!=(const std::chi_squared_distribution<_RealType>& __d1, const std::chi_squared_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A cauchy_distribution random number distribution. * * The formula for the normal probability mass function is * @f$p(x|a,b) = (\pi b (1 + (\frac{x-a}{b})^2))^{-1}@f$ */ template<typename _RealType = double> class cauchy_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef cauchy_distribution<_RealType> distribution_type; explicit param_type(_RealType __a = _RealType(0), _RealType __b = _RealType(1)) : _M_a(__a), _M_b(__b) { } _RealType a() const { return _M_a; } _RealType b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_a; _RealType _M_b; }; explicit cauchy_distribution(_RealType __a = _RealType(0), _RealType __b = _RealType(1)) : _M_param(__a, __b) { } explicit cauchy_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * */ _RealType a() const { return _M_param.a(); } _RealType b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return std::numeric_limits<result_type>::lowest(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Cauchy distributions have * the same parameters. */ friend bool operator==(const cauchy_distribution& __d1, const cauchy_distribution& __d2) { return __d1._M_param == __d2._M_param; } private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two Cauchy distributions have * different parameters. */ template<typename _RealType> inline bool operator!=(const std::cauchy_distribution<_RealType>& __d1, const std::cauchy_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief Inserts a %cauchy_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %cauchy_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::cauchy_distribution<_RealType>& __x); /** * @brief Extracts a %cauchy_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %cauchy_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::cauchy_distribution<_RealType>& __x); /** * @brief A fisher_f_distribution random number distribution. * * The formula for the normal probability mass function is * @f[ * p(x|m,n) = \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)} * (\frac{m}{n})^{m/2} x^{(m/2)-1} * (1 + \frac{mx}{n})^{-(m+n)/2} * @f] */ template<typename _RealType = double> class fisher_f_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef fisher_f_distribution<_RealType> distribution_type; explicit param_type(_RealType __m = _RealType(1), _RealType __n = _RealType(1)) : _M_m(__m), _M_n(__n) { } _RealType m() const { return _M_m; } _RealType n() const { return _M_n; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_m == __p2._M_m && __p1._M_n == __p2._M_n; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_m; _RealType _M_n; }; explicit fisher_f_distribution(_RealType __m = _RealType(1), _RealType __n = _RealType(1)) : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2) { } explicit fisher_f_distribution(const param_type& __p) : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd_x.reset(); _M_gd_y.reset(); } /** * */ _RealType m() const { return _M_param.m(); } _RealType n() const { return _M_param.n(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typedef typename std::gamma_distribution<result_type>::param_type param_type; return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n()) / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m())); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate_impl(__f, __t, __urng); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng) { this->__generate_impl(__f, __t, __urng); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Fisher f distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const fisher_f_distribution& __d1, const fisher_f_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_gd_x == __d2._M_gd_x && __d1._M_gd_y == __d2._M_gd_y); } /** * @brief Inserts a %fisher_f_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %fisher_f_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::fisher_f_distribution<_RealType1>& __x); /** * @brief Extracts a %fisher_f_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %fisher_f_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::fisher_f_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::gamma_distribution<result_type> _M_gd_x, _M_gd_y; }; /** * @brief Return true if two Fisher f distributions are different. */ template<typename _RealType> inline bool operator!=(const std::fisher_f_distribution<_RealType>& __d1, const std::fisher_f_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A student_t_distribution random number distribution. * * The formula for the normal probability mass function is: * @f[ * p(x|n) = \frac{1}{\sqrt(n\pi)} \frac{\Gamma((n+1)/2)}{\Gamma(n/2)} * (1 + \frac{x^2}{n}) ^{-(n+1)/2} * @f] */ template<typename _RealType = double> class student_t_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef student_t_distribution<_RealType> distribution_type; explicit param_type(_RealType __n = _RealType(1)) : _M_n(__n) { } _RealType n() const { return _M_n; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_n == __p2._M_n; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_n; }; explicit student_t_distribution(_RealType __n = _RealType(1)) : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2) { } explicit student_t_distribution(const param_type& __p) : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2) { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); _M_gd.reset(); } /** * */ _RealType n() const { return _M_param.n(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return std::numeric_limits<result_type>::lowest(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { typedef typename std::gamma_distribution<result_type>::param_type param_type; const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2)); return _M_nd(__urng) * std::sqrt(__p.n() / __g); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate_impl(__f, __t, __urng); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng) { this->__generate_impl(__f, __t, __urng); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Student t distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const student_t_distribution& __d1, const student_t_distribution& __d2) { return (__d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd && __d1._M_gd == __d2._M_gd); } /** * @brief Inserts a %student_t_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %student_t_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::student_t_distribution<_RealType1>& __x); /** * @brief Extracts a %student_t_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %student_t_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::student_t_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::normal_distribution<result_type> _M_nd; std::gamma_distribution<result_type> _M_gd; }; /** * @brief Return true if two Student t distributions are different. */ template<typename _RealType> inline bool operator!=(const std::student_t_distribution<_RealType>& __d1, const std::student_t_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /* @} */ // group random_distributions_normal /** * @addtogroup random_distributions_bernoulli Bernoulli Distributions * @ingroup random_distributions * @{ */ /** * @brief A Bernoulli random number distribution. * * Generates a sequence of true and false values with likelihood @f$p@f$ * that true will come up and @f$(1 - p)@f$ that false will appear. */ class bernoulli_distribution { public: /** The type of the range of the distribution. */ typedef bool result_type; /** Parameter type. */ struct param_type { typedef bernoulli_distribution distribution_type; explicit param_type(double __p = 0.5) : _M_p(__p) { __glibcxx_assert((_M_p >= 0.0) && (_M_p <= 1.0)); } double p() const { return _M_p; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_p == __p2._M_p; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: double _M_p; }; public: /** * @brief Constructs a Bernoulli distribution with likelihood @p p. * * @param __p [IN] The likelihood of a true result being returned. * Must be in the interval @f$[0, 1]@f$. */ explicit bernoulli_distribution(double __p = 0.5) : _M_param(__p) { } explicit bernoulli_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. * * Does nothing for a Bernoulli distribution. */ void reset() { } /** * @brief Returns the @p p parameter of the distribution. */ double p() const { return _M_param.p(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return std::numeric_limits<result_type>::min(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { __detail::_Adaptor<_UniformRandomNumberGenerator, double> __aurng(__urng); if ((__aurng() - __aurng.min()) < __p.p() * (__aurng.max() - __aurng.min())) return true; return false; } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Bernoulli distributions have * the same parameters. */ friend bool operator==(const bernoulli_distribution& __d1, const bernoulli_distribution& __d2) { return __d1._M_param == __d2._M_param; } private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two Bernoulli distributions have * different parameters. */ inline bool operator!=(const std::bernoulli_distribution& __d1, const std::bernoulli_distribution& __d2) { return !(__d1 == __d2); } /** * @brief Inserts a %bernoulli_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %bernoulli_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::bernoulli_distribution& __x); /** * @brief Extracts a %bernoulli_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %bernoulli_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::bernoulli_distribution& __x) { double __p; if (__is >> __p) __x.param(bernoulli_distribution::param_type(__p)); return __is; } /** * @brief A discrete binomial random number distribution. * * The formula for the binomial probability density function is * @f$p(i|t,p) = \binom{t}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$ * and @f$p@f$ are the parameters of the distribution. */ template<typename _IntType = int> class binomial_distribution { static_assert(std::is_integral<_IntType>::value, "result_type must be an integral type"); public: /** The type of the range of the distribution. */ typedef _IntType result_type; /** Parameter type. */ struct param_type { typedef binomial_distribution<_IntType> distribution_type; friend class binomial_distribution<_IntType>; explicit param_type(_IntType __t = _IntType(1), double __p = 0.5) : _M_t(__t), _M_p(__p) { __glibcxx_assert((_M_t >= _IntType(0)) && (_M_p >= 0.0) && (_M_p <= 1.0)); _M_initialize(); } _IntType t() const { return _M_t; } double p() const { return _M_p; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_t == __p2._M_t && __p1._M_p == __p2._M_p; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); _IntType _M_t; double _M_p; double _M_q; #if _GLIBCXX_USE_C99_MATH_TR1 double _M_d1, _M_d2, _M_s1, _M_s2, _M_c, _M_a1, _M_a123, _M_s, _M_lf, _M_lp1p; #endif bool _M_easy; }; // constructors and member function explicit binomial_distribution(_IntType __t = _IntType(1), double __p = 0.5) : _M_param(__t, __p), _M_nd() { } explicit binomial_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * @brief Returns the distribution @p t parameter. */ _IntType t() const { return _M_param.t(); } /** * @brief Returns the distribution @p p parameter. */ double p() const { return _M_param.p(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return 0; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return _M_param.t(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two binomial distributions have * the same parameters and the sequences that would * be generated are equal. */ friend bool operator==(const binomial_distribution& __d1, const binomial_distribution& __d2) #ifdef _GLIBCXX_USE_C99_MATH_TR1 { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; } #else { return __d1._M_param == __d2._M_param; } #endif /** * @brief Inserts a %binomial_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %binomial_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _IntType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::binomial_distribution<_IntType1>& __x); /** * @brief Extracts a %binomial_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %binomial_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error * state. */ template<typename _IntType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::binomial_distribution<_IntType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _UniformRandomNumberGenerator> result_type _M_waiting(_UniformRandomNumberGenerator& __urng, _IntType __t, double __q); param_type _M_param; // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. std::normal_distribution<double> _M_nd; }; /** * @brief Return true if two binomial distributions are different. */ template<typename _IntType> inline bool operator!=(const std::binomial_distribution<_IntType>& __d1, const std::binomial_distribution<_IntType>& __d2) { return !(__d1 == __d2); } /** * @brief A discrete geometric random number distribution. * * The formula for the geometric probability density function is * @f$p(i|p) = p(1 - p)^{i}@f$ where @f$p@f$ is the parameter of the * distribution. */ template<typename _IntType = int> class geometric_distribution { static_assert(std::is_integral<_IntType>::value, "result_type must be an integral type"); public: /** The type of the range of the distribution. */ typedef _IntType result_type; /** Parameter type. */ struct param_type { typedef geometric_distribution<_IntType> distribution_type; friend class geometric_distribution<_IntType>; explicit param_type(double __p = 0.5) : _M_p(__p) { __glibcxx_assert((_M_p > 0.0) && (_M_p < 1.0)); _M_initialize(); } double p() const { return _M_p; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_p == __p2._M_p; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize() { _M_log_1_p = std::log(1.0 - _M_p); } double _M_p; double _M_log_1_p; }; // constructors and member function explicit geometric_distribution(double __p = 0.5) : _M_param(__p) { } explicit geometric_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. * * Does nothing for the geometric distribution. */ void reset() { } /** * @brief Returns the distribution parameter @p p. */ double p() const { return _M_param.p(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return 0; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two geometric distributions have * the same parameters. */ friend bool operator==(const geometric_distribution& __d1, const geometric_distribution& __d2) { return __d1._M_param == __d2._M_param; } private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two geometric distributions have * different parameters. */ template<typename _IntType> inline bool operator!=(const std::geometric_distribution<_IntType>& __d1, const std::geometric_distribution<_IntType>& __d2) { return !(__d1 == __d2); } /** * @brief Inserts a %geometric_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %geometric_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _IntType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::geometric_distribution<_IntType>& __x); /** * @brief Extracts a %geometric_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %geometric_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _IntType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::geometric_distribution<_IntType>& __x); /** * @brief A negative_binomial_distribution random number distribution. * * The formula for the negative binomial probability mass function is * @f$p(i) = \binom{n}{i} p^i (1 - p)^{t - i}@f$ where @f$t@f$ * and @f$p@f$ are the parameters of the distribution. */ template<typename _IntType = int> class negative_binomial_distribution { static_assert(std::is_integral<_IntType>::value, "result_type must be an integral type"); public: /** The type of the range of the distribution. */ typedef _IntType result_type; /** Parameter type. */ struct param_type { typedef negative_binomial_distribution<_IntType> distribution_type; explicit param_type(_IntType __k = 1, double __p = 0.5) : _M_k(__k), _M_p(__p) { __glibcxx_assert((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0)); } _IntType k() const { return _M_k; } double p() const { return _M_p; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_k == __p2._M_k && __p1._M_p == __p2._M_p; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _IntType _M_k; double _M_p; }; explicit negative_binomial_distribution(_IntType __k = 1, double __p = 0.5) : _M_param(__k, __p), _M_gd(__k, (1.0 - __p) / __p) { } explicit negative_binomial_distribution(const param_type& __p) : _M_param(__p), _M_gd(__p.k(), (1.0 - __p.p()) / __p.p()) { } /** * @brief Resets the distribution state. */ void reset() { _M_gd.reset(); } /** * @brief Return the @f$k@f$ parameter of the distribution. */ _IntType k() const { return _M_param.k(); } /** * @brief Return the @f$p@f$ parameter of the distribution. */ double p() const { return _M_param.p(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng); template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate_impl(__f, __t, __urng); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng) { this->__generate_impl(__f, __t, __urng); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two negative binomial distributions have * the same parameters and the sequences that would be * generated are equal. */ friend bool operator==(const negative_binomial_distribution& __d1, const negative_binomial_distribution& __d2) { return __d1._M_param == __d2._M_param && __d1._M_gd == __d2._M_gd; } /** * @brief Inserts a %negative_binomial_distribution random * number distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %negative_binomial_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _IntType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::negative_binomial_distribution<_IntType1>& __x); /** * @brief Extracts a %negative_binomial_distribution random number * distribution @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %negative_binomial_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _IntType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::negative_binomial_distribution<_IntType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; std::gamma_distribution<double> _M_gd; }; /** * @brief Return true if two negative binomial distributions are different. */ template<typename _IntType> inline bool operator!=(const std::negative_binomial_distribution<_IntType>& __d1, const std::negative_binomial_distribution<_IntType>& __d2) { return !(__d1 == __d2); } /* @} */ // group random_distributions_bernoulli /** * @addtogroup random_distributions_poisson Poisson Distributions * @ingroup random_distributions * @{ */ /** * @brief A discrete Poisson random number distribution. * * The formula for the Poisson probability density function is * @f$p(i|\mu) = \frac{\mu^i}{i!} e^{-\mu}@f$ where @f$\mu@f$ is the * parameter of the distribution. */ template<typename _IntType = int> class poisson_distribution { static_assert(std::is_integral<_IntType>::value, "result_type must be an integral type"); public: /** The type of the range of the distribution. */ typedef _IntType result_type; /** Parameter type. */ struct param_type { typedef poisson_distribution<_IntType> distribution_type; friend class poisson_distribution<_IntType>; explicit param_type(double __mean = 1.0) : _M_mean(__mean) { __glibcxx_assert(_M_mean > 0.0); _M_initialize(); } double mean() const { return _M_mean; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_mean == __p2._M_mean; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: // Hosts either log(mean) or the threshold of the simple method. void _M_initialize(); double _M_mean; double _M_lm_thr; #if _GLIBCXX_USE_C99_MATH_TR1 double _M_lfm, _M_sm, _M_d, _M_scx, _M_1cx, _M_c2b, _M_cb; #endif }; // constructors and member function explicit poisson_distribution(double __mean = 1.0) : _M_param(__mean), _M_nd() { } explicit poisson_distribution(const param_type& __p) : _M_param(__p), _M_nd() { } /** * @brief Resets the distribution state. */ void reset() { _M_nd.reset(); } /** * @brief Returns the distribution parameter @p mean. */ double mean() const { return _M_param.mean(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return 0; } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Poisson distributions have the same * parameters and the sequences that would be generated * are equal. */ friend bool operator==(const poisson_distribution& __d1, const poisson_distribution& __d2) #ifdef _GLIBCXX_USE_C99_MATH_TR1 { return __d1._M_param == __d2._M_param && __d1._M_nd == __d2._M_nd; } #else { return __d1._M_param == __d2._M_param; } #endif /** * @brief Inserts a %poisson_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %poisson_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _IntType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::poisson_distribution<_IntType1>& __x); /** * @brief Extracts a %poisson_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %poisson_distribution random number generator engine. * * @returns The input stream with @p __x extracted or in an error * state. */ template<typename _IntType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::poisson_distribution<_IntType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; // NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined. std::normal_distribution<double> _M_nd; }; /** * @brief Return true if two Poisson distributions are different. */ template<typename _IntType> inline bool operator!=(const std::poisson_distribution<_IntType>& __d1, const std::poisson_distribution<_IntType>& __d2) { return !(__d1 == __d2); } /** * @brief An exponential continuous distribution for random numbers. * * The formula for the exponential probability density function is * @f$p(x|\lambda) = \lambda e^{-\lambda x}@f$. * * <table border=1 cellpadding=10 cellspacing=0> * <caption align=top>Distribution Statistics</caption> * <tr><td>Mean</td><td>@f$\frac{1}{\lambda}@f$</td></tr> * <tr><td>Median</td><td>@f$\frac{\ln 2}{\lambda}@f$</td></tr> * <tr><td>Mode</td><td>@f$zero@f$</td></tr> * <tr><td>Range</td><td>@f$[0, \infty]@f$</td></tr> * <tr><td>Standard Deviation</td><td>@f$\frac{1}{\lambda}@f$</td></tr> * </table> */ template<typename _RealType = double> class exponential_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef exponential_distribution<_RealType> distribution_type; explicit param_type(_RealType __lambda = _RealType(1)) : _M_lambda(__lambda) { __glibcxx_assert(_M_lambda > _RealType(0)); } _RealType lambda() const { return _M_lambda; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_lambda == __p2._M_lambda; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_lambda; }; public: /** * @brief Constructs an exponential distribution with inverse scale * parameter @f$\lambda@f$. */ explicit exponential_distribution(const result_type& __lambda = result_type(1)) : _M_param(__lambda) { } explicit exponential_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. * * Has no effect on exponential distributions. */ void reset() { } /** * @brief Returns the inverse scale parameter of the distribution. */ _RealType lambda() const { return _M_param.lambda(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p) { __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); return -std::log(result_type(1) - __aurng()) / __p.lambda(); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two exponential distributions have the same * parameters. */ friend bool operator==(const exponential_distribution& __d1, const exponential_distribution& __d2) { return __d1._M_param == __d2._M_param; } private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two exponential distributions have different * parameters. */ template<typename _RealType> inline bool operator!=(const std::exponential_distribution<_RealType>& __d1, const std::exponential_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief Inserts a %exponential_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %exponential_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::exponential_distribution<_RealType>& __x); /** * @brief Extracts a %exponential_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %exponential_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::exponential_distribution<_RealType>& __x); /** * @brief A weibull_distribution random number distribution. * * The formula for the normal probability density function is: * @f[ * p(x|\alpha,\beta) = \frac{\alpha}{\beta} (\frac{x}{\beta})^{\alpha-1} * \exp{(-(\frac{x}{\beta})^\alpha)} * @f] */ template<typename _RealType = double> class weibull_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef weibull_distribution<_RealType> distribution_type; explicit param_type(_RealType __a = _RealType(1), _RealType __b = _RealType(1)) : _M_a(__a), _M_b(__b) { } _RealType a() const { return _M_a; } _RealType b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_a; _RealType _M_b; }; explicit weibull_distribution(_RealType __a = _RealType(1), _RealType __b = _RealType(1)) : _M_param(__a, __b) { } explicit weibull_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Return the @f$a@f$ parameter of the distribution. */ _RealType a() const { return _M_param.a(); } /** * @brief Return the @f$b@f$ parameter of the distribution. */ _RealType b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two Weibull distributions have the same * parameters. */ friend bool operator==(const weibull_distribution& __d1, const weibull_distribution& __d2) { return __d1._M_param == __d2._M_param; } private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two Weibull distributions have different * parameters. */ template<typename _RealType> inline bool operator!=(const std::weibull_distribution<_RealType>& __d1, const std::weibull_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief Inserts a %weibull_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %weibull_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::weibull_distribution<_RealType>& __x); /** * @brief Extracts a %weibull_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %weibull_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::weibull_distribution<_RealType>& __x); /** * @brief A extreme_value_distribution random number distribution. * * The formula for the normal probability mass function is * @f[ * p(x|a,b) = \frac{1}{b} * \exp( \frac{a-x}{b} - \exp(\frac{a-x}{b})) * @f] */ template<typename _RealType = double> class extreme_value_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef extreme_value_distribution<_RealType> distribution_type; explicit param_type(_RealType __a = _RealType(0), _RealType __b = _RealType(1)) : _M_a(__a), _M_b(__b) { } _RealType a() const { return _M_a; } _RealType b() const { return _M_b; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_a == __p2._M_a && __p1._M_b == __p2._M_b; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: _RealType _M_a; _RealType _M_b; }; explicit extreme_value_distribution(_RealType __a = _RealType(0), _RealType __b = _RealType(1)) : _M_param(__a, __b) { } explicit extreme_value_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Return the @f$a@f$ parameter of the distribution. */ _RealType a() const { return _M_param.a(); } /** * @brief Return the @f$b@f$ parameter of the distribution. */ _RealType b() const { return _M_param.b(); } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return std::numeric_limits<result_type>::lowest(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return std::numeric_limits<result_type>::max(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two extreme value distributions have the same * parameters. */ friend bool operator==(const extreme_value_distribution& __d1, const extreme_value_distribution& __d2) { return __d1._M_param == __d2._M_param; } private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two extreme value distributions have different * parameters. */ template<typename _RealType> inline bool operator!=(const std::extreme_value_distribution<_RealType>& __d1, const std::extreme_value_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief Inserts a %extreme_value_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %extreme_value_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType, typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::extreme_value_distribution<_RealType>& __x); /** * @brief Extracts a %extreme_value_distribution random number * distribution @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %extreme_value_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ template<typename _RealType, typename _CharT, typename _Traits> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::extreme_value_distribution<_RealType>& __x); /** * @brief A discrete_distribution random number distribution. * * The formula for the discrete probability mass function is * */ template<typename _IntType = int> class discrete_distribution { static_assert(std::is_integral<_IntType>::value, "result_type must be an integral type"); public: /** The type of the range of the distribution. */ typedef _IntType result_type; /** Parameter type. */ struct param_type { typedef discrete_distribution<_IntType> distribution_type; friend class discrete_distribution<_IntType>; param_type() : _M_prob(), _M_cp() { } template<typename _InputIterator> param_type(_InputIterator __wbegin, _InputIterator __wend) : _M_prob(__wbegin, __wend), _M_cp() { _M_initialize(); } param_type(initializer_list<double> __wil) : _M_prob(__wil.begin(), __wil.end()), _M_cp() { _M_initialize(); } template<typename _Func> param_type(size_t __nw, double __xmin, double __xmax, _Func __fw); // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/ param_type(const param_type&) = default; param_type& operator=(const param_type&) = default; std::vector<double> probabilities() const { return _M_prob.empty() ? std::vector<double>(1, 1.0) : _M_prob; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_prob == __p2._M_prob; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); std::vector<double> _M_prob; std::vector<double> _M_cp; }; discrete_distribution() : _M_param() { } template<typename _InputIterator> discrete_distribution(_InputIterator __wbegin, _InputIterator __wend) : _M_param(__wbegin, __wend) { } discrete_distribution(initializer_list<double> __wl) : _M_param(__wl) { } template<typename _Func> discrete_distribution(size_t __nw, double __xmin, double __xmax, _Func __fw) : _M_param(__nw, __xmin, __xmax, __fw) { } explicit discrete_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns the probabilities of the distribution. */ std::vector<double> probabilities() const { return _M_param._M_prob.empty() ? std::vector<double>(1, 1.0) : _M_param._M_prob; } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return result_type(0); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return _M_param._M_prob.empty() ? result_type(0) : result_type(_M_param._M_prob.size() - 1); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two discrete distributions have the same * parameters. */ friend bool operator==(const discrete_distribution& __d1, const discrete_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %discrete_distribution random number distribution * @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %discrete_distribution random number distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _IntType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::discrete_distribution<_IntType1>& __x); /** * @brief Extracts a %discrete_distribution random number distribution * @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %discrete_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error * state. */ template<typename _IntType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::discrete_distribution<_IntType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two discrete distributions have different * parameters. */ template<typename _IntType> inline bool operator!=(const std::discrete_distribution<_IntType>& __d1, const std::discrete_distribution<_IntType>& __d2) { return !(__d1 == __d2); } /** * @brief A piecewise_constant_distribution random number distribution. * * The formula for the piecewise constant probability mass function is * */ template<typename _RealType = double> class piecewise_constant_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef piecewise_constant_distribution<_RealType> distribution_type; friend class piecewise_constant_distribution<_RealType>; param_type() : _M_int(), _M_den(), _M_cp() { } template<typename _InputIteratorB, typename _InputIteratorW> param_type(_InputIteratorB __bfirst, _InputIteratorB __bend, _InputIteratorW __wbegin); template<typename _Func> param_type(initializer_list<_RealType> __bi, _Func __fw); template<typename _Func> param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw); // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/ param_type(const param_type&) = default; param_type& operator=(const param_type&) = default; std::vector<_RealType> intervals() const { if (_M_int.empty()) { std::vector<_RealType> __tmp(2); __tmp[1] = _RealType(1); return __tmp; } else return _M_int; } std::vector<double> densities() const { return _M_den.empty() ? std::vector<double>(1, 1.0) : _M_den; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); std::vector<_RealType> _M_int; std::vector<double> _M_den; std::vector<double> _M_cp; }; explicit piecewise_constant_distribution() : _M_param() { } template<typename _InputIteratorB, typename _InputIteratorW> piecewise_constant_distribution(_InputIteratorB __bfirst, _InputIteratorB __bend, _InputIteratorW __wbegin) : _M_param(__bfirst, __bend, __wbegin) { } template<typename _Func> piecewise_constant_distribution(initializer_list<_RealType> __bl, _Func __fw) : _M_param(__bl, __fw) { } template<typename _Func> piecewise_constant_distribution(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw) : _M_param(__nw, __xmin, __xmax, __fw) { } explicit piecewise_constant_distribution(const param_type& __p) : _M_param(__p) { } /** * @brief Resets the distribution state. */ void reset() { } /** * @brief Returns a vector of the intervals. */ std::vector<_RealType> intervals() const { if (_M_param._M_int.empty()) { std::vector<_RealType> __tmp(2); __tmp[1] = _RealType(1); return __tmp; } else return _M_param._M_int; } /** * @brief Returns a vector of the probability densities. */ std::vector<double> densities() const { return _M_param._M_den.empty() ? std::vector<double>(1, 1.0) : _M_param._M_den; } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return _M_param._M_int.empty() ? result_type(0) : _M_param._M_int.front(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return _M_param._M_int.empty() ? result_type(1) : _M_param._M_int.back(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two piecewise constant distributions have the * same parameters. */ friend bool operator==(const piecewise_constant_distribution& __d1, const piecewise_constant_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %piecewise_constant_distribution random * number distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %piecewise_constant_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::piecewise_constant_distribution<_RealType1>& __x); /** * @brief Extracts a %piecewise_constant_distribution random * number distribution @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %piecewise_constant_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error * state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::piecewise_constant_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two piecewise constant distributions have * different parameters. */ template<typename _RealType> inline bool operator!=(const std::piecewise_constant_distribution<_RealType>& __d1, const std::piecewise_constant_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /** * @brief A piecewise_linear_distribution random number distribution. * * The formula for the piecewise linear probability mass function is * */ template<typename _RealType = double> class piecewise_linear_distribution { static_assert(std::is_floating_point<_RealType>::value, "result_type must be a floating point type"); public: /** The type of the range of the distribution. */ typedef _RealType result_type; /** Parameter type. */ struct param_type { typedef piecewise_linear_distribution<_RealType> distribution_type; friend class piecewise_linear_distribution<_RealType>; param_type() : _M_int(), _M_den(), _M_cp(), _M_m() { } template<typename _InputIteratorB, typename _InputIteratorW> param_type(_InputIteratorB __bfirst, _InputIteratorB __bend, _InputIteratorW __wbegin); template<typename _Func> param_type(initializer_list<_RealType> __bl, _Func __fw); template<typename _Func> param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw); // See: http://cpp-next.com/archive/2010/10/implicit-move-must-go/ param_type(const param_type&) = default; param_type& operator=(const param_type&) = default; std::vector<_RealType> intervals() const { if (_M_int.empty()) { std::vector<_RealType> __tmp(2); __tmp[1] = _RealType(1); return __tmp; } else return _M_int; } std::vector<double> densities() const { return _M_den.empty() ? std::vector<double>(2, 1.0) : _M_den; } friend bool operator==(const param_type& __p1, const param_type& __p2) { return __p1._M_int == __p2._M_int && __p1._M_den == __p2._M_den; } friend bool operator!=(const param_type& __p1, const param_type& __p2) { return !(__p1 == __p2); } private: void _M_initialize(); std::vector<_RealType> _M_int; std::vector<double> _M_den; std::vector<double> _M_cp; std::vector<double> _M_m; }; explicit piecewise_linear_distribution() : _M_param() { } template<typename _InputIteratorB, typename _InputIteratorW> piecewise_linear_distribution(_InputIteratorB __bfirst, _InputIteratorB __bend, _InputIteratorW __wbegin) : _M_param(__bfirst, __bend, __wbegin) { } template<typename _Func> piecewise_linear_distribution(initializer_list<_RealType> __bl, _Func __fw) : _M_param(__bl, __fw) { } template<typename _Func> piecewise_linear_distribution(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw) : _M_param(__nw, __xmin, __xmax, __fw) { } explicit piecewise_linear_distribution(const param_type& __p) : _M_param(__p) { } /** * Resets the distribution state. */ void reset() { } /** * @brief Return the intervals of the distribution. */ std::vector<_RealType> intervals() const { if (_M_param._M_int.empty()) { std::vector<_RealType> __tmp(2); __tmp[1] = _RealType(1); return __tmp; } else return _M_param._M_int; } /** * @brief Return a vector of the probability densities of the * distribution. */ std::vector<double> densities() const { return _M_param._M_den.empty() ? std::vector<double>(2, 1.0) : _M_param._M_den; } /** * @brief Returns the parameter set of the distribution. */ param_type param() const { return _M_param; } /** * @brief Sets the parameter set of the distribution. * @param __param The new parameter set of the distribution. */ void param(const param_type& __param) { _M_param = __param; } /** * @brief Returns the greatest lower bound value of the distribution. */ result_type min() const { return _M_param._M_int.empty() ? result_type(0) : _M_param._M_int.front(); } /** * @brief Returns the least upper bound value of the distribution. */ result_type max() const { return _M_param._M_int.empty() ? result_type(1) : _M_param._M_int.back(); } /** * @brief Generating functions. */ template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng) { return this->operator()(__urng, _M_param); } template<typename _UniformRandomNumberGenerator> result_type operator()(_UniformRandomNumberGenerator& __urng, const param_type& __p); template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng) { this->__generate(__f, __t, __urng, _M_param); } template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } template<typename _UniformRandomNumberGenerator> void __generate(result_type* __f, result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __p) { this->__generate_impl(__f, __t, __urng, __p); } /** * @brief Return true if two piecewise linear distributions have the * same parameters. */ friend bool operator==(const piecewise_linear_distribution& __d1, const piecewise_linear_distribution& __d2) { return __d1._M_param == __d2._M_param; } /** * @brief Inserts a %piecewise_linear_distribution random number * distribution @p __x into the output stream @p __os. * * @param __os An output stream. * @param __x A %piecewise_linear_distribution random number * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const std::piecewise_linear_distribution<_RealType1>& __x); /** * @brief Extracts a %piecewise_linear_distribution random number * distribution @p __x from the input stream @p __is. * * @param __is An input stream. * @param __x A %piecewise_linear_distribution random number * generator engine. * * @returns The input stream with @p __x extracted or in an error * state. */ template<typename _RealType1, typename _CharT, typename _Traits> friend std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, std::piecewise_linear_distribution<_RealType1>& __x); private: template<typename _ForwardIterator, typename _UniformRandomNumberGenerator> void __generate_impl(_ForwardIterator __f, _ForwardIterator __t, _UniformRandomNumberGenerator& __urng, const param_type& __p); param_type _M_param; }; /** * @brief Return true if two piecewise linear distributions have * different parameters. */ template<typename _RealType> inline bool operator!=(const std::piecewise_linear_distribution<_RealType>& __d1, const std::piecewise_linear_distribution<_RealType>& __d2) { return !(__d1 == __d2); } /* @} */ // group random_distributions_poisson /* @} */ // group random_distributions /** * @addtogroup random_utilities Random Number Utilities * @ingroup random * @{ */ /** * @brief The seed_seq class generates sequences of seeds for random * number generators. */ class seed_seq { public: /** The type of the seed vales. */ typedef uint_least32_t result_type; /** Default constructor. */ seed_seq() noexcept : _M_v() { } template<typename _IntType> seed_seq(std::initializer_list<_IntType> __il); template<typename _InputIterator> seed_seq(_InputIterator __begin, _InputIterator __end); // generating functions template<typename _RandomAccessIterator> void generate(_RandomAccessIterator __begin, _RandomAccessIterator __end); // property functions size_t size() const noexcept { return _M_v.size(); } template<typename _OutputIterator> void param(_OutputIterator __dest) const { std::copy(_M_v.begin(), _M_v.end(), __dest); } // no copy functions seed_seq(const seed_seq&) = delete; seed_seq& operator=(const seed_seq&) = delete; private: std::vector<result_type> _M_v; }; /* @} */ // group random_utilities /* @} */ // group random _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/shared_ptr.h 0000644 00000055611 15146341150 0010540 0 ustar 00 // shared_ptr and weak_ptr implementation -*- C++ -*- // Copyright (C) 2007-2018 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/>. // GCC Note: Based on files from version 1.32.0 of the Boost library. // shared_count.hpp // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. // shared_ptr.hpp // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. // Copyright (C) 2001, 2002, 2003 Peter Dimov // weak_ptr.hpp // Copyright (C) 2001, 2002, 2003 Peter Dimov // enable_shared_from_this.hpp // Copyright (C) 2002 Peter Dimov // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) /** @file * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _SHARED_PTR_H #define _SHARED_PTR_H 1 #include <bits/shared_ptr_base.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup pointer_abstractions * @{ */ /// 20.7.2.2.11 shared_ptr I/O template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> inline std::basic_ostream<_Ch, _Tr>& operator<<(std::basic_ostream<_Ch, _Tr>& __os, const __shared_ptr<_Tp, _Lp>& __p) { __os << __p.get(); return __os; } template<typename _Del, typename _Tp, _Lock_policy _Lp> inline _Del* get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept { #if __cpp_rtti return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); #else return 0; #endif } /// 20.7.2.2.10 shared_ptr get_deleter template<typename _Del, typename _Tp> inline _Del* get_deleter(const shared_ptr<_Tp>& __p) noexcept { #if __cpp_rtti return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); #else return 0; #endif } /** * @brief A smart pointer with reference-counted copy semantics. * * The object pointed to is deleted when the last shared_ptr pointing to * it is destroyed or reset. */ template<typename _Tp> class shared_ptr : public __shared_ptr<_Tp> { template<typename... _Args> using _Constructible = typename enable_if< is_constructible<__shared_ptr<_Tp>, _Args...>::value >::type; template<typename _Arg> using _Assignable = typename enable_if< is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr& >::type; public: using element_type = typename __shared_ptr<_Tp>::element_type; #if __cplusplus > 201402L # define __cpp_lib_shared_ptr_weak_type 201606 using weak_type = weak_ptr<_Tp>; #endif /** * @brief Construct an empty %shared_ptr. * @post use_count()==0 && get()==0 */ constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { } shared_ptr(const shared_ptr&) noexcept = default; /** * @brief Construct a %shared_ptr that owns the pointer @a __p. * @param __p A pointer that is convertible to element_type*. * @post use_count() == 1 && get() == __p * @throw std::bad_alloc, in which case @c delete @a __p is called. */ template<typename _Yp, typename = _Constructible<_Yp*>> explicit shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { } /** * @brief Construct a %shared_ptr that owns the pointer @a __p * and the deleter @a __d. * @param __p A pointer. * @param __d A deleter. * @post use_count() == 1 && get() == __p * @throw std::bad_alloc, in which case @a __d(__p) is called. * * Requirements: _Deleter's copy constructor and destructor must * not throw * * __shared_ptr will release __p by calling __d(__p) */ template<typename _Yp, typename _Deleter, typename = _Constructible<_Yp*, _Deleter>> shared_ptr(_Yp* __p, _Deleter __d) : __shared_ptr<_Tp>(__p, std::move(__d)) { } /** * @brief Construct a %shared_ptr that owns a null pointer * and the deleter @a __d. * @param __p A null pointer constant. * @param __d A deleter. * @post use_count() == 1 && get() == __p * @throw std::bad_alloc, in which case @a __d(__p) is called. * * Requirements: _Deleter's copy constructor and destructor must * not throw * * The last owner will call __d(__p) */ template<typename _Deleter> shared_ptr(nullptr_t __p, _Deleter __d) : __shared_ptr<_Tp>(__p, std::move(__d)) { } /** * @brief Construct a %shared_ptr that owns the pointer @a __p * and the deleter @a __d. * @param __p A pointer. * @param __d A deleter. * @param __a An allocator. * @post use_count() == 1 && get() == __p * @throw std::bad_alloc, in which case @a __d(__p) is called. * * Requirements: _Deleter's copy constructor and destructor must * not throw _Alloc's copy constructor and destructor must not * throw. * * __shared_ptr will release __p by calling __d(__p) */ template<typename _Yp, typename _Deleter, typename _Alloc, typename = _Constructible<_Yp*, _Deleter, _Alloc>> shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } /** * @brief Construct a %shared_ptr that owns a null pointer * and the deleter @a __d. * @param __p A null pointer constant. * @param __d A deleter. * @param __a An allocator. * @post use_count() == 1 && get() == __p * @throw std::bad_alloc, in which case @a __d(__p) is called. * * Requirements: _Deleter's copy constructor and destructor must * not throw _Alloc's copy constructor and destructor must not * throw. * * The last owner will call __d(__p) */ template<typename _Deleter, typename _Alloc> shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } // Aliasing constructor /** * @brief Constructs a %shared_ptr instance that stores @a __p * and shares ownership with @a __r. * @param __r A %shared_ptr. * @param __p A pointer that will remain valid while @a *__r is valid. * @post get() == __p && use_count() == __r.use_count() * * This can be used to construct a @c shared_ptr to a sub-object * of an object managed by an existing @c shared_ptr. * * @code * shared_ptr< pair<int,int> > pii(new pair<int,int>()); * shared_ptr<int> pi(pii, &pii->first); * assert(pii.use_count() == 2); * @endcode */ template<typename _Yp> shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept : __shared_ptr<_Tp>(__r, __p) { } /** * @brief If @a __r is empty, constructs an empty %shared_ptr; * otherwise construct a %shared_ptr that shares ownership * with @a __r. * @param __r A %shared_ptr. * @post get() == __r.get() && use_count() == __r.use_count() */ template<typename _Yp, typename = _Constructible<const shared_ptr<_Yp>&>> shared_ptr(const shared_ptr<_Yp>& __r) noexcept : __shared_ptr<_Tp>(__r) { } /** * @brief Move-constructs a %shared_ptr instance from @a __r. * @param __r A %shared_ptr rvalue. * @post *this contains the old value of @a __r, @a __r is empty. */ shared_ptr(shared_ptr&& __r) noexcept : __shared_ptr<_Tp>(std::move(__r)) { } /** * @brief Move-constructs a %shared_ptr instance from @a __r. * @param __r A %shared_ptr rvalue. * @post *this contains the old value of @a __r, @a __r is empty. */ template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>> shared_ptr(shared_ptr<_Yp>&& __r) noexcept : __shared_ptr<_Tp>(std::move(__r)) { } /** * @brief Constructs a %shared_ptr that shares ownership with @a __r * and stores a copy of the pointer stored in @a __r. * @param __r A weak_ptr. * @post use_count() == __r.use_count() * @throw bad_weak_ptr when __r.expired(), * in which case the constructor has no effect. */ template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> explicit shared_ptr(const weak_ptr<_Yp>& __r) : __shared_ptr<_Tp>(__r) { } #if _GLIBCXX_USE_DEPRECATED #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>> shared_ptr(auto_ptr<_Yp>&& __r); #pragma GCC diagnostic pop #endif // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2399. shared_ptr's constructor from unique_ptr should be constrained template<typename _Yp, typename _Del, typename = _Constructible<unique_ptr<_Yp, _Del>>> shared_ptr(unique_ptr<_Yp, _Del>&& __r) : __shared_ptr<_Tp>(std::move(__r)) { } #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED // This non-standard constructor exists to support conversions that // were possible in C++11 and C++14 but are ill-formed in C++17. // If an exception is thrown this constructor has no effect. template<typename _Yp, typename _Del, _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0> shared_ptr(unique_ptr<_Yp, _Del>&& __r) : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { } #endif /** * @brief Construct an empty %shared_ptr. * @post use_count() == 0 && get() == nullptr */ constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } shared_ptr& operator=(const shared_ptr&) noexcept = default; template<typename _Yp> _Assignable<const shared_ptr<_Yp>&> operator=(const shared_ptr<_Yp>& __r) noexcept { this->__shared_ptr<_Tp>::operator=(__r); return *this; } #if _GLIBCXX_USE_DEPRECATED #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" template<typename _Yp> _Assignable<auto_ptr<_Yp>> operator=(auto_ptr<_Yp>&& __r) { this->__shared_ptr<_Tp>::operator=(std::move(__r)); return *this; } #pragma GCC diagnostic pop #endif shared_ptr& operator=(shared_ptr&& __r) noexcept { this->__shared_ptr<_Tp>::operator=(std::move(__r)); return *this; } template<class _Yp> _Assignable<shared_ptr<_Yp>> operator=(shared_ptr<_Yp>&& __r) noexcept { this->__shared_ptr<_Tp>::operator=(std::move(__r)); return *this; } template<typename _Yp, typename _Del> _Assignable<unique_ptr<_Yp, _Del>> operator=(unique_ptr<_Yp, _Del>&& __r) { this->__shared_ptr<_Tp>::operator=(std::move(__r)); return *this; } private: // This constructor is non-standard, it is used by allocate_shared. template<typename _Alloc, typename... _Args> shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...) { } template<typename _Yp, typename _Alloc, typename... _Args> friend shared_ptr<_Yp> allocate_shared(const _Alloc& __a, _Args&&... __args); // This constructor is non-standard, it is used by weak_ptr::lock(). shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) : __shared_ptr<_Tp>(__r, std::nothrow) { } friend class weak_ptr<_Tp>; }; #if __cpp_deduction_guides >= 201606 template<typename _Tp> shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; template<typename _Tp, typename _Del> shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>; #endif // 20.7.2.2.7 shared_ptr comparisons template<typename _Tp, typename _Up> inline bool operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { return __a.get() == __b.get(); } template<typename _Tp> inline bool operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { return !__a; } template<typename _Tp> inline bool operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { return !__a; } template<typename _Tp, typename _Up> inline bool operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { return __a.get() != __b.get(); } template<typename _Tp> inline bool operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { return (bool)__a; } template<typename _Tp> inline bool operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { return (bool)__a; } template<typename _Tp, typename _Up> inline bool operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { using _Tp_elt = typename shared_ptr<_Tp>::element_type; using _Up_elt = typename shared_ptr<_Up>::element_type; using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; return less<_Vp>()(__a.get(), __b.get()); } template<typename _Tp> inline bool operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { using _Tp_elt = typename shared_ptr<_Tp>::element_type; return less<_Tp_elt*>()(__a.get(), nullptr); } template<typename _Tp> inline bool operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { using _Tp_elt = typename shared_ptr<_Tp>::element_type; return less<_Tp_elt*>()(nullptr, __a.get()); } template<typename _Tp, typename _Up> inline bool operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { return !(__b < __a); } template<typename _Tp> inline bool operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { return !(nullptr < __a); } template<typename _Tp> inline bool operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { return !(__a < nullptr); } template<typename _Tp, typename _Up> inline bool operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { return (__b < __a); } template<typename _Tp> inline bool operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { return nullptr < __a; } template<typename _Tp> inline bool operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { return __a < nullptr; } template<typename _Tp, typename _Up> inline bool operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept { return !(__a < __b); } template<typename _Tp> inline bool operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept { return !(__a < nullptr); } template<typename _Tp> inline bool operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept { return !(nullptr < __a); } template<typename _Tp> struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> { }; // 20.7.2.2.8 shared_ptr specialized algorithms. template<typename _Tp> inline void swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept { __a.swap(__b); } // 20.7.2.2.9 shared_ptr casts. template<typename _Tp, typename _Up> inline shared_ptr<_Tp> static_pointer_cast(const shared_ptr<_Up>& __r) noexcept { using _Sp = shared_ptr<_Tp>; return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get())); } template<typename _Tp, typename _Up> inline shared_ptr<_Tp> const_pointer_cast(const shared_ptr<_Up>& __r) noexcept { using _Sp = shared_ptr<_Tp>; return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get())); } template<typename _Tp, typename _Up> inline shared_ptr<_Tp> dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept { using _Sp = shared_ptr<_Tp>; if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get())) return _Sp(__r, __p); return _Sp(); } #if __cplusplus > 201402L template<typename _Tp, typename _Up> inline shared_ptr<_Tp> reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept { using _Sp = shared_ptr<_Tp>; return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get())); } #endif /** * @brief A smart pointer with weak semantics. * * With forwarding constructors and assignment operators. */ template<typename _Tp> class weak_ptr : public __weak_ptr<_Tp> { template<typename _Arg> using _Constructible = typename enable_if< is_constructible<__weak_ptr<_Tp>, _Arg>::value >::type; template<typename _Arg> using _Assignable = typename enable_if< is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr& >::type; public: constexpr weak_ptr() noexcept = default; template<typename _Yp, typename = _Constructible<const shared_ptr<_Yp>&>> weak_ptr(const shared_ptr<_Yp>& __r) noexcept : __weak_ptr<_Tp>(__r) { } weak_ptr(const weak_ptr&) noexcept = default; template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> weak_ptr(const weak_ptr<_Yp>& __r) noexcept : __weak_ptr<_Tp>(__r) { } weak_ptr(weak_ptr&&) noexcept = default; template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>> weak_ptr(weak_ptr<_Yp>&& __r) noexcept : __weak_ptr<_Tp>(std::move(__r)) { } weak_ptr& operator=(const weak_ptr& __r) noexcept = default; template<typename _Yp> _Assignable<const weak_ptr<_Yp>&> operator=(const weak_ptr<_Yp>& __r) noexcept { this->__weak_ptr<_Tp>::operator=(__r); return *this; } template<typename _Yp> _Assignable<const shared_ptr<_Yp>&> operator=(const shared_ptr<_Yp>& __r) noexcept { this->__weak_ptr<_Tp>::operator=(__r); return *this; } weak_ptr& operator=(weak_ptr&& __r) noexcept = default; template<typename _Yp> _Assignable<weak_ptr<_Yp>> operator=(weak_ptr<_Yp>&& __r) noexcept { this->__weak_ptr<_Tp>::operator=(std::move(__r)); return *this; } shared_ptr<_Tp> lock() const noexcept { return shared_ptr<_Tp>(*this, std::nothrow); } }; #if __cpp_deduction_guides >= 201606 template<typename _Tp> weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; #endif // 20.7.2.3.6 weak_ptr specialized algorithms. template<typename _Tp> inline void swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept { __a.swap(__b); } /// Primary template owner_less template<typename _Tp = void> struct owner_less; /// Void specialization of owner_less template<> struct owner_less<void> : _Sp_owner_less<void, void> { }; /// Partial specialization of owner_less for shared_ptr. template<typename _Tp> struct owner_less<shared_ptr<_Tp>> : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> { }; /// Partial specialization of owner_less for weak_ptr. template<typename _Tp> struct owner_less<weak_ptr<_Tp>> : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> { }; /** * @brief Base class allowing use of member function shared_from_this. */ template<typename _Tp> class enable_shared_from_this { protected: constexpr enable_shared_from_this() noexcept { } enable_shared_from_this(const enable_shared_from_this&) noexcept { } enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept { return *this; } ~enable_shared_from_this() { } public: shared_ptr<_Tp> shared_from_this() { return shared_ptr<_Tp>(this->_M_weak_this); } shared_ptr<const _Tp> shared_from_this() const { return shared_ptr<const _Tp>(this->_M_weak_this); } #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 #define __cpp_lib_enable_shared_from_this 201603 weak_ptr<_Tp> weak_from_this() noexcept { return this->_M_weak_this; } weak_ptr<const _Tp> weak_from_this() const noexcept { return this->_M_weak_this; } #endif private: template<typename _Tp1> void _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept { _M_weak_this._M_assign(__p, __n); } // Found by ADL when this is an associated class. friend const enable_shared_from_this* __enable_shared_from_this_base(const __shared_count<>&, const enable_shared_from_this* __p) { return __p; } template<typename, _Lock_policy> friend class __shared_ptr; mutable weak_ptr<_Tp> _M_weak_this; }; /** * @brief Create an object that is owned by a shared_ptr. * @param __a An allocator. * @param __args Arguments for the @a _Tp object's constructor. * @return A shared_ptr that owns the newly created object. * @throw An exception thrown from @a _Alloc::allocate or from the * constructor of @a _Tp. * * A copy of @a __a will be used to allocate memory for the shared_ptr * and the new object. */ template<typename _Tp, typename _Alloc, typename... _Args> inline shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&&... __args) { static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported"); return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a}, std::forward<_Args>(__args)...); } /** * @brief Create an object that is owned by a shared_ptr. * @param __args Arguments for the @a _Tp object's constructor. * @return A shared_ptr that owns the newly created object. * @throw std::bad_alloc, or an exception thrown from the * constructor of @a _Tp. */ template<typename _Tp, typename... _Args> inline shared_ptr<_Tp> make_shared(_Args&&... __args) { typedef typename std::remove_cv<_Tp>::type _Tp_nc; return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), std::forward<_Args>(__args)...); } /// std::hash specialization for shared_ptr. template<typename _Tp> struct hash<shared_ptr<_Tp>> : public __hash_base<size_t, shared_ptr<_Tp>> { size_t operator()(const shared_ptr<_Tp>& __s) const noexcept { return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get()); } }; // @} group pointer_abstractions _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _SHARED_PTR_H c++/8/bits/streambuf_iterator.h 0000644 00000032676 15146341150 0012314 0 ustar 00 // Streambuf iterators // Copyright (C) 1997-2018 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/streambuf_iterator.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iterator} */ #ifndef _STREAMBUF_ITERATOR_H #define _STREAMBUF_ITERATOR_H 1 #pragma GCC system_header #include <streambuf> #include <debug/debug.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup iterators * @{ */ // 24.5.3 Template class istreambuf_iterator /// Provides input iterator semantics for streambufs. template<typename _CharT, typename _Traits> class istreambuf_iterator : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, _CharT*, #if __cplusplus >= 201103L // LWG 445. _CharT> #else _CharT&> #endif { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef _Traits traits_type; typedef typename _Traits::int_type int_type; typedef basic_streambuf<_CharT, _Traits> streambuf_type; typedef basic_istream<_CharT, _Traits> istream_type; //@} template<typename _CharT2> friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, ostreambuf_iterator<_CharT2> >::__type copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, ostreambuf_iterator<_CharT2>); template<bool _IsMove, typename _CharT2> friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, _CharT2*>::__type __copy_move_a2(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, _CharT2*); template<typename _CharT2> friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, istreambuf_iterator<_CharT2> >::__type find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); template<typename _CharT2, typename _Distance> friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, void>::__type advance(istreambuf_iterator<_CharT2>&, _Distance); private: // 24.5.3 istreambuf_iterator // p 1 // If the end of stream is reached (streambuf_type::sgetc() // returns traits_type::eof()), the iterator becomes equal to // the "end of stream" iterator value. // NB: This implementation assumes the "end of stream" value // is EOF, or -1. mutable streambuf_type* _M_sbuf; int_type _M_c; public: /// Construct end of input stream iterator. _GLIBCXX_CONSTEXPR istreambuf_iterator() _GLIBCXX_USE_NOEXCEPT : _M_sbuf(0), _M_c(traits_type::eof()) { } #if __cplusplus >= 201103L istreambuf_iterator(const istreambuf_iterator&) noexcept = default; ~istreambuf_iterator() = default; #endif /// Construct start of input stream iterator. istreambuf_iterator(istream_type& __s) _GLIBCXX_USE_NOEXCEPT : _M_sbuf(__s.rdbuf()), _M_c(traits_type::eof()) { } /// Construct start of streambuf iterator. istreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT : _M_sbuf(__s), _M_c(traits_type::eof()) { } /// Return the current character pointed to by iterator. This returns /// streambuf.sgetc(). It cannot be assigned. NB: The result of /// operator*() on an end of stream is undefined. char_type operator*() const { int_type __c = _M_get(); #ifdef _GLIBCXX_DEBUG_PEDANTIC // Dereferencing a past-the-end istreambuf_iterator is a // libstdc++ extension __glibcxx_requires_cond(!_S_is_eof(__c), _M_message(__gnu_debug::__msg_deref_istreambuf) ._M_iterator(*this)); #endif return traits_type::to_char_type(__c); } /// Advance the iterator. Calls streambuf.sbumpc(). istreambuf_iterator& operator++() { __glibcxx_requires_cond(_M_sbuf && (!_S_is_eof(_M_c) || !_S_is_eof(_M_sbuf->sgetc())), _M_message(__gnu_debug::__msg_inc_istreambuf) ._M_iterator(*this)); _M_sbuf->sbumpc(); _M_c = traits_type::eof(); return *this; } /// Advance the iterator. Calls streambuf.sbumpc(). istreambuf_iterator operator++(int) { __glibcxx_requires_cond(_M_sbuf && (!_S_is_eof(_M_c) || !_S_is_eof(_M_sbuf->sgetc())), _M_message(__gnu_debug::__msg_inc_istreambuf) ._M_iterator(*this)); istreambuf_iterator __old = *this; __old._M_c = _M_sbuf->sbumpc(); _M_c = traits_type::eof(); return __old; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 110 istreambuf_iterator::equal not const // NB: there is also number 111 (NAD) relevant to this function. /// Return true both iterators are end or both are not end. bool equal(const istreambuf_iterator& __b) const { return _M_at_eof() == __b._M_at_eof(); } private: int_type _M_get() const { int_type __ret = _M_c; if (_M_sbuf && _S_is_eof(__ret) && _S_is_eof(__ret = _M_sbuf->sgetc())) _M_sbuf = 0; return __ret; } bool _M_at_eof() const { return _S_is_eof(_M_get()); } static bool _S_is_eof(int_type __c) { const int_type __eof = traits_type::eof(); return traits_type::eq_int_type(__c, __eof); } }; template<typename _CharT, typename _Traits> inline bool operator==(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { return __a.equal(__b); } template<typename _CharT, typename _Traits> inline bool operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { return !__a.equal(__b); } /// Provides output iterator semantics for streambufs. template<typename _CharT, typename _Traits> class ostreambuf_iterator : public iterator<output_iterator_tag, void, void, void, void> { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef _Traits traits_type; typedef basic_streambuf<_CharT, _Traits> streambuf_type; typedef basic_ostream<_CharT, _Traits> ostream_type; //@} template<typename _CharT2> friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, ostreambuf_iterator<_CharT2> >::__type copy(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, ostreambuf_iterator<_CharT2>); private: streambuf_type* _M_sbuf; bool _M_failed; public: /// Construct output iterator from ostream. ostreambuf_iterator(ostream_type& __s) _GLIBCXX_USE_NOEXCEPT : _M_sbuf(__s.rdbuf()), _M_failed(!_M_sbuf) { } /// Construct output iterator from streambuf. ostreambuf_iterator(streambuf_type* __s) _GLIBCXX_USE_NOEXCEPT : _M_sbuf(__s), _M_failed(!_M_sbuf) { } /// Write character to streambuf. Calls streambuf.sputc(). ostreambuf_iterator& operator=(_CharT __c) { if (!_M_failed && _Traits::eq_int_type(_M_sbuf->sputc(__c), _Traits::eof())) _M_failed = true; return *this; } /// Return *this. ostreambuf_iterator& operator*() { return *this; } /// Return *this. ostreambuf_iterator& operator++(int) { return *this; } /// Return *this. ostreambuf_iterator& operator++() { return *this; } /// Return true if previous operator=() failed. bool failed() const _GLIBCXX_USE_NOEXCEPT { return _M_failed; } ostreambuf_iterator& _M_put(const _CharT* __ws, streamsize __len) { if (__builtin_expect(!_M_failed, true) && __builtin_expect(this->_M_sbuf->sputn(__ws, __len) != __len, false)) _M_failed = true; return *this; } }; // Overloads for streambuf iterators. template<typename _CharT> typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, ostreambuf_iterator<_CharT> >::__type copy(istreambuf_iterator<_CharT> __first, istreambuf_iterator<_CharT> __last, ostreambuf_iterator<_CharT> __result) { if (__first._M_sbuf && !__last._M_sbuf && !__result._M_failed) { bool __ineof; __copy_streambufs_eof(__first._M_sbuf, __result._M_sbuf, __ineof); if (!__ineof) __result._M_failed = true; } return __result; } template<bool _IsMove, typename _CharT> typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, ostreambuf_iterator<_CharT> >::__type __copy_move_a2(_CharT* __first, _CharT* __last, ostreambuf_iterator<_CharT> __result) { const streamsize __num = __last - __first; if (__num > 0) __result._M_put(__first, __num); return __result; } template<bool _IsMove, typename _CharT> typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, ostreambuf_iterator<_CharT> >::__type __copy_move_a2(const _CharT* __first, const _CharT* __last, ostreambuf_iterator<_CharT> __result) { const streamsize __num = __last - __first; if (__num > 0) __result._M_put(__first, __num); return __result; } template<bool _IsMove, typename _CharT> typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, _CharT*>::__type __copy_move_a2(istreambuf_iterator<_CharT> __first, istreambuf_iterator<_CharT> __last, _CharT* __result) { typedef istreambuf_iterator<_CharT> __is_iterator_type; typedef typename __is_iterator_type::traits_type traits_type; typedef typename __is_iterator_type::streambuf_type streambuf_type; typedef typename traits_type::int_type int_type; if (__first._M_sbuf && !__last._M_sbuf) { streambuf_type* __sb = __first._M_sbuf; int_type __c = __sb->sgetc(); while (!traits_type::eq_int_type(__c, traits_type::eof())) { const streamsize __n = __sb->egptr() - __sb->gptr(); if (__n > 1) { traits_type::copy(__result, __sb->gptr(), __n); __sb->__safe_gbump(__n); __result += __n; __c = __sb->underflow(); } else { *__result++ = traits_type::to_char_type(__c); __c = __sb->snextc(); } } } return __result; } template<typename _CharT> typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, istreambuf_iterator<_CharT> >::__type find(istreambuf_iterator<_CharT> __first, istreambuf_iterator<_CharT> __last, const _CharT& __val) { typedef istreambuf_iterator<_CharT> __is_iterator_type; typedef typename __is_iterator_type::traits_type traits_type; typedef typename __is_iterator_type::streambuf_type streambuf_type; typedef typename traits_type::int_type int_type; const int_type __eof = traits_type::eof(); if (__first._M_sbuf && !__last._M_sbuf) { const int_type __ival = traits_type::to_int_type(__val); streambuf_type* __sb = __first._M_sbuf; int_type __c = __sb->sgetc(); while (!traits_type::eq_int_type(__c, __eof) && !traits_type::eq_int_type(__c, __ival)) { streamsize __n = __sb->egptr() - __sb->gptr(); if (__n > 1) { const _CharT* __p = traits_type::find(__sb->gptr(), __n, __val); if (__p) __n = __p - __sb->gptr(); __sb->__safe_gbump(__n); __c = __sb->sgetc(); } else __c = __sb->snextc(); } __first._M_c = __eof; } return __first; } template<typename _CharT, typename _Distance> typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, void>::__type advance(istreambuf_iterator<_CharT>& __i, _Distance __n) { if (__n == 0) return; __glibcxx_assert(__n > 0); __glibcxx_requires_cond(!__i._M_at_eof(), _M_message(__gnu_debug::__msg_inc_istreambuf) ._M_iterator(__i)); typedef istreambuf_iterator<_CharT> __is_iterator_type; typedef typename __is_iterator_type::traits_type traits_type; typedef typename __is_iterator_type::streambuf_type streambuf_type; typedef typename traits_type::int_type int_type; const int_type __eof = traits_type::eof(); streambuf_type* __sb = __i._M_sbuf; while (__n > 0) { streamsize __size = __sb->egptr() - __sb->gptr(); if (__size > __n) { __sb->__safe_gbump(__n); break; } __sb->__safe_gbump(__size); __n -= __size; if (traits_type::eq_int_type(__sb->underflow(), __eof)) { __glibcxx_requires_cond(__n == 0, _M_message(__gnu_debug::__msg_inc_istreambuf) ._M_iterator(__i)); break; } } __i._M_c = __eof; } // @} group iterators _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/bits/forward_list.tcc 0000644 00000031561 15146341150 0011424 0 ustar 00 // <forward_list.tcc> -*- C++ -*- // Copyright (C) 2008-2018 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)); } template<typename _Tp, typename _Alloc> void forward_list<_Tp, _Alloc>:: remove(const _Tp& __val) { _Node_base* __curr = &this->_M_impl._M_head; _Node_base* __extra = nullptr; while (_Node* __tmp = static_cast<_Node*>(__curr->_M_next)) { if (*__tmp->_M_valptr() == __val) { if (__tmp->_M_valptr() != std::__addressof(__val)) { this->_M_erase_after(__curr); continue; } else __extra = __curr; } __curr = __curr->_M_next; } if (__extra) this->_M_erase_after(__extra); } template<typename _Tp, typename _Alloc> template<typename _Pred> void forward_list<_Tp, _Alloc>:: remove_if(_Pred __pred) { _Node_base* __curr = &this->_M_impl._M_head; while (_Node* __tmp = static_cast<_Node*>(__curr->_M_next)) { if (__pred(*__tmp->_M_valptr())) this->_M_erase_after(__curr); else __curr = __curr->_M_next; } } template<typename _Tp, typename _Alloc> template<typename _BinPred> void forward_list<_Tp, _Alloc>:: unique(_BinPred __binary_pred) { iterator __first = begin(); iterator __last = end(); if (__first == __last) return; iterator __next = __first; while (++__next != __last) { if (__binary_pred(*__first, *__next)) erase_after(__first); else __first = __next; __next = __first; } } template<typename _Tp, typename _Alloc> template<typename _Comp> void forward_list<_Tp, _Alloc>:: merge(forward_list&& __list, _Comp __comp) { _Node_base* __node = &this->_M_impl._M_head; while (__node->_M_next && __list._M_impl._M_head._M_next) { if (__comp(*static_cast<_Node*> (__list._M_impl._M_head._M_next)->_M_valptr(), *static_cast<_Node*> (__node->_M_next)->_M_valptr())) __node->_M_transfer_after(&__list._M_impl._M_head, __list._M_impl._M_head._M_next); __node = __node->_M_next; } if (__list._M_impl._M_head._M_next) *__node = std::move(__list._M_impl._M_head); } template<typename _Tp, typename _Alloc> bool operator==(const forward_list<_Tp, _Alloc>& __lx, const forward_list<_Tp, _Alloc>& __ly) { // We don't have size() so we need to walk through both lists // making sure both iterators are valid. auto __ix = __lx.cbegin(); auto __iy = __ly.cbegin(); while (__ix != __lx.cend() && __iy != __ly.cend()) { if (!(*__ix == *__iy)) return false; ++__ix; ++__iy; } if (__ix == __lx.cend() && __iy == __ly.cend()) return true; else return false; } template<typename _Tp, class _Alloc> template<typename _Comp> void forward_list<_Tp, _Alloc>:: sort(_Comp __comp) { // If `next' is nullptr, return immediately. _Node* __list = static_cast<_Node*>(this->_M_impl._M_head._M_next); if (!__list) return; unsigned long __insize = 1; while (1) { _Node* __p = __list; __list = nullptr; _Node* __tail = nullptr; // Count number of merges we do in this pass. unsigned long __nmerges = 0; while (__p) { ++__nmerges; // There exists a merge to be done. // Step `insize' places along from p. _Node* __q = __p; unsigned long __psize = 0; for (unsigned long __i = 0; __i < __insize; ++__i) { ++__psize; __q = static_cast<_Node*>(__q->_M_next); if (!__q) break; } // If q hasn't fallen off end, we have two lists to merge. unsigned long __qsize = __insize; // Now we have two lists; merge them. while (__psize > 0 || (__qsize > 0 && __q)) { // Decide whether next node of merge comes from p or q. _Node* __e; if (__psize == 0) { // p is empty; e must come from q. __e = __q; __q = static_cast<_Node*>(__q->_M_next); --__qsize; } else if (__qsize == 0 || !__q) { // q is empty; e must come from p. __e = __p; __p = static_cast<_Node*>(__p->_M_next); --__psize; } else if (!__comp(*__q->_M_valptr(), *__p->_M_valptr())) { // First node of q is not lower; e must come from p. __e = __p; __p = static_cast<_Node*>(__p->_M_next); --__psize; } else { // First node of q is lower; e must come from q. __e = __q; __q = static_cast<_Node*>(__q->_M_next); --__qsize; } // Add the next node to the merged list. if (__tail) __tail->_M_next = __e; else __list = __e; __tail = __e; } // Now p has stepped `insize' places along, and q has too. __p = __q; } __tail->_M_next = nullptr; // If we have done only one merge, we're finished. // Allow for nmerges == 0, the empty list case. if (__nmerges <= 1) { this->_M_impl._M_head._M_next = __list; return; } // Otherwise repeat, merging lists twice the size. __insize *= 2; } } _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _FORWARD_LIST_TCC */ c++/8/bits/exception_defines.h 0000644 00000003155 15146341150 0012074 0 ustar 00 // -fno-exceptions Support -*- C++ -*- // Copyright (C) 2001-2018 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 c++/8/bits/locale_facets.tcc 0000644 00000115174 15146341150 0011514 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 1997-2018 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/locale_facets.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ #ifndef _LOCALE_FACETS_TCC #define _LOCALE_FACETS_TCC 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Routine to access a cache for the facet. If the cache didn't // exist before, it gets constructed on the fly. template<typename _Facet> struct __use_cache { const _Facet* operator() (const locale& __loc) const; }; // Specializations. template<typename _CharT> struct __use_cache<__numpunct_cache<_CharT> > { const __numpunct_cache<_CharT>* operator() (const locale& __loc) const { const size_t __i = numpunct<_CharT>::id._M_id(); const locale::facet** __caches = __loc._M_impl->_M_caches; if (!__caches[__i]) { __numpunct_cache<_CharT>* __tmp = 0; __try { __tmp = new __numpunct_cache<_CharT>; __tmp->_M_cache(__loc); } __catch(...) { delete __tmp; __throw_exception_again; } __loc._M_impl->_M_install_cache(__tmp, __i); } return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]); } }; template<typename _CharT> void __numpunct_cache<_CharT>::_M_cache(const locale& __loc) { const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); char* __grouping = 0; _CharT* __truename = 0; _CharT* __falsename = 0; __try { const string& __g = __np.grouping(); _M_grouping_size = __g.size(); __grouping = new char[_M_grouping_size]; __g.copy(__grouping, _M_grouping_size); _M_use_grouping = (_M_grouping_size && static_cast<signed char>(__grouping[0]) > 0 && (__grouping[0] != __gnu_cxx::__numeric_traits<char>::__max)); const basic_string<_CharT>& __tn = __np.truename(); _M_truename_size = __tn.size(); __truename = new _CharT[_M_truename_size]; __tn.copy(__truename, _M_truename_size); const basic_string<_CharT>& __fn = __np.falsename(); _M_falsename_size = __fn.size(); __falsename = new _CharT[_M_falsename_size]; __fn.copy(__falsename, _M_falsename_size); _M_decimal_point = __np.decimal_point(); _M_thousands_sep = __np.thousands_sep(); const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); __ct.widen(__num_base::_S_atoms_out, __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out); __ct.widen(__num_base::_S_atoms_in, __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in); _M_grouping = __grouping; _M_truename = __truename; _M_falsename = __falsename; _M_allocated = true; } __catch(...) { delete [] __grouping; delete [] __truename; delete [] __falsename; __throw_exception_again; } } // Used by both numeric and monetary facets. // Check to make sure that the __grouping_tmp string constructed in // money_get or num_get matches the canonical grouping for a given // locale. // __grouping_tmp is parsed L to R // 1,222,444 == __grouping_tmp of "\1\3\3" // __grouping is parsed R to L // 1,222,444 == __grouping of "\3" == "\3\3\3" _GLIBCXX_PURE bool __verify_grouping(const char* __grouping, size_t __grouping_size, const string& __grouping_tmp) throw (); _GLIBCXX_BEGIN_NAMESPACE_LDBL template<typename _CharT, typename _InIter> _GLIBCXX_DEFAULT_ABI_TAG _InIter num_get<_CharT, _InIter>:: _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, ios_base::iostate& __err, string& __xtrc) const { typedef char_traits<_CharT> __traits_type; typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); const _CharT* __lit = __lc->_M_atoms_in; char_type __c = char_type(); // True if __beg becomes equal to __end. bool __testeof = __beg == __end; // First check for sign. if (!__testeof) { __c = *__beg; const bool __plus = __c == __lit[__num_base::_S_iplus]; if ((__plus || __c == __lit[__num_base::_S_iminus]) && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) && !(__c == __lc->_M_decimal_point)) { __xtrc += __plus ? '+' : '-'; if (++__beg != __end) __c = *__beg; else __testeof = true; } } // Next, look for leading zeros. bool __found_mantissa = false; int __sep_pos = 0; while (!__testeof) { if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) || __c == __lc->_M_decimal_point) break; else if (__c == __lit[__num_base::_S_izero]) { if (!__found_mantissa) { __xtrc += '0'; __found_mantissa = true; } ++__sep_pos; if (++__beg != __end) __c = *__beg; else __testeof = true; } else break; } // Only need acceptable digits for floating point numbers. bool __found_dec = false; bool __found_sci = false; string __found_grouping; if (__lc->_M_use_grouping) __found_grouping.reserve(32); const char_type* __lit_zero = __lit + __num_base::_S_izero; if (!__lc->_M_allocated) // "C" locale while (!__testeof) { const int __digit = _M_find(__lit_zero, 10, __c); if (__digit != -1) { __xtrc += '0' + __digit; __found_mantissa = true; } else if (__c == __lc->_M_decimal_point && !__found_dec && !__found_sci) { __xtrc += '.'; __found_dec = true; } else if ((__c == __lit[__num_base::_S_ie] || __c == __lit[__num_base::_S_iE]) && !__found_sci && __found_mantissa) { // Scientific notation. __xtrc += 'e'; __found_sci = true; // Remove optional plus or minus sign, if they exist. if (++__beg != __end) { __c = *__beg; const bool __plus = __c == __lit[__num_base::_S_iplus]; if (__plus || __c == __lit[__num_base::_S_iminus]) __xtrc += __plus ? '+' : '-'; else continue; } else { __testeof = true; break; } } else break; if (++__beg != __end) __c = *__beg; else __testeof = true; } else while (!__testeof) { // According to 22.2.2.1.2, p8-9, first look for thousands_sep // and decimal_point. if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) { if (!__found_dec && !__found_sci) { // NB: Thousands separator at the beginning of a string // is a no-no, as is two consecutive thousands separators. if (__sep_pos) { __found_grouping += static_cast<char>(__sep_pos); __sep_pos = 0; } else { // NB: __convert_to_v will not assign __v and will // set the failbit. __xtrc.clear(); break; } } else break; } else if (__c == __lc->_M_decimal_point) { if (!__found_dec && !__found_sci) { // If no grouping chars are seen, no grouping check // is applied. Therefore __found_grouping is adjusted // only if decimal_point comes after some thousands_sep. if (__found_grouping.size()) __found_grouping += static_cast<char>(__sep_pos); __xtrc += '.'; __found_dec = true; } else break; } else { const char_type* __q = __traits_type::find(__lit_zero, 10, __c); if (__q) { __xtrc += '0' + (__q - __lit_zero); __found_mantissa = true; ++__sep_pos; } else if ((__c == __lit[__num_base::_S_ie] || __c == __lit[__num_base::_S_iE]) && !__found_sci && __found_mantissa) { // Scientific notation. if (__found_grouping.size() && !__found_dec) __found_grouping += static_cast<char>(__sep_pos); __xtrc += 'e'; __found_sci = true; // Remove optional plus or minus sign, if they exist. if (++__beg != __end) { __c = *__beg; const bool __plus = __c == __lit[__num_base::_S_iplus]; if ((__plus || __c == __lit[__num_base::_S_iminus]) && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) && !(__c == __lc->_M_decimal_point)) __xtrc += __plus ? '+' : '-'; else continue; } else { __testeof = true; break; } } else break; } if (++__beg != __end) __c = *__beg; else __testeof = true; } // Digit grouping is checked. If grouping and found_grouping don't // match, then get very very upset, and set failbit. if (__found_grouping.size()) { // Add the ending grouping if a decimal or 'e'/'E' wasn't found. if (!__found_dec && !__found_sci) __found_grouping += static_cast<char>(__sep_pos); if (!std::__verify_grouping(__lc->_M_grouping, __lc->_M_grouping_size, __found_grouping)) __err = ios_base::failbit; } return __beg; } template<typename _CharT, typename _InIter> template<typename _ValueT> _GLIBCXX_DEFAULT_ABI_TAG _InIter num_get<_CharT, _InIter>:: _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, ios_base::iostate& __err, _ValueT& __v) const { typedef char_traits<_CharT> __traits_type; using __gnu_cxx::__add_unsigned; typedef typename __add_unsigned<_ValueT>::__type __unsigned_type; typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); const _CharT* __lit = __lc->_M_atoms_in; char_type __c = char_type(); // NB: Iff __basefield == 0, __base can change based on contents. const ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield; const bool __oct = __basefield == ios_base::oct; int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); // True if __beg becomes equal to __end. bool __testeof = __beg == __end; // First check for sign. bool __negative = false; if (!__testeof) { __c = *__beg; __negative = __c == __lit[__num_base::_S_iminus]; if ((__negative || __c == __lit[__num_base::_S_iplus]) && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) && !(__c == __lc->_M_decimal_point)) { if (++__beg != __end) __c = *__beg; else __testeof = true; } } // Next, look for leading zeros and check required digits // for base formats. bool __found_zero = false; int __sep_pos = 0; while (!__testeof) { if ((__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) || __c == __lc->_M_decimal_point) break; else if (__c == __lit[__num_base::_S_izero] && (!__found_zero || __base == 10)) { __found_zero = true; ++__sep_pos; if (__basefield == 0) __base = 8; if (__base == 8) __sep_pos = 0; } else if (__found_zero && (__c == __lit[__num_base::_S_ix] || __c == __lit[__num_base::_S_iX])) { if (__basefield == 0) __base = 16; if (__base == 16) { __found_zero = false; __sep_pos = 0; } else break; } else break; if (++__beg != __end) { __c = *__beg; if (!__found_zero) break; } else __testeof = true; } // At this point, base is determined. If not hex, only allow // base digits as valid input. const size_t __len = (__base == 16 ? __num_base::_S_iend - __num_base::_S_izero : __base); // Extract. typedef __gnu_cxx::__numeric_traits<_ValueT> __num_traits; string __found_grouping; if (__lc->_M_use_grouping) __found_grouping.reserve(32); bool __testfail = false; bool __testoverflow = false; const __unsigned_type __max = (__negative && __num_traits::__is_signed) ? -static_cast<__unsigned_type>(__num_traits::__min) : __num_traits::__max; const __unsigned_type __smax = __max / __base; __unsigned_type __result = 0; int __digit = 0; const char_type* __lit_zero = __lit + __num_base::_S_izero; if (!__lc->_M_allocated) // "C" locale while (!__testeof) { __digit = _M_find(__lit_zero, __len, __c); if (__digit == -1) break; if (__result > __smax) __testoverflow = true; else { __result *= __base; __testoverflow |= __result > __max - __digit; __result += __digit; ++__sep_pos; } if (++__beg != __end) __c = *__beg; else __testeof = true; } else while (!__testeof) { // According to 22.2.2.1.2, p8-9, first look for thousands_sep // and decimal_point. if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) { // NB: Thousands separator at the beginning of a string // is a no-no, as is two consecutive thousands separators. if (__sep_pos) { __found_grouping += static_cast<char>(__sep_pos); __sep_pos = 0; } else { __testfail = true; break; } } else if (__c == __lc->_M_decimal_point) break; else { const char_type* __q = __traits_type::find(__lit_zero, __len, __c); if (!__q) break; __digit = __q - __lit_zero; if (__digit > 15) __digit -= 6; if (__result > __smax) __testoverflow = true; else { __result *= __base; __testoverflow |= __result > __max - __digit; __result += __digit; ++__sep_pos; } } if (++__beg != __end) __c = *__beg; else __testeof = true; } // Digit grouping is checked. If grouping and found_grouping don't // match, then get very very upset, and set failbit. if (__found_grouping.size()) { // Add the ending grouping. __found_grouping += static_cast<char>(__sep_pos); if (!std::__verify_grouping(__lc->_M_grouping, __lc->_M_grouping_size, __found_grouping)) __err = ios_base::failbit; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 23. Num_get overflow result. if ((!__sep_pos && !__found_zero && !__found_grouping.size()) || __testfail) { __v = 0; __err = ios_base::failbit; } else if (__testoverflow) { if (__negative && __num_traits::__is_signed) __v = __num_traits::__min; else __v = __num_traits::__max; __err = ios_base::failbit; } else __v = __negative ? -__result : __result; if (__testeof) __err |= ios_base::eofbit; return __beg; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 17. Bad bool parsing template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, bool& __v) const { if (!(__io.flags() & ios_base::boolalpha)) { // Parse bool values as long. // NB: We can't just call do_get(long) here, as it might // refer to a derived class. long __l = -1; __beg = _M_extract_int(__beg, __end, __io, __err, __l); if (__l == 0 || __l == 1) __v = bool(__l); else { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 23. Num_get overflow result. __v = true; __err = ios_base::failbit; if (__beg == __end) __err |= ios_base::eofbit; } } else { // Parse bool values as alphanumeric. typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); bool __testf = true; bool __testt = true; bool __donef = __lc->_M_falsename_size == 0; bool __donet = __lc->_M_truename_size == 0; bool __testeof = false; size_t __n = 0; while (!__donef || !__donet) { if (__beg == __end) { __testeof = true; break; } const char_type __c = *__beg; if (!__donef) __testf = __c == __lc->_M_falsename[__n]; if (!__testf && __donet) break; if (!__donet) __testt = __c == __lc->_M_truename[__n]; if (!__testt && __donef) break; if (!__testt && !__testf) break; ++__n; ++__beg; __donef = !__testf || __n >= __lc->_M_falsename_size; __donet = !__testt || __n >= __lc->_M_truename_size; } if (__testf && __n == __lc->_M_falsename_size && __n) { __v = false; if (__testt && __n == __lc->_M_truename_size) __err = ios_base::failbit; else __err = __testeof ? ios_base::eofbit : ios_base::goodbit; } else if (__testt && __n == __lc->_M_truename_size && __n) { __v = true; __err = __testeof ? ios_base::eofbit : ios_base::goodbit; } else { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 23. Num_get overflow result. __v = false; __err = ios_base::failbit; if (__testeof) __err |= ios_base::eofbit; } } return __beg; } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, float& __v) const { string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); if (__beg == __end) __err |= ios_base::eofbit; return __beg; } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, double& __v) const { string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); if (__beg == __end) __err |= ios_base::eofbit; return __beg; } #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: __do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, double& __v) const { string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); if (__beg == __end) __err |= ios_base::eofbit; return __beg; } #endif template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, long double& __v) const { string __xtrc; __xtrc.reserve(32); __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); if (__beg == __end) __err |= ios_base::eofbit; return __beg; } template<typename _CharT, typename _InIter> _InIter num_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, void*& __v) const { // Prepare for hex formatted input. typedef ios_base::fmtflags fmtflags; const fmtflags __fmt = __io.flags(); __io.flags((__fmt & ~ios_base::basefield) | ios_base::hex); typedef __gnu_cxx::__conditional_type<(sizeof(void*) <= sizeof(unsigned long)), unsigned long, unsigned long long>::__type _UIntPtrType; _UIntPtrType __ul; __beg = _M_extract_int(__beg, __end, __io, __err, __ul); // Reset from hex formatted input. __io.flags(__fmt); __v = reinterpret_cast<void*>(__ul); return __beg; } // For use by integer and floating-point types after they have been // converted into a char_type string. template<typename _CharT, typename _OutIter> void num_put<_CharT, _OutIter>:: _M_pad(_CharT __fill, streamsize __w, ios_base& __io, _CharT* __new, const _CharT* __cs, int& __len) const { // [22.2.2.2.2] Stage 3. // If necessary, pad. __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, __w, __len); __len = static_cast<int>(__w); } _GLIBCXX_END_NAMESPACE_LDBL template<typename _CharT, typename _ValueT> int __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit, ios_base::fmtflags __flags, bool __dec) { _CharT* __buf = __bufend; if (__builtin_expect(__dec, true)) { // Decimal. do { *--__buf = __lit[(__v % 10) + __num_base::_S_odigits]; __v /= 10; } while (__v != 0); } else if ((__flags & ios_base::basefield) == ios_base::oct) { // Octal. do { *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits]; __v >>= 3; } while (__v != 0); } else { // Hex. const bool __uppercase = __flags & ios_base::uppercase; const int __case_offset = __uppercase ? __num_base::_S_oudigits : __num_base::_S_odigits; do { *--__buf = __lit[(__v & 0xf) + __case_offset]; __v >>= 4; } while (__v != 0); } return __bufend - __buf; } _GLIBCXX_BEGIN_NAMESPACE_LDBL template<typename _CharT, typename _OutIter> void num_put<_CharT, _OutIter>:: _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep, ios_base&, _CharT* __new, _CharT* __cs, int& __len) const { _CharT* __p = std::__add_grouping(__new, __sep, __grouping, __grouping_size, __cs, __cs + __len); __len = __p - __new; } template<typename _CharT, typename _OutIter> template<typename _ValueT> _OutIter num_put<_CharT, _OutIter>:: _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, _ValueT __v) const { using __gnu_cxx::__add_unsigned; typedef typename __add_unsigned<_ValueT>::__type __unsigned_type; typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); const _CharT* __lit = __lc->_M_atoms_out; const ios_base::fmtflags __flags = __io.flags(); // Long enough to hold hex, dec, and octal representations. const int __ilen = 5 * sizeof(_ValueT); _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __ilen)); // [22.2.2.2.2] Stage 1, numeric conversion to character. // Result is returned right-justified in the buffer. const ios_base::fmtflags __basefield = __flags & ios_base::basefield; const bool __dec = (__basefield != ios_base::oct && __basefield != ios_base::hex); const __unsigned_type __u = ((__v > 0 || !__dec) ? __unsigned_type(__v) : -__unsigned_type(__v)); int __len = __int_to_char(__cs + __ilen, __u, __lit, __flags, __dec); __cs += __ilen - __len; // Add grouping, if necessary. if (__lc->_M_use_grouping) { // Grouping can add (almost) as many separators as the number // of digits + space is reserved for numeric base or sign. _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__len + 1) * 2)); _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size, __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len); __cs = __cs2 + 2; } // Complete Stage 1, prepend numeric base or sign. if (__builtin_expect(__dec, true)) { // Decimal. if (__v >= 0) { if (bool(__flags & ios_base::showpos) && __gnu_cxx::__numeric_traits<_ValueT>::__is_signed) *--__cs = __lit[__num_base::_S_oplus], ++__len; } else *--__cs = __lit[__num_base::_S_ominus], ++__len; } else if (bool(__flags & ios_base::showbase) && __v) { if (__basefield == ios_base::oct) *--__cs = __lit[__num_base::_S_odigits], ++__len; else { // 'x' or 'X' const bool __uppercase = __flags & ios_base::uppercase; *--__cs = __lit[__num_base::_S_ox + __uppercase]; // '0' *--__cs = __lit[__num_base::_S_odigits]; __len += 2; } } // Pad. const streamsize __w = __io.width(); if (__w > static_cast<streamsize>(__len)) { _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); _M_pad(__fill, __w, __io, __cs3, __cs, __len); __cs = __cs3; } __io.width(0); // [22.2.2.2.2] Stage 4. // Write resulting, fully-formatted string to output iterator. return std::__write(__s, __cs, __len); } template<typename _CharT, typename _OutIter> void num_put<_CharT, _OutIter>:: _M_group_float(const char* __grouping, size_t __grouping_size, _CharT __sep, const _CharT* __p, _CharT* __new, _CharT* __cs, int& __len) const { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 282. What types does numpunct grouping refer to? // Add grouping, if necessary. const int __declen = __p ? __p - __cs : __len; _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping, __grouping_size, __cs, __cs + __declen); // Tack on decimal part. int __newlen = __p2 - __new; if (__p) { char_traits<_CharT>::copy(__p2, __p, __len - __declen); __newlen += __len - __declen; } __len = __newlen; } // The following code uses vsnprintf (or vsprintf(), when // _GLIBCXX_USE_C99_STDIO is not defined) to convert floating point // values for insertion into a stream. An optimization would be to // replace them with code that works directly on a wide buffer and // then use __pad to do the padding. It would be good to replace // them anyway to gain back the efficiency that C++ provides by // knowing up front the type of the values to insert. Also, sprintf // is dangerous since may lead to accidental buffer overruns. This // implementation follows the C++ standard fairly directly as // outlined in 22.2.2.2 [lib.locale.num.put] template<typename _CharT, typename _OutIter> template<typename _ValueT> _OutIter num_put<_CharT, _OutIter>:: _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, _ValueT __v) const { typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); // Use default precision if out of range. const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision(); const int __max_digits = __gnu_cxx::__numeric_traits<_ValueT>::__digits10; // [22.2.2.2.2] Stage 1, numeric conversion to character. int __len; // Long enough for the max format spec. char __fbuf[16]; __num_base::_S_format_float(__io, __fbuf, __mod); #if _GLIBCXX_USE_C99_STDIO && !_GLIBCXX_HAVE_BROKEN_VSNPRINTF // Precision is always used except for hexfloat format. const bool __use_prec = (__io.flags() & ios_base::floatfield) != ios_base::floatfield; // First try a buffer perhaps big enough (most probably sufficient // for non-ios_base::fixed outputs) int __cs_size = __max_digits * 3; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); if (__use_prec) __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, __fbuf, __prec, __v); else __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, __fbuf, __v); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast<char*>(__builtin_alloca(__cs_size)); if (__use_prec) __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, __fbuf, __prec, __v); else __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, __fbuf, __v); } #else // Consider the possibility of long ios_base::fixed outputs const bool __fixed = __io.flags() & ios_base::fixed; const int __max_exp = __gnu_cxx::__numeric_traits<_ValueT>::__max_exponent10; // The size of the output string is computed as follows. // ios_base::fixed outputs may need up to __max_exp + 1 chars // for the integer part + __prec chars for the fractional part // + 3 chars for sign, decimal point, '\0'. On the other hand, // for non-fixed outputs __max_digits * 2 + __prec chars are // largely sufficient. const int __cs_size = __fixed ? __max_exp + __prec + 4 : __max_digits * 2 + __prec; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf, __prec, __v); #endif // [22.2.2.2.2] Stage 2, convert to char_type, using correct // numpunct.decimal_point() values for '.' and adding grouping. const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); __ctype.widen(__cs, __cs + __len, __ws); // Replace decimal point. _CharT* __wp = 0; const char* __p = char_traits<char>::find(__cs, __len, '.'); if (__p) { __wp = __ws + (__p - __cs); *__wp = __lc->_M_decimal_point; } // Add grouping, if necessary. // N.B. Make sure to not group things like 2e20, i.e., no decimal // point, scientific notation. if (__lc->_M_use_grouping && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9' && __cs[1] >= '0' && __cs[2] >= '0'))) { // Grouping can add (almost) as many separators as the // number of digits, but no more. _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len * 2)); streamsize __off = 0; if (__cs[0] == '-' || __cs[0] == '+') { __off = 1; __ws2[0] = __ws[0]; __len -= 1; } _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size, __lc->_M_thousands_sep, __wp, __ws2 + __off, __ws + __off, __len); __len += __off; __ws = __ws2; } // Pad. const streamsize __w = __io.width(); if (__w > static_cast<streamsize>(__len)) { _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); _M_pad(__fill, __w, __io, __ws3, __ws, __len); __ws = __ws3; } __io.width(0); // [22.2.2.2.2] Stage 4. // Write resulting, fully-formatted string to output iterator. return std::__write(__s, __ws, __len); } template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const { const ios_base::fmtflags __flags = __io.flags(); if ((__flags & ios_base::boolalpha) == 0) { const long __l = __v; __s = _M_insert_int(__s, __io, __fill, __l); } else { typedef __numpunct_cache<_CharT> __cache_type; __use_cache<__cache_type> __uc; const locale& __loc = __io._M_getloc(); const __cache_type* __lc = __uc(__loc); const _CharT* __name = __v ? __lc->_M_truename : __lc->_M_falsename; int __len = __v ? __lc->_M_truename_size : __lc->_M_falsename_size; const streamsize __w = __io.width(); if (__w > static_cast<streamsize>(__len)) { const streamsize __plen = __w - __len; _CharT* __ps = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __plen)); char_traits<_CharT>::assign(__ps, __plen, __fill); __io.width(0); if ((__flags & ios_base::adjustfield) == ios_base::left) { __s = std::__write(__s, __name, __len); __s = std::__write(__s, __ps, __plen); } else { __s = std::__write(__s, __ps, __plen); __s = std::__write(__s, __name, __len); } return __s; } __io.width(0); __s = std::__write(__s, __name, __len); } return __s; } template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const { return _M_insert_float(__s, __io, __fill, char(), __v); } #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const { return _M_insert_float(__s, __io, __fill, char(), __v); } #endif template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, long double __v) const { return _M_insert_float(__s, __io, __fill, 'L', __v); } template<typename _CharT, typename _OutIter> _OutIter num_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type __fill, const void* __v) const { const ios_base::fmtflags __flags = __io.flags(); const ios_base::fmtflags __fmt = ~(ios_base::basefield | ios_base::uppercase); __io.flags((__flags & __fmt) | (ios_base::hex | ios_base::showbase)); typedef __gnu_cxx::__conditional_type<(sizeof(const void*) <= sizeof(unsigned long)), unsigned long, unsigned long long>::__type _UIntPtrType; __s = _M_insert_int(__s, __io, __fill, reinterpret_cast<_UIntPtrType>(__v)); __io.flags(__flags); return __s; } _GLIBCXX_END_NAMESPACE_LDBL // Construct correctly padded string, as per 22.2.2.2.2 // Assumes // __newlen > __oldlen // __news is allocated for __newlen size // NB: Of the two parameters, _CharT can be deduced from the // function arguments. The other (_Traits) has to be explicitly specified. template<typename _CharT, typename _Traits> void __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds, streamsize __newlen, streamsize __oldlen) { const size_t __plen = static_cast<size_t>(__newlen - __oldlen); const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; // Padding last. if (__adjust == ios_base::left) { _Traits::copy(__news, __olds, __oldlen); _Traits::assign(__news + __oldlen, __plen, __fill); return; } size_t __mod = 0; if (__adjust == ios_base::internal) { // Pad after the sign, if there is one. // Pad after 0[xX], if there is one. // Who came up with these rules, anyway? Jeeze. const locale& __loc = __io._M_getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); if (__ctype.widen('-') == __olds[0] || __ctype.widen('+') == __olds[0]) { __news[0] = __olds[0]; __mod = 1; ++__news; } else if (__ctype.widen('0') == __olds[0] && __oldlen > 1 && (__ctype.widen('x') == __olds[1] || __ctype.widen('X') == __olds[1])) { __news[0] = __olds[0]; __news[1] = __olds[1]; __mod = 2; __news += 2; } // else Padding first. } _Traits::assign(__news, __plen, __fill); _Traits::copy(__news + __plen, __olds + __mod, __oldlen - __mod); } template<typename _CharT> _CharT* __add_grouping(_CharT* __s, _CharT __sep, const char* __gbeg, size_t __gsize, const _CharT* __first, const _CharT* __last) { size_t __idx = 0; size_t __ctr = 0; while (__last - __first > __gbeg[__idx] && static_cast<signed char>(__gbeg[__idx]) > 0 && __gbeg[__idx] != __gnu_cxx::__numeric_traits<char>::__max) { __last -= __gbeg[__idx]; __idx < __gsize - 1 ? ++__idx : ++__ctr; } while (__first != __last) *__s++ = *__first++; while (__ctr--) { *__s++ = __sep; for (char __i = __gbeg[__idx]; __i > 0; --__i) *__s++ = *__first++; } while (__idx--) { *__s++ = __sep; for (char __i = __gbeg[__idx]; __i > 0; --__i) *__s++ = *__first++; } return __s; } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct<char>; extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct_byname<char>; extern template class _GLIBCXX_NAMESPACE_LDBL num_get<char>; extern template class _GLIBCXX_NAMESPACE_LDBL num_put<char>; extern template class ctype_byname<char>; extern template const ctype<char>& use_facet<ctype<char> >(const locale&); extern template const numpunct<char>& use_facet<numpunct<char> >(const locale&); extern template const num_put<char>& use_facet<num_put<char> >(const locale&); extern template const num_get<char>& use_facet<num_get<char> >(const locale&); extern template bool has_facet<ctype<char> >(const locale&); extern template bool has_facet<numpunct<char> >(const locale&); extern template bool has_facet<num_put<char> >(const locale&); extern template bool has_facet<num_get<char> >(const locale&); #ifdef _GLIBCXX_USE_WCHAR_T extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct<wchar_t>; extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct_byname<wchar_t>; extern template class _GLIBCXX_NAMESPACE_LDBL num_get<wchar_t>; extern template class _GLIBCXX_NAMESPACE_LDBL num_put<wchar_t>; extern template class ctype_byname<wchar_t>; extern template const ctype<wchar_t>& use_facet<ctype<wchar_t> >(const locale&); extern template const numpunct<wchar_t>& use_facet<numpunct<wchar_t> >(const locale&); extern template const num_put<wchar_t>& use_facet<num_put<wchar_t> >(const locale&); extern template const num_get<wchar_t>& use_facet<num_get<wchar_t> >(const locale&); extern template bool has_facet<ctype<wchar_t> >(const locale&); extern template bool has_facet<numpunct<wchar_t> >(const locale&); extern template bool has_facet<num_put<wchar_t> >(const locale&); extern template bool has_facet<num_get<wchar_t> >(const locale&); #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/bits/stl_bvector.h 0000644 00000101700 15146341150 0010722 0 ustar 00 // vector<bool> specialization -*- C++ -*- // Copyright (C) 2001-2018 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-1999 * 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/stl_bvector.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{vector} */ #ifndef _STL_BVECTOR_H #define _STL_BVECTOR_H 1 #if __cplusplus >= 201103L #include <initializer_list> #include <bits/functional_hash.h> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typedef unsigned long _Bit_type; enum { _S_word_bit = int(__CHAR_BIT__ * sizeof(_Bit_type)) }; struct _Bit_reference { _Bit_type * _M_p; _Bit_type _M_mask; _Bit_reference(_Bit_type * __x, _Bit_type __y) : _M_p(__x), _M_mask(__y) { } _Bit_reference() _GLIBCXX_NOEXCEPT : _M_p(0), _M_mask(0) { } operator bool() const _GLIBCXX_NOEXCEPT { return !!(*_M_p & _M_mask); } _Bit_reference& operator=(bool __x) _GLIBCXX_NOEXCEPT { if (__x) *_M_p |= _M_mask; else *_M_p &= ~_M_mask; return *this; } _Bit_reference& operator=(const _Bit_reference& __x) _GLIBCXX_NOEXCEPT { return *this = bool(__x); } bool operator==(const _Bit_reference& __x) const { return bool(*this) == bool(__x); } bool operator<(const _Bit_reference& __x) const { return !bool(*this) && bool(__x); } void flip() _GLIBCXX_NOEXCEPT { *_M_p ^= _M_mask; } }; #if __cplusplus >= 201103L inline void swap(_Bit_reference __x, _Bit_reference __y) noexcept { bool __tmp = __x; __x = __y; __y = __tmp; } inline void swap(_Bit_reference __x, bool& __y) noexcept { bool __tmp = __x; __x = __y; __y = __tmp; } inline void swap(bool& __x, _Bit_reference __y) noexcept { bool __tmp = __x; __x = __y; __y = __tmp; } #endif struct _Bit_iterator_base : public std::iterator<std::random_access_iterator_tag, bool> { _Bit_type * _M_p; unsigned int _M_offset; _Bit_iterator_base(_Bit_type * __x, unsigned int __y) : _M_p(__x), _M_offset(__y) { } void _M_bump_up() { if (_M_offset++ == int(_S_word_bit) - 1) { _M_offset = 0; ++_M_p; } } void _M_bump_down() { if (_M_offset-- == 0) { _M_offset = int(_S_word_bit) - 1; --_M_p; } } void _M_incr(ptrdiff_t __i) { difference_type __n = __i + _M_offset; _M_p += __n / int(_S_word_bit); __n = __n % int(_S_word_bit); if (__n < 0) { __n += int(_S_word_bit); --_M_p; } _M_offset = static_cast<unsigned int>(__n); } bool operator==(const _Bit_iterator_base& __i) const { return _M_p == __i._M_p && _M_offset == __i._M_offset; } bool operator<(const _Bit_iterator_base& __i) const { return _M_p < __i._M_p || (_M_p == __i._M_p && _M_offset < __i._M_offset); } bool operator!=(const _Bit_iterator_base& __i) const { return !(*this == __i); } bool operator>(const _Bit_iterator_base& __i) const { return __i < *this; } bool operator<=(const _Bit_iterator_base& __i) const { return !(__i < *this); } bool operator>=(const _Bit_iterator_base& __i) const { return !(*this < __i); } }; inline ptrdiff_t operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y) { return (int(_S_word_bit) * (__x._M_p - __y._M_p) + __x._M_offset - __y._M_offset); } struct _Bit_iterator : public _Bit_iterator_base { typedef _Bit_reference reference; typedef _Bit_reference* pointer; typedef _Bit_iterator iterator; _Bit_iterator() : _Bit_iterator_base(0, 0) { } _Bit_iterator(_Bit_type * __x, unsigned int __y) : _Bit_iterator_base(__x, __y) { } iterator _M_const_cast() const { return *this; } reference operator*() const { return reference(_M_p, 1UL << _M_offset); } iterator& operator++() { _M_bump_up(); return *this; } iterator operator++(int) { iterator __tmp = *this; _M_bump_up(); return __tmp; } iterator& operator--() { _M_bump_down(); return *this; } iterator operator--(int) { iterator __tmp = *this; _M_bump_down(); return __tmp; } iterator& operator+=(difference_type __i) { _M_incr(__i); return *this; } iterator& operator-=(difference_type __i) { *this += -__i; return *this; } iterator operator+(difference_type __i) const { iterator __tmp = *this; return __tmp += __i; } iterator operator-(difference_type __i) const { iterator __tmp = *this; return __tmp -= __i; } reference operator[](difference_type __i) const { return *(*this + __i); } }; inline _Bit_iterator operator+(ptrdiff_t __n, const _Bit_iterator& __x) { return __x + __n; } struct _Bit_const_iterator : public _Bit_iterator_base { typedef bool reference; typedef bool const_reference; typedef const bool* pointer; typedef _Bit_const_iterator const_iterator; _Bit_const_iterator() : _Bit_iterator_base(0, 0) { } _Bit_const_iterator(_Bit_type * __x, unsigned int __y) : _Bit_iterator_base(__x, __y) { } _Bit_const_iterator(const _Bit_iterator& __x) : _Bit_iterator_base(__x._M_p, __x._M_offset) { } _Bit_iterator _M_const_cast() const { return _Bit_iterator(_M_p, _M_offset); } const_reference operator*() const { return _Bit_reference(_M_p, 1UL << _M_offset); } const_iterator& operator++() { _M_bump_up(); return *this; } const_iterator operator++(int) { const_iterator __tmp = *this; _M_bump_up(); return __tmp; } const_iterator& operator--() { _M_bump_down(); return *this; } const_iterator operator--(int) { const_iterator __tmp = *this; _M_bump_down(); return __tmp; } const_iterator& operator+=(difference_type __i) { _M_incr(__i); return *this; } const_iterator& operator-=(difference_type __i) { *this += -__i; return *this; } const_iterator operator+(difference_type __i) const { const_iterator __tmp = *this; return __tmp += __i; } const_iterator operator-(difference_type __i) const { const_iterator __tmp = *this; return __tmp -= __i; } const_reference operator[](difference_type __i) const { return *(*this + __i); } }; inline _Bit_const_iterator operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) { return __x + __n; } inline void __fill_bvector(_Bit_type * __v, unsigned int __first, unsigned int __last, bool __x) { const _Bit_type __fmask = ~0ul << __first; const _Bit_type __lmask = ~0ul >> (_S_word_bit - __last); const _Bit_type __mask = __fmask & __lmask; if (__x) *__v |= __mask; else *__v &= ~__mask; } inline void fill(_Bit_iterator __first, _Bit_iterator __last, const bool& __x) { if (__first._M_p != __last._M_p) { _Bit_type* __first_p = __first._M_p; if (__first._M_offset != 0) __fill_bvector(__first_p++, __first._M_offset, _S_word_bit, __x); __builtin_memset(__first_p, __x ? ~0 : 0, (__last._M_p - __first_p) * sizeof(_Bit_type)); if (__last._M_offset != 0) __fill_bvector(__last._M_p, 0, __last._M_offset, __x); } else if (__first._M_offset != __last._M_offset) __fill_bvector(__first._M_p, __first._M_offset, __last._M_offset, __x); } template<typename _Alloc> struct _Bvector_base { typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Bit_type>::other _Bit_alloc_type; typedef typename __gnu_cxx::__alloc_traits<_Bit_alloc_type> _Bit_alloc_traits; typedef typename _Bit_alloc_traits::pointer _Bit_pointer; struct _Bvector_impl_data { _Bit_iterator _M_start; _Bit_iterator _M_finish; _Bit_pointer _M_end_of_storage; _Bvector_impl_data() _GLIBCXX_NOEXCEPT : _M_start(), _M_finish(), _M_end_of_storage() { } #if __cplusplus >= 201103L _Bvector_impl_data(_Bvector_impl_data&& __x) noexcept : _M_start(__x._M_start), _M_finish(__x._M_finish) , _M_end_of_storage(__x._M_end_of_storage) { __x._M_reset(); } void _M_move_data(_Bvector_impl_data&& __x) noexcept { this->_M_start = __x._M_start; this->_M_finish = __x._M_finish; this->_M_end_of_storage = __x._M_end_of_storage; __x._M_reset(); } #endif void _M_reset() _GLIBCXX_NOEXCEPT { _M_start = _M_finish = _Bit_iterator(); _M_end_of_storage = _Bit_pointer(); } }; struct _Bvector_impl : public _Bit_alloc_type, public _Bvector_impl_data { public: _Bvector_impl() _GLIBCXX_NOEXCEPT_IF( is_nothrow_default_constructible<_Bit_alloc_type>::value) : _Bit_alloc_type() { } _Bvector_impl(const _Bit_alloc_type& __a) _GLIBCXX_NOEXCEPT : _Bit_alloc_type(__a) { } #if __cplusplus >= 201103L _Bvector_impl(_Bvector_impl&&) = default; #endif _Bit_type* _M_end_addr() const _GLIBCXX_NOEXCEPT { if (this->_M_end_of_storage) return std::__addressof(this->_M_end_of_storage[-1]) + 1; return 0; } }; public: typedef _Alloc allocator_type; _Bit_alloc_type& _M_get_Bit_allocator() _GLIBCXX_NOEXCEPT { return this->_M_impl; } const _Bit_alloc_type& _M_get_Bit_allocator() const _GLIBCXX_NOEXCEPT { return this->_M_impl; } allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_get_Bit_allocator()); } #if __cplusplus >= 201103L _Bvector_base() = default; #else _Bvector_base() { } #endif _Bvector_base(const allocator_type& __a) : _M_impl(__a) { } #if __cplusplus >= 201103L _Bvector_base(_Bvector_base&&) = default; #endif ~_Bvector_base() { this->_M_deallocate(); } protected: _Bvector_impl _M_impl; _Bit_pointer _M_allocate(size_t __n) { return _Bit_alloc_traits::allocate(_M_impl, _S_nword(__n)); } void _M_deallocate() { if (_M_impl._M_start._M_p) { const size_t __n = _M_impl._M_end_addr() - _M_impl._M_start._M_p; _Bit_alloc_traits::deallocate(_M_impl, _M_impl._M_end_of_storage - __n, __n); _M_impl._M_reset(); } } #if __cplusplus >= 201103L void _M_move_data(_Bvector_base&& __x) noexcept { _M_impl._M_move_data(std::move(__x._M_impl)); } #endif static size_t _S_nword(size_t __n) { return (__n + int(_S_word_bit) - 1) / int(_S_word_bit); } }; _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION } // namespace std // Declare a partial specialization of vector<T, Alloc>. #include <bits/stl_vector.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** * @brief A specialization of vector for booleans which offers fixed time * access to individual elements in any order. * * @ingroup sequences * * @tparam _Alloc Allocator type. * * Note that vector<bool> does not actually meet the requirements for being * a container. This is because the reference and pointer types are not * really references and pointers to bool. See DR96 for details. @see * vector for function documentation. * * In some terminology a %vector can be described as a dynamic * C-style array, it offers fast and efficient access to individual * elements in any order and saves the user from worrying about * memory and size allocation. Subscripting ( @c [] ) access is * also provided as with C-style arrays. */ template<typename _Alloc> class vector<bool, _Alloc> : protected _Bvector_base<_Alloc> { typedef _Bvector_base<_Alloc> _Base; typedef typename _Base::_Bit_pointer _Bit_pointer; typedef typename _Base::_Bit_alloc_traits _Bit_alloc_traits; #if __cplusplus >= 201103L friend struct std::hash<vector>; #endif public: typedef bool value_type; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Bit_reference reference; typedef bool const_reference; typedef _Bit_reference* pointer; typedef const bool* const_pointer; typedef _Bit_iterator iterator; typedef _Bit_const_iterator const_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef _Alloc allocator_type; allocator_type get_allocator() const { return _Base::get_allocator(); } protected: using _Base::_M_allocate; using _Base::_M_deallocate; using _Base::_S_nword; using _Base::_M_get_Bit_allocator; public: #if __cplusplus >= 201103L vector() = default; #else vector() { } #endif explicit vector(const allocator_type& __a) : _Base(__a) { } #if __cplusplus >= 201103L explicit vector(size_type __n, const allocator_type& __a = allocator_type()) : vector(__n, false, __a) { } vector(size_type __n, const bool& __value, const allocator_type& __a = allocator_type()) #else explicit vector(size_type __n, const bool& __value = bool(), const allocator_type& __a = allocator_type()) #endif : _Base(__a) { _M_initialize(__n); _M_initialize_value(__value); } vector(const vector& __x) : _Base(_Bit_alloc_traits::_S_select_on_copy(__x._M_get_Bit_allocator())) { _M_initialize(__x.size()); _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start); } #if __cplusplus >= 201103L vector(vector&&) = default; vector(vector&& __x, const allocator_type& __a) noexcept(_Bit_alloc_traits::_S_always_equal()) : _Base(__a) { if (__x.get_allocator() == __a) this->_M_move_data(std::move(__x)); else { _M_initialize(__x.size()); _M_copy_aligned(__x.begin(), __x.end(), begin()); __x.clear(); } } vector(const vector& __x, const allocator_type& __a) : _Base(__a) { _M_initialize(__x.size()); _M_copy_aligned(__x.begin(), __x.end(), this->_M_impl._M_start); } vector(initializer_list<bool> __l, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_initialize_range(__l.begin(), __l.end(), random_access_iterator_tag()); } #endif #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_initialize_dispatch(__first, __last, __false_type()); } #else template<typename _InputIterator> vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } #endif ~vector() _GLIBCXX_NOEXCEPT { } vector& operator=(const vector& __x) { if (&__x == this) return *this; #if __cplusplus >= 201103L if (_Bit_alloc_traits::_S_propagate_on_copy_assign()) { if (this->_M_get_Bit_allocator() != __x._M_get_Bit_allocator()) { this->_M_deallocate(); std::__alloc_on_copy(_M_get_Bit_allocator(), __x._M_get_Bit_allocator()); _M_initialize(__x.size()); } else std::__alloc_on_copy(_M_get_Bit_allocator(), __x._M_get_Bit_allocator()); } #endif if (__x.size() > capacity()) { this->_M_deallocate(); _M_initialize(__x.size()); } this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(), begin()); return *this; } #if __cplusplus >= 201103L vector& operator=(vector&& __x) noexcept(_Bit_alloc_traits::_S_nothrow_move()) { if (_Bit_alloc_traits::_S_propagate_on_move_assign() || this->_M_get_Bit_allocator() == __x._M_get_Bit_allocator()) { this->_M_deallocate(); this->_M_move_data(std::move(__x)); std::__alloc_on_move(_M_get_Bit_allocator(), __x._M_get_Bit_allocator()); } else { if (__x.size() > capacity()) { this->_M_deallocate(); _M_initialize(__x.size()); } this->_M_impl._M_finish = _M_copy_aligned(__x.begin(), __x.end(), begin()); __x.clear(); } return *this; } vector& operator=(initializer_list<bool> __l) { this->assign (__l.begin(), __l.end()); return *this; } #endif // assign(), a generalized assignment member function. Two // versions: one that takes a count, and one that takes a range. // The range version is a member template, so we dispatch on whether // or not the type is an integer. void assign(size_type __n, const bool& __x) { _M_fill_assign(__n, __x); } #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> void assign(_InputIterator __first, _InputIterator __last) { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } #else template<typename _InputIterator> void assign(_InputIterator __first, _InputIterator __last) { typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_assign_dispatch(__first, __last, _Integral()); } #endif #if __cplusplus >= 201103L void assign(initializer_list<bool> __l) { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); } #endif iterator begin() _GLIBCXX_NOEXCEPT { return this->_M_impl._M_start; } const_iterator begin() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_start; } iterator end() _GLIBCXX_NOEXCEPT { return this->_M_impl._M_finish; } const_iterator end() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_finish; } reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return reverse_iterator(end()); } const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(end()); } reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(begin()); } const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L const_iterator cbegin() const noexcept { return this->_M_impl._M_start; } const_iterator cend() const noexcept { return this->_M_impl._M_finish; } const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } #endif size_type size() const _GLIBCXX_NOEXCEPT { return size_type(end() - begin()); } size_type max_size() const _GLIBCXX_NOEXCEPT { const size_type __isize = __gnu_cxx::__numeric_traits<difference_type>::__max - int(_S_word_bit) + 1; const size_type __asize = _Bit_alloc_traits::max_size(_M_get_Bit_allocator()); return (__asize <= __isize / int(_S_word_bit) ? __asize * int(_S_word_bit) : __isize); } size_type capacity() const _GLIBCXX_NOEXCEPT { return size_type(const_iterator(this->_M_impl._M_end_addr(), 0) - begin()); } bool empty() const _GLIBCXX_NOEXCEPT { return begin() == end(); } reference operator[](size_type __n) { return *iterator(this->_M_impl._M_start._M_p + __n / int(_S_word_bit), __n % int(_S_word_bit)); } const_reference operator[](size_type __n) const { return *const_iterator(this->_M_impl._M_start._M_p + __n / int(_S_word_bit), __n % int(_S_word_bit)); } protected: void _M_range_check(size_type __n) const { if (__n >= this->size()) __throw_out_of_range_fmt(__N("vector<bool>::_M_range_check: __n " "(which is %zu) >= this->size() " "(which is %zu)"), __n, this->size()); } public: reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } const_reference at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } void reserve(size_type __n) { if (__n > max_size()) __throw_length_error(__N("vector::reserve")); if (capacity() < __n) _M_reallocate(__n); } reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(end() - 1); } const_reference back() const { return *(end() - 1); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 464. Suggestion for new member functions in standard containers. // N.B. DR 464 says nothing about vector<bool> but we need something // here due to the way we are implementing DR 464 in the debug-mode // vector class. void data() _GLIBCXX_NOEXCEPT { } void push_back(bool __x) { if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr()) *this->_M_impl._M_finish++ = __x; else _M_insert_aux(end(), __x); } void swap(vector& __x) _GLIBCXX_NOEXCEPT { std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage); _Bit_alloc_traits::_S_on_swap(_M_get_Bit_allocator(), __x._M_get_Bit_allocator()); } // [23.2.5]/1, third-to-last entry in synopsis listing static void swap(reference __x, reference __y) _GLIBCXX_NOEXCEPT { bool __tmp = __x; __x = __y; __y = __tmp; } iterator #if __cplusplus >= 201103L insert(const_iterator __position, const bool& __x = bool()) #else insert(iterator __position, const bool& __x = bool()) #endif { const difference_type __n = __position - begin(); if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr() && __position == end()) *this->_M_impl._M_finish++ = __x; else _M_insert_aux(__position._M_const_cast(), __x); return begin() + __n; } #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> iterator insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { difference_type __offset = __position - cbegin(); _M_insert_dispatch(__position._M_const_cast(), __first, __last, __false_type()); return begin() + __offset; } #else template<typename _InputIterator> void insert(iterator __position, _InputIterator __first, _InputIterator __last) { typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); } #endif #if __cplusplus >= 201103L iterator insert(const_iterator __position, size_type __n, const bool& __x) { difference_type __offset = __position - cbegin(); _M_fill_insert(__position._M_const_cast(), __n, __x); return begin() + __offset; } #else void insert(iterator __position, size_type __n, const bool& __x) { _M_fill_insert(__position, __n, __x); } #endif #if __cplusplus >= 201103L iterator insert(const_iterator __p, initializer_list<bool> __l) { return this->insert(__p, __l.begin(), __l.end()); } #endif void pop_back() { --this->_M_impl._M_finish; } iterator #if __cplusplus >= 201103L erase(const_iterator __position) #else erase(iterator __position) #endif { return _M_erase(__position._M_const_cast()); } iterator #if __cplusplus >= 201103L erase(const_iterator __first, const_iterator __last) #else erase(iterator __first, iterator __last) #endif { return _M_erase(__first._M_const_cast(), __last._M_const_cast()); } void resize(size_type __new_size, bool __x = bool()) { if (__new_size < size()) _M_erase_at_end(begin() + difference_type(__new_size)); else insert(end(), __new_size - size(), __x); } #if __cplusplus >= 201103L void shrink_to_fit() { _M_shrink_to_fit(); } #endif void flip() _GLIBCXX_NOEXCEPT { _Bit_type * const __end = this->_M_impl._M_end_addr(); for (_Bit_type * __p = this->_M_impl._M_start._M_p; __p != __end; ++__p) *__p = ~*__p; } void clear() _GLIBCXX_NOEXCEPT { _M_erase_at_end(begin()); } #if __cplusplus >= 201103L template<typename... _Args> #if __cplusplus > 201402L reference #else void #endif emplace_back(_Args&&... __args) { push_back(bool(__args...)); #if __cplusplus > 201402L return back(); #endif } template<typename... _Args> iterator emplace(const_iterator __pos, _Args&&... __args) { return insert(__pos, bool(__args...)); } #endif protected: // Precondition: __first._M_offset == 0 && __result._M_offset == 0. iterator _M_copy_aligned(const_iterator __first, const_iterator __last, iterator __result) { _Bit_type* __q = std::copy(__first._M_p, __last._M_p, __result._M_p); return std::copy(const_iterator(__last._M_p, 0), __last, iterator(__q, 0)); } void _M_initialize(size_type __n) { if (__n) { _Bit_pointer __q = this->_M_allocate(__n); this->_M_impl._M_end_of_storage = __q + _S_nword(__n); this->_M_impl._M_start = iterator(std::__addressof(*__q), 0); } else { this->_M_impl._M_end_of_storage = _Bit_pointer(); this->_M_impl._M_start = iterator(0, 0); } this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n); } void _M_initialize_value(bool __x) { if (_Bit_type* __p = this->_M_impl._M_start._M_p) __builtin_memset(__p, __x ? ~0 : 0, (this->_M_impl._M_end_addr() - __p) * sizeof(_Bit_type)); } void _M_reallocate(size_type __n); #if __cplusplus >= 201103L bool _M_shrink_to_fit(); #endif // Check whether it's an integral type. If so, it's not an iterator. // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { _M_initialize(static_cast<size_type>(__n)); _M_initialize_value(__x); } template<typename _InputIterator> void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { _M_initialize_range(__first, __last, std::__iterator_category(__first)); } template<typename _InputIterator> void _M_initialize_range(_InputIterator __first, _InputIterator __last, std::input_iterator_tag) { for (; __first != __last; ++__first) push_back(*__first); } template<typename _ForwardIterator> void _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { const size_type __n = std::distance(__first, __last); _M_initialize(__n); std::copy(__first, __last, this->_M_impl._M_start); } #if __cplusplus < 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign(__n, __val); } template<class _InputIterator> void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } #endif void _M_fill_assign(size_t __n, bool __x) { if (__n > size()) { _M_initialize_value(__x); insert(end(), __n - size(), __x); } else { _M_erase_at_end(begin() + __n); _M_initialize_value(__x); } } template<typename _InputIterator> void _M_assign_aux(_InputIterator __first, _InputIterator __last, std::input_iterator_tag) { iterator __cur = begin(); for (; __first != __last && __cur != end(); ++__cur, ++__first) *__cur = *__first; if (__first == __last) _M_erase_at_end(__cur); else insert(end(), __first, __last); } template<typename _ForwardIterator> void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { const size_type __len = std::distance(__first, __last); if (__len < size()) _M_erase_at_end(std::copy(__first, __last, begin())); else { _ForwardIterator __mid = __first; std::advance(__mid, size()); std::copy(__first, __mid, begin()); insert(end(), __mid, __last); } } // Check whether it's an integral type. If so, it's not an iterator. // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type) { _M_fill_insert(__pos, __n, __x); } template<typename _InputIterator> void _M_insert_dispatch(iterator __pos, _InputIterator __first, _InputIterator __last, __false_type) { _M_insert_range(__pos, __first, __last, std::__iterator_category(__first)); } void _M_fill_insert(iterator __position, size_type __n, bool __x); template<typename _InputIterator> void _M_insert_range(iterator __pos, _InputIterator __first, _InputIterator __last, std::input_iterator_tag) { for (; __first != __last; ++__first) { __pos = insert(__pos, *__first); ++__pos; } } template<typename _ForwardIterator> void _M_insert_range(iterator __position, _ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag); void _M_insert_aux(iterator __position, bool __x); size_type _M_check_len(size_type __n, const char* __s) const { if (max_size() - size() < __n) __throw_length_error(__N(__s)); const size_type __len = size() + std::max(size(), __n); return (__len < size() || __len > max_size()) ? max_size() : __len; } void _M_erase_at_end(iterator __pos) { this->_M_impl._M_finish = __pos; } iterator _M_erase(iterator __pos); iterator _M_erase(iterator __first, iterator __last); }; _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #if __cplusplus >= 201103L namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // DR 1182. /// std::hash specialization for vector<bool>. template<typename _Alloc> struct hash<_GLIBCXX_STD_C::vector<bool, _Alloc>> : public __hash_base<size_t, _GLIBCXX_STD_C::vector<bool, _Alloc>> { size_t operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>&) const noexcept; }; _GLIBCXX_END_NAMESPACE_VERSION }// namespace std #endif // C++11 #endif c++/8/bits/basic_ios.tcc 0000644 00000013703 15146341150 0010656 0 ustar 00 // basic_ios member functions -*- C++ -*- // Copyright (C) 1999-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/basic_ios.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ios} */ #ifndef _BASIC_IOS_TCC #define _BASIC_IOS_TCC 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits> void basic_ios<_CharT, _Traits>::clear(iostate __state) { if (this->rdbuf()) _M_streambuf_state = __state; else _M_streambuf_state = __state | badbit; if (this->exceptions() & this->rdstate()) __throw_ios_failure(__N("basic_ios::clear")); } template<typename _CharT, typename _Traits> basic_streambuf<_CharT, _Traits>* basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb) { basic_streambuf<_CharT, _Traits>* __old = _M_streambuf; _M_streambuf = __sb; this->clear(); return __old; } template<typename _CharT, typename _Traits> basic_ios<_CharT, _Traits>& basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 292. effects of a.copyfmt (a) if (this != &__rhs) { // Per 27.1.1, do not call imbue, yet must trash all caches // associated with imbue() // Alloc any new word array first, so if it fails we have "rollback". _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ? _M_local_word : new _Words[__rhs._M_word_size]; // Bump refs before doing callbacks, for safety. _Callback_list* __cb = __rhs._M_callbacks; if (__cb) __cb->_M_add_reference(); _M_call_callbacks(erase_event); if (_M_word != _M_local_word) { delete [] _M_word; _M_word = 0; } _M_dispose_callbacks(); // NB: Don't want any added during above. _M_callbacks = __cb; for (int __i = 0; __i < __rhs._M_word_size; ++__i) __words[__i] = __rhs._M_word[__i]; _M_word = __words; _M_word_size = __rhs._M_word_size; this->flags(__rhs.flags()); this->width(__rhs.width()); this->precision(__rhs.precision()); this->tie(__rhs.tie()); this->fill(__rhs.fill()); _M_ios_locale = __rhs.getloc(); _M_cache_locale(_M_ios_locale); _M_call_callbacks(copyfmt_event); // The next is required to be the last assignment. this->exceptions(__rhs.exceptions()); } return *this; } // Locales: template<typename _CharT, typename _Traits> locale basic_ios<_CharT, _Traits>::imbue(const locale& __loc) { locale __old(this->getloc()); ios_base::imbue(__loc); _M_cache_locale(__loc); if (this->rdbuf() != 0) this->rdbuf()->pubimbue(__loc); return __old; } template<typename _CharT, typename _Traits> void basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb) { // NB: This may be called more than once on the same object. ios_base::_M_init(); // Cache locale data and specific facets used by iostreams. _M_cache_locale(_M_ios_locale); // NB: The 27.4.4.1 Postconditions Table specifies requirements // after basic_ios::init() has been called. As part of this, // fill() must return widen(' ') any time after init() has been // called, which needs an imbued ctype facet of char_type to // return without throwing an exception. Unfortunately, // ctype<char_type> is not necessarily a required facet, so // streams with char_type != [char, wchar_t] will not have it by // default. Because of this, the correct value for _M_fill is // constructed on the first call of fill(). That way, // unformatted input and output with non-required basic_ios // instantiations is possible even without imbuing the expected // ctype<char_type> facet. _M_fill = _CharT(); _M_fill_init = false; _M_tie = 0; _M_exception = goodbit; _M_streambuf = __sb; _M_streambuf_state = __sb ? goodbit : badbit; } template<typename _CharT, typename _Traits> void basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc) { if (__builtin_expect(has_facet<__ctype_type>(__loc), true)) _M_ctype = std::__addressof(use_facet<__ctype_type>(__loc)); else _M_ctype = 0; if (__builtin_expect(has_facet<__num_put_type>(__loc), true)) _M_num_put = std::__addressof(use_facet<__num_put_type>(__loc)); else _M_num_put = 0; if (__builtin_expect(has_facet<__num_get_type>(__loc), true)) _M_num_get = std::__addressof(use_facet<__num_get_type>(__loc)); else _M_num_get = 0; } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_ios<char>; #ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_ios<wchar_t>; #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/indirect_array.h 0000644 00000017265 15146341150 0011407 0 ustar 00 // The template and inlines for the -*- C++ -*- indirect_array class. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/indirect_array.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{valarray} */ // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> #ifndef _INDIRECT_ARRAY_H #define _INDIRECT_ARRAY_H 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup numeric_arrays * @{ */ /** * @brief Reference to arbitrary subset of an array. * * An indirect_array is a reference to the actual elements of an array * specified by an ordered array of indices. The way to get an * indirect_array is to call operator[](valarray<size_t>) on a valarray. * The returned indirect_array then permits carrying operations out on the * referenced subset of elements in the original valarray. * * For example, if an indirect_array is obtained using the array (4,2,0) as * an argument, and then assigned to an array containing (1,2,3), then the * underlying array will have array[0]==3, array[2]==2, and array[4]==1. * * @param Tp Element type. */ template <class _Tp> class indirect_array { public: typedef _Tp value_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 253. valarray helper functions are almost entirely useless /// Copy constructor. Both slices refer to the same underlying array. indirect_array(const indirect_array&); /// Assignment operator. Assigns elements to corresponding elements /// of @a a. indirect_array& operator=(const indirect_array&); /// Assign slice elements to corresponding elements of @a v. void operator=(const valarray<_Tp>&) const; /// Multiply slice elements by corresponding elements of @a v. void operator*=(const valarray<_Tp>&) const; /// Divide slice elements by corresponding elements of @a v. void operator/=(const valarray<_Tp>&) const; /// Modulo slice elements by corresponding elements of @a v. void operator%=(const valarray<_Tp>&) const; /// Add corresponding elements of @a v to slice elements. void operator+=(const valarray<_Tp>&) const; /// Subtract corresponding elements of @a v from slice elements. void operator-=(const valarray<_Tp>&) const; /// Logical xor slice elements with corresponding elements of @a v. void operator^=(const valarray<_Tp>&) const; /// Logical and slice elements with corresponding elements of @a v. void operator&=(const valarray<_Tp>&) const; /// Logical or slice elements with corresponding elements of @a v. void operator|=(const valarray<_Tp>&) const; /// Left shift slice elements by corresponding elements of @a v. void operator<<=(const valarray<_Tp>&) const; /// Right shift slice elements by corresponding elements of @a v. void operator>>=(const valarray<_Tp>&) const; /// Assign all slice elements to @a t. void operator= (const _Tp&) const; // ~indirect_array(); template<class _Dom> void operator=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator*=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator/=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator%=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator+=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator-=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator^=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator&=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator|=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator<<=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator>>=(const _Expr<_Dom, _Tp>&) const; private: /// Copy constructor. Both slices refer to the same underlying array. indirect_array(_Array<_Tp>, size_t, _Array<size_t>); friend class valarray<_Tp>; friend class gslice_array<_Tp>; const size_t _M_sz; const _Array<size_t> _M_index; const _Array<_Tp> _M_array; // not implemented indirect_array(); }; template<typename _Tp> inline indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a) : _M_sz(__a._M_sz), _M_index(__a._M_index), _M_array(__a._M_array) {} template<typename _Tp> inline indirect_array<_Tp>::indirect_array(_Array<_Tp> __a, size_t __s, _Array<size_t> __i) : _M_sz(__s), _M_index(__i), _M_array(__a) {} template<typename _Tp> inline indirect_array<_Tp>& indirect_array<_Tp>::operator=(const indirect_array<_Tp>& __a) { std::__valarray_copy(__a._M_array, _M_sz, __a._M_index, _M_array, _M_index); return *this; } template<typename _Tp> inline void indirect_array<_Tp>::operator=(const _Tp& __t) const { std::__valarray_fill(_M_array, _M_index, _M_sz, __t); } template<typename _Tp> inline void indirect_array<_Tp>::operator=(const valarray<_Tp>& __v) const { std::__valarray_copy(_Array<_Tp>(__v), _M_sz, _M_array, _M_index); } template<typename _Tp> template<class _Dom> inline void indirect_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const { std::__valarray_copy(__e, _M_sz, _M_array, _M_index); } #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ template<typename _Tp> \ inline void \ indirect_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const\ { \ _Array_augmented_##_Name(_M_array, _M_index, _Array<_Tp>(__v), _M_sz); \ } \ \ template<typename _Tp> \ template<class _Dom> \ inline void \ indirect_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\ { \ _Array_augmented_##_Name(_M_array, _M_index, __e, _M_sz); \ } _DEFINE_VALARRAY_OPERATOR(*, __multiplies) _DEFINE_VALARRAY_OPERATOR(/, __divides) _DEFINE_VALARRAY_OPERATOR(%, __modulus) _DEFINE_VALARRAY_OPERATOR(+, __plus) _DEFINE_VALARRAY_OPERATOR(-, __minus) _DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) _DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) _DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) _DEFINE_VALARRAY_OPERATOR(<<, __shift_left) _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) #undef _DEFINE_VALARRAY_OPERATOR // @} group numeric_arrays _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _INDIRECT_ARRAY_H */ c++/8/bits/gslice_array.h 0000644 00000017131 15146341150 0011044 0 ustar 00 // The template and inlines for the -*- C++ -*- gslice_array class. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/gslice_array.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{valarray} */ // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> #ifndef _GSLICE_ARRAY_H #define _GSLICE_ARRAY_H 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup numeric_arrays * @{ */ /** * @brief Reference to multi-dimensional subset of an array. * * A gslice_array is a reference to the actual elements of an array * specified by a gslice. The way to get a gslice_array is to call * operator[](gslice) on a valarray. The returned gslice_array then * permits carrying operations out on the referenced subset of elements in * the original valarray. For example, operator+=(valarray) will add * values to the subset of elements in the underlying valarray this * gslice_array refers to. * * @param Tp Element type. */ template<typename _Tp> class gslice_array { public: typedef _Tp value_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 253. valarray helper functions are almost entirely useless /// Copy constructor. Both slices refer to the same underlying array. gslice_array(const gslice_array&); /// Assignment operator. Assigns slice elements to corresponding /// elements of @a a. gslice_array& operator=(const gslice_array&); /// Assign slice elements to corresponding elements of @a v. void operator=(const valarray<_Tp>&) const; /// Multiply slice elements by corresponding elements of @a v. void operator*=(const valarray<_Tp>&) const; /// Divide slice elements by corresponding elements of @a v. void operator/=(const valarray<_Tp>&) const; /// Modulo slice elements by corresponding elements of @a v. void operator%=(const valarray<_Tp>&) const; /// Add corresponding elements of @a v to slice elements. void operator+=(const valarray<_Tp>&) const; /// Subtract corresponding elements of @a v from slice elements. void operator-=(const valarray<_Tp>&) const; /// Logical xor slice elements with corresponding elements of @a v. void operator^=(const valarray<_Tp>&) const; /// Logical and slice elements with corresponding elements of @a v. void operator&=(const valarray<_Tp>&) const; /// Logical or slice elements with corresponding elements of @a v. void operator|=(const valarray<_Tp>&) const; /// Left shift slice elements by corresponding elements of @a v. void operator<<=(const valarray<_Tp>&) const; /// Right shift slice elements by corresponding elements of @a v. void operator>>=(const valarray<_Tp>&) const; /// Assign all slice elements to @a t. void operator=(const _Tp&) const; template<class _Dom> void operator=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator*=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator/=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator%=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator+=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator-=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator^=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator&=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator|=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator<<=(const _Expr<_Dom, _Tp>&) const; template<class _Dom> void operator>>=(const _Expr<_Dom, _Tp>&) const; private: _Array<_Tp> _M_array; const valarray<size_t>& _M_index; friend class valarray<_Tp>; gslice_array(_Array<_Tp>, const valarray<size_t>&); // not implemented gslice_array(); }; template<typename _Tp> inline gslice_array<_Tp>::gslice_array(_Array<_Tp> __a, const valarray<size_t>& __i) : _M_array(__a), _M_index(__i) {} template<typename _Tp> inline gslice_array<_Tp>::gslice_array(const gslice_array<_Tp>& __a) : _M_array(__a._M_array), _M_index(__a._M_index) {} template<typename _Tp> inline gslice_array<_Tp>& gslice_array<_Tp>::operator=(const gslice_array<_Tp>& __a) { std::__valarray_copy(_Array<_Tp>(__a._M_array), _Array<size_t>(__a._M_index), _M_index.size(), _M_array, _Array<size_t>(_M_index)); return *this; } template<typename _Tp> inline void gslice_array<_Tp>::operator=(const _Tp& __t) const { std::__valarray_fill(_M_array, _Array<size_t>(_M_index), _M_index.size(), __t); } template<typename _Tp> inline void gslice_array<_Tp>::operator=(const valarray<_Tp>& __v) const { std::__valarray_copy(_Array<_Tp>(__v), __v.size(), _M_array, _Array<size_t>(_M_index)); } template<typename _Tp> template<class _Dom> inline void gslice_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const { std::__valarray_copy (__e, _M_index.size(), _M_array, _Array<size_t>(_M_index)); } #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ template<typename _Tp> \ inline void \ gslice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ { \ _Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index), \ _Array<_Tp>(__v), __v.size()); \ } \ \ template<typename _Tp> \ template<class _Dom> \ inline void \ gslice_array<_Tp>::operator _Op##= (const _Expr<_Dom, _Tp>& __e) const\ { \ _Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index), __e,\ _M_index.size()); \ } _DEFINE_VALARRAY_OPERATOR(*, __multiplies) _DEFINE_VALARRAY_OPERATOR(/, __divides) _DEFINE_VALARRAY_OPERATOR(%, __modulus) _DEFINE_VALARRAY_OPERATOR(+, __plus) _DEFINE_VALARRAY_OPERATOR(-, __minus) _DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) _DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) _DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) _DEFINE_VALARRAY_OPERATOR(<<, __shift_left) _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) #undef _DEFINE_VALARRAY_OPERATOR // @} group numeric_arrays _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _GSLICE_ARRAY_H */ c++/8/bits/allocator.h 0000644 00000016621 15146341150 0010363 0 ustar 00 // Allocators -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /* * Copyright (c) 1996-1997 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file bits/allocator.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _ALLOCATOR_H #define _ALLOCATOR_H 1 #include <bits/c++allocator.h> // Define the base class to std::allocator. #include <bits/memoryfwd.h> #if __cplusplus >= 201103L #include <type_traits> #endif #define __cpp_lib_incomplete_container_elements 201505 #if __cplusplus >= 201103L # define __cpp_lib_allocator_is_always_equal 201411 #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup allocators * @{ */ /// allocator<void> specialization. template<> class allocator<void> { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template<typename _Tp1> struct rebind { typedef allocator<_Tp1> other; }; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment typedef true_type propagate_on_container_move_assignment; typedef true_type is_always_equal; template<typename _Up, typename... _Args> void construct(_Up* __p, _Args&&... __args) { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } template<typename _Up> void destroy(_Up* __p) { __p->~_Up(); } #endif }; /** * @brief The @a standard allocator, as per [20.4]. * * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/memory.html#std.util.memory.allocator * for further details. * * @tparam _Tp Type of allocated object. */ template<typename _Tp> class allocator : public __allocator_base<_Tp> { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef _Tp value_type; template<typename _Tp1> struct rebind { typedef allocator<_Tp1> other; }; #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment typedef true_type propagate_on_container_move_assignment; typedef true_type is_always_equal; #endif allocator() throw() { } allocator(const allocator& __a) throw() : __allocator_base<_Tp>(__a) { } template<typename _Tp1> allocator(const allocator<_Tp1>&) throw() { } ~allocator() throw() { } // Inherit everything else. }; template<typename _T1, typename _T2> inline bool operator==(const allocator<_T1>&, const allocator<_T2>&) _GLIBCXX_USE_NOEXCEPT { return true; } template<typename _Tp> inline bool operator==(const allocator<_Tp>&, const allocator<_Tp>&) _GLIBCXX_USE_NOEXCEPT { return true; } template<typename _T1, typename _T2> inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&) _GLIBCXX_USE_NOEXCEPT { return false; } template<typename _Tp> inline bool operator!=(const allocator<_Tp>&, const allocator<_Tp>&) _GLIBCXX_USE_NOEXCEPT { return false; } // Invalid allocator<cv T> partial specializations. // allocator_traits::rebind_alloc can be used to form a valid allocator type. template<typename _Tp> class allocator<const _Tp> { public: typedef _Tp value_type; template<typename _Up> allocator(const allocator<_Up>&) { } }; template<typename _Tp> class allocator<volatile _Tp> { public: typedef _Tp value_type; template<typename _Up> allocator(const allocator<_Up>&) { } }; template<typename _Tp> class allocator<const volatile _Tp> { public: typedef _Tp value_type; template<typename _Up> allocator(const allocator<_Up>&) { } }; /// @} group allocator // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template class allocator<char>; extern template class allocator<wchar_t>; #endif // Undefine. #undef __allocator_base // To implement Option 3 of DR 431. template<typename _Alloc, bool = __is_empty(_Alloc)> struct __alloc_swap { static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } }; template<typename _Alloc> struct __alloc_swap<_Alloc, false> { static void _S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT { // Precondition: swappable allocators. if (__one != __two) swap(__one, __two); } }; // Optimize for stateless allocators. template<typename _Alloc, bool = __is_empty(_Alloc)> struct __alloc_neq { static bool _S_do_it(const _Alloc&, const _Alloc&) { return false; } }; template<typename _Alloc> struct __alloc_neq<_Alloc, false> { static bool _S_do_it(const _Alloc& __one, const _Alloc& __two) { return __one != __two; } }; #if __cplusplus >= 201103L template<typename _Tp, bool = __or_<is_copy_constructible<typename _Tp::value_type>, is_nothrow_move_constructible<typename _Tp::value_type>>::value> struct __shrink_to_fit_aux { static bool _S_do_it(_Tp&) noexcept { return false; } }; template<typename _Tp> struct __shrink_to_fit_aux<_Tp, true> { static bool _S_do_it(_Tp& __c) noexcept { #if __cpp_exceptions try { _Tp(__make_move_if_noexcept_iterator(__c.begin()), __make_move_if_noexcept_iterator(__c.end()), __c.get_allocator()).swap(__c); return true; } catch(...) { return false; } #else return false; #endif } }; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/valarray_before.h 0000644 00000044121 15146341150 0011542 0 ustar 00 // The template and inlines for the -*- C++ -*- internal _Meta class. // Copyright (C) 1997-2018 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/valarray_before.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{valarray} */ // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr> #ifndef _VALARRAY_BEFORE_H #define _VALARRAY_BEFORE_H 1 #pragma GCC system_header #include <bits/slice_array.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // // Implementing a loosened valarray return value is tricky. // First we need to meet 26.3.1/3: we should not add more than // two levels of template nesting. Therefore we resort to template // template to "flatten" loosened return value types. // At some point we use partial specialization to remove one level // template nesting due to _Expr<> // // This class is NOT defined. It doesn't need to. template<typename _Tp1, typename _Tp2> class _Constant; // Implementations of unary functions applied to valarray<>s. // I use hard-coded object functions here instead of a generic // approach like pointers to function: // 1) correctness: some functions take references, others values. // we can't deduce the correct type afterwards. // 2) efficiency -- object functions can be easily inlined // 3) be Koenig-lookup-friendly struct _Abs { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return abs(__t); } }; struct _Cos { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return cos(__t); } }; struct _Acos { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return acos(__t); } }; struct _Cosh { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return cosh(__t); } }; struct _Sin { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return sin(__t); } }; struct _Asin { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return asin(__t); } }; struct _Sinh { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return sinh(__t); } }; struct _Tan { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return tan(__t); } }; struct _Atan { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return atan(__t); } }; struct _Tanh { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return tanh(__t); } }; struct _Exp { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return exp(__t); } }; struct _Log { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return log(__t); } }; struct _Log10 { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return log10(__t); } }; struct _Sqrt { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return sqrt(__t); } }; // In the past, we used to tailor operator applications semantics // to the specialization of standard function objects (i.e. plus<>, etc.) // That is incorrect. Therefore we provide our own surrogates. struct __unary_plus { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return +__t; } }; struct __negate { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return -__t; } }; struct __bitwise_not { template<typename _Tp> _Tp operator()(const _Tp& __t) const { return ~__t; } }; struct __plus { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } }; struct __minus { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } }; struct __multiplies { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } }; struct __divides { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } }; struct __modulus { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } }; struct __bitwise_xor { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x ^ __y; } }; struct __bitwise_and { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x & __y; } }; struct __bitwise_or { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x | __y; } }; struct __shift_left { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x << __y; } }; struct __shift_right { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x >> __y; } }; struct __logical_and { template<typename _Tp> bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } }; struct __logical_or { template<typename _Tp> bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } }; struct __logical_not { template<typename _Tp> bool operator()(const _Tp& __x) const { return !__x; } }; struct __equal_to { template<typename _Tp> bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } }; struct __not_equal_to { template<typename _Tp> bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } }; struct __less { template<typename _Tp> bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } }; struct __greater { template<typename _Tp> bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; struct __less_equal { template<typename _Tp> bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } }; struct __greater_equal { template<typename _Tp> bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } }; // The few binary functions we miss. struct _Atan2 { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return atan2(__x, __y); } }; struct _Pow { template<typename _Tp> _Tp operator()(const _Tp& __x, const _Tp& __y) const { return pow(__x, __y); } }; template<typename _Tp, bool _IsValidValarrayValue = !__is_abstract(_Tp)> struct __fun_with_valarray { typedef _Tp result_type; }; template<typename _Tp> struct __fun_with_valarray<_Tp, false> { // No result type defined for invalid value types. }; // We need these bits in order to recover the return type of // some functions/operators now that we're no longer using // function templates. template<typename, typename _Tp> struct __fun : __fun_with_valarray<_Tp> { }; // several specializations for relational operators. template<typename _Tp> struct __fun<__logical_not, _Tp> { typedef bool result_type; }; template<typename _Tp> struct __fun<__logical_and, _Tp> { typedef bool result_type; }; template<typename _Tp> struct __fun<__logical_or, _Tp> { typedef bool result_type; }; template<typename _Tp> struct __fun<__less, _Tp> { typedef bool result_type; }; template<typename _Tp> struct __fun<__greater, _Tp> { typedef bool result_type; }; template<typename _Tp> struct __fun<__less_equal, _Tp> { typedef bool result_type; }; template<typename _Tp> struct __fun<__greater_equal, _Tp> { typedef bool result_type; }; template<typename _Tp> struct __fun<__equal_to, _Tp> { typedef bool result_type; }; template<typename _Tp> struct __fun<__not_equal_to, _Tp> { typedef bool result_type; }; // // Apply function taking a value/const reference closure // template<typename _Dom, typename _Arg> class _FunBase { public: typedef typename _Dom::value_type value_type; _FunBase(const _Dom& __e, value_type __f(_Arg)) : _M_expr(__e), _M_func(__f) {} value_type operator[](size_t __i) const { return _M_func (_M_expr[__i]); } size_t size() const { return _M_expr.size ();} private: const _Dom& _M_expr; value_type (*_M_func)(_Arg); }; template<class _Dom> struct _ValFunClos<_Expr,_Dom> : _FunBase<_Dom, typename _Dom::value_type> { typedef _FunBase<_Dom, typename _Dom::value_type> _Base; typedef typename _Base::value_type value_type; typedef value_type _Tp; _ValFunClos(const _Dom& __e, _Tp __f(_Tp)) : _Base(__e, __f) {} }; template<typename _Tp> struct _ValFunClos<_ValArray,_Tp> : _FunBase<valarray<_Tp>, _Tp> { typedef _FunBase<valarray<_Tp>, _Tp> _Base; typedef _Tp value_type; _ValFunClos(const valarray<_Tp>& __v, _Tp __f(_Tp)) : _Base(__v, __f) {} }; template<class _Dom> struct _RefFunClos<_Expr, _Dom> : _FunBase<_Dom, const typename _Dom::value_type&> { typedef _FunBase<_Dom, const typename _Dom::value_type&> _Base; typedef typename _Base::value_type value_type; typedef value_type _Tp; _RefFunClos(const _Dom& __e, _Tp __f(const _Tp&)) : _Base(__e, __f) {} }; template<typename _Tp> struct _RefFunClos<_ValArray, _Tp> : _FunBase<valarray<_Tp>, const _Tp&> { typedef _FunBase<valarray<_Tp>, const _Tp&> _Base; typedef _Tp value_type; _RefFunClos(const valarray<_Tp>& __v, _Tp __f(const _Tp&)) : _Base(__v, __f) {} }; // // Unary expression closure. // template<class _Oper, class _Arg> class _UnBase { public: typedef typename _Arg::value_type _Vt; typedef typename __fun<_Oper, _Vt>::result_type value_type; _UnBase(const _Arg& __e) : _M_expr(__e) {} value_type operator[](size_t __i) const { return _Oper()(_M_expr[__i]); } size_t size() const { return _M_expr.size(); } private: const _Arg& _M_expr; }; template<class _Oper, class _Dom> struct _UnClos<_Oper, _Expr, _Dom> : _UnBase<_Oper, _Dom> { typedef _Dom _Arg; typedef _UnBase<_Oper, _Dom> _Base; typedef typename _Base::value_type value_type; _UnClos(const _Arg& __e) : _Base(__e) {} }; template<class _Oper, typename _Tp> struct _UnClos<_Oper, _ValArray, _Tp> : _UnBase<_Oper, valarray<_Tp> > { typedef valarray<_Tp> _Arg; typedef _UnBase<_Oper, valarray<_Tp> > _Base; typedef typename _Base::value_type value_type; _UnClos(const _Arg& __e) : _Base(__e) {} }; // // Binary expression closure. // template<class _Oper, class _FirstArg, class _SecondArg> class _BinBase { public: typedef typename _FirstArg::value_type _Vt; typedef typename __fun<_Oper, _Vt>::result_type value_type; _BinBase(const _FirstArg& __e1, const _SecondArg& __e2) : _M_expr1(__e1), _M_expr2(__e2) {} value_type operator[](size_t __i) const { return _Oper()(_M_expr1[__i], _M_expr2[__i]); } size_t size() const { return _M_expr1.size(); } private: const _FirstArg& _M_expr1; const _SecondArg& _M_expr2; }; template<class _Oper, class _Clos> class _BinBase2 { public: typedef typename _Clos::value_type _Vt; typedef typename __fun<_Oper, _Vt>::result_type value_type; _BinBase2(const _Clos& __e, const _Vt& __t) : _M_expr1(__e), _M_expr2(__t) {} value_type operator[](size_t __i) const { return _Oper()(_M_expr1[__i], _M_expr2); } size_t size() const { return _M_expr1.size(); } private: const _Clos& _M_expr1; const _Vt& _M_expr2; }; template<class _Oper, class _Clos> class _BinBase1 { public: typedef typename _Clos::value_type _Vt; typedef typename __fun<_Oper, _Vt>::result_type value_type; _BinBase1(const _Vt& __t, const _Clos& __e) : _M_expr1(__t), _M_expr2(__e) {} value_type operator[](size_t __i) const { return _Oper()(_M_expr1, _M_expr2[__i]); } size_t size() const { return _M_expr2.size(); } private: const _Vt& _M_expr1; const _Clos& _M_expr2; }; template<class _Oper, class _Dom1, class _Dom2> struct _BinClos<_Oper, _Expr, _Expr, _Dom1, _Dom2> : _BinBase<_Oper, _Dom1, _Dom2> { typedef _BinBase<_Oper, _Dom1, _Dom2> _Base; typedef typename _Base::value_type value_type; _BinClos(const _Dom1& __e1, const _Dom2& __e2) : _Base(__e1, __e2) {} }; template<class _Oper, typename _Tp> struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp> : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > { typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base; typedef typename _Base::value_type value_type; _BinClos(const valarray<_Tp>& __v, const valarray<_Tp>& __w) : _Base(__v, __w) {} }; template<class _Oper, class _Dom> struct _BinClos<_Oper, _Expr, _ValArray, _Dom, typename _Dom::value_type> : _BinBase<_Oper, _Dom, valarray<typename _Dom::value_type> > { typedef typename _Dom::value_type _Tp; typedef _BinBase<_Oper,_Dom,valarray<_Tp> > _Base; typedef typename _Base::value_type value_type; _BinClos(const _Dom& __e1, const valarray<_Tp>& __e2) : _Base(__e1, __e2) {} }; template<class _Oper, class _Dom> struct _BinClos<_Oper, _ValArray, _Expr, typename _Dom::value_type, _Dom> : _BinBase<_Oper, valarray<typename _Dom::value_type>,_Dom> { typedef typename _Dom::value_type _Tp; typedef _BinBase<_Oper, valarray<_Tp>, _Dom> _Base; typedef typename _Base::value_type value_type; _BinClos(const valarray<_Tp>& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} }; template<class _Oper, class _Dom> struct _BinClos<_Oper, _Expr, _Constant, _Dom, typename _Dom::value_type> : _BinBase2<_Oper, _Dom> { typedef typename _Dom::value_type _Tp; typedef _BinBase2<_Oper,_Dom> _Base; typedef typename _Base::value_type value_type; _BinClos(const _Dom& __e1, const _Tp& __e2) : _Base(__e1, __e2) {} }; template<class _Oper, class _Dom> struct _BinClos<_Oper, _Constant, _Expr, typename _Dom::value_type, _Dom> : _BinBase1<_Oper, _Dom> { typedef typename _Dom::value_type _Tp; typedef _BinBase1<_Oper, _Dom> _Base; typedef typename _Base::value_type value_type; _BinClos(const _Tp& __e1, const _Dom& __e2) : _Base(__e1, __e2) {} }; template<class _Oper, typename _Tp> struct _BinClos<_Oper, _ValArray, _Constant, _Tp, _Tp> : _BinBase2<_Oper, valarray<_Tp> > { typedef _BinBase2<_Oper,valarray<_Tp> > _Base; typedef typename _Base::value_type value_type; _BinClos(const valarray<_Tp>& __v, const _Tp& __t) : _Base(__v, __t) {} }; template<class _Oper, typename _Tp> struct _BinClos<_Oper, _Constant, _ValArray, _Tp, _Tp> : _BinBase1<_Oper, valarray<_Tp> > { typedef _BinBase1<_Oper, valarray<_Tp> > _Base; typedef typename _Base::value_type value_type; _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} }; // // slice_array closure. // template<typename _Dom> class _SBase { public: typedef typename _Dom::value_type value_type; _SBase (const _Dom& __e, const slice& __s) : _M_expr (__e), _M_slice (__s) {} value_type operator[] (size_t __i) const { return _M_expr[_M_slice.start () + __i * _M_slice.stride ()]; } size_t size() const { return _M_slice.size (); } private: const _Dom& _M_expr; const slice& _M_slice; }; template<typename _Tp> class _SBase<_Array<_Tp> > { public: typedef _Tp value_type; _SBase (_Array<_Tp> __a, const slice& __s) : _M_array (__a._M_data+__s.start()), _M_size (__s.size()), _M_stride (__s.stride()) {} value_type operator[] (size_t __i) const { return _M_array._M_data[__i * _M_stride]; } size_t size() const { return _M_size; } private: const _Array<_Tp> _M_array; const size_t _M_size; const size_t _M_stride; }; template<class _Dom> struct _SClos<_Expr, _Dom> : _SBase<_Dom> { typedef _SBase<_Dom> _Base; typedef typename _Base::value_type value_type; _SClos (const _Dom& __e, const slice& __s) : _Base (__e, __s) {} }; template<typename _Tp> struct _SClos<_ValArray, _Tp> : _SBase<_Array<_Tp> > { typedef _SBase<_Array<_Tp> > _Base; typedef _Tp value_type; _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _CPP_VALARRAY_BEFORE_H */ c++/8/bits/std_mutex.h 0000644 00000022122 15146341150 0010410 0 ustar 00 // std::mutex implementation -*- C++ -*- // Copyright (C) 2003-2018 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/std_mutex.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{mutex} */ #ifndef _GLIBCXX_MUTEX_H #define _GLIBCXX_MUTEX_H 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <system_error> #include <bits/functexcept.h> #include <bits/gthr.h> #include <bits/move.h> // for std::swap #ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup mutexes Mutexes * @ingroup concurrency * * Classes for mutex support. * @{ */ #ifdef _GLIBCXX_HAS_GTHREADS // Common base class for std::mutex and std::timed_mutex class __mutex_base { protected: typedef __gthread_mutex_t __native_type; #ifdef __GTHREAD_MUTEX_INIT __native_type _M_mutex = __GTHREAD_MUTEX_INIT; constexpr __mutex_base() noexcept = default; #else __native_type _M_mutex; __mutex_base() noexcept { // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may) __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex); } ~__mutex_base() noexcept { __gthread_mutex_destroy(&_M_mutex); } #endif __mutex_base(const __mutex_base&) = delete; __mutex_base& operator=(const __mutex_base&) = delete; }; /// The standard mutex type. class mutex : private __mutex_base { public: typedef __native_type* native_handle_type; #ifdef __GTHREAD_MUTEX_INIT constexpr #endif mutex() noexcept = default; ~mutex() = default; mutex(const mutex&) = delete; mutex& operator=(const mutex&) = delete; void lock() { int __e = __gthread_mutex_lock(&_M_mutex); // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may) if (__e) __throw_system_error(__e); } bool try_lock() noexcept { // XXX EINVAL, EAGAIN, EBUSY return !__gthread_mutex_trylock(&_M_mutex); } void unlock() { // XXX EINVAL, EAGAIN, EPERM __gthread_mutex_unlock(&_M_mutex); } native_handle_type native_handle() noexcept { return &_M_mutex; } }; #endif // _GLIBCXX_HAS_GTHREADS /// Do not acquire ownership of the mutex. struct defer_lock_t { explicit defer_lock_t() = default; }; /// Try to acquire ownership of the mutex without blocking. struct try_to_lock_t { explicit try_to_lock_t() = default; }; /// Assume the calling thread has already obtained mutex ownership /// and manage it. struct adopt_lock_t { explicit adopt_lock_t() = default; }; /// Tag used to prevent a scoped lock from acquiring ownership of a mutex. _GLIBCXX17_INLINE constexpr defer_lock_t defer_lock { }; /// Tag used to prevent a scoped lock from blocking if a mutex is locked. _GLIBCXX17_INLINE constexpr try_to_lock_t try_to_lock { }; /// Tag used to make a scoped lock take ownership of a locked mutex. _GLIBCXX17_INLINE constexpr adopt_lock_t adopt_lock { }; /** @brief A simple scoped lock type. * * A lock_guard controls mutex ownership within a scope, releasing * ownership in the destructor. */ template<typename _Mutex> class lock_guard { public: typedef _Mutex mutex_type; explicit lock_guard(mutex_type& __m) : _M_device(__m) { _M_device.lock(); } lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m) { } // calling thread owns mutex ~lock_guard() { _M_device.unlock(); } lock_guard(const lock_guard&) = delete; lock_guard& operator=(const lock_guard&) = delete; private: mutex_type& _M_device; }; /** @brief A movable scoped lock type. * * A unique_lock controls mutex ownership within a scope. Ownership of the * mutex can be delayed until after construction and can be transferred * to another unique_lock by move construction or move assignment. If a * mutex lock is owned when the destructor runs ownership will be released. */ template<typename _Mutex> class unique_lock { public: typedef _Mutex mutex_type; unique_lock() noexcept : _M_device(0), _M_owns(false) { } explicit unique_lock(mutex_type& __m) : _M_device(std::__addressof(__m)), _M_owns(false) { lock(); _M_owns = true; } unique_lock(mutex_type& __m, defer_lock_t) noexcept : _M_device(std::__addressof(__m)), _M_owns(false) { } unique_lock(mutex_type& __m, try_to_lock_t) : _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock()) { } unique_lock(mutex_type& __m, adopt_lock_t) noexcept : _M_device(std::__addressof(__m)), _M_owns(true) { // XXX calling thread owns mutex } template<typename _Clock, typename _Duration> unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __atime) : _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock_until(__atime)) { } template<typename _Rep, typename _Period> unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rtime) : _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock_for(__rtime)) { } ~unique_lock() { if (_M_owns) unlock(); } unique_lock(const unique_lock&) = delete; unique_lock& operator=(const unique_lock&) = delete; unique_lock(unique_lock&& __u) noexcept : _M_device(__u._M_device), _M_owns(__u._M_owns) { __u._M_device = 0; __u._M_owns = false; } unique_lock& operator=(unique_lock&& __u) noexcept { if(_M_owns) unlock(); unique_lock(std::move(__u)).swap(*this); __u._M_device = 0; __u._M_owns = false; return *this; } void lock() { if (!_M_device) __throw_system_error(int(errc::operation_not_permitted)); else if (_M_owns) __throw_system_error(int(errc::resource_deadlock_would_occur)); else { _M_device->lock(); _M_owns = true; } } bool try_lock() { if (!_M_device) __throw_system_error(int(errc::operation_not_permitted)); else if (_M_owns) __throw_system_error(int(errc::resource_deadlock_would_occur)); else { _M_owns = _M_device->try_lock(); return _M_owns; } } template<typename _Clock, typename _Duration> bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime) { if (!_M_device) __throw_system_error(int(errc::operation_not_permitted)); else if (_M_owns) __throw_system_error(int(errc::resource_deadlock_would_occur)); else { _M_owns = _M_device->try_lock_until(__atime); return _M_owns; } } template<typename _Rep, typename _Period> bool try_lock_for(const chrono::duration<_Rep, _Period>& __rtime) { if (!_M_device) __throw_system_error(int(errc::operation_not_permitted)); else if (_M_owns) __throw_system_error(int(errc::resource_deadlock_would_occur)); else { _M_owns = _M_device->try_lock_for(__rtime); return _M_owns; } } void unlock() { if (!_M_owns) __throw_system_error(int(errc::operation_not_permitted)); else if (_M_device) { _M_device->unlock(); _M_owns = false; } } void swap(unique_lock& __u) noexcept { std::swap(_M_device, __u._M_device); std::swap(_M_owns, __u._M_owns); } mutex_type* release() noexcept { mutex_type* __ret = _M_device; _M_device = 0; _M_owns = false; return __ret; } bool owns_lock() const noexcept { return _M_owns; } explicit operator bool() const noexcept { return owns_lock(); } mutex_type* mutex() const noexcept { return _M_device; } private: mutex_type* _M_device; bool _M_owns; // XXX use atomic_bool }; /// Swap overload for unique_lock objects. template<typename _Mutex> inline void swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) noexcept { __x.swap(__y); } // @} group mutexes _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif // _GLIBCXX_MUTEX_H c++/8/bits/std_function.h 0000644 00000055334 15146341150 0011106 0 ustar 00 // Implementation of std::function -*- C++ -*- // Copyright (C) 2004-2018 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/std_function.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{functional} */ #ifndef _GLIBCXX_STD_FUNCTION_H #define _GLIBCXX_STD_FUNCTION_H 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #if __cpp_rtti # include <typeinfo> #endif #include <bits/stl_function.h> #include <bits/invoke.h> #include <bits/refwrap.h> #include <bits/functexcept.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Exception class thrown when class template function's * operator() is called with an empty target. * @ingroup exceptions */ class bad_function_call : public std::exception { public: virtual ~bad_function_call() noexcept; const char* what() const noexcept; }; /** * Trait identifying "location-invariant" types, meaning that the * address of the object (or any of its members) will not escape. * Trivially copyable types are location-invariant and users can * specialize this trait for other types. */ template<typename _Tp> struct __is_location_invariant : is_trivially_copyable<_Tp>::type { }; class _Undefined_class; union _Nocopy_types { void* _M_object; const void* _M_const_object; void (*_M_function_pointer)(); void (_Undefined_class::*_M_member_pointer)(); }; union [[gnu::may_alias]] _Any_data { void* _M_access() { return &_M_pod_data[0]; } const void* _M_access() const { return &_M_pod_data[0]; } template<typename _Tp> _Tp& _M_access() { return *static_cast<_Tp*>(_M_access()); } template<typename _Tp> const _Tp& _M_access() const { return *static_cast<const _Tp*>(_M_access()); } _Nocopy_types _M_unused; char _M_pod_data[sizeof(_Nocopy_types)]; }; enum _Manager_operation { __get_type_info, __get_functor_ptr, __clone_functor, __destroy_functor }; // Simple type wrapper that helps avoid annoying const problems // when casting between void pointers and pointers-to-pointers. template<typename _Tp> struct _Simple_type_wrapper { _Simple_type_wrapper(_Tp __value) : __value(__value) { } _Tp __value; }; template<typename _Tp> struct __is_location_invariant<_Simple_type_wrapper<_Tp> > : __is_location_invariant<_Tp> { }; template<typename _Signature> class function; /// Base class of all polymorphic function object wrappers. class _Function_base { public: static const std::size_t _M_max_size = sizeof(_Nocopy_types); static const std::size_t _M_max_align = __alignof__(_Nocopy_types); template<typename _Functor> class _Base_manager { protected: static const bool __stored_locally = (__is_location_invariant<_Functor>::value && sizeof(_Functor) <= _M_max_size && __alignof__(_Functor) <= _M_max_align && (_M_max_align % __alignof__(_Functor) == 0)); typedef integral_constant<bool, __stored_locally> _Local_storage; // Retrieve a pointer to the function object static _Functor* _M_get_pointer(const _Any_data& __source) { const _Functor* __ptr = __stored_locally? std::__addressof(__source._M_access<_Functor>()) /* have stored a pointer */ : __source._M_access<_Functor*>(); return const_cast<_Functor*>(__ptr); } // Clone a location-invariant function object that fits within // an _Any_data structure. static void _M_clone(_Any_data& __dest, const _Any_data& __source, true_type) { ::new (__dest._M_access()) _Functor(__source._M_access<_Functor>()); } // Clone a function object that is not location-invariant or // that cannot fit into an _Any_data structure. static void _M_clone(_Any_data& __dest, const _Any_data& __source, false_type) { __dest._M_access<_Functor*>() = new _Functor(*__source._M_access<_Functor*>()); } // Destroying a location-invariant object may still require // destruction. static void _M_destroy(_Any_data& __victim, true_type) { __victim._M_access<_Functor>().~_Functor(); } // Destroying an object located on the heap. static void _M_destroy(_Any_data& __victim, false_type) { delete __victim._M_access<_Functor*>(); } public: static bool _M_manager(_Any_data& __dest, const _Any_data& __source, _Manager_operation __op) { switch (__op) { #if __cpp_rtti case __get_type_info: __dest._M_access<const type_info*>() = &typeid(_Functor); break; #endif case __get_functor_ptr: __dest._M_access<_Functor*>() = _M_get_pointer(__source); break; case __clone_functor: _M_clone(__dest, __source, _Local_storage()); break; case __destroy_functor: _M_destroy(__dest, _Local_storage()); break; } return false; } static void _M_init_functor(_Any_data& __functor, _Functor&& __f) { _M_init_functor(__functor, std::move(__f), _Local_storage()); } template<typename _Signature> static bool _M_not_empty_function(const function<_Signature>& __f) { return static_cast<bool>(__f); } template<typename _Tp> static bool _M_not_empty_function(_Tp* __fp) { return __fp != nullptr; } template<typename _Class, typename _Tp> static bool _M_not_empty_function(_Tp _Class::* __mp) { return __mp != nullptr; } template<typename _Tp> static bool _M_not_empty_function(const _Tp&) { return true; } private: static void _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type) { ::new (__functor._M_access()) _Functor(std::move(__f)); } static void _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type) { __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); } }; _Function_base() : _M_manager(nullptr) { } ~_Function_base() { if (_M_manager) _M_manager(_M_functor, _M_functor, __destroy_functor); } bool _M_empty() const { return !_M_manager; } typedef bool (*_Manager_type)(_Any_data&, const _Any_data&, _Manager_operation); _Any_data _M_functor; _Manager_type _M_manager; }; template<typename _Signature, typename _Functor> class _Function_handler; template<typename _Res, typename _Functor, typename... _ArgTypes> class _Function_handler<_Res(_ArgTypes...), _Functor> : public _Function_base::_Base_manager<_Functor> { typedef _Function_base::_Base_manager<_Functor> _Base; public: static _Res _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) { return (*_Base::_M_get_pointer(__functor))( std::forward<_ArgTypes>(__args)...); } }; template<typename _Functor, typename... _ArgTypes> class _Function_handler<void(_ArgTypes...), _Functor> : public _Function_base::_Base_manager<_Functor> { typedef _Function_base::_Base_manager<_Functor> _Base; public: static void _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) { (*_Base::_M_get_pointer(__functor))( std::forward<_ArgTypes>(__args)...); } }; template<typename _Class, typename _Member, typename _Res, typename... _ArgTypes> class _Function_handler<_Res(_ArgTypes...), _Member _Class::*> : public _Function_handler<void(_ArgTypes...), _Member _Class::*> { typedef _Function_handler<void(_ArgTypes...), _Member _Class::*> _Base; public: static _Res _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) { return std::__invoke(_Base::_M_get_pointer(__functor)->__value, std::forward<_ArgTypes>(__args)...); } }; template<typename _Class, typename _Member, typename... _ArgTypes> class _Function_handler<void(_ArgTypes...), _Member _Class::*> : public _Function_base::_Base_manager< _Simple_type_wrapper< _Member _Class::* > > { typedef _Member _Class::* _Functor; typedef _Simple_type_wrapper<_Functor> _Wrapper; typedef _Function_base::_Base_manager<_Wrapper> _Base; public: static bool _M_manager(_Any_data& __dest, const _Any_data& __source, _Manager_operation __op) { switch (__op) { #if __cpp_rtti case __get_type_info: __dest._M_access<const type_info*>() = &typeid(_Functor); break; #endif case __get_functor_ptr: __dest._M_access<_Functor*>() = &_Base::_M_get_pointer(__source)->__value; break; default: _Base::_M_manager(__dest, __source, __op); } return false; } static void _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) { std::__invoke(_Base::_M_get_pointer(__functor)->__value, std::forward<_ArgTypes>(__args)...); } }; template<typename _From, typename _To> using __check_func_return_type = __or_<is_void<_To>, is_same<_From, _To>, is_convertible<_From, _To>>; /** * @brief Primary class template for std::function. * @ingroup functors * * Polymorphic function wrapper. */ template<typename _Res, typename... _ArgTypes> class function<_Res(_ArgTypes...)> : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>, private _Function_base { template<typename _Func, typename _Res2 = typename result_of<_Func&(_ArgTypes...)>::type> struct _Callable : __check_func_return_type<_Res2, _Res> { }; // Used so the return type convertibility checks aren't done when // performing overload resolution for copy construction/assignment. template<typename _Tp> struct _Callable<function, _Tp> : false_type { }; template<typename _Cond, typename _Tp> using _Requires = typename enable_if<_Cond::value, _Tp>::type; public: typedef _Res result_type; // [3.7.2.1] construct/copy/destroy /** * @brief Default construct creates an empty function call wrapper. * @post @c !(bool)*this */ function() noexcept : _Function_base() { } /** * @brief Creates an empty function call wrapper. * @post @c !(bool)*this */ function(nullptr_t) noexcept : _Function_base() { } /** * @brief %Function copy constructor. * @param __x A %function object with identical call signature. * @post @c bool(*this) == bool(__x) * * The newly-created %function contains a copy of the target of @a * __x (if it has one). */ function(const function& __x); /** * @brief %Function move constructor. * @param __x A %function object rvalue with identical call signature. * * The newly-created %function contains the target of @a __x * (if it has one). */ function(function&& __x) noexcept : _Function_base() { __x.swap(*this); } /** * @brief Builds a %function that targets a copy of the incoming * function object. * @param __f A %function object that is callable with parameters of * type @c T1, @c T2, ..., @c TN and returns a value convertible * to @c Res. * * The newly-created %function object will target a copy of * @a __f. If @a __f is @c reference_wrapper<F>, then this function * object will contain a reference to the function object @c * __f.get(). If @a __f is a NULL function pointer or NULL * pointer-to-member, the newly-created object will be empty. * * If @a __f is a non-NULL function pointer or an object of type @c * reference_wrapper<F>, this function will not throw. */ template<typename _Functor, typename = _Requires<__not_<is_same<_Functor, function>>, void>, typename = _Requires<_Callable<_Functor>, void>> function(_Functor); /** * @brief %Function assignment operator. * @param __x A %function with identical call signature. * @post @c (bool)*this == (bool)x * @returns @c *this * * The target of @a __x is copied to @c *this. If @a __x has no * target, then @c *this will be empty. * * If @a __x targets a function pointer or a reference to a function * object, then this operation will not throw an %exception. */ function& operator=(const function& __x) { function(__x).swap(*this); return *this; } /** * @brief %Function move-assignment operator. * @param __x A %function rvalue with identical call signature. * @returns @c *this * * The target of @a __x is moved to @c *this. If @a __x has no * target, then @c *this will be empty. * * If @a __x targets a function pointer or a reference to a function * object, then this operation will not throw an %exception. */ function& operator=(function&& __x) noexcept { function(std::move(__x)).swap(*this); return *this; } /** * @brief %Function assignment to zero. * @post @c !(bool)*this * @returns @c *this * * The target of @c *this is deallocated, leaving it empty. */ function& operator=(nullptr_t) noexcept { if (_M_manager) { _M_manager(_M_functor, _M_functor, __destroy_functor); _M_manager = nullptr; _M_invoker = nullptr; } return *this; } /** * @brief %Function assignment to a new target. * @param __f A %function object that is callable with parameters of * type @c T1, @c T2, ..., @c TN and returns a value convertible * to @c Res. * @return @c *this * * This %function object wrapper will target a copy of @a * __f. If @a __f is @c reference_wrapper<F>, then this function * object will contain a reference to the function object @c * __f.get(). If @a __f is a NULL function pointer or NULL * pointer-to-member, @c this object will be empty. * * If @a __f is a non-NULL function pointer or an object of type @c * reference_wrapper<F>, this function will not throw. */ template<typename _Functor> _Requires<_Callable<typename decay<_Functor>::type>, function&> operator=(_Functor&& __f) { function(std::forward<_Functor>(__f)).swap(*this); return *this; } /// @overload template<typename _Functor> function& operator=(reference_wrapper<_Functor> __f) noexcept { function(__f).swap(*this); return *this; } // [3.7.2.2] function modifiers /** * @brief Swap the targets of two %function objects. * @param __x A %function with identical call signature. * * Swap the targets of @c this function object and @a __f. This * function will not throw an %exception. */ void swap(function& __x) noexcept { std::swap(_M_functor, __x._M_functor); std::swap(_M_manager, __x._M_manager); std::swap(_M_invoker, __x._M_invoker); } // [3.7.2.3] function capacity /** * @brief Determine if the %function wrapper has a target. * * @return @c true when this %function object contains a target, * or @c false when it is empty. * * This function will not throw an %exception. */ explicit operator bool() const noexcept { return !_M_empty(); } // [3.7.2.4] function invocation /** * @brief Invokes the function targeted by @c *this. * @returns the result of the target. * @throws bad_function_call when @c !(bool)*this * * The function call operator invokes the target function object * stored by @c this. */ _Res operator()(_ArgTypes... __args) const; #if __cpp_rtti // [3.7.2.5] function target access /** * @brief Determine the type of the target of this function object * wrapper. * * @returns the type identifier of the target function object, or * @c typeid(void) if @c !(bool)*this. * * This function will not throw an %exception. */ const type_info& target_type() const noexcept; /** * @brief Access the stored target function object. * * @return Returns a pointer to the stored target function object, * if @c typeid(_Functor).equals(target_type()); otherwise, a NULL * pointer. * * This function does not throw exceptions. * * @{ */ template<typename _Functor> _Functor* target() noexcept; template<typename _Functor> const _Functor* target() const noexcept; // @} #endif private: using _Invoker_type = _Res (*)(const _Any_data&, _ArgTypes&&...); _Invoker_type _M_invoker; }; #if __cpp_deduction_guides >= 201606 template<typename> struct __function_guide_helper { }; template<typename _Res, typename _Tp, bool _Nx, typename... _Args> struct __function_guide_helper< _Res (_Tp::*) (_Args...) noexcept(_Nx) > { using type = _Res(_Args...); }; template<typename _Res, typename _Tp, bool _Nx, typename... _Args> struct __function_guide_helper< _Res (_Tp::*) (_Args...) & noexcept(_Nx) > { using type = _Res(_Args...); }; template<typename _Res, typename _Tp, bool _Nx, typename... _Args> struct __function_guide_helper< _Res (_Tp::*) (_Args...) const noexcept(_Nx) > { using type = _Res(_Args...); }; template<typename _Res, typename _Tp, bool _Nx, typename... _Args> struct __function_guide_helper< _Res (_Tp::*) (_Args...) const & noexcept(_Nx) > { using type = _Res(_Args...); }; template<typename _Res, typename... _ArgTypes> function(_Res(*)(_ArgTypes...)) -> function<_Res(_ArgTypes...)>; template<typename _Functor, typename _Signature = typename __function_guide_helper<decltype(&_Functor::operator())>::type> function(_Functor) -> function<_Signature>; #endif // Out-of-line member definitions. template<typename _Res, typename... _ArgTypes> function<_Res(_ArgTypes...)>:: function(const function& __x) : _Function_base() { if (static_cast<bool>(__x)) { __x._M_manager(_M_functor, __x._M_functor, __clone_functor); _M_invoker = __x._M_invoker; _M_manager = __x._M_manager; } } template<typename _Res, typename... _ArgTypes> template<typename _Functor, typename, typename> function<_Res(_ArgTypes...)>:: function(_Functor __f) : _Function_base() { typedef _Function_handler<_Res(_ArgTypes...), _Functor> _My_handler; if (_My_handler::_M_not_empty_function(__f)) { _My_handler::_M_init_functor(_M_functor, std::move(__f)); _M_invoker = &_My_handler::_M_invoke; _M_manager = &_My_handler::_M_manager; } } template<typename _Res, typename... _ArgTypes> _Res function<_Res(_ArgTypes...)>:: operator()(_ArgTypes... __args) const { if (_M_empty()) __throw_bad_function_call(); return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...); } #if __cpp_rtti template<typename _Res, typename... _ArgTypes> const type_info& function<_Res(_ArgTypes...)>:: target_type() const noexcept { if (_M_manager) { _Any_data __typeinfo_result; _M_manager(__typeinfo_result, _M_functor, __get_type_info); return *__typeinfo_result._M_access<const type_info*>(); } else return typeid(void); } template<typename _Res, typename... _ArgTypes> template<typename _Functor> _Functor* function<_Res(_ArgTypes...)>:: target() noexcept { const function* __const_this = this; const _Functor* __func = __const_this->template target<_Functor>(); return const_cast<_Functor*>(__func); } template<typename _Res, typename... _ArgTypes> template<typename _Functor> const _Functor* function<_Res(_ArgTypes...)>:: target() const noexcept { if (typeid(_Functor) == target_type() && _M_manager) { _Any_data __ptr; _M_manager(__ptr, _M_functor, __get_functor_ptr); return __ptr._M_access<const _Functor*>(); } else return nullptr; } #endif // [20.7.15.2.6] null pointer comparisons /** * @brief Compares a polymorphic function object wrapper against 0 * (the NULL pointer). * @returns @c true if the wrapper has no target, @c false otherwise * * This function will not throw an %exception. */ template<typename _Res, typename... _Args> inline bool operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept { return !static_cast<bool>(__f); } /// @overload template<typename _Res, typename... _Args> inline bool operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept { return !static_cast<bool>(__f); } /** * @brief Compares a polymorphic function object wrapper against 0 * (the NULL pointer). * @returns @c false if the wrapper has no target, @c true otherwise * * This function will not throw an %exception. */ template<typename _Res, typename... _Args> inline bool operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept { return static_cast<bool>(__f); } /// @overload template<typename _Res, typename... _Args> inline bool operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept { return static_cast<bool>(__f); } // [20.7.15.2.7] specialized algorithms /** * @brief Swap the targets of two polymorphic function object wrappers. * * This function will not throw an %exception. */ // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2062. Effect contradictions w/o no-throw guarantee of std::function swaps template<typename _Res, typename... _Args> inline void swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y) noexcept { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_STD_FUNCTION_H c++/8/bits/stl_queue.h 0000644 00000057011 15146341150 0010407 0 ustar 00 // Queue implementation -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_queue.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{queue} */ #ifndef _STL_QUEUE_H #define _STL_QUEUE_H 1 #include <bits/concept_check.h> #include <debug/debug.h> #if __cplusplus >= 201103L # include <bits/uses_allocator.h> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief A standard container giving FIFO behavior. * * @ingroup sequences * * @tparam _Tp Type of element. * @tparam _Sequence Type of underlying sequence, defaults to deque<_Tp>. * * Meets many of the requirements of a * <a href="tables.html#65">container</a>, * but does not define anything to do with iterators. Very few of the * other standard container interfaces are defined. * * This is not a true container, but an @e adaptor. It holds another * container, and provides a wrapper interface to that container. The * wrapper is what enforces strict first-in-first-out %queue behavior. * * The second template parameter defines the type of the underlying * sequence/container. It defaults to std::deque, but it can be any type * that supports @c front, @c back, @c push_back, and @c pop_front, * such as std::list or an appropriate user-defined type. * * Members not found in @a normal containers are @c container_type, * which is a typedef for the second Sequence parameter, and @c push and * @c pop, which are standard %queue/FIFO operations. */ template<typename _Tp, typename _Sequence = deque<_Tp> > class queue { #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename _Sequence::value_type _Sequence_value_type; # if __cplusplus < 201103L __glibcxx_class_requires(_Tp, _SGIAssignableConcept) # endif __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept) __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) #endif template<typename _Tp1, typename _Seq1> friend bool operator==(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); template<typename _Tp1, typename _Seq1> friend bool operator<(const queue<_Tp1, _Seq1>&, const queue<_Tp1, _Seq1>&); #if __cplusplus >= 201103L template<typename _Alloc> using _Uses = typename enable_if<uses_allocator<_Sequence, _Alloc>::value>::type; #endif public: typedef typename _Sequence::value_type value_type; typedef typename _Sequence::reference reference; typedef typename _Sequence::const_reference const_reference; typedef typename _Sequence::size_type size_type; typedef _Sequence container_type; protected: /* Maintainers wondering why this isn't uglified as per style * guidelines should note that this name is specified in the standard, * C++98 [23.2.3.1]. * (Why? Presumably for the same reason that it's protected instead * of private: to allow derivation. But none of the other * containers allow for derivation. Odd.) */ /// @c c is the underlying container. _Sequence c; public: /** * @brief Default constructor creates no elements. */ #if __cplusplus < 201103L explicit queue(const _Sequence& __c = _Sequence()) : c(__c) { } #else template<typename _Seq = _Sequence, typename _Requires = typename enable_if<is_default_constructible<_Seq>::value>::type> queue() : c() { } explicit queue(const _Sequence& __c) : c(__c) { } explicit queue(_Sequence&& __c) : c(std::move(__c)) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> explicit queue(const _Alloc& __a) : c(__a) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> queue(const _Sequence& __c, const _Alloc& __a) : c(__c, __a) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> queue(_Sequence&& __c, const _Alloc& __a) : c(std::move(__c), __a) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> queue(const queue& __q, const _Alloc& __a) : c(__q.c, __a) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> queue(queue&& __q, const _Alloc& __a) : c(std::move(__q.c), __a) { } #endif /** * Returns true if the %queue is empty. */ bool empty() const { return c.empty(); } /** Returns the number of elements in the %queue. */ size_type size() const { return c.size(); } /** * Returns a read/write reference to the data at the first * element of the %queue. */ reference front() { __glibcxx_requires_nonempty(); return c.front(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %queue. */ const_reference front() const { __glibcxx_requires_nonempty(); return c.front(); } /** * Returns a read/write reference to the data at the last * element of the %queue. */ reference back() { __glibcxx_requires_nonempty(); return c.back(); } /** * Returns a read-only (constant) reference to the data at the last * element of the %queue. */ const_reference back() const { __glibcxx_requires_nonempty(); return c.back(); } /** * @brief Add data to the end of the %queue. * @param __x Data to be added. * * This is a typical %queue operation. The function creates an * element at the end of the %queue and assigns the given data * to it. The time complexity of the operation depends on the * underlying sequence. */ void push(const value_type& __x) { c.push_back(__x); } #if __cplusplus >= 201103L void push(value_type&& __x) { c.push_back(std::move(__x)); } #if __cplusplus > 201402L template<typename... _Args> decltype(auto) emplace(_Args&&... __args) { return c.emplace_back(std::forward<_Args>(__args)...); } #else template<typename... _Args> void emplace(_Args&&... __args) { c.emplace_back(std::forward<_Args>(__args)...); } #endif #endif /** * @brief Removes first element. * * This is a typical %queue operation. It shrinks the %queue by one. * The time complexity of the operation depends on the underlying * sequence. * * Note that no data is returned, and if the first element's * data is needed, it should be retrieved before pop() is * called. */ void pop() { __glibcxx_requires_nonempty(); c.pop_front(); } #if __cplusplus >= 201103L void swap(queue& __q) #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 noexcept(__is_nothrow_swappable<_Sequence>::value) #else noexcept(__is_nothrow_swappable<_Tp>::value) #endif { using std::swap; swap(c, __q.c); } #endif // __cplusplus >= 201103L }; #if __cpp_deduction_guides >= 201606 template<typename _Container, typename = enable_if_t<!__is_allocator<_Container>::value>> queue(_Container) -> queue<typename _Container::value_type, _Container>; template<typename _Container, typename _Allocator, typename = enable_if_t<!__is_allocator<_Container>::value>, typename = enable_if_t<__is_allocator<_Allocator>::value>> queue(_Container, _Allocator) -> queue<typename _Container::value_type, _Container>; #endif /** * @brief Queue equality comparison. * @param __x A %queue. * @param __y A %queue of the same type as @a __x. * @return True iff the size and elements of the queues are equal. * * This is an equivalence relation. Complexity and semantics depend on the * underlying sequence type, but the expected rules are: this relation is * linear in the size of the sequences, and queues are considered equivalent * if their sequences compare equal. */ template<typename _Tp, typename _Seq> inline bool operator==(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) { return __x.c == __y.c; } /** * @brief Queue ordering relation. * @param __x A %queue. * @param __y A %queue of the same type as @a x. * @return True iff @a __x is lexicographically less than @a __y. * * This is an total ordering relation. Complexity and semantics * depend on the underlying sequence type, but the expected rules * are: this relation is linear in the size of the sequences, the * elements must be comparable with @c <, and * std::lexicographical_compare() is usually used to make the * determination. */ template<typename _Tp, typename _Seq> inline bool operator<(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) { return __x.c < __y.c; } /// Based on operator== template<typename _Tp, typename _Seq> inline bool operator!=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) { return !(__x == __y); } /// Based on operator< template<typename _Tp, typename _Seq> inline bool operator>(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) { return __y < __x; } /// Based on operator< template<typename _Tp, typename _Seq> inline bool operator<=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) { return !(__y < __x); } /// Based on operator< template<typename _Tp, typename _Seq> inline bool operator>=(const queue<_Tp, _Seq>& __x, const queue<_Tp, _Seq>& __y) { return !(__x < __y); } #if __cplusplus >= 201103L template<typename _Tp, typename _Seq> inline #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 // Constrained free swap overload, see p0185r1 typename enable_if<__is_swappable<_Seq>::value>::type #else void #endif swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<typename _Tp, typename _Seq, typename _Alloc> struct uses_allocator<queue<_Tp, _Seq>, _Alloc> : public uses_allocator<_Seq, _Alloc>::type { }; #endif // __cplusplus >= 201103L /** * @brief A standard container automatically sorting its contents. * * @ingroup sequences * * @tparam _Tp Type of element. * @tparam _Sequence Type of underlying sequence, defaults to vector<_Tp>. * @tparam _Compare Comparison function object type, defaults to * less<_Sequence::value_type>. * * This is not a true container, but an @e adaptor. It holds * another container, and provides a wrapper interface to that * container. The wrapper is what enforces priority-based sorting * and %queue behavior. Very few of the standard container/sequence * interface requirements are met (e.g., iterators). * * The second template parameter defines the type of the underlying * sequence/container. It defaults to std::vector, but it can be * any type that supports @c front(), @c push_back, @c pop_back, * and random-access iterators, such as std::deque or an * appropriate user-defined type. * * The third template parameter supplies the means of making * priority comparisons. It defaults to @c less<value_type> but * can be anything defining a strict weak ordering. * * Members not found in @a normal containers are @c container_type, * which is a typedef for the second Sequence parameter, and @c * push, @c pop, and @c top, which are standard %queue operations. * * @note No equality/comparison operators are provided for * %priority_queue. * * @note Sorting of the elements takes place as they are added to, * and removed from, the %priority_queue using the * %priority_queue's member functions. If you access the elements * by other means, and change their data such that the sorting * order would be different, the %priority_queue will not re-sort * the elements for you. (How could it know to do so?) */ template<typename _Tp, typename _Sequence = vector<_Tp>, typename _Compare = less<typename _Sequence::value_type> > class priority_queue { #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename _Sequence::value_type _Sequence_value_type; # if __cplusplus < 201103L __glibcxx_class_requires(_Tp, _SGIAssignableConcept) # endif __glibcxx_class_requires(_Sequence, _SequenceConcept) __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept) __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) __glibcxx_class_requires4(_Compare, bool, _Tp, _Tp, _BinaryFunctionConcept) #endif #if __cplusplus >= 201103L template<typename _Alloc> using _Uses = typename enable_if<uses_allocator<_Sequence, _Alloc>::value>::type; #endif public: typedef typename _Sequence::value_type value_type; typedef typename _Sequence::reference reference; typedef typename _Sequence::const_reference const_reference; typedef typename _Sequence::size_type size_type; typedef _Sequence container_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 2684. priority_queue lacking comparator typedef typedef _Compare value_compare; protected: // See queue::c for notes on these names. _Sequence c; _Compare comp; public: /** * @brief Default constructor creates no elements. */ #if __cplusplus < 201103L explicit priority_queue(const _Compare& __x = _Compare(), const _Sequence& __s = _Sequence()) : c(__s), comp(__x) { std::make_heap(c.begin(), c.end(), comp); } #else template<typename _Seq = _Sequence, typename _Requires = typename enable_if<__and_<is_default_constructible<_Compare>, is_default_constructible<_Seq>>::value>::type> priority_queue() : c(), comp() { } explicit priority_queue(const _Compare& __x, const _Sequence& __s) : c(__s), comp(__x) { std::make_heap(c.begin(), c.end(), comp); } explicit priority_queue(const _Compare& __x, _Sequence&& __s = _Sequence()) : c(std::move(__s)), comp(__x) { std::make_heap(c.begin(), c.end(), comp); } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> explicit priority_queue(const _Alloc& __a) : c(__a), comp() { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> priority_queue(const _Compare& __x, const _Alloc& __a) : c(__a), comp(__x) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2537. Constructors [...] taking allocators should call make_heap template<typename _Alloc, typename _Requires = _Uses<_Alloc>> priority_queue(const _Compare& __x, const _Sequence& __c, const _Alloc& __a) : c(__c, __a), comp(__x) { std::make_heap(c.begin(), c.end(), comp); } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> priority_queue(const _Compare& __x, _Sequence&& __c, const _Alloc& __a) : c(std::move(__c), __a), comp(__x) { std::make_heap(c.begin(), c.end(), comp); } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> priority_queue(const priority_queue& __q, const _Alloc& __a) : c(__q.c, __a), comp(__q.comp) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> priority_queue(priority_queue&& __q, const _Alloc& __a) : c(std::move(__q.c), __a), comp(std::move(__q.comp)) { } #endif /** * @brief Builds a %queue from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __x A comparison functor describing a strict weak ordering. * @param __s An initial sequence with which to start. * * Begins by copying @a __s, inserting a copy of the elements * from @a [first,last) into the copy of @a __s, then ordering * the copy according to @a __x. * * For more information on function objects, see the * documentation on @link functors functor base * classes@endlink. */ #if __cplusplus < 201103L template<typename _InputIterator> priority_queue(_InputIterator __first, _InputIterator __last, const _Compare& __x = _Compare(), const _Sequence& __s = _Sequence()) : c(__s), comp(__x) { __glibcxx_requires_valid_range(__first, __last); c.insert(c.end(), __first, __last); std::make_heap(c.begin(), c.end(), comp); } #else template<typename _InputIterator> priority_queue(_InputIterator __first, _InputIterator __last, const _Compare& __x, const _Sequence& __s) : c(__s), comp(__x) { __glibcxx_requires_valid_range(__first, __last); c.insert(c.end(), __first, __last); std::make_heap(c.begin(), c.end(), comp); } template<typename _InputIterator> priority_queue(_InputIterator __first, _InputIterator __last, const _Compare& __x = _Compare(), _Sequence&& __s = _Sequence()) : c(std::move(__s)), comp(__x) { __glibcxx_requires_valid_range(__first, __last); c.insert(c.end(), __first, __last); std::make_heap(c.begin(), c.end(), comp); } #endif /** * Returns true if the %queue is empty. */ bool empty() const { return c.empty(); } /** Returns the number of elements in the %queue. */ size_type size() const { return c.size(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %queue. */ const_reference top() const { __glibcxx_requires_nonempty(); return c.front(); } /** * @brief Add data to the %queue. * @param __x Data to be added. * * This is a typical %queue operation. * The time complexity of the operation depends on the underlying * sequence. */ void push(const value_type& __x) { c.push_back(__x); std::push_heap(c.begin(), c.end(), comp); } #if __cplusplus >= 201103L void push(value_type&& __x) { c.push_back(std::move(__x)); std::push_heap(c.begin(), c.end(), comp); } template<typename... _Args> void emplace(_Args&&... __args) { c.emplace_back(std::forward<_Args>(__args)...); std::push_heap(c.begin(), c.end(), comp); } #endif /** * @brief Removes first element. * * This is a typical %queue operation. It shrinks the %queue * by one. The time complexity of the operation depends on the * underlying sequence. * * Note that no data is returned, and if the first element's * data is needed, it should be retrieved before pop() is * called. */ void pop() { __glibcxx_requires_nonempty(); std::pop_heap(c.begin(), c.end(), comp); c.pop_back(); } #if __cplusplus >= 201103L void swap(priority_queue& __pq) noexcept(__and_< #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 __is_nothrow_swappable<_Sequence>, #else __is_nothrow_swappable<_Tp>, #endif __is_nothrow_swappable<_Compare> >::value) { using std::swap; swap(c, __pq.c); swap(comp, __pq.comp); } #endif // __cplusplus >= 201103L }; #if __cpp_deduction_guides >= 201606 template<typename _Compare, typename _Container, typename = enable_if_t<!__is_allocator<_Compare>::value>, typename = enable_if_t<!__is_allocator<_Container>::value>> priority_queue(_Compare, _Container) -> priority_queue<typename _Container::value_type, _Container, _Compare>; template<typename _InputIterator, typename _ValT = typename iterator_traits<_InputIterator>::value_type, typename _Compare = less<_ValT>, typename _Container = vector<_ValT>, typename = _RequireInputIter<_InputIterator>, typename = enable_if_t<!__is_allocator<_Compare>::value>, typename = enable_if_t<!__is_allocator<_Container>::value>> priority_queue(_InputIterator, _InputIterator, _Compare = _Compare(), _Container = _Container()) -> priority_queue<_ValT, _Container, _Compare>; template<typename _Compare, typename _Container, typename _Allocator, typename = enable_if_t<!__is_allocator<_Compare>::value>, typename = enable_if_t<!__is_allocator<_Container>::value>, typename = enable_if_t<__is_allocator<_Allocator>::value>> priority_queue(_Compare, _Container, _Allocator) -> priority_queue<typename _Container::value_type, _Container, _Compare>; #endif // No equality/comparison operators are provided for priority_queue. #if __cplusplus >= 201103L template<typename _Tp, typename _Sequence, typename _Compare> inline #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 // Constrained free swap overload, see p0185r1 typename enable_if<__and_<__is_swappable<_Sequence>, __is_swappable<_Compare>>::value>::type #else void #endif swap(priority_queue<_Tp, _Sequence, _Compare>& __x, priority_queue<_Tp, _Sequence, _Compare>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<typename _Tp, typename _Sequence, typename _Compare, typename _Alloc> struct uses_allocator<priority_queue<_Tp, _Sequence, _Compare>, _Alloc> : public uses_allocator<_Sequence, _Alloc>::type { }; #endif // __cplusplus >= 201103L _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _STL_QUEUE_H */ c++/8/bits/vector.tcc 0000644 00000071714 15146341150 0010233 0 ustar 00 // Vector implementation (out of line) -*- C++ -*- // Copyright (C) 2001-2018 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 * 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/vector.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{vector} */ #ifndef _VECTOR_TCC #define _VECTOR_TCC 1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Alloc> void vector<_Tp, _Alloc>:: reserve(size_type __n) { if (__n > this->max_size()) __throw_length_error(__N("vector::reserve")); if (this->capacity() < __n) { const size_type __old_size = size(); pointer __tmp = _M_allocate_and_copy(__n, _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start), _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish)); _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); this->_M_impl._M_start = __tmp; this->_M_impl._M_finish = __tmp + __old_size; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; } } #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> template<typename... _Args> #if __cplusplus > 201402L typename vector<_Tp, _Alloc>::reference #else void #endif vector<_Tp, _Alloc>:: emplace_back(_Args&&... __args) { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, std::forward<_Args>(__args)...); ++this->_M_impl._M_finish; _GLIBCXX_ASAN_ANNOTATE_GREW(1); } else _M_realloc_insert(end(), std::forward<_Args>(__args)...); #if __cplusplus > 201402L return back(); #endif } #endif template<typename _Tp, typename _Alloc> typename vector<_Tp, _Alloc>::iterator vector<_Tp, _Alloc>:: #if __cplusplus >= 201103L insert(const_iterator __position, const value_type& __x) #else insert(iterator __position, const value_type& __x) #endif { const size_type __n = __position - begin(); if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) if (__position == end()) { _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x); ++this->_M_impl._M_finish; _GLIBCXX_ASAN_ANNOTATE_GREW(1); } else { #if __cplusplus >= 201103L const auto __pos = begin() + (__position - cbegin()); // __x could be an existing element of this vector, so make a // copy of it before _M_insert_aux moves elements around. _Temporary_value __x_copy(this, __x); _M_insert_aux(__pos, std::move(__x_copy._M_val())); #else _M_insert_aux(__position, __x); #endif } else #if __cplusplus >= 201103L _M_realloc_insert(begin() + (__position - cbegin()), __x); #else _M_realloc_insert(__position, __x); #endif return iterator(this->_M_impl._M_start + __n); } template<typename _Tp, typename _Alloc> typename vector<_Tp, _Alloc>::iterator vector<_Tp, _Alloc>:: _M_erase(iterator __position) { if (__position + 1 != end()) _GLIBCXX_MOVE3(__position + 1, end(), __position); --this->_M_impl._M_finish; _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); _GLIBCXX_ASAN_ANNOTATE_SHRINK(1); return __position; } template<typename _Tp, typename _Alloc> typename vector<_Tp, _Alloc>::iterator vector<_Tp, _Alloc>:: _M_erase(iterator __first, iterator __last) { if (__first != __last) { if (__last != end()) _GLIBCXX_MOVE3(__last, end(), __first); _M_erase_at_end(__first.base() + (end() - __last)); } return __first; } template<typename _Tp, typename _Alloc> vector<_Tp, _Alloc>& vector<_Tp, _Alloc>:: operator=(const vector<_Tp, _Alloc>& __x) { if (&__x != this) { _GLIBCXX_ASAN_ANNOTATE_REINIT; #if __cplusplus >= 201103L if (_Alloc_traits::_S_propagate_on_copy_assign()) { if (!_Alloc_traits::_S_always_equal() && _M_get_Tp_allocator() != __x._M_get_Tp_allocator()) { // replacement allocator cannot free existing storage this->clear(); _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); this->_M_impl._M_start = nullptr; this->_M_impl._M_finish = nullptr; this->_M_impl._M_end_of_storage = nullptr; } std::__alloc_on_copy(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); } #endif const size_type __xlen = __x.size(); if (__xlen > capacity()) { pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); this->_M_impl._M_start = __tmp; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; } else if (size() >= __xlen) { std::_Destroy(std::copy(__x.begin(), __x.end(), begin()), end(), _M_get_Tp_allocator()); } else { std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(), this->_M_impl._M_start); std::__uninitialized_copy_a(__x._M_impl._M_start + size(), __x._M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); } this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; } return *this; } template<typename _Tp, typename _Alloc> void vector<_Tp, _Alloc>:: _M_fill_assign(size_t __n, const value_type& __val) { if (__n > capacity()) { vector __tmp(__n, __val, _M_get_Tp_allocator()); __tmp._M_impl._M_swap_data(this->_M_impl); } else if (__n > size()) { std::fill(begin(), end(), __val); const size_type __add = __n - size(); _GLIBCXX_ASAN_ANNOTATE_GROW(__add); this->_M_impl._M_finish = std::__uninitialized_fill_n_a(this->_M_impl._M_finish, __add, __val, _M_get_Tp_allocator()); _GLIBCXX_ASAN_ANNOTATE_GREW(__add); } else _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val)); } template<typename _Tp, typename _Alloc> template<typename _InputIterator> void vector<_Tp, _Alloc>:: _M_assign_aux(_InputIterator __first, _InputIterator __last, std::input_iterator_tag) { pointer __cur(this->_M_impl._M_start); for (; __first != __last && __cur != this->_M_impl._M_finish; ++__cur, ++__first) *__cur = *__first; if (__first == __last) _M_erase_at_end(__cur); else _M_range_insert(end(), __first, __last, std::__iterator_category(__first)); } template<typename _Tp, typename _Alloc> template<typename _ForwardIterator> void vector<_Tp, _Alloc>:: _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { const size_type __len = std::distance(__first, __last); if (__len > capacity()) { pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); this->_M_impl._M_start = __tmp; this->_M_impl._M_finish = this->_M_impl._M_start + __len; this->_M_impl._M_end_of_storage = this->_M_impl._M_finish; } else if (size() >= __len) _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start)); else { _ForwardIterator __mid = __first; std::advance(__mid, size()); std::copy(__first, __mid, this->_M_impl._M_start); const size_type __attribute__((__unused__)) __n = __len - size(); _GLIBCXX_ASAN_ANNOTATE_GROW(__n); this->_M_impl._M_finish = std::__uninitialized_copy_a(__mid, __last, this->_M_impl._M_finish, _M_get_Tp_allocator()); _GLIBCXX_ASAN_ANNOTATE_GREW(__n); } } #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> auto vector<_Tp, _Alloc>:: _M_insert_rval(const_iterator __position, value_type&& __v) -> iterator { const auto __n = __position - cbegin(); if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) if (__position == cend()) { _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, std::move(__v)); ++this->_M_impl._M_finish; _GLIBCXX_ASAN_ANNOTATE_GREW(1); } else _M_insert_aux(begin() + __n, std::move(__v)); else _M_realloc_insert(begin() + __n, std::move(__v)); return iterator(this->_M_impl._M_start + __n); } template<typename _Tp, typename _Alloc> template<typename... _Args> auto vector<_Tp, _Alloc>:: _M_emplace_aux(const_iterator __position, _Args&&... __args) -> iterator { const auto __n = __position - cbegin(); if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) if (__position == cend()) { _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, std::forward<_Args>(__args)...); ++this->_M_impl._M_finish; _GLIBCXX_ASAN_ANNOTATE_GREW(1); } else { // We need to construct a temporary because something in __args... // could alias one of the elements of the container and so we // need to use it before _M_insert_aux moves elements around. _Temporary_value __tmp(this, std::forward<_Args>(__args)...); _M_insert_aux(begin() + __n, std::move(__tmp._M_val())); } else _M_realloc_insert(begin() + __n, std::forward<_Args>(__args)...); return iterator(this->_M_impl._M_start + __n); } template<typename _Tp, typename _Alloc> template<typename _Arg> void vector<_Tp, _Alloc>:: _M_insert_aux(iterator __position, _Arg&& __arg) #else template<typename _Tp, typename _Alloc> void vector<_Tp, _Alloc>:: _M_insert_aux(iterator __position, const _Tp& __x) #endif { _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, _GLIBCXX_MOVE(*(this->_M_impl._M_finish - 1))); ++this->_M_impl._M_finish; _GLIBCXX_ASAN_ANNOTATE_GREW(1); #if __cplusplus < 201103L _Tp __x_copy = __x; #endif _GLIBCXX_MOVE_BACKWARD3(__position.base(), this->_M_impl._M_finish - 2, this->_M_impl._M_finish - 1); #if __cplusplus < 201103L *__position = __x_copy; #else *__position = std::forward<_Arg>(__arg); #endif } #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> template<typename... _Args> void vector<_Tp, _Alloc>:: _M_realloc_insert(iterator __position, _Args&&... __args) #else template<typename _Tp, typename _Alloc> void vector<_Tp, _Alloc>:: _M_realloc_insert(iterator __position, const _Tp& __x) #endif { const size_type __len = _M_check_len(size_type(1), "vector::_M_realloc_insert"); pointer __old_start = this->_M_impl._M_start; pointer __old_finish = this->_M_impl._M_finish; const size_type __elems_before = __position - begin(); pointer __new_start(this->_M_allocate(__len)); pointer __new_finish(__new_start); __try { // The order of the three operations is dictated by the C++11 // case, where the moves could alter a new element belonging // to the existing vector. This is an issue only for callers // taking the element by lvalue ref (see last bullet of C++11 // [res.on.arguments]). _Alloc_traits::construct(this->_M_impl, __new_start + __elems_before, #if __cplusplus >= 201103L std::forward<_Args>(__args)...); #else __x); #endif __new_finish = pointer(); __new_finish = std::__uninitialized_move_if_noexcept_a (__old_start, __position.base(), __new_start, _M_get_Tp_allocator()); ++__new_finish; __new_finish = std::__uninitialized_move_if_noexcept_a (__position.base(), __old_finish, __new_finish, _M_get_Tp_allocator()); } __catch(...) { if (!__new_finish) _Alloc_traits::destroy(this->_M_impl, __new_start + __elems_before); else std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); _M_deallocate(__new_start, __len); __throw_exception_again; } _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(__old_start, __old_finish, _M_get_Tp_allocator()); _M_deallocate(__old_start, this->_M_impl._M_end_of_storage - __old_start); this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_finish; this->_M_impl._M_end_of_storage = __new_start + __len; } template<typename _Tp, typename _Alloc> void vector<_Tp, _Alloc>:: _M_fill_insert(iterator __position, size_type __n, const value_type& __x) { if (__n != 0) { if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { #if __cplusplus < 201103L value_type __x_copy = __x; #else _Temporary_value __tmp(this, __x); value_type& __x_copy = __tmp._M_val(); #endif const size_type __elems_after = end() - __position; pointer __old_finish(this->_M_impl._M_finish); if (__elems_after > __n) { _GLIBCXX_ASAN_ANNOTATE_GROW(__n); std::__uninitialized_move_a(this->_M_impl._M_finish - __n, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n; _GLIBCXX_ASAN_ANNOTATE_GREW(__n); _GLIBCXX_MOVE_BACKWARD3(__position.base(), __old_finish - __n, __old_finish); std::fill(__position.base(), __position.base() + __n, __x_copy); } else { _GLIBCXX_ASAN_ANNOTATE_GROW(__n); this->_M_impl._M_finish = std::__uninitialized_fill_n_a(this->_M_impl._M_finish, __n - __elems_after, __x_copy, _M_get_Tp_allocator()); _GLIBCXX_ASAN_ANNOTATE_GREW(__n - __elems_after); std::__uninitialized_move_a(__position.base(), __old_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __elems_after; _GLIBCXX_ASAN_ANNOTATE_GREW(__elems_after); std::fill(__position.base(), __old_finish, __x_copy); } } else { const size_type __len = _M_check_len(__n, "vector::_M_fill_insert"); const size_type __elems_before = __position - begin(); pointer __new_start(this->_M_allocate(__len)); pointer __new_finish(__new_start); __try { // See _M_realloc_insert above. std::__uninitialized_fill_n_a(__new_start + __elems_before, __n, __x, _M_get_Tp_allocator()); __new_finish = pointer(); __new_finish = std::__uninitialized_move_if_noexcept_a (this->_M_impl._M_start, __position.base(), __new_start, _M_get_Tp_allocator()); __new_finish += __n; __new_finish = std::__uninitialized_move_if_noexcept_a (__position.base(), this->_M_impl._M_finish, __new_finish, _M_get_Tp_allocator()); } __catch(...) { if (!__new_finish) std::_Destroy(__new_start + __elems_before, __new_start + __elems_before + __n, _M_get_Tp_allocator()); else std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); _M_deallocate(__new_start, __len); __throw_exception_again; } _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_finish; this->_M_impl._M_end_of_storage = __new_start + __len; } } } #if __cplusplus >= 201103L template<typename _Tp, typename _Alloc> void vector<_Tp, _Alloc>:: _M_default_append(size_type __n) { if (__n != 0) { const size_type __size = size(); size_type __navail = size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish); if (__size > max_size() || __navail > max_size() - __size) __builtin_unreachable(); if (__navail >= __n) { _GLIBCXX_ASAN_ANNOTATE_GROW(__n); this->_M_impl._M_finish = std::__uninitialized_default_n_a(this->_M_impl._M_finish, __n, _M_get_Tp_allocator()); _GLIBCXX_ASAN_ANNOTATE_GREW(__n); } else { const size_type __len = _M_check_len(__n, "vector::_M_default_append"); pointer __new_start(this->_M_allocate(__len)); pointer __destroy_from = pointer(); __try { std::__uninitialized_default_n_a(__new_start + __size, __n, _M_get_Tp_allocator()); __destroy_from = __new_start + __size; std::__uninitialized_move_if_noexcept_a( this->_M_impl._M_start, this->_M_impl._M_finish, __new_start, _M_get_Tp_allocator()); } __catch(...) { if (__destroy_from) std::_Destroy(__destroy_from, __destroy_from + __n, _M_get_Tp_allocator()); _M_deallocate(__new_start, __len); __throw_exception_again; } _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_start + __size + __n; this->_M_impl._M_end_of_storage = __new_start + __len; } } } template<typename _Tp, typename _Alloc> bool vector<_Tp, _Alloc>:: _M_shrink_to_fit() { if (capacity() == size()) return false; _GLIBCXX_ASAN_ANNOTATE_REINIT; return std::__shrink_to_fit_aux<vector>::_S_do_it(*this); } #endif template<typename _Tp, typename _Alloc> template<typename _InputIterator> void vector<_Tp, _Alloc>:: _M_range_insert(iterator __pos, _InputIterator __first, _InputIterator __last, std::input_iterator_tag) { if (__pos == end()) { for (; __first != __last; ++__first) insert(end(), *__first); } else if (__first != __last) { vector __tmp(__first, __last, _M_get_Tp_allocator()); insert(__pos, _GLIBCXX_MAKE_MOVE_ITERATOR(__tmp.begin()), _GLIBCXX_MAKE_MOVE_ITERATOR(__tmp.end())); } } template<typename _Tp, typename _Alloc> template<typename _ForwardIterator> void vector<_Tp, _Alloc>:: _M_range_insert(iterator __position, _ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { if (__first != __last) { const size_type __n = std::distance(__first, __last); if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { const size_type __elems_after = end() - __position; pointer __old_finish(this->_M_impl._M_finish); if (__elems_after > __n) { _GLIBCXX_ASAN_ANNOTATE_GROW(__n); std::__uninitialized_move_a(this->_M_impl._M_finish - __n, this->_M_impl._M_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n; _GLIBCXX_ASAN_ANNOTATE_GREW(__n); _GLIBCXX_MOVE_BACKWARD3(__position.base(), __old_finish - __n, __old_finish); std::copy(__first, __last, __position); } else { _ForwardIterator __mid = __first; std::advance(__mid, __elems_after); _GLIBCXX_ASAN_ANNOTATE_GROW(__n); std::__uninitialized_copy_a(__mid, __last, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n - __elems_after; _GLIBCXX_ASAN_ANNOTATE_GREW(__n - __elems_after); std::__uninitialized_move_a(__position.base(), __old_finish, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish += __elems_after; _GLIBCXX_ASAN_ANNOTATE_GREW(__elems_after); std::copy(__first, __mid, __position); } } else { const size_type __len = _M_check_len(__n, "vector::_M_range_insert"); pointer __new_start(this->_M_allocate(__len)); pointer __new_finish(__new_start); __try { __new_finish = std::__uninitialized_move_if_noexcept_a (this->_M_impl._M_start, __position.base(), __new_start, _M_get_Tp_allocator()); __new_finish = std::__uninitialized_copy_a(__first, __last, __new_finish, _M_get_Tp_allocator()); __new_finish = std::__uninitialized_move_if_noexcept_a (__position.base(), this->_M_impl._M_finish, __new_finish, _M_get_Tp_allocator()); } __catch(...) { std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); _M_deallocate(__new_start, __len); __throw_exception_again; } _GLIBCXX_ASAN_ANNOTATE_REINIT; std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - this->_M_impl._M_start); this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_finish; this->_M_impl._M_end_of_storage = __new_start + __len; } } } // vector<bool> template<typename _Alloc> void vector<bool, _Alloc>:: _M_reallocate(size_type __n) { _Bit_pointer __q = this->_M_allocate(__n); iterator __start(std::__addressof(*__q), 0); iterator __finish(_M_copy_aligned(begin(), end(), __start)); this->_M_deallocate(); this->_M_impl._M_start = __start; this->_M_impl._M_finish = __finish; this->_M_impl._M_end_of_storage = __q + _S_nword(__n); } template<typename _Alloc> void vector<bool, _Alloc>:: _M_fill_insert(iterator __position, size_type __n, bool __x) { if (__n == 0) return; if (capacity() - size() >= __n) { std::copy_backward(__position, end(), this->_M_impl._M_finish + difference_type(__n)); std::fill(__position, __position + difference_type(__n), __x); this->_M_impl._M_finish += difference_type(__n); } else { const size_type __len = _M_check_len(__n, "vector<bool>::_M_fill_insert"); _Bit_pointer __q = this->_M_allocate(__len); iterator __start(std::__addressof(*__q), 0); iterator __i = _M_copy_aligned(begin(), __position, __start); std::fill(__i, __i + difference_type(__n), __x); iterator __finish = std::copy(__position, end(), __i + difference_type(__n)); this->_M_deallocate(); this->_M_impl._M_end_of_storage = __q + _S_nword(__len); this->_M_impl._M_start = __start; this->_M_impl._M_finish = __finish; } } template<typename _Alloc> template<typename _ForwardIterator> void vector<bool, _Alloc>:: _M_insert_range(iterator __position, _ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { if (__first != __last) { size_type __n = std::distance(__first, __last); if (capacity() - size() >= __n) { std::copy_backward(__position, end(), this->_M_impl._M_finish + difference_type(__n)); std::copy(__first, __last, __position); this->_M_impl._M_finish += difference_type(__n); } else { const size_type __len = _M_check_len(__n, "vector<bool>::_M_insert_range"); _Bit_pointer __q = this->_M_allocate(__len); iterator __start(std::__addressof(*__q), 0); iterator __i = _M_copy_aligned(begin(), __position, __start); __i = std::copy(__first, __last, __i); iterator __finish = std::copy(__position, end(), __i); this->_M_deallocate(); this->_M_impl._M_end_of_storage = __q + _S_nword(__len); this->_M_impl._M_start = __start; this->_M_impl._M_finish = __finish; } } } template<typename _Alloc> void vector<bool, _Alloc>:: _M_insert_aux(iterator __position, bool __x) { if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr()) { std::copy_backward(__position, this->_M_impl._M_finish, this->_M_impl._M_finish + 1); *__position = __x; ++this->_M_impl._M_finish; } else { const size_type __len = _M_check_len(size_type(1), "vector<bool>::_M_insert_aux"); _Bit_pointer __q = this->_M_allocate(__len); iterator __start(std::__addressof(*__q), 0); iterator __i = _M_copy_aligned(begin(), __position, __start); *__i++ = __x; iterator __finish = std::copy(__position, end(), __i); this->_M_deallocate(); this->_M_impl._M_end_of_storage = __q + _S_nword(__len); this->_M_impl._M_start = __start; this->_M_impl._M_finish = __finish; } } template<typename _Alloc> typename vector<bool, _Alloc>::iterator vector<bool, _Alloc>:: _M_erase(iterator __position) { if (__position + 1 != end()) std::copy(__position + 1, end(), __position); --this->_M_impl._M_finish; return __position; } template<typename _Alloc> typename vector<bool, _Alloc>::iterator vector<bool, _Alloc>:: _M_erase(iterator __first, iterator __last) { if (__first != __last) _M_erase_at_end(std::copy(__last, end(), __first)); return __first; } #if __cplusplus >= 201103L template<typename _Alloc> bool vector<bool, _Alloc>:: _M_shrink_to_fit() { if (capacity() - size() < int(_S_word_bit)) return false; __try { _M_reallocate(size()); return true; } __catch(...) { return false; } } #endif _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #if __cplusplus >= 201103L namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Alloc> size_t hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>:: operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>& __b) const noexcept { size_t __hash = 0; using _GLIBCXX_STD_C::_S_word_bit; using _GLIBCXX_STD_C::_Bit_type; const size_t __words = __b.size() / _S_word_bit; if (__words) { const size_t __clength = __words * sizeof(_Bit_type); __hash = std::_Hash_impl::hash(__b._M_impl._M_start._M_p, __clength); } const size_t __extrabits = __b.size() % _S_word_bit; if (__extrabits) { _Bit_type __hiword = *__b._M_impl._M_finish._M_p; __hiword &= ~((~static_cast<_Bit_type>(0)) << __extrabits); const size_t __clength = (__extrabits + __CHAR_BIT__ - 1) / __CHAR_BIT__; if (__words) __hash = std::_Hash_impl::hash(&__hiword, __clength, __hash); else __hash = std::_Hash_impl::hash(&__hiword, __clength); } return __hash; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #undef _GLIBCXX_ASAN_ANNOTATE_REINIT #undef _GLIBCXX_ASAN_ANNOTATE_GROW #undef _GLIBCXX_ASAN_ANNOTATE_GREW #undef _GLIBCXX_ASAN_ANNOTATE_SHRINK #endif /* _VECTOR_TCC */ c++/8/bits/atomic_futex.h 0000644 00000022550 15146341150 0011070 0 ustar 00 // -*- C++ -*- header. // Copyright (C) 2015-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/atomic_futex.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. */ #ifndef _GLIBCXX_ATOMIC_FUTEX_H #define _GLIBCXX_ATOMIC_FUTEX_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <atomic> #include <chrono> #if ! (defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1) #include <mutex> #include <condition_variable> #endif #ifndef _GLIBCXX_ALWAYS_INLINE #define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) #if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1 struct __atomic_futex_unsigned_base { // Returns false iff a timeout occurred. bool _M_futex_wait_until(unsigned *__addr, unsigned __val, bool __has_timeout, chrono::seconds __s, chrono::nanoseconds __ns); // This can be executed after the object has been destroyed. static void _M_futex_notify_all(unsigned* __addr); }; template <unsigned _Waiter_bit = 0x80000000> class __atomic_futex_unsigned : __atomic_futex_unsigned_base { typedef chrono::system_clock __clock_t; // This must be lock-free and at offset 0. atomic<unsigned> _M_data; public: explicit __atomic_futex_unsigned(unsigned __data) : _M_data(__data) { } _GLIBCXX_ALWAYS_INLINE unsigned _M_load(memory_order __mo) { return _M_data.load(__mo) & ~_Waiter_bit; } private: // If a timeout occurs, returns a current value after the timeout; // otherwise, returns the operand's value if equal is true or a different // value if equal is false. // The assumed value is the caller's assumption about the current value // when making the call. unsigned _M_load_and_test_until(unsigned __assumed, unsigned __operand, bool __equal, memory_order __mo, bool __has_timeout, chrono::seconds __s, chrono::nanoseconds __ns) { for (;;) { // Don't bother checking the value again because we expect the caller // to have done it recently. // memory_order_relaxed is sufficient because we can rely on just the // modification order (store_notify uses an atomic RMW operation too), // and the futex syscalls synchronize between themselves. _M_data.fetch_or(_Waiter_bit, memory_order_relaxed); bool __ret = _M_futex_wait_until((unsigned*)(void*)&_M_data, __assumed | _Waiter_bit, __has_timeout, __s, __ns); // Fetch the current value after waiting (clears _Waiter_bit). __assumed = _M_load(__mo); if (!__ret || ((__operand == __assumed) == __equal)) return __assumed; // TODO adapt wait time } } // Returns the operand's value if equal is true or a different value if // equal is false. // The assumed value is the caller's assumption about the current value // when making the call. unsigned _M_load_and_test(unsigned __assumed, unsigned __operand, bool __equal, memory_order __mo) { return _M_load_and_test_until(__assumed, __operand, __equal, __mo, false, {}, {}); } // If a timeout occurs, returns a current value after the timeout; // otherwise, returns the operand's value if equal is true or a different // value if equal is false. // The assumed value is the caller's assumption about the current value // when making the call. template<typename _Dur> unsigned _M_load_and_test_until_impl(unsigned __assumed, unsigned __operand, bool __equal, memory_order __mo, const chrono::time_point<__clock_t, _Dur>& __atime) { auto __s = chrono::time_point_cast<chrono::seconds>(__atime); auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s); // XXX correct? return _M_load_and_test_until(__assumed, __operand, __equal, __mo, true, __s.time_since_epoch(), __ns); } public: _GLIBCXX_ALWAYS_INLINE unsigned _M_load_when_not_equal(unsigned __val, memory_order __mo) { unsigned __i = _M_load(__mo); if ((__i & ~_Waiter_bit) != __val) return (__i & ~_Waiter_bit); // TODO Spin-wait first. return _M_load_and_test(__i, __val, false, __mo); } _GLIBCXX_ALWAYS_INLINE void _M_load_when_equal(unsigned __val, memory_order __mo) { unsigned __i = _M_load(__mo); if ((__i & ~_Waiter_bit) == __val) return; // TODO Spin-wait first. _M_load_and_test(__i, __val, true, __mo); } // Returns false iff a timeout occurred. template<typename _Rep, typename _Period> _GLIBCXX_ALWAYS_INLINE bool _M_load_when_equal_for(unsigned __val, memory_order __mo, const chrono::duration<_Rep, _Period>& __rtime) { return _M_load_when_equal_until(__val, __mo, __clock_t::now() + __rtime); } // Returns false iff a timeout occurred. template<typename _Clock, typename _Duration> _GLIBCXX_ALWAYS_INLINE bool _M_load_when_equal_until(unsigned __val, memory_order __mo, const chrono::time_point<_Clock, _Duration>& __atime) { // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __atime - __c_entry; const auto __s_atime = __s_entry + __delta; return _M_load_when_equal_until(__val, __mo, __s_atime); } // Returns false iff a timeout occurred. template<typename _Duration> _GLIBCXX_ALWAYS_INLINE bool _M_load_when_equal_until(unsigned __val, memory_order __mo, const chrono::time_point<__clock_t, _Duration>& __atime) { unsigned __i = _M_load(__mo); if ((__i & ~_Waiter_bit) == __val) return true; // TODO Spin-wait first. Ignore effect on timeout. __i = _M_load_and_test_until_impl(__i, __val, true, __mo, __atime); return (__i & ~_Waiter_bit) == __val; } _GLIBCXX_ALWAYS_INLINE void _M_store_notify_all(unsigned __val, memory_order __mo) { unsigned* __futex = (unsigned *)(void *)&_M_data; if (_M_data.exchange(__val, __mo) & _Waiter_bit) _M_futex_notify_all(__futex); } }; #else // ! (_GLIBCXX_HAVE_LINUX_FUTEX && ATOMIC_INT_LOCK_FREE > 1) // If futexes are not available, use a mutex and a condvar to wait. // Because we access the data only within critical sections, all accesses // are sequentially consistent; thus, we satisfy any provided memory_order. template <unsigned _Waiter_bit = 0x80000000> class __atomic_futex_unsigned { typedef chrono::system_clock __clock_t; unsigned _M_data; mutex _M_mutex; condition_variable _M_condvar; public: explicit __atomic_futex_unsigned(unsigned __data) : _M_data(__data) { } _GLIBCXX_ALWAYS_INLINE unsigned _M_load(memory_order __mo) { unique_lock<mutex> __lock(_M_mutex); return _M_data; } _GLIBCXX_ALWAYS_INLINE unsigned _M_load_when_not_equal(unsigned __val, memory_order __mo) { unique_lock<mutex> __lock(_M_mutex); while (_M_data == __val) _M_condvar.wait(__lock); return _M_data; } _GLIBCXX_ALWAYS_INLINE void _M_load_when_equal(unsigned __val, memory_order __mo) { unique_lock<mutex> __lock(_M_mutex); while (_M_data != __val) _M_condvar.wait(__lock); } template<typename _Rep, typename _Period> _GLIBCXX_ALWAYS_INLINE bool _M_load_when_equal_for(unsigned __val, memory_order __mo, const chrono::duration<_Rep, _Period>& __rtime) { unique_lock<mutex> __lock(_M_mutex); return _M_condvar.wait_for(__lock, __rtime, [&] { return _M_data == __val;}); } template<typename _Clock, typename _Duration> _GLIBCXX_ALWAYS_INLINE bool _M_load_when_equal_until(unsigned __val, memory_order __mo, const chrono::time_point<_Clock, _Duration>& __atime) { unique_lock<mutex> __lock(_M_mutex); return _M_condvar.wait_until(__lock, __atime, [&] { return _M_data == __val;}); } _GLIBCXX_ALWAYS_INLINE void _M_store_notify_all(unsigned __val, memory_order __mo) { unique_lock<mutex> __lock(_M_mutex); _M_data = __val; _M_condvar.notify_all(); } }; #endif // _GLIBCXX_HAVE_LINUX_FUTEX && ATOMIC_INT_LOCK_FREE > 1 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/regex_compiler.tcc 0000644 00000045530 15146341150 0011732 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2013-2018 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/regex_compiler.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ // FIXME make comments doxygen format. /* // This compiler refers to "Regular Expression Matching Can Be Simple And Fast" // (http://swtch.com/~rsc/regexp/regexp1.html), // but doesn't strictly follow it. // // When compiling, states are *chained* instead of tree- or graph-constructed. // It's more like structured programs: there's if statement and loop statement. // // For alternative structure (say "a|b"), aka "if statement", two branches // should be constructed. However, these two shall merge to an "end_tag" at // the end of this operator: // // branch1 // / \ // => begin_tag end_tag => // \ / // branch2 // // This is the difference between this implementation and that in Russ's // article. // // That's why we introduced dummy node here ------ "end_tag" is a dummy node. // All dummy nodes will be eliminated at the end of compilation. */ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { template<typename _TraitsT> _Compiler<_TraitsT>:: _Compiler(_IterT __b, _IterT __e, const typename _TraitsT::locale_type& __loc, _FlagT __flags) : _M_flags((__flags & (regex_constants::ECMAScript | regex_constants::basic | regex_constants::extended | regex_constants::grep | regex_constants::egrep | regex_constants::awk)) ? __flags : __flags | regex_constants::ECMAScript), _M_scanner(__b, __e, _M_flags, __loc), _M_nfa(make_shared<_RegexT>(__loc, _M_flags)), _M_traits(_M_nfa->_M_traits), _M_ctype(std::use_facet<_CtypeT>(__loc)) { _StateSeqT __r(*_M_nfa, _M_nfa->_M_start()); __r._M_append(_M_nfa->_M_insert_subexpr_begin()); this->_M_disjunction(); if (!_M_match_token(_ScannerT::_S_token_eof)) __throw_regex_error(regex_constants::error_paren); __r._M_append(_M_pop()); __glibcxx_assert(_M_stack.empty()); __r._M_append(_M_nfa->_M_insert_subexpr_end()); __r._M_append(_M_nfa->_M_insert_accept()); _M_nfa->_M_eliminate_dummy(); } template<typename _TraitsT> void _Compiler<_TraitsT>:: _M_disjunction() { this->_M_alternative(); while (_M_match_token(_ScannerT::_S_token_or)) { _StateSeqT __alt1 = _M_pop(); this->_M_alternative(); _StateSeqT __alt2 = _M_pop(); auto __end = _M_nfa->_M_insert_dummy(); __alt1._M_append(__end); __alt2._M_append(__end); // __alt2 is state._M_next, __alt1 is state._M_alt. The executor // executes _M_alt before _M_next, as well as executing left // alternative before right one. _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_alt( __alt2._M_start, __alt1._M_start, false), __end)); } } template<typename _TraitsT> void _Compiler<_TraitsT>:: _M_alternative() { if (this->_M_term()) { _StateSeqT __re = _M_pop(); this->_M_alternative(); __re._M_append(_M_pop()); _M_stack.push(__re); } else _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_dummy())); } template<typename _TraitsT> bool _Compiler<_TraitsT>:: _M_term() { if (this->_M_assertion()) return true; if (this->_M_atom()) { while (this->_M_quantifier()) ; return true; } return false; } template<typename _TraitsT> bool _Compiler<_TraitsT>:: _M_assertion() { if (_M_match_token(_ScannerT::_S_token_line_begin)) _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_line_begin())); else if (_M_match_token(_ScannerT::_S_token_line_end)) _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_line_end())); else if (_M_match_token(_ScannerT::_S_token_word_bound)) // _M_value[0] == 'n' means it's negative, say "not word boundary". _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa-> _M_insert_word_bound(_M_value[0] == 'n'))); else if (_M_match_token(_ScannerT::_S_token_subexpr_lookahead_begin)) { auto __neg = _M_value[0] == 'n'; this->_M_disjunction(); if (!_M_match_token(_ScannerT::_S_token_subexpr_end)) __throw_regex_error(regex_constants::error_paren, "Parenthesis is not closed."); auto __tmp = _M_pop(); __tmp._M_append(_M_nfa->_M_insert_accept()); _M_stack.push( _StateSeqT( *_M_nfa, _M_nfa->_M_insert_lookahead(__tmp._M_start, __neg))); } else return false; return true; } template<typename _TraitsT> bool _Compiler<_TraitsT>:: _M_quantifier() { bool __neg = (_M_flags & regex_constants::ECMAScript); auto __init = [this, &__neg]() { if (_M_stack.empty()) __throw_regex_error(regex_constants::error_badrepeat, "Nothing to repeat before a quantifier."); __neg = __neg && _M_match_token(_ScannerT::_S_token_opt); }; if (_M_match_token(_ScannerT::_S_token_closure0)) { __init(); auto __e = _M_pop(); _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_repeat(_S_invalid_state_id, __e._M_start, __neg)); __e._M_append(__r); _M_stack.push(__r); } else if (_M_match_token(_ScannerT::_S_token_closure1)) { __init(); auto __e = _M_pop(); __e._M_append(_M_nfa->_M_insert_repeat(_S_invalid_state_id, __e._M_start, __neg)); _M_stack.push(__e); } else if (_M_match_token(_ScannerT::_S_token_opt)) { __init(); auto __e = _M_pop(); auto __end = _M_nfa->_M_insert_dummy(); _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_repeat(_S_invalid_state_id, __e._M_start, __neg)); __e._M_append(__end); __r._M_append(__end); _M_stack.push(__r); } else if (_M_match_token(_ScannerT::_S_token_interval_begin)) { if (_M_stack.empty()) __throw_regex_error(regex_constants::error_badrepeat, "Nothing to repeat before a quantifier."); if (!_M_match_token(_ScannerT::_S_token_dup_count)) __throw_regex_error(regex_constants::error_badbrace, "Unexpected token in brace expression."); _StateSeqT __r(_M_pop()); _StateSeqT __e(*_M_nfa, _M_nfa->_M_insert_dummy()); long __min_rep = _M_cur_int_value(10); bool __infi = false; long __n; // {3 if (_M_match_token(_ScannerT::_S_token_comma)) if (_M_match_token(_ScannerT::_S_token_dup_count)) // {3,7} __n = _M_cur_int_value(10) - __min_rep; else __infi = true; else __n = 0; if (!_M_match_token(_ScannerT::_S_token_interval_end)) __throw_regex_error(regex_constants::error_brace, "Unexpected end of brace expression."); __neg = __neg && _M_match_token(_ScannerT::_S_token_opt); for (long __i = 0; __i < __min_rep; ++__i) __e._M_append(__r._M_clone()); if (__infi) { auto __tmp = __r._M_clone(); _StateSeqT __s(*_M_nfa, _M_nfa->_M_insert_repeat(_S_invalid_state_id, __tmp._M_start, __neg)); __tmp._M_append(__s); __e._M_append(__s); } else { if (__n < 0) __throw_regex_error(regex_constants::error_badbrace, "Invalid range in brace expression."); auto __end = _M_nfa->_M_insert_dummy(); // _M_alt is the "match more" branch, and _M_next is the // "match less" one. Switch _M_alt and _M_next of all created // nodes. This is a hack but IMO works well. std::stack<_StateIdT> __stack; for (long __i = 0; __i < __n; ++__i) { auto __tmp = __r._M_clone(); auto __alt = _M_nfa->_M_insert_repeat(__tmp._M_start, __end, __neg); __stack.push(__alt); __e._M_append(_StateSeqT(*_M_nfa, __alt, __tmp._M_end)); } __e._M_append(__end); while (!__stack.empty()) { auto& __tmp = (*_M_nfa)[__stack.top()]; __stack.pop(); std::swap(__tmp._M_next, __tmp._M_alt); } } _M_stack.push(__e); } else return false; return true; } #define __INSERT_REGEX_MATCHER(__func, ...)\ do {\ if (!(_M_flags & regex_constants::icase))\ if (!(_M_flags & regex_constants::collate))\ __func<false, false>(__VA_ARGS__);\ else\ __func<false, true>(__VA_ARGS__);\ else\ if (!(_M_flags & regex_constants::collate))\ __func<true, false>(__VA_ARGS__);\ else\ __func<true, true>(__VA_ARGS__);\ } while (false) template<typename _TraitsT> bool _Compiler<_TraitsT>:: _M_atom() { if (_M_match_token(_ScannerT::_S_token_anychar)) { if (!(_M_flags & regex_constants::ECMAScript)) __INSERT_REGEX_MATCHER(_M_insert_any_matcher_posix); else __INSERT_REGEX_MATCHER(_M_insert_any_matcher_ecma); } else if (_M_try_char()) __INSERT_REGEX_MATCHER(_M_insert_char_matcher); else if (_M_match_token(_ScannerT::_S_token_backref)) _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa-> _M_insert_backref(_M_cur_int_value(10)))); else if (_M_match_token(_ScannerT::_S_token_quoted_class)) __INSERT_REGEX_MATCHER(_M_insert_character_class_matcher); else if (_M_match_token(_ScannerT::_S_token_subexpr_no_group_begin)) { _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_dummy()); this->_M_disjunction(); if (!_M_match_token(_ScannerT::_S_token_subexpr_end)) __throw_regex_error(regex_constants::error_paren, "Parenthesis is not closed."); __r._M_append(_M_pop()); _M_stack.push(__r); } else if (_M_match_token(_ScannerT::_S_token_subexpr_begin)) { _StateSeqT __r(*_M_nfa, _M_nfa->_M_insert_subexpr_begin()); this->_M_disjunction(); if (!_M_match_token(_ScannerT::_S_token_subexpr_end)) __throw_regex_error(regex_constants::error_paren, "Parenthesis is not closed."); __r._M_append(_M_pop()); __r._M_append(_M_nfa->_M_insert_subexpr_end()); _M_stack.push(__r); } else if (!_M_bracket_expression()) return false; return true; } template<typename _TraitsT> bool _Compiler<_TraitsT>:: _M_bracket_expression() { bool __neg = _M_match_token(_ScannerT::_S_token_bracket_neg_begin); if (!(__neg || _M_match_token(_ScannerT::_S_token_bracket_begin))) return false; __INSERT_REGEX_MATCHER(_M_insert_bracket_matcher, __neg); return true; } #undef __INSERT_REGEX_MATCHER template<typename _TraitsT> template<bool __icase, bool __collate> void _Compiler<_TraitsT>:: _M_insert_any_matcher_ecma() { _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_matcher (_AnyMatcher<_TraitsT, true, __icase, __collate> (_M_traits)))); } template<typename _TraitsT> template<bool __icase, bool __collate> void _Compiler<_TraitsT>:: _M_insert_any_matcher_posix() { _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_matcher (_AnyMatcher<_TraitsT, false, __icase, __collate> (_M_traits)))); } template<typename _TraitsT> template<bool __icase, bool __collate> void _Compiler<_TraitsT>:: _M_insert_char_matcher() { _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_matcher (_CharMatcher<_TraitsT, __icase, __collate> (_M_value[0], _M_traits)))); } template<typename _TraitsT> template<bool __icase, bool __collate> void _Compiler<_TraitsT>:: _M_insert_character_class_matcher() { __glibcxx_assert(_M_value.size() == 1); _BracketMatcher<__icase, __collate> __matcher (_M_ctype.is(_CtypeT::upper, _M_value[0]), _M_traits); __matcher._M_add_character_class(_M_value, false); __matcher._M_ready(); _M_stack.push(_StateSeqT(*_M_nfa, _M_nfa->_M_insert_matcher(std::move(__matcher)))); } template<typename _TraitsT> template<bool __icase, bool __collate> void _Compiler<_TraitsT>:: _M_insert_bracket_matcher(bool __neg) { _BracketMatcher<__icase, __collate> __matcher(__neg, _M_traits); _BracketState __last_char; if (_M_try_char()) __last_char.set(_M_value[0]); else if (_M_match_token(_ScannerT::_S_token_bracket_dash)) // Dash as first character is a normal character. __last_char.set('-'); while (_M_expression_term(__last_char, __matcher)) ; if (__last_char._M_is_char()) __matcher._M_add_char(__last_char.get()); __matcher._M_ready(); _M_stack.push(_StateSeqT( *_M_nfa, _M_nfa->_M_insert_matcher(std::move(__matcher)))); } template<typename _TraitsT> template<bool __icase, bool __collate> bool _Compiler<_TraitsT>:: _M_expression_term(_BracketState& __last_char, _BracketMatcher<__icase, __collate>& __matcher) { if (_M_match_token(_ScannerT::_S_token_bracket_end)) return false; // Add any previously cached char into the matcher and update cache. const auto __push_char = [&](_CharT __ch) { if (__last_char._M_is_char()) __matcher._M_add_char(__last_char.get()); __last_char.set(__ch); }; // Add any previously cached char into the matcher and update cache. const auto __push_class = [&] { if (__last_char._M_is_char()) __matcher._M_add_char(__last_char.get()); // We don't cache anything here, just record that the last thing // processed was a character class (or similar). __last_char.reset(_BracketState::_Type::_Class); }; if (_M_match_token(_ScannerT::_S_token_collsymbol)) { auto __symbol = __matcher._M_add_collate_element(_M_value); if (__symbol.size() == 1) __push_char(__symbol[0]); else __push_class(); } else if (_M_match_token(_ScannerT::_S_token_equiv_class_name)) { __push_class(); __matcher._M_add_equivalence_class(_M_value); } else if (_M_match_token(_ScannerT::_S_token_char_class_name)) { __push_class(); __matcher._M_add_character_class(_M_value, false); } else if (_M_try_char()) __push_char(_M_value[0]); // POSIX doesn't allow '-' as a start-range char (say [a-z--0]), // except when the '-' is the first or last character in the bracket // expression ([--0]). ECMAScript treats all '-' after a range as a // normal character. Also see above, where _M_expression_term gets called. // // As a result, POSIX rejects [-----], but ECMAScript doesn't. // Boost (1.57.0) always uses POSIX style even in its ECMAScript syntax. // Clang (3.5) always uses ECMAScript style even in its POSIX syntax. // // It turns out that no one reads BNFs ;) else if (_M_match_token(_ScannerT::_S_token_bracket_dash)) { if (_M_match_token(_ScannerT::_S_token_bracket_end)) { // For "-]" the dash is a literal character. __push_char('-'); return false; } else if (__last_char._M_is_class()) { // "\\w-" is invalid, start of range must be a single char. __throw_regex_error(regex_constants::error_range, "Invalid start of range in bracket expression."); } else if (__last_char._M_is_char()) { if (_M_try_char()) { // "x-y" __matcher._M_make_range(__last_char.get(), _M_value[0]); __last_char.reset(); } else if (_M_match_token(_ScannerT::_S_token_bracket_dash)) { // "x--" __matcher._M_make_range(__last_char.get(), '-'); __last_char.reset(); } else __throw_regex_error(regex_constants::error_range, "Invalid end of range in bracket expression."); } else if (_M_flags & regex_constants::ECMAScript) { // A dash that is not part of an existing range. Might be the // start of a new range, or might just be a literal '-' char. // Only ECMAScript allows that in the middle of a bracket expr. __push_char('-'); } else __throw_regex_error(regex_constants::error_range, "Invalid dash in bracket expression."); } else if (_M_match_token(_ScannerT::_S_token_quoted_class)) { __push_class(); __matcher._M_add_character_class(_M_value, _M_ctype.is(_CtypeT::upper, _M_value[0])); } else __throw_regex_error(regex_constants::error_brack, "Unexpected character in bracket expression."); return true; } template<typename _TraitsT> bool _Compiler<_TraitsT>:: _M_try_char() { bool __is_char = false; if (_M_match_token(_ScannerT::_S_token_oct_num)) { __is_char = true; _M_value.assign(1, _M_cur_int_value(8)); } else if (_M_match_token(_ScannerT::_S_token_hex_num)) { __is_char = true; _M_value.assign(1, _M_cur_int_value(16)); } else if (_M_match_token(_ScannerT::_S_token_ord_char)) __is_char = true; return __is_char; } template<typename _TraitsT> bool _Compiler<_TraitsT>:: _M_match_token(_TokenT __token) { if (__token == _M_scanner._M_get_token()) { _M_value = _M_scanner._M_get_value(); _M_scanner._M_advance(); return true; } return false; } template<typename _TraitsT> int _Compiler<_TraitsT>:: _M_cur_int_value(int __radix) { long __v = 0; for (typename _StringT::size_type __i = 0; __i < _M_value.length(); ++__i) __v =__v * __radix + _M_traits.value(_M_value[__i], __radix); return __v; } template<typename _TraitsT, bool __icase, bool __collate> bool _BracketMatcher<_TraitsT, __icase, __collate>:: _M_apply(_CharT __ch, false_type) const { return [this, __ch] { if (std::binary_search(_M_char_set.begin(), _M_char_set.end(), _M_translator._M_translate(__ch))) return true; auto __s = _M_translator._M_transform(__ch); for (auto& __it : _M_range_set) if (_M_translator._M_match_range(__it.first, __it.second, __s)) return true; if (_M_traits.isctype(__ch, _M_class_set)) return true; if (std::find(_M_equiv_set.begin(), _M_equiv_set.end(), _M_traits.transform_primary(&__ch, &__ch+1)) != _M_equiv_set.end()) return true; for (auto& __it : _M_neg_class_set) if (!_M_traits.isctype(__ch, __it)) return true; return false; }() ^ _M_is_non_matching; } } // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/bits/stl_algobase.h 0000644 00000142476 15146341150 0011052 0 ustar 00 // Core algorithmic facilities -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_algobase.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{algorithm} */ #ifndef _STL_ALGOBASE_H #define _STL_ALGOBASE_H 1 #include <bits/c++config.h> #include <bits/functexcept.h> #include <bits/cpp_type_traits.h> #include <ext/type_traits.h> #include <ext/numeric_traits.h> #include <bits/stl_pair.h> #include <bits/stl_iterator_base_types.h> #include <bits/stl_iterator_base_funcs.h> #include <bits/stl_iterator.h> #include <bits/concept_check.h> #include <debug/debug.h> #include <bits/move.h> // For std::swap #include <bits/predefined_ops.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus < 201103L // See http://gcc.gnu.org/ml/libstdc++/2004-08/msg00167.html: in a // nutshell, we are partially implementing the resolution of DR 187, // when it's safe, i.e., the value_types are equal. template<bool _BoolType> struct __iter_swap { template<typename _ForwardIterator1, typename _ForwardIterator2> static void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) { typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType1; _ValueType1 __tmp = *__a; *__a = *__b; *__b = __tmp; } }; template<> struct __iter_swap<true> { template<typename _ForwardIterator1, typename _ForwardIterator2> static void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) { swap(*__a, *__b); } }; #endif /** * @brief Swaps the contents of two iterators. * @ingroup mutating_algorithms * @param __a An iterator. * @param __b Another iterator. * @return Nothing. * * This function swaps the values pointed to by two iterators, not the * iterators themselves. */ template<typename _ForwardIterator1, typename _ForwardIterator2> inline void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator1>) __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator2>) #if __cplusplus < 201103L typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType1; typedef typename iterator_traits<_ForwardIterator2>::value_type _ValueType2; __glibcxx_function_requires(_ConvertibleConcept<_ValueType1, _ValueType2>) __glibcxx_function_requires(_ConvertibleConcept<_ValueType2, _ValueType1>) typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1; typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2; std::__iter_swap<__are_same<_ValueType1, _ValueType2>::__value && __are_same<_ValueType1&, _ReferenceType1>::__value && __are_same<_ValueType2&, _ReferenceType2>::__value>:: iter_swap(__a, __b); #else swap(*__a, *__b); #endif } /** * @brief Swap the elements of two sequences. * @ingroup mutating_algorithms * @param __first1 A forward iterator. * @param __last1 A forward iterator. * @param __first2 A forward iterator. * @return An iterator equal to @p first2+(last1-first1). * * Swaps each element in the range @p [first1,last1) with the * corresponding element in the range @p [first2,(last1-first1)). * The ranges must not overlap. */ template<typename _ForwardIterator1, typename _ForwardIterator2> _ForwardIterator2 swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator1>) __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator2>) __glibcxx_requires_valid_range(__first1, __last1); for (; __first1 != __last1; ++__first1, (void)++__first2) std::iter_swap(__first1, __first2); return __first2; } /** * @brief This does what you think it does. * @ingroup sorting_algorithms * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @return The lesser of the parameters. * * This is the simple classic generic implementation. It will work on * temporary expressions, since they are only evaluated once, unlike a * preprocessor macro. */ template<typename _Tp> _GLIBCXX14_CONSTEXPR inline const _Tp& min(const _Tp& __a, const _Tp& __b) { // concept requirements __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) //return __b < __a ? __b : __a; if (__b < __a) return __b; return __a; } /** * @brief This does what you think it does. * @ingroup sorting_algorithms * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @return The greater of the parameters. * * This is the simple classic generic implementation. It will work on * temporary expressions, since they are only evaluated once, unlike a * preprocessor macro. */ template<typename _Tp> _GLIBCXX14_CONSTEXPR inline const _Tp& max(const _Tp& __a, const _Tp& __b) { // concept requirements __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) //return __a < __b ? __b : __a; if (__a < __b) return __b; return __a; } /** * @brief This does what you think it does. * @ingroup sorting_algorithms * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @param __comp A @link comparison_functors comparison functor@endlink. * @return The lesser of the parameters. * * This will work on temporary expressions, since they are only evaluated * once, unlike a preprocessor macro. */ template<typename _Tp, typename _Compare> _GLIBCXX14_CONSTEXPR inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) { //return __comp(__b, __a) ? __b : __a; if (__comp(__b, __a)) return __b; return __a; } /** * @brief This does what you think it does. * @ingroup sorting_algorithms * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @param __comp A @link comparison_functors comparison functor@endlink. * @return The greater of the parameters. * * This will work on temporary expressions, since they are only evaluated * once, unlike a preprocessor macro. */ template<typename _Tp, typename _Compare> _GLIBCXX14_CONSTEXPR inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) { //return __comp(__a, __b) ? __b : __a; if (__comp(__a, __b)) return __b; return __a; } // Fallback implementation of the function in bits/stl_iterator.h used to // remove the __normal_iterator wrapper. See copy, fill, ... template<typename _Iterator> inline _Iterator __niter_base(_Iterator __it) { return __it; } // All of these auxiliary structs serve two purposes. (1) Replace // calls to copy with memmove whenever possible. (Memmove, not memcpy, // because the input and output ranges are permitted to overlap.) // (2) If we're using random access iterators, then write the loop as // a for loop with an explicit count. template<bool, bool, typename> struct __copy_move { template<typename _II, typename _OI> static _OI __copy_m(_II __first, _II __last, _OI __result) { for (; __first != __last; ++__result, (void)++__first) *__result = *__first; return __result; } }; #if __cplusplus >= 201103L template<typename _Category> struct __copy_move<true, false, _Category> { template<typename _II, typename _OI> static _OI __copy_m(_II __first, _II __last, _OI __result) { for (; __first != __last; ++__result, (void)++__first) *__result = std::move(*__first); return __result; } }; #endif template<> struct __copy_move<false, false, random_access_iterator_tag> { template<typename _II, typename _OI> static _OI __copy_m(_II __first, _II __last, _OI __result) { typedef typename iterator_traits<_II>::difference_type _Distance; for(_Distance __n = __last - __first; __n > 0; --__n) { *__result = *__first; ++__first; ++__result; } return __result; } }; #if __cplusplus >= 201103L template<> struct __copy_move<true, false, random_access_iterator_tag> { template<typename _II, typename _OI> static _OI __copy_m(_II __first, _II __last, _OI __result) { typedef typename iterator_traits<_II>::difference_type _Distance; for(_Distance __n = __last - __first; __n > 0; --__n) { *__result = std::move(*__first); ++__first; ++__result; } return __result; } }; #endif template<bool _IsMove> struct __copy_move<_IsMove, true, random_access_iterator_tag> { template<typename _Tp> static _Tp* __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result) { #if __cplusplus >= 201103L using __assignable = conditional<_IsMove, is_move_assignable<_Tp>, is_copy_assignable<_Tp>>; // trivial types can have deleted assignment static_assert( __assignable::type::value, "type is not assignable" ); #endif const ptrdiff_t _Num = __last - __first; if (_Num) __builtin_memmove(__result, __first, sizeof(_Tp) * _Num); return __result + _Num; } }; template<bool _IsMove, typename _II, typename _OI> inline _OI __copy_move_a(_II __first, _II __last, _OI __result) { typedef typename iterator_traits<_II>::value_type _ValueTypeI; typedef typename iterator_traits<_OI>::value_type _ValueTypeO; typedef typename iterator_traits<_II>::iterator_category _Category; const bool __simple = (__is_trivial(_ValueTypeI) && __is_pointer<_II>::__value && __is_pointer<_OI>::__value && __are_same<_ValueTypeI, _ValueTypeO>::__value); return std::__copy_move<_IsMove, __simple, _Category>::__copy_m(__first, __last, __result); } // Helpers for streambuf iterators (either istream or ostream). // NB: avoid including <iosfwd>, relatively large. template<typename _CharT> struct char_traits; template<typename _CharT, typename _Traits> class istreambuf_iterator; template<typename _CharT, typename _Traits> class ostreambuf_iterator; template<bool _IsMove, typename _CharT> typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type __copy_move_a2(_CharT*, _CharT*, ostreambuf_iterator<_CharT, char_traits<_CharT> >); template<bool _IsMove, typename _CharT> typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, ostreambuf_iterator<_CharT, char_traits<_CharT> > >::__type __copy_move_a2(const _CharT*, const _CharT*, ostreambuf_iterator<_CharT, char_traits<_CharT> >); template<bool _IsMove, typename _CharT> typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, _CharT*>::__type __copy_move_a2(istreambuf_iterator<_CharT, char_traits<_CharT> >, istreambuf_iterator<_CharT, char_traits<_CharT> >, _CharT*); template<bool _IsMove, typename _II, typename _OI> inline _OI __copy_move_a2(_II __first, _II __last, _OI __result) { return _OI(std::__copy_move_a<_IsMove>(std::__niter_base(__first), std::__niter_base(__last), std::__niter_base(__result))); } /** * @brief Copies the range [first,last) into result. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @return result + (first - last) * * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). Result may not be contained within * [first,last); the copy_backward function should be used instead. * * Note that the end of the output range is permitted to be contained * within [first,last). */ template<typename _II, typename _OI> inline _OI copy(_II __first, _II __last, _OI __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_II>) __glibcxx_function_requires(_OutputIteratorConcept<_OI, typename iterator_traits<_II>::value_type>) __glibcxx_requires_valid_range(__first, __last); return (std::__copy_move_a2<__is_move_iterator<_II>::__value> (std::__miter_base(__first), std::__miter_base(__last), __result)); } #if __cplusplus >= 201103L /** * @brief Moves the range [first,last) into result. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @return result + (first - last) * * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). Result may not be contained within * [first,last); the move_backward function should be used instead. * * Note that the end of the output range is permitted to be contained * within [first,last). */ template<typename _II, typename _OI> inline _OI move(_II __first, _II __last, _OI __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_II>) __glibcxx_function_requires(_OutputIteratorConcept<_OI, typename iterator_traits<_II>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__copy_move_a2<true>(std::__miter_base(__first), std::__miter_base(__last), __result); } #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::move(_Tp, _Up, _Vp) #else #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::copy(_Tp, _Up, _Vp) #endif template<bool, bool, typename> struct __copy_move_backward { template<typename _BI1, typename _BI2> static _BI2 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) { while (__first != __last) *--__result = *--__last; return __result; } }; #if __cplusplus >= 201103L template<typename _Category> struct __copy_move_backward<true, false, _Category> { template<typename _BI1, typename _BI2> static _BI2 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) { while (__first != __last) *--__result = std::move(*--__last); return __result; } }; #endif template<> struct __copy_move_backward<false, false, random_access_iterator_tag> { template<typename _BI1, typename _BI2> static _BI2 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) { typename iterator_traits<_BI1>::difference_type __n; for (__n = __last - __first; __n > 0; --__n) *--__result = *--__last; return __result; } }; #if __cplusplus >= 201103L template<> struct __copy_move_backward<true, false, random_access_iterator_tag> { template<typename _BI1, typename _BI2> static _BI2 __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result) { typename iterator_traits<_BI1>::difference_type __n; for (__n = __last - __first; __n > 0; --__n) *--__result = std::move(*--__last); return __result; } }; #endif template<bool _IsMove> struct __copy_move_backward<_IsMove, true, random_access_iterator_tag> { template<typename _Tp> static _Tp* __copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result) { #if __cplusplus >= 201103L using __assignable = conditional<_IsMove, is_move_assignable<_Tp>, is_copy_assignable<_Tp>>; // trivial types can have deleted assignment static_assert( __assignable::type::value, "type is not assignable" ); #endif const ptrdiff_t _Num = __last - __first; if (_Num) __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num); return __result - _Num; } }; template<bool _IsMove, typename _BI1, typename _BI2> inline _BI2 __copy_move_backward_a(_BI1 __first, _BI1 __last, _BI2 __result) { typedef typename iterator_traits<_BI1>::value_type _ValueType1; typedef typename iterator_traits<_BI2>::value_type _ValueType2; typedef typename iterator_traits<_BI1>::iterator_category _Category; const bool __simple = (__is_trivial(_ValueType1) && __is_pointer<_BI1>::__value && __is_pointer<_BI2>::__value && __are_same<_ValueType1, _ValueType2>::__value); return std::__copy_move_backward<_IsMove, __simple, _Category>::__copy_move_b(__first, __last, __result); } template<bool _IsMove, typename _BI1, typename _BI2> inline _BI2 __copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result) { return _BI2(std::__copy_move_backward_a<_IsMove> (std::__niter_base(__first), std::__niter_base(__last), std::__niter_base(__result))); } /** * @brief Copies the range [first,last) into result. * @ingroup mutating_algorithms * @param __first A bidirectional iterator. * @param __last A bidirectional iterator. * @param __result A bidirectional iterator. * @return result - (first - last) * * The function has the same effect as copy, but starts at the end of the * range and works its way to the start, returning the start of the result. * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). * * Result may not be in the range (first,last]. Use copy instead. Note * that the start of the output range may overlap [first,last). */ template<typename _BI1, typename _BI2> inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>) __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>) __glibcxx_function_requires(_ConvertibleConcept< typename iterator_traits<_BI1>::value_type, typename iterator_traits<_BI2>::value_type>) __glibcxx_requires_valid_range(__first, __last); return (std::__copy_move_backward_a2<__is_move_iterator<_BI1>::__value> (std::__miter_base(__first), std::__miter_base(__last), __result)); } #if __cplusplus >= 201103L /** * @brief Moves the range [first,last) into result. * @ingroup mutating_algorithms * @param __first A bidirectional iterator. * @param __last A bidirectional iterator. * @param __result A bidirectional iterator. * @return result - (first - last) * * The function has the same effect as move, but starts at the end of the * range and works its way to the start, returning the start of the result. * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). * * Result may not be in the range (first,last]. Use move instead. Note * that the start of the output range may overlap [first,last). */ template<typename _BI1, typename _BI2> inline _BI2 move_backward(_BI1 __first, _BI1 __last, _BI2 __result) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept<_BI1>) __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept<_BI2>) __glibcxx_function_requires(_ConvertibleConcept< typename iterator_traits<_BI1>::value_type, typename iterator_traits<_BI2>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__copy_move_backward_a2<true>(std::__miter_base(__first), std::__miter_base(__last), __result); } #define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::move_backward(_Tp, _Up, _Vp) #else #define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::copy_backward(_Tp, _Up, _Vp) #endif template<typename _ForwardIterator, typename _Tp> inline typename __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, void>::__type __fill_a(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { for (; __first != __last; ++__first) *__first = __value; } template<typename _ForwardIterator, typename _Tp> inline typename __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, void>::__type __fill_a(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { const _Tp __tmp = __value; for (; __first != __last; ++__first) *__first = __tmp; } // Specialization: for char types we can use memset. template<typename _Tp> inline typename __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, void>::__type __fill_a(_Tp* __first, _Tp* __last, const _Tp& __c) { const _Tp __tmp = __c; if (const size_t __len = __last - __first) __builtin_memset(__first, static_cast<unsigned char>(__tmp), __len); } /** * @brief Fills the range [first,last) with copies of value. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __value A reference-to-const of arbitrary type. * @return Nothing. * * This function fills a range with copies of the same value. For char * types filling contiguous areas of memory, this becomes an inline call * to @c memset or @c wmemset. */ template<typename _ForwardIterator, typename _Tp> inline void fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_requires_valid_range(__first, __last); std::__fill_a(std::__niter_base(__first), std::__niter_base(__last), __value); } template<typename _OutputIterator, typename _Size, typename _Tp> inline typename __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, _OutputIterator>::__type __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value) { for (__decltype(__n + 0) __niter = __n; __niter > 0; --__niter, (void) ++__first) *__first = __value; return __first; } template<typename _OutputIterator, typename _Size, typename _Tp> inline typename __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, _OutputIterator>::__type __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value) { const _Tp __tmp = __value; for (__decltype(__n + 0) __niter = __n; __niter > 0; --__niter, (void) ++__first) *__first = __tmp; return __first; } template<typename _Size, typename _Tp> inline typename __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, _Tp*>::__type __fill_n_a(_Tp* __first, _Size __n, const _Tp& __c) { std::__fill_a(__first, __first + __n, __c); return __first + __n; } /** * @brief Fills the range [first,first+n) with copies of value. * @ingroup mutating_algorithms * @param __first An output iterator. * @param __n The count of copies to perform. * @param __value A reference-to-const of arbitrary type. * @return The iterator at first+n. * * This function fills a range with copies of the same value. For char * types filling contiguous areas of memory, this becomes an inline call * to @c memset or @ wmemset. * * _GLIBCXX_RESOLVE_LIB_DEFECTS * DR 865. More algorithms that throw away information */ template<typename _OI, typename _Size, typename _Tp> inline _OI fill_n(_OI __first, _Size __n, const _Tp& __value) { // concept requirements __glibcxx_function_requires(_OutputIteratorConcept<_OI, _Tp>) return _OI(std::__fill_n_a(std::__niter_base(__first), __n, __value)); } template<bool _BoolType> struct __equal { template<typename _II1, typename _II2> static bool equal(_II1 __first1, _II1 __last1, _II2 __first2) { for (; __first1 != __last1; ++__first1, (void) ++__first2) if (!(*__first1 == *__first2)) return false; return true; } }; template<> struct __equal<true> { template<typename _Tp> static bool equal(const _Tp* __first1, const _Tp* __last1, const _Tp* __first2) { if (const size_t __len = (__last1 - __first1)) return !__builtin_memcmp(__first1, __first2, sizeof(_Tp) * __len); return true; } }; template<typename _II1, typename _II2> inline bool __equal_aux(_II1 __first1, _II1 __last1, _II2 __first2) { typedef typename iterator_traits<_II1>::value_type _ValueType1; typedef typename iterator_traits<_II2>::value_type _ValueType2; const bool __simple = ((__is_integer<_ValueType1>::__value || __is_pointer<_ValueType1>::__value) && __is_pointer<_II1>::__value && __is_pointer<_II2>::__value && __are_same<_ValueType1, _ValueType2>::__value); return std::__equal<__simple>::equal(__first1, __last1, __first2); } template<typename, typename> struct __lc_rai { template<typename _II1, typename _II2> static _II1 __newlast1(_II1, _II1 __last1, _II2, _II2) { return __last1; } template<typename _II> static bool __cnd2(_II __first, _II __last) { return __first != __last; } }; template<> struct __lc_rai<random_access_iterator_tag, random_access_iterator_tag> { template<typename _RAI1, typename _RAI2> static _RAI1 __newlast1(_RAI1 __first1, _RAI1 __last1, _RAI2 __first2, _RAI2 __last2) { const typename iterator_traits<_RAI1>::difference_type __diff1 = __last1 - __first1; const typename iterator_traits<_RAI2>::difference_type __diff2 = __last2 - __first2; return __diff2 < __diff1 ? __first1 + __diff2 : __last1; } template<typename _RAI> static bool __cnd2(_RAI, _RAI) { return true; } }; template<typename _II1, typename _II2, typename _Compare> bool __lexicographical_compare_impl(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2, _Compare __comp) { typedef typename iterator_traits<_II1>::iterator_category _Category1; typedef typename iterator_traits<_II2>::iterator_category _Category2; typedef std::__lc_rai<_Category1, _Category2> __rai_type; __last1 = __rai_type::__newlast1(__first1, __last1, __first2, __last2); for (; __first1 != __last1 && __rai_type::__cnd2(__first2, __last2); ++__first1, (void)++__first2) { if (__comp(__first1, __first2)) return true; if (__comp(__first2, __first1)) return false; } return __first1 == __last1 && __first2 != __last2; } template<bool _BoolType> struct __lexicographical_compare { template<typename _II1, typename _II2> static bool __lc(_II1, _II1, _II2, _II2); }; template<bool _BoolType> template<typename _II1, typename _II2> bool __lexicographical_compare<_BoolType>:: __lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { return std::__lexicographical_compare_impl(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_less_iter()); } template<> struct __lexicographical_compare<true> { template<typename _Tp, typename _Up> static bool __lc(const _Tp* __first1, const _Tp* __last1, const _Up* __first2, const _Up* __last2) { const size_t __len1 = __last1 - __first1; const size_t __len2 = __last2 - __first2; if (const size_t __len = std::min(__len1, __len2)) if (int __result = __builtin_memcmp(__first1, __first2, __len)) return __result < 0; return __len1 < __len2; } }; template<typename _II1, typename _II2> inline bool __lexicographical_compare_aux(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { typedef typename iterator_traits<_II1>::value_type _ValueType1; typedef typename iterator_traits<_II2>::value_type _ValueType2; const bool __simple = (__is_byte<_ValueType1>::__value && __is_byte<_ValueType2>::__value && !__gnu_cxx::__numeric_traits<_ValueType1>::__is_signed && !__gnu_cxx::__numeric_traits<_ValueType2>::__is_signed && __is_pointer<_II1>::__value && __is_pointer<_II2>::__value); return std::__lexicographical_compare<__simple>::__lc(__first1, __last1, __first2, __last2); } template<typename _ForwardIterator, typename _Tp, typename _Compare> _ForwardIterator __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType; _DistanceType __len = std::distance(__first, __last); while (__len > 0) { _DistanceType __half = __len >> 1; _ForwardIterator __middle = __first; std::advance(__middle, __half); if (__comp(__middle, __val)) { __first = __middle; ++__first; __len = __len - __half - 1; } else __len = __half; } return __first; } /** * @brief Finds the first position in which @a val could be inserted * without changing the ordering. * @param __first An iterator. * @param __last Another iterator. * @param __val The search term. * @return An iterator pointing to the first element <em>not less * than</em> @a val, or end() if every element is less than * @a val. * @ingroup binary_search_algorithms */ template<typename _ForwardIterator, typename _Tp> inline _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_requires_partitioned_lower(__first, __last, __val); return std::__lower_bound(__first, __last, __val, __gnu_cxx::__ops::__iter_less_val()); } /// This is a helper function for the sort routines and for random.tcc. // Precondition: __n > 0. inline _GLIBCXX_CONSTEXPR int __lg(int __n) { return (int)sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); } inline _GLIBCXX_CONSTEXPR unsigned __lg(unsigned __n) { return (int)sizeof(int) * __CHAR_BIT__ - 1 - __builtin_clz(__n); } inline _GLIBCXX_CONSTEXPR long __lg(long __n) { return (int)sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); } inline _GLIBCXX_CONSTEXPR unsigned long __lg(unsigned long __n) { return (int)sizeof(long) * __CHAR_BIT__ - 1 - __builtin_clzl(__n); } inline _GLIBCXX_CONSTEXPR long long __lg(long long __n) { return (int)sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); } inline _GLIBCXX_CONSTEXPR unsigned long long __lg(unsigned long long __n) { return (int)sizeof(long long) * __CHAR_BIT__ - 1 - __builtin_clzll(__n); } _GLIBCXX_BEGIN_NAMESPACE_ALGO /** * @brief Tests a range for element-wise equality. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @return A boolean true or false. * * This compares the elements of two ranges using @c == and returns true or * false depending on whether all of the corresponding elements of the * ranges are equal. */ template<typename _II1, typename _II2> inline bool equal(_II1 __first1, _II1 __last1, _II2 __first2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_II1>) __glibcxx_function_requires(_InputIteratorConcept<_II2>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_II1>::value_type, typename iterator_traits<_II2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); return std::__equal_aux(std::__niter_base(__first1), std::__niter_base(__last1), std::__niter_base(__first2)); } /** * @brief Tests a range for element-wise equality. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __binary_pred A binary predicate @link functors * functor@endlink. * @return A boolean true or false. * * This compares the elements of two ranges using the binary_pred * parameter, and returns true or * false depending on whether all of the corresponding elements of the * ranges are equal. */ template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> inline bool equal(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_IIter1>) __glibcxx_function_requires(_InputIteratorConcept<_IIter2>) __glibcxx_requires_valid_range(__first1, __last1); for (; __first1 != __last1; ++__first1, (void)++__first2) if (!bool(__binary_pred(*__first1, *__first2))) return false; return true; } #if __cplusplus >= 201103L // 4-iterator version of std::equal<It1, It2> for use in C++11. template<typename _II1, typename _II2> inline bool __equal4(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { using _RATag = random_access_iterator_tag; using _Cat1 = typename iterator_traits<_II1>::iterator_category; using _Cat2 = typename iterator_traits<_II2>::iterator_category; using _RAIters = __and_<is_same<_Cat1, _RATag>, is_same<_Cat2, _RATag>>; if (_RAIters()) { auto __d1 = std::distance(__first1, __last1); auto __d2 = std::distance(__first2, __last2); if (__d1 != __d2) return false; return _GLIBCXX_STD_A::equal(__first1, __last1, __first2); } for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) if (!(*__first1 == *__first2)) return false; return __first1 == __last1 && __first2 == __last2; } // 4-iterator version of std::equal<It1, It2, BinaryPred> for use in C++11. template<typename _II1, typename _II2, typename _BinaryPredicate> inline bool __equal4(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2, _BinaryPredicate __binary_pred) { using _RATag = random_access_iterator_tag; using _Cat1 = typename iterator_traits<_II1>::iterator_category; using _Cat2 = typename iterator_traits<_II2>::iterator_category; using _RAIters = __and_<is_same<_Cat1, _RATag>, is_same<_Cat2, _RATag>>; if (_RAIters()) { auto __d1 = std::distance(__first1, __last1); auto __d2 = std::distance(__first2, __last2); if (__d1 != __d2) return false; return _GLIBCXX_STD_A::equal(__first1, __last1, __first2, __binary_pred); } for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) if (!bool(__binary_pred(*__first1, *__first2))) return false; return __first1 == __last1 && __first2 == __last2; } #endif // C++11 #if __cplusplus > 201103L #define __cpp_lib_robust_nonmodifying_seq_ops 201304 /** * @brief Tests a range for element-wise equality. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @return A boolean true or false. * * This compares the elements of two ranges using @c == and returns true or * false depending on whether all of the corresponding elements of the * ranges are equal. */ template<typename _II1, typename _II2> inline bool equal(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_II1>) __glibcxx_function_requires(_InputIteratorConcept<_II2>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_II1>::value_type, typename iterator_traits<_II2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return _GLIBCXX_STD_A::__equal4(__first1, __last1, __first2, __last2); } /** * @brief Tests a range for element-wise equality. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @param __binary_pred A binary predicate @link functors * functor@endlink. * @return A boolean true or false. * * This compares the elements of two ranges using the binary_pred * parameter, and returns true or * false depending on whether all of the corresponding elements of the * ranges are equal. */ template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> inline bool equal(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _IIter2 __last2, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_IIter1>) __glibcxx_function_requires(_InputIteratorConcept<_IIter2>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return _GLIBCXX_STD_A::__equal4(__first1, __last1, __first2, __last2, __binary_pred); } #endif // C++14 /** * @brief Performs @b dictionary comparison on ranges. * @ingroup sorting_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @return A boolean true or false. * * <em>Returns true if the sequence of elements defined by the range * [first1,last1) is lexicographically less than the sequence of elements * defined by the range [first2,last2). Returns false otherwise.</em> * (Quoted from [25.3.8]/1.) If the iterators are all character pointers, * then this is an inline call to @c memcmp. */ template<typename _II1, typename _II2> inline bool lexicographical_compare(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2) { #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename iterator_traits<_II1>::value_type _ValueType1; typedef typename iterator_traits<_II2>::value_type _ValueType2; #endif __glibcxx_function_requires(_InputIteratorConcept<_II1>) __glibcxx_function_requires(_InputIteratorConcept<_II2>) __glibcxx_function_requires(_LessThanOpConcept<_ValueType1, _ValueType2>) __glibcxx_function_requires(_LessThanOpConcept<_ValueType2, _ValueType1>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return std::__lexicographical_compare_aux(std::__niter_base(__first1), std::__niter_base(__last1), std::__niter_base(__first2), std::__niter_base(__last2)); } /** * @brief Performs @b dictionary comparison on ranges. * @ingroup sorting_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @param __comp A @link comparison_functors comparison functor@endlink. * @return A boolean true or false. * * The same as the four-parameter @c lexicographical_compare, but uses the * comp parameter instead of @c <. */ template<typename _II1, typename _II2, typename _Compare> inline bool lexicographical_compare(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2, _Compare __comp) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_II1>) __glibcxx_function_requires(_InputIteratorConcept<_II2>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return std::__lexicographical_compare_impl (__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate> pair<_InputIterator1, _InputIterator2> __mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __binary_pred) { while (__first1 != __last1 && __binary_pred(__first1, __first2)) { ++__first1; ++__first2; } return pair<_InputIterator1, _InputIterator2>(__first1, __first2); } /** * @brief Finds the places in ranges which don't match. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @return A pair of iterators pointing to the first mismatch. * * This compares the elements of two ranges using @c == and returns a pair * of iterators. The first iterator points into the first range, the * second iterator points into the second range, and the elements pointed * to by the iterators are not equal. */ template<typename _InputIterator1, typename _InputIterator2> inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __gnu_cxx::__ops::__iter_equal_to_iter()); } /** * @brief Finds the places in ranges which don't match. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __binary_pred A binary predicate @link functors * functor@endlink. * @return A pair of iterators pointing to the first mismatch. * * This compares the elements of two ranges using the binary_pred * parameter, and returns a pair * of iterators. The first iterator points into the first range, the * second iterator points into the second range, and the elements pointed * to by the iterators are not equal. */ template<typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate> inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_requires_valid_range(__first1, __last1); return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); } #if __cplusplus > 201103L template<typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate> pair<_InputIterator1, _InputIterator2> __mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __binary_pred) { while (__first1 != __last1 && __first2 != __last2 && __binary_pred(__first1, __first2)) { ++__first1; ++__first2; } return pair<_InputIterator1, _InputIterator2>(__first1, __first2); } /** * @brief Finds the places in ranges which don't match. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @return A pair of iterators pointing to the first mismatch. * * This compares the elements of two ranges using @c == and returns a pair * of iterators. The first iterator points into the first range, the * second iterator points into the second range, and the elements pointed * to by the iterators are not equal. */ template<typename _InputIterator1, typename _InputIterator2> inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_equal_to_iter()); } /** * @brief Finds the places in ranges which don't match. * @ingroup non_mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __last2 An input iterator. * @param __binary_pred A binary predicate @link functors * functor@endlink. * @return A pair of iterators pointing to the first mismatch. * * This compares the elements of two ranges using the binary_pred * parameter, and returns a pair * of iterators. The first iterator points into the first range, the * second iterator points into the second range, and the elements pointed * to by the iterators are not equal. */ template<typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicate> inline pair<_InputIterator1, _InputIterator2> mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); } #endif _GLIBCXX_END_NAMESPACE_ALGO _GLIBCXX_END_NAMESPACE_VERSION } // namespace std // NB: This file is included within many other C++ includes, as a way // of getting the base algorithms. So, make sure that parallel bits // come in too if requested. #ifdef _GLIBCXX_PARALLEL # include <parallel/algobase.h> #endif #endif c++/8/bits/gslice.h 0000644 00000012616 15146341150 0007651 0 ustar 00 // The template and inlines for the -*- C++ -*- gslice class. // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/gslice.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{valarray} */ // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> #ifndef _GSLICE_H #define _GSLICE_H 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup numeric_arrays * @{ */ /** * @brief Class defining multi-dimensional subset of an array. * * The slice class represents a multi-dimensional subset of an array, * specified by three parameter sets: start offset, size array, and stride * array. The start offset is the index of the first element of the array * that is part of the subset. The size and stride array describe each * dimension of the slice. Size is the number of elements in that * dimension, and stride is the distance in the array between successive * elements in that dimension. Each dimension's size and stride is taken * to begin at an array element described by the previous dimension. The * size array and stride array must be the same size. * * For example, if you have offset==3, stride[0]==11, size[1]==3, * stride[1]==3, then slice[0,0]==array[3], slice[0,1]==array[6], * slice[0,2]==array[9], slice[1,0]==array[14], slice[1,1]==array[17], * slice[1,2]==array[20]. */ class gslice { public: /// Construct an empty slice. gslice(); /** * @brief Construct a slice. * * Constructs a slice with as many dimensions as the length of the @a l * and @a s arrays. * * @param __o Offset in array of first element. * @param __l Array of dimension lengths. * @param __s Array of dimension strides between array elements. */ gslice(size_t __o, const valarray<size_t>& __l, const valarray<size_t>& __s); // XXX: the IS says the copy-ctor and copy-assignment operators are // synthesized by the compiler but they are just unsuitable // for a ref-counted semantic /// Copy constructor. gslice(const gslice&); /// Destructor. ~gslice(); // XXX: See the note above. /// Assignment operator. gslice& operator=(const gslice&); /// Return array offset of first slice element. size_t start() const; /// Return array of sizes of slice dimensions. valarray<size_t> size() const; /// Return array of array strides for each dimension. valarray<size_t> stride() const; private: struct _Indexer { size_t _M_count; size_t _M_start; valarray<size_t> _M_size; valarray<size_t> _M_stride; valarray<size_t> _M_index; // Linear array of referenced indices _Indexer() : _M_count(1), _M_start(0), _M_size(), _M_stride(), _M_index() {} _Indexer(size_t, const valarray<size_t>&, const valarray<size_t>&); void _M_increment_use() { ++_M_count; } size_t _M_decrement_use() { return --_M_count; } }; _Indexer* _M_index; template<typename _Tp> friend class valarray; }; inline size_t gslice::start() const { return _M_index ? _M_index->_M_start : 0; } inline valarray<size_t> gslice::size() const { return _M_index ? _M_index->_M_size : valarray<size_t>(); } inline valarray<size_t> gslice::stride() const { return _M_index ? _M_index->_M_stride : valarray<size_t>(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 543. valarray slice default constructor inline gslice::gslice() : _M_index(new gslice::_Indexer()) {} inline gslice::gslice(size_t __o, const valarray<size_t>& __l, const valarray<size_t>& __s) : _M_index(new gslice::_Indexer(__o, __l, __s)) {} inline gslice::gslice(const gslice& __g) : _M_index(__g._M_index) { if (_M_index) _M_index->_M_increment_use(); } inline gslice::~gslice() { if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; } inline gslice& gslice::operator=(const gslice& __g) { if (__g._M_index) __g._M_index->_M_increment_use(); if (_M_index && _M_index->_M_decrement_use() == 0) delete _M_index; _M_index = __g._M_index; return *this; } // @} group numeric_arrays _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _GSLICE_H */ c++/8/bits/regex_compiler.h 0000644 00000043202 15146341150 0011402 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2010-2018 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/regex_compiler.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename> class regex_traits; _GLIBCXX_END_NAMESPACE_CXX11 namespace __detail { /** * @addtogroup regex-detail * @{ */ template<typename, bool, bool> struct _BracketMatcher; /** * @brief Builds an NFA from an input iterator range. * * The %_TraitsT type should fulfill requirements [28.3]. */ template<typename _TraitsT> class _Compiler { public: typedef typename _TraitsT::char_type _CharT; typedef const _CharT* _IterT; typedef _NFA<_TraitsT> _RegexT; typedef regex_constants::syntax_option_type _FlagT; _Compiler(_IterT __b, _IterT __e, const typename _TraitsT::locale_type& __traits, _FlagT __flags); shared_ptr<const _RegexT> _M_get_nfa() { return std::move(_M_nfa); } private: typedef _Scanner<_CharT> _ScannerT; typedef typename _TraitsT::string_type _StringT; typedef typename _ScannerT::_TokenT _TokenT; typedef _StateSeq<_TraitsT> _StateSeqT; typedef std::stack<_StateSeqT> _StackT; typedef std::ctype<_CharT> _CtypeT; // accepts a specific token or returns false. bool _M_match_token(_TokenT __token); void _M_disjunction(); void _M_alternative(); bool _M_term(); bool _M_assertion(); bool _M_quantifier(); bool _M_atom(); bool _M_bracket_expression(); template<bool __icase, bool __collate> void _M_insert_any_matcher_ecma(); template<bool __icase, bool __collate> void _M_insert_any_matcher_posix(); template<bool __icase, bool __collate> void _M_insert_char_matcher(); template<bool __icase, bool __collate> void _M_insert_character_class_matcher(); template<bool __icase, bool __collate> void _M_insert_bracket_matcher(bool __neg); // Cache of the last atom seen in a bracketed range expression. struct _BracketState { enum class _Type : char { _None, _Char, _Class } _M_type = _Type::_None; _CharT _M_char; void set(_CharT __c) noexcept { _M_type = _Type::_Char; _M_char = __c; } _GLIBCXX_NODISCARD _CharT get() const noexcept { return _M_char; } void reset(_Type __t = _Type::_None) noexcept { _M_type = __t; } explicit operator bool() const noexcept { return _M_type != _Type::_None; } // Previous token was a single character. _GLIBCXX_NODISCARD bool _M_is_char() const noexcept { return _M_type == _Type::_Char; } // Previous token was a character class, equivalent class, // collating symbol etc. _GLIBCXX_NODISCARD bool _M_is_class() const noexcept { return _M_type == _Type::_Class; } }; template<bool __icase, bool __collate> using _BracketMatcher = std::__detail::_BracketMatcher<_TraitsT, __icase, __collate>; // Returns true if successfully parsed one term and should continue // compiling a bracket expression. // Returns false if the compiler should move on. template<bool __icase, bool __collate> bool _M_expression_term(_BracketState& __last_char, _BracketMatcher<__icase, __collate>& __matcher); int _M_cur_int_value(int __radix); bool _M_try_char(); _StateSeqT _M_pop() { auto ret = _M_stack.top(); _M_stack.pop(); return ret; } _FlagT _M_flags; _ScannerT _M_scanner; shared_ptr<_RegexT> _M_nfa; _StringT _M_value; _StackT _M_stack; const _TraitsT& _M_traits; const _CtypeT& _M_ctype; }; template<typename _Tp> struct __has_contiguous_iter : std::false_type { }; template<typename _Ch, typename _Tr, typename _Alloc> struct __has_contiguous_iter<std::basic_string<_Ch, _Tr, _Alloc>> : std::true_type { }; template<typename _Tp, typename _Alloc> struct __has_contiguous_iter<std::vector<_Tp, _Alloc>> : std::true_type { }; template<typename _Tp> struct __is_contiguous_normal_iter : std::false_type { }; template<typename _CharT> struct __is_contiguous_normal_iter<_CharT*> : std::true_type { }; template<typename _Tp, typename _Cont> struct __is_contiguous_normal_iter<__gnu_cxx::__normal_iterator<_Tp, _Cont>> : __has_contiguous_iter<_Cont>::type { }; template<typename _Iter, typename _TraitsT> using __enable_if_contiguous_normal_iter = typename enable_if< __is_contiguous_normal_iter<_Iter>::value, std::shared_ptr<const _NFA<_TraitsT>> >::type; template<typename _Iter, typename _TraitsT> using __disable_if_contiguous_normal_iter = typename enable_if< !__is_contiguous_normal_iter<_Iter>::value, std::shared_ptr<const _NFA<_TraitsT>> >::type; template<typename _TraitsT, typename _FwdIter> inline __enable_if_contiguous_normal_iter<_FwdIter, _TraitsT> __compile_nfa(_FwdIter __first, _FwdIter __last, const typename _TraitsT::locale_type& __loc, regex_constants::syntax_option_type __flags) { size_t __len = __last - __first; const auto* __cfirst = __len ? std::__addressof(*__first) : nullptr; using _Cmplr = _Compiler<_TraitsT>; return _Cmplr(__cfirst, __cfirst + __len, __loc, __flags)._M_get_nfa(); } template<typename _TraitsT, typename _FwdIter> inline __disable_if_contiguous_normal_iter<_FwdIter, _TraitsT> __compile_nfa(_FwdIter __first, _FwdIter __last, const typename _TraitsT::locale_type& __loc, regex_constants::syntax_option_type __flags) { const basic_string<typename _TraitsT::char_type> __str(__first, __last); return __compile_nfa<_TraitsT>(__str.data(), __str.data() + __str.size(), __loc, __flags); } // [28.13.14] template<typename _TraitsT, bool __icase, bool __collate> class _RegexTranslatorBase { public: typedef typename _TraitsT::char_type _CharT; typedef typename _TraitsT::string_type _StringT; typedef _StringT _StrTransT; explicit _RegexTranslatorBase(const _TraitsT& __traits) : _M_traits(__traits) { } _CharT _M_translate(_CharT __ch) const { if (__icase) return _M_traits.translate_nocase(__ch); else if (__collate) return _M_traits.translate(__ch); else return __ch; } _StrTransT _M_transform(_CharT __ch) const { _StrTransT __str(1, __ch); return _M_traits.transform(__str.begin(), __str.end()); } // See LWG 523. It's not efficiently implementable when _TraitsT is not // std::regex_traits<>, and __collate is true. See specializations for // implementations of other cases. bool _M_match_range(const _StrTransT& __first, const _StrTransT& __last, const _StrTransT& __s) const { return __first <= __s && __s <= __last; } protected: bool _M_in_range_icase(_CharT __first, _CharT __last, _CharT __ch) const { typedef std::ctype<_CharT> __ctype_type; const auto& __fctyp = use_facet<__ctype_type>(this->_M_traits.getloc()); auto __lower = __fctyp.tolower(__ch); auto __upper = __fctyp.toupper(__ch); return (__first <= __lower && __lower <= __last) || (__first <= __upper && __upper <= __last); } const _TraitsT& _M_traits; }; template<typename _TraitsT, bool __icase, bool __collate> class _RegexTranslator : public _RegexTranslatorBase<_TraitsT, __icase, __collate> { public: typedef _RegexTranslatorBase<_TraitsT, __icase, __collate> _Base; using _Base::_Base; }; template<typename _TraitsT, bool __icase> class _RegexTranslator<_TraitsT, __icase, false> : public _RegexTranslatorBase<_TraitsT, __icase, false> { public: typedef _RegexTranslatorBase<_TraitsT, __icase, false> _Base; typedef typename _Base::_CharT _CharT; typedef _CharT _StrTransT; using _Base::_Base; _StrTransT _M_transform(_CharT __ch) const { return __ch; } bool _M_match_range(_CharT __first, _CharT __last, _CharT __ch) const { if (!__icase) return __first <= __ch && __ch <= __last; return this->_M_in_range_icase(__first, __last, __ch); } }; template<typename _CharType> class _RegexTranslator<std::regex_traits<_CharType>, true, true> : public _RegexTranslatorBase<std::regex_traits<_CharType>, true, true> { public: typedef _RegexTranslatorBase<std::regex_traits<_CharType>, true, true> _Base; typedef typename _Base::_CharT _CharT; typedef typename _Base::_StrTransT _StrTransT; using _Base::_Base; bool _M_match_range(const _StrTransT& __first, const _StrTransT& __last, const _StrTransT& __str) const { __glibcxx_assert(__first.size() == 1); __glibcxx_assert(__last.size() == 1); __glibcxx_assert(__str.size() == 1); return this->_M_in_range_icase(__first[0], __last[0], __str[0]); } }; template<typename _TraitsT> class _RegexTranslator<_TraitsT, false, false> { public: typedef typename _TraitsT::char_type _CharT; typedef _CharT _StrTransT; explicit _RegexTranslator(const _TraitsT&) { } _CharT _M_translate(_CharT __ch) const { return __ch; } _StrTransT _M_transform(_CharT __ch) const { return __ch; } bool _M_match_range(_CharT __first, _CharT __last, _CharT __ch) const { return __first <= __ch && __ch <= __last; } }; template<typename _TraitsT, bool __is_ecma, bool __icase, bool __collate> struct _AnyMatcher; template<typename _TraitsT, bool __icase, bool __collate> struct _AnyMatcher<_TraitsT, false, __icase, __collate> { typedef _RegexTranslator<_TraitsT, __icase, __collate> _TransT; typedef typename _TransT::_CharT _CharT; explicit _AnyMatcher(const _TraitsT& __traits) : _M_translator(__traits) { } bool operator()(_CharT __ch) const { static auto __nul = _M_translator._M_translate('\0'); return _M_translator._M_translate(__ch) != __nul; } _TransT _M_translator; }; template<typename _TraitsT, bool __icase, bool __collate> struct _AnyMatcher<_TraitsT, true, __icase, __collate> { typedef _RegexTranslator<_TraitsT, __icase, __collate> _TransT; typedef typename _TransT::_CharT _CharT; explicit _AnyMatcher(const _TraitsT& __traits) : _M_translator(__traits) { } bool operator()(_CharT __ch) const { return _M_apply(__ch, typename is_same<_CharT, char>::type()); } bool _M_apply(_CharT __ch, true_type) const { auto __c = _M_translator._M_translate(__ch); auto __n = _M_translator._M_translate('\n'); auto __r = _M_translator._M_translate('\r'); return __c != __n && __c != __r; } bool _M_apply(_CharT __ch, false_type) const { auto __c = _M_translator._M_translate(__ch); auto __n = _M_translator._M_translate('\n'); auto __r = _M_translator._M_translate('\r'); auto __u2028 = _M_translator._M_translate(u'\u2028'); auto __u2029 = _M_translator._M_translate(u'\u2029'); return __c != __n && __c != __r && __c != __u2028 && __c != __u2029; } _TransT _M_translator; }; template<typename _TraitsT, bool __icase, bool __collate> struct _CharMatcher { typedef _RegexTranslator<_TraitsT, __icase, __collate> _TransT; typedef typename _TransT::_CharT _CharT; _CharMatcher(_CharT __ch, const _TraitsT& __traits) : _M_translator(__traits), _M_ch(_M_translator._M_translate(__ch)) { } bool operator()(_CharT __ch) const { return _M_ch == _M_translator._M_translate(__ch); } _TransT _M_translator; _CharT _M_ch; }; /// Matches a character range (bracket expression) template<typename _TraitsT, bool __icase, bool __collate> struct _BracketMatcher { public: typedef _RegexTranslator<_TraitsT, __icase, __collate> _TransT; typedef typename _TransT::_CharT _CharT; typedef typename _TransT::_StrTransT _StrTransT; typedef typename _TraitsT::string_type _StringT; typedef typename _TraitsT::char_class_type _CharClassT; public: _BracketMatcher(bool __is_non_matching, const _TraitsT& __traits) : _M_class_set(0), _M_translator(__traits), _M_traits(__traits), _M_is_non_matching(__is_non_matching) { } bool operator()(_CharT __ch) const { _GLIBCXX_DEBUG_ASSERT(_M_is_ready); return _M_apply(__ch, _UseCache()); } void _M_add_char(_CharT __c) { _M_char_set.push_back(_M_translator._M_translate(__c)); _GLIBCXX_DEBUG_ONLY(_M_is_ready = false); } _StringT _M_add_collate_element(const _StringT& __s) { auto __st = _M_traits.lookup_collatename(__s.data(), __s.data() + __s.size()); if (__st.empty()) __throw_regex_error(regex_constants::error_collate, "Invalid collate element."); _M_char_set.push_back(_M_translator._M_translate(__st[0])); _GLIBCXX_DEBUG_ONLY(_M_is_ready = false); return __st; } void _M_add_equivalence_class(const _StringT& __s) { auto __st = _M_traits.lookup_collatename(__s.data(), __s.data() + __s.size()); if (__st.empty()) __throw_regex_error(regex_constants::error_collate, "Invalid equivalence class."); __st = _M_traits.transform_primary(__st.data(), __st.data() + __st.size()); _M_equiv_set.push_back(__st); _GLIBCXX_DEBUG_ONLY(_M_is_ready = false); } // __neg should be true for \D, \S and \W only. void _M_add_character_class(const _StringT& __s, bool __neg) { auto __mask = _M_traits.lookup_classname(__s.data(), __s.data() + __s.size(), __icase); if (__mask == 0) __throw_regex_error(regex_constants::error_collate, "Invalid character class."); if (!__neg) _M_class_set |= __mask; else _M_neg_class_set.push_back(__mask); _GLIBCXX_DEBUG_ONLY(_M_is_ready = false); } void _M_make_range(_CharT __l, _CharT __r) { if (__l > __r) __throw_regex_error(regex_constants::error_range, "Invalid range in bracket expression."); _M_range_set.push_back(make_pair(_M_translator._M_transform(__l), _M_translator._M_transform(__r))); _GLIBCXX_DEBUG_ONLY(_M_is_ready = false); } void _M_ready() { std::sort(_M_char_set.begin(), _M_char_set.end()); auto __end = std::unique(_M_char_set.begin(), _M_char_set.end()); _M_char_set.erase(__end, _M_char_set.end()); _M_make_cache(_UseCache()); _GLIBCXX_DEBUG_ONLY(_M_is_ready = true); } private: // Currently we only use the cache for char typedef typename std::is_same<_CharT, char>::type _UseCache; static constexpr size_t _S_cache_size() { return 1ul << (sizeof(_CharT) * __CHAR_BIT__ * int(_UseCache::value)); } struct _Dummy { }; typedef typename std::conditional<_UseCache::value, std::bitset<_S_cache_size()>, _Dummy>::type _CacheT; typedef typename std::make_unsigned<_CharT>::type _UnsignedCharT; bool _M_apply(_CharT __ch, false_type) const; bool _M_apply(_CharT __ch, true_type) const { return _M_cache[static_cast<_UnsignedCharT>(__ch)]; } void _M_make_cache(true_type) { for (unsigned __i = 0; __i < _M_cache.size(); __i++) _M_cache[__i] = _M_apply(static_cast<_CharT>(__i), false_type()); } void _M_make_cache(false_type) { } private: std::vector<_CharT> _M_char_set; std::vector<_StringT> _M_equiv_set; std::vector<pair<_StrTransT, _StrTransT>> _M_range_set; std::vector<_CharClassT> _M_neg_class_set; _CharClassT _M_class_set; _TransT _M_translator; const _TraitsT& _M_traits; bool _M_is_non_matching; _CacheT _M_cache; #ifdef _GLIBCXX_DEBUG bool _M_is_ready = false; #endif }; //@} regex-detail } // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #include <bits/regex_compiler.tcc> c++/8/bits/localefwd.h 0000644 00000013016 15146341150 0010336 0 ustar 00 // <locale> Forward declarations -*- C++ -*- // Copyright (C) 1997-2018 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/localefwd.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.1 Locales // #ifndef _LOCALE_FWD_H #define _LOCALE_FWD_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/c++locale.h> // Defines __c_locale, config-specific include #include <iosfwd> // For ostreambuf_iterator, istreambuf_iterator #include <cctype> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup locales Locales * * Classes and functions for internationalization and localization. */ // 22.1.1 Locale class locale; template<typename _Facet> bool has_facet(const locale&) throw(); template<typename _Facet> const _Facet& use_facet(const locale&); // 22.1.3 Convenience interfaces template<typename _CharT> bool isspace(_CharT, const locale&); template<typename _CharT> bool isprint(_CharT, const locale&); template<typename _CharT> bool iscntrl(_CharT, const locale&); template<typename _CharT> bool isupper(_CharT, const locale&); template<typename _CharT> bool islower(_CharT, const locale&); template<typename _CharT> bool isalpha(_CharT, const locale&); template<typename _CharT> bool isdigit(_CharT, const locale&); template<typename _CharT> bool ispunct(_CharT, const locale&); template<typename _CharT> bool isxdigit(_CharT, const locale&); template<typename _CharT> bool isalnum(_CharT, const locale&); template<typename _CharT> bool isgraph(_CharT, const locale&); #if __cplusplus >= 201103L template<typename _CharT> bool isblank(_CharT, const locale&); #endif template<typename _CharT> _CharT toupper(_CharT, const locale&); template<typename _CharT> _CharT tolower(_CharT, const locale&); // 22.2.1 and 22.2.1.3 ctype class ctype_base; template<typename _CharT> class ctype; template<> class ctype<char>; #ifdef _GLIBCXX_USE_WCHAR_T template<> class ctype<wchar_t>; #endif template<typename _CharT> class ctype_byname; // NB: Specialized for char and wchar_t in locale_facets.h. class codecvt_base; template<typename _InternT, typename _ExternT, typename _StateT> class codecvt; template<> class codecvt<char, char, mbstate_t>; #ifdef _GLIBCXX_USE_WCHAR_T template<> class codecvt<wchar_t, char, mbstate_t>; #endif template<typename _InternT, typename _ExternT, typename _StateT> class codecvt_byname; // 22.2.2 and 22.2.3 numeric _GLIBCXX_BEGIN_NAMESPACE_LDBL template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > class num_get; template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > class num_put; _GLIBCXX_END_NAMESPACE_LDBL _GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _CharT> class numpunct; template<typename _CharT> class numpunct_byname; _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11 // 22.2.4 collation template<typename _CharT> class collate; template<typename _CharT> class collate_byname; _GLIBCXX_END_NAMESPACE_CXX11 // 22.2.5 date and time class time_base; _GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > class time_get; template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > class time_get_byname; _GLIBCXX_END_NAMESPACE_CXX11 template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > class time_put; template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > class time_put_byname; // 22.2.6 money class money_base; _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 template<typename _CharT, typename _InIter = istreambuf_iterator<_CharT> > class money_get; template<typename _CharT, typename _OutIter = ostreambuf_iterator<_CharT> > class money_put; _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _CharT, bool _Intl = false> class moneypunct; template<typename _CharT, bool _Intl = false> class moneypunct_byname; _GLIBCXX_END_NAMESPACE_CXX11 // 22.2.7 message retrieval class messages_base; _GLIBCXX_BEGIN_NAMESPACE_CXX11 template<typename _CharT> class messages; template<typename _CharT> class messages_byname; _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/fs_ops.h 0000644 00000023002 15146341150 0007663 0 ustar 00 // Filesystem operational functions -*- C++ -*- // Copyright (C) 2014-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your __option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file include/bits/fs_fwd.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{filesystem} */ #ifndef _GLIBCXX_FS_OPS_H #define _GLIBCXX_FS_OPS_H 1 #if __cplusplus >= 201703L #include <cstdint> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace filesystem { /** * @ingroup filesystem * @{ */ path absolute(const path& __p); path absolute(const path& __p, error_code& __ec); path canonical(const path& __p); path canonical(const path& __p, error_code& __ec); inline void copy(const path& __from, const path& __to) { copy(__from, __to, copy_options::none); } inline void copy(const path& __from, const path& __to, error_code& __ec) { copy(__from, __to, copy_options::none, __ec); } void copy(const path& __from, const path& __to, copy_options __options); void copy(const path& __from, const path& __to, copy_options __options, error_code& __ec); inline bool copy_file(const path& __from, const path& __to) { return copy_file(__from, __to, copy_options::none); } inline bool copy_file(const path& __from, const path& __to, error_code& __ec) { return copy_file(__from, __to, copy_options::none, __ec); } bool copy_file(const path& __from, const path& __to, copy_options __option); bool copy_file(const path& __from, const path& __to, copy_options __option, error_code& __ec); void copy_symlink(const path& __existing_symlink, const path& __new_symlink); void copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code& __ec) noexcept; bool create_directories(const path& __p); bool create_directories(const path& __p, error_code& __ec); bool create_directory(const path& __p); bool create_directory(const path& __p, error_code& __ec) noexcept; bool create_directory(const path& __p, const path& attributes); bool create_directory(const path& __p, const path& attributes, error_code& __ec) noexcept; void create_directory_symlink(const path& __to, const path& __new_symlink); void create_directory_symlink(const path& __to, const path& __new_symlink, error_code& __ec) noexcept; void create_hard_link(const path& __to, const path& __new_hard_link); void create_hard_link(const path& __to, const path& __new_hard_link, error_code& __ec) noexcept; void create_symlink(const path& __to, const path& __new_symlink); void create_symlink(const path& __to, const path& __new_symlink, error_code& __ec) noexcept; path current_path(); path current_path(error_code& __ec); void current_path(const path& __p); void current_path(const path& __p, error_code& __ec) noexcept; bool equivalent(const path& __p1, const path& __p2); bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept; inline bool exists(file_status __s) noexcept { return status_known(__s) && __s.type() != file_type::not_found; } inline bool exists(const path& __p) { return exists(status(__p)); } inline bool exists(const path& __p, error_code& __ec) noexcept { auto __s = status(__p, __ec); if (status_known(__s)) { __ec.clear(); return __s.type() != file_type::not_found; } return false; } uintmax_t file_size(const path& __p); uintmax_t file_size(const path& __p, error_code& __ec) noexcept; uintmax_t hard_link_count(const path& __p); uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept; inline bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; } inline bool is_block_file(const path& __p) { return is_block_file(status(__p)); } inline bool is_block_file(const path& __p, error_code& __ec) noexcept { return is_block_file(status(__p, __ec)); } inline bool is_character_file(file_status __s) noexcept { return __s.type() == file_type::character; } inline bool is_character_file(const path& __p) { return is_character_file(status(__p)); } inline bool is_character_file(const path& __p, error_code& __ec) noexcept { return is_character_file(status(__p, __ec)); } inline bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; } inline bool is_directory(const path& __p) { return is_directory(status(__p)); } inline bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(status(__p, __ec)); } bool is_empty(const path& __p); bool is_empty(const path& __p, error_code& __ec); inline bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; } inline bool is_fifo(const path& __p) { return is_fifo(status(__p)); } inline bool is_fifo(const path& __p, error_code& __ec) noexcept { return is_fifo(status(__p, __ec)); } inline bool is_other(file_status __s) noexcept { return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); } inline bool is_other(const path& __p) { return is_other(status(__p)); } inline bool is_other(const path& __p, error_code& __ec) noexcept { return is_other(status(__p, __ec)); } inline bool is_regular_file(file_status __s) noexcept { return __s.type() == file_type::regular; } inline bool is_regular_file(const path& __p) { return is_regular_file(status(__p)); } inline bool is_regular_file(const path& __p, error_code& __ec) noexcept { return is_regular_file(status(__p, __ec)); } inline bool is_socket(file_status __s) noexcept { return __s.type() == file_type::socket; } inline bool is_socket(const path& __p) { return is_socket(status(__p)); } inline bool is_socket(const path& __p, error_code& __ec) noexcept { return is_socket(status(__p, __ec)); } inline bool is_symlink(file_status __s) noexcept { return __s.type() == file_type::symlink; } inline bool is_symlink(const path& __p) { return is_symlink(symlink_status(__p)); } inline bool is_symlink(const path& __p, error_code& __ec) noexcept { return is_symlink(symlink_status(__p, __ec)); } file_time_type last_write_time(const path& __p); file_time_type last_write_time(const path& __p, error_code& __ec) noexcept; void last_write_time(const path& __p, file_time_type __new_time); void last_write_time(const path& __p, file_time_type __new_time, error_code& __ec) noexcept; void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace); inline void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { permissions(__p, __prms, perm_options::replace, __ec); } void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) noexcept; inline path proximate(const path& __p, error_code& __ec) { return proximate(__p, current_path(), __ec); } path proximate(const path& __p, const path& __base = current_path()); path proximate(const path& __p, const path& __base, error_code& __ec); path read_symlink(const path& __p); path read_symlink(const path& __p, error_code& __ec); inline path relative(const path& __p, error_code& __ec) { return relative(__p, current_path(), __ec); } path relative(const path& __p, const path& __base = current_path()); path relative(const path& __p, const path& __base, error_code& __ec); bool remove(const path& __p); bool remove(const path& __p, error_code& __ec) noexcept; uintmax_t remove_all(const path& __p); uintmax_t remove_all(const path& __p, error_code& __ec); void rename(const path& __from, const path& __to); void rename(const path& __from, const path& __to, error_code& __ec) noexcept; void resize_file(const path& __p, uintmax_t __size); void resize_file(const path& __p, uintmax_t __size, error_code& __ec) noexcept; space_info space(const path& __p); space_info space(const path& __p, error_code& __ec) noexcept; file_status status(const path& __p); file_status status(const path& __p, error_code& __ec) noexcept; inline bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; } file_status symlink_status(const path& __p); file_status symlink_status(const path& __p, error_code& __ec) noexcept; path temp_directory_path(); path temp_directory_path(error_code& __ec); path weakly_canonical(const path& __p); path weakly_canonical(const path& __p, error_code& __ec); // @} group filesystem } // namespace filesystem _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++17 #endif // _GLIBCXX_FS_OPS_H c++/8/bits/postypes.h 0000644 00000020020 15146341150 0010255 0 ustar 00 // Position types -*- C++ -*- // Copyright (C) 1997-2018 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/postypes.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iosfwd} */ // // ISO C++ 14882: 27.4.1 - Types // ISO C++ 14882: 27.4.3 - Template class fpos // #ifndef _GLIBCXX_POSTYPES_H #define _GLIBCXX_POSTYPES_H 1 #pragma GCC system_header #include <cwchar> // For mbstate_t // XXX If <stdint.h> is really needed, make sure to define the macros // before including it, in order not to break <tr1/cstdint> (and <cstdint> // in C++11). Reconsider all this as soon as possible... #if (defined(_GLIBCXX_HAVE_INT64_T) && !defined(_GLIBCXX_HAVE_INT64_T_LONG) \ && !defined(_GLIBCXX_HAVE_INT64_T_LONG_LONG)) #ifndef __STDC_LIMIT_MACROS # define _UNDEF__STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS # define _UNDEF__STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif #include <stdint.h> // For int64_t #ifdef _UNDEF__STDC_LIMIT_MACROS # undef __STDC_LIMIT_MACROS # undef _UNDEF__STDC_LIMIT_MACROS #endif #ifdef _UNDEF__STDC_CONSTANT_MACROS # undef __STDC_CONSTANT_MACROS # undef _UNDEF__STDC_CONSTANT_MACROS #endif #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // The types streamoff, streampos and wstreampos and the class // template fpos<> are described in clauses 21.1.2, 21.1.3, 27.1.2, // 27.2, 27.4.1, 27.4.3 and D.6. Despite all this verbiage, the // behaviour of these types is mostly implementation defined or // unspecified. The behaviour in this implementation is as noted // below. /** * @brief Type used by fpos, char_traits<char>, and char_traits<wchar_t>. * * In clauses 21.1.3.1 and 27.4.1 streamoff is described as an * implementation defined type. * Note: In versions of GCC up to and including GCC 3.3, streamoff * was typedef long. */ #ifdef _GLIBCXX_HAVE_INT64_T_LONG typedef long streamoff; #elif defined(_GLIBCXX_HAVE_INT64_T_LONG_LONG) typedef long long streamoff; #elif defined(_GLIBCXX_HAVE_INT64_T) typedef int64_t streamoff; #else typedef long long streamoff; #endif /// Integral type for I/O operation counts and buffer sizes. typedef ptrdiff_t streamsize; // Signed integral type /** * @brief Class representing stream positions. * * The standard places no requirements upon the template parameter StateT. * In this implementation StateT must be DefaultConstructible, * CopyConstructible and Assignable. The standard only requires that fpos * should contain a member of type StateT. In this implementation it also * contains an offset stored as a signed integer. * * @param StateT Type passed to and returned from state(). */ template<typename _StateT> class fpos { private: streamoff _M_off; _StateT _M_state; public: // The standard doesn't require that fpos objects can be default // constructed. This implementation provides a default // constructor that initializes the offset to 0 and default // constructs the state. fpos() : _M_off(0), _M_state() { } // The standard requires that fpos objects can be constructed // from streamoff objects using the constructor syntax, and // fails to give any meaningful semantics. In this // implementation implicit conversion is also allowed, and this // constructor stores the streamoff as the offset and default // constructs the state. /// Construct position from offset. fpos(streamoff __off) : _M_off(__off), _M_state() { } /// Convert to streamoff. operator streamoff() const { return _M_off; } /// Remember the value of @a st. void state(_StateT __st) { _M_state = __st; } /// Return the last set value of @a st. _StateT state() const { return _M_state; } // The standard requires that this operator must be defined, but // gives no semantics. In this implementation it just adds its // argument to the stored offset and returns *this. /// Add offset to this position. fpos& operator+=(streamoff __off) { _M_off += __off; return *this; } // The standard requires that this operator must be defined, but // gives no semantics. In this implementation it just subtracts // its argument from the stored offset and returns *this. /// Subtract offset from this position. fpos& operator-=(streamoff __off) { _M_off -= __off; return *this; } // The standard requires that this operator must be defined, but // defines its semantics only in terms of operator-. In this // implementation it constructs a copy of *this, adds the // argument to that copy using operator+= and then returns the // copy. /// Add position and offset. fpos operator+(streamoff __off) const { fpos __pos(*this); __pos += __off; return __pos; } // The standard requires that this operator must be defined, but // defines its semantics only in terms of operator+. In this // implementation it constructs a copy of *this, subtracts the // argument from that copy using operator-= and then returns the // copy. /// Subtract offset from position. fpos operator-(streamoff __off) const { fpos __pos(*this); __pos -= __off; return __pos; } // The standard requires that this operator must be defined, but // defines its semantics only in terms of operator+. In this // implementation it returns the difference between the offset // stored in *this and in the argument. /// Subtract position to return offset. streamoff operator-(const fpos& __other) const { return _M_off - __other._M_off; } }; // The standard only requires that operator== must be an // equivalence relation. In this implementation two fpos<StateT> // objects belong to the same equivalence class if the contained // offsets compare equal. /// Test if equivalent to another position. template<typename _StateT> inline bool operator==(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs) { return streamoff(__lhs) == streamoff(__rhs); } template<typename _StateT> inline bool operator!=(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs) { return streamoff(__lhs) != streamoff(__rhs); } // Clauses 21.1.3.1 and 21.1.3.2 describe streampos and wstreampos // as implementation defined types, but clause 27.2 requires that // they must both be typedefs for fpos<mbstate_t> /// File position for char streams. typedef fpos<mbstate_t> streampos; /// File position for wchar_t streams. typedef fpos<mbstate_t> wstreampos; #if __cplusplus >= 201103L /// File position for char16_t streams. typedef fpos<mbstate_t> u16streampos; /// File position for char32_t streams. typedef fpos<mbstate_t> u32streampos; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/bits/c++0x_warning.h 0000644 00000002702 15146341150 0010743 0 ustar 00 // Copyright (C) 2007-2018 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 c++/8/bits/string_view.tcc 0000644 00000015052 15146341150 0011262 0 ustar 00 // Components for manipulating non-owning sequences of characters -*- C++ -*- // Copyright (C) 2013-2018 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/string_view.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{string_view} */ // // N3762 basic_string_view library // #ifndef _GLIBCXX_STRING_VIEW_TCC #define _GLIBCXX_STRING_VIEW_TCC 1 #pragma GCC system_header #if __cplusplus >= 201703L namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits> constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: find(const _CharT* __str, size_type __pos, size_type __n) const noexcept { __glibcxx_requires_string_len(__str, __n); if (__n == 0) return __pos <= this->_M_len ? __pos : npos; if (__n <= this->_M_len) { for (; __pos <= this->_M_len - __n; ++__pos) if (traits_type::eq(this->_M_str[__pos], __str[0]) && traits_type::compare(this->_M_str + __pos + 1, __str + 1, __n - 1) == 0) return __pos; } return npos; } template<typename _CharT, typename _Traits> constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: find(_CharT __c, size_type __pos) const noexcept { size_type __ret = npos; if (__pos < this->_M_len) { const size_type __n = this->_M_len - __pos; const _CharT* __p = traits_type::find(this->_M_str + __pos, __n, __c); if (__p) __ret = __p - this->_M_str; } return __ret; } template<typename _CharT, typename _Traits> constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept { __glibcxx_requires_string_len(__str, __n); if (__n <= this->_M_len) { __pos = std::min(size_type(this->_M_len - __n), __pos); do { if (traits_type::compare(this->_M_str + __pos, __str, __n) == 0) return __pos; } while (__pos-- > 0); } return npos; } template<typename _CharT, typename _Traits> constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: rfind(_CharT __c, size_type __pos) const noexcept { size_type __size = this->_M_len; if (__size > 0) { if (--__size > __pos) __size = __pos; for (++__size; __size-- > 0; ) if (traits_type::eq(this->_M_str[__size], __c)) return __size; } return npos; } template<typename _CharT, typename _Traits> constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: find_first_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept { __glibcxx_requires_string_len(__str, __n); for (; __n && __pos < this->_M_len; ++__pos) { const _CharT* __p = traits_type::find(__str, __n, this->_M_str[__pos]); if (__p) return __pos; } return npos; } template<typename _CharT, typename _Traits> constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: find_last_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept { __glibcxx_requires_string_len(__str, __n); size_type __size = this->size(); if (__size && __n) { if (--__size > __pos) __size = __pos; do { if (traits_type::find(__str, __n, this->_M_str[__size])) return __size; } while (__size-- != 0); } return npos; } template<typename _CharT, typename _Traits> constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: find_first_not_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept { __glibcxx_requires_string_len(__str, __n); for (; __pos < this->_M_len; ++__pos) if (!traits_type::find(__str, __n, this->_M_str[__pos])) return __pos; return npos; } template<typename _CharT, typename _Traits> constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: find_first_not_of(_CharT __c, size_type __pos) const noexcept { for (; __pos < this->_M_len; ++__pos) if (!traits_type::eq(this->_M_str[__pos], __c)) return __pos; return npos; } template<typename _CharT, typename _Traits> constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: find_last_not_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept { __glibcxx_requires_string_len(__str, __n); size_type __size = this->_M_len; if (__size) { if (--__size > __pos) __size = __pos; do { if (!traits_type::find(__str, __n, this->_M_str[__size])) return __size; } while (__size--); } return npos; } template<typename _CharT, typename _Traits> constexpr typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>:: find_last_not_of(_CharT __c, size_type __pos) const noexcept { size_type __size = this->_M_len; if (__size) { if (--__size > __pos) __size = __pos; do { if (!traits_type::eq(this->_M_str[__size], __c)) return __size; } while (__size--); } return npos; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // __cplusplus <= 201402L #endif // _GLIBCXX_STRING_VIEW_TCC c++/8/bits/stl_multimap.h 0000644 00000121125 15146341150 0011111 0 ustar 00 // Multimap implementation -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_multimap.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{map} */ #ifndef _STL_MULTIMAP_H #define _STL_MULTIMAP_H 1 #include <bits/concept_check.h> #if __cplusplus >= 201103L #include <initializer_list> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> class map; /** * @brief A standard container made up of (key,value) pairs, which can be * retrieved based on a key, in logarithmic time. * * @ingroup associative_containers * * @tparam _Key Type of key objects. * @tparam _Tp Type of mapped objects. * @tparam _Compare Comparison function object type, defaults to less<_Key>. * @tparam _Alloc Allocator type, defaults to * allocator<pair<const _Key, _Tp>. * * Meets the requirements of a <a href="tables.html#65">container</a>, a * <a href="tables.html#66">reversible container</a>, and an * <a href="tables.html#69">associative container</a> (using equivalent * keys). For a @c multimap<Key,T> the key_type is Key, the mapped_type * is T, and the value_type is std::pair<const Key,T>. * * Multimaps support bidirectional iterators. * * The private tree data is declared exactly the same way for map and * multimap; the distinction is made entirely in how the tree functions are * called (*_unique versus *_equal, same as the standard). */ template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > class multimap { public: typedef _Key key_type; typedef _Tp mapped_type; typedef std::pair<const _Key, _Tp> value_type; typedef _Compare key_compare; typedef _Alloc allocator_type; private: #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename _Alloc::value_type _Alloc_value_type; # if __cplusplus < 201103L __glibcxx_class_requires(_Tp, _SGIAssignableConcept) # endif __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept) #endif #if __cplusplus >= 201103L && defined(__STRICT_ANSI__) static_assert(is_same<typename _Alloc::value_type, value_type>::value, "std::multimap must have the same value_type as its allocator"); #endif public: class value_compare : public std::binary_function<value_type, value_type, bool> { friend class multimap<_Key, _Tp, _Compare, _Alloc>; protected: _Compare comp; value_compare(_Compare __c) : comp(__c) { } public: bool operator()(const value_type& __x, const value_type& __y) const { return comp(__x.first, __y.first); } }; private: /// This turns a red-black tree into a [multi]map. typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<value_type>::other _Pair_alloc_type; typedef _Rb_tree<key_type, value_type, _Select1st<value_type>, key_compare, _Pair_alloc_type> _Rep_type; /// The actual tree structure. _Rep_type _M_t; typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits; public: // many of these are specified differently in ISO, but the following are // "functionally equivalent" 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 _Rep_type::iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; typedef typename _Rep_type::size_type size_type; typedef typename _Rep_type::difference_type difference_type; typedef typename _Rep_type::reverse_iterator reverse_iterator; typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; #if __cplusplus > 201402L using node_type = typename _Rep_type::node_type; #endif // [23.3.2] construct/copy/destroy // (get_allocator() is also listed in this section) /** * @brief Default constructor creates no elements. */ #if __cplusplus < 201103L multimap() : _M_t() { } #else multimap() = default; #endif /** * @brief Creates a %multimap with no elements. * @param __comp A comparison object. * @param __a An allocator object. */ explicit multimap(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Pair_alloc_type(__a)) { } /** * @brief %Multimap copy constructor. * * Whether the allocator is copied depends on the allocator traits. */ #if __cplusplus < 201103L multimap(const multimap& __x) : _M_t(__x._M_t) { } #else multimap(const multimap&) = default; /** * @brief %Multimap move constructor. * * The newly-created %multimap contains the exact contents of the * moved instance. The moved instance is a valid, but unspecified * %multimap. */ multimap(multimap&&) = default; /** * @brief Builds a %multimap from an initializer_list. * @param __l An initializer_list. * @param __comp A comparison functor. * @param __a An allocator object. * * Create a %multimap consisting of copies of the elements from * the initializer_list. This is linear in N if the list is already * sorted, and NlogN otherwise (where N is @a __l.size()). */ multimap(initializer_list<value_type> __l, const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _M_t(__comp, _Pair_alloc_type(__a)) { _M_t._M_insert_equal(__l.begin(), __l.end()); } /// Allocator-extended default constructor. explicit multimap(const allocator_type& __a) : _M_t(_Compare(), _Pair_alloc_type(__a)) { } /// Allocator-extended copy constructor. multimap(const multimap& __m, const allocator_type& __a) : _M_t(__m._M_t, _Pair_alloc_type(__a)) { } /// Allocator-extended move constructor. multimap(multimap&& __m, const allocator_type& __a) noexcept(is_nothrow_copy_constructible<_Compare>::value && _Alloc_traits::_S_always_equal()) : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { } /// Allocator-extended initialier-list constructor. multimap(initializer_list<value_type> __l, const allocator_type& __a) : _M_t(_Compare(), _Pair_alloc_type(__a)) { _M_t._M_insert_equal(__l.begin(), __l.end()); } /// Allocator-extended range constructor. template<typename _InputIterator> multimap(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : _M_t(_Compare(), _Pair_alloc_type(__a)) { _M_t._M_insert_equal(__first, __last); } #endif /** * @brief Builds a %multimap from a range. * @param __first An input iterator. * @param __last An input iterator. * * Create a %multimap consisting of copies of the elements from * [__first,__last). This is linear in N if the range is already sorted, * and NlogN otherwise (where N is distance(__first,__last)). */ template<typename _InputIterator> multimap(_InputIterator __first, _InputIterator __last) : _M_t() { _M_t._M_insert_equal(__first, __last); } /** * @brief Builds a %multimap from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __comp A comparison functor. * @param __a An allocator object. * * Create a %multimap consisting of copies of the elements from * [__first,__last). This is linear in N if the range is already sorted, * and NlogN otherwise (where N is distance(__first,__last)). */ template<typename _InputIterator> multimap(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Pair_alloc_type(__a)) { _M_t._M_insert_equal(__first, __last); } #if __cplusplus >= 201103L /** * The dtor only erases the elements, and note that if the elements * themselves are pointers, the pointed-to memory is not touched in any * way. Managing the pointer is the user's responsibility. */ ~multimap() = default; #endif /** * @brief %Multimap assignment operator. * * Whether the allocator is copied depends on the allocator traits. */ #if __cplusplus < 201103L multimap& operator=(const multimap& __x) { _M_t = __x._M_t; return *this; } #else multimap& operator=(const multimap&) = default; /// Move assignment operator. multimap& operator=(multimap&&) = default; /** * @brief %Multimap list assignment operator. * @param __l An initializer_list. * * This function fills a %multimap with copies of the elements * in the initializer list @a __l. * * Note that the assignment completely changes the %multimap and * that the resulting %multimap's size is the same as the number * of elements assigned. */ multimap& operator=(initializer_list<value_type> __l) { _M_t._M_assign_equal(__l.begin(), __l.end()); return *this; } #endif /// Get a copy of the memory allocation object. allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_t.get_allocator()); } // iterators /** * Returns a read/write iterator that points to the first pair in the * %multimap. Iteration is done in ascending order according to the * keys. */ iterator begin() _GLIBCXX_NOEXCEPT { return _M_t.begin(); } /** * Returns a read-only (constant) iterator that points to the first pair * in the %multimap. Iteration is done in ascending order according to * the keys. */ const_iterator begin() const _GLIBCXX_NOEXCEPT { return _M_t.begin(); } /** * Returns a read/write iterator that points one past the last pair in * the %multimap. Iteration is done in ascending order according to the * keys. */ iterator end() _GLIBCXX_NOEXCEPT { return _M_t.end(); } /** * Returns a read-only (constant) iterator that points one past the last * pair in the %multimap. Iteration is done in ascending order according * to the keys. */ const_iterator end() const _GLIBCXX_NOEXCEPT { return _M_t.end(); } /** * Returns a read/write reverse iterator that points to the last pair in * the %multimap. Iteration is done in descending order according to the * keys. */ reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return _M_t.rbegin(); } /** * Returns a read-only (constant) reverse iterator that points to the * last pair in the %multimap. Iteration is done in descending order * according to the keys. */ const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return _M_t.rbegin(); } /** * Returns a read/write reverse iterator that points to one before the * first pair in the %multimap. Iteration is done in descending order * according to the keys. */ reverse_iterator rend() _GLIBCXX_NOEXCEPT { return _M_t.rend(); } /** * Returns a read-only (constant) reverse iterator that points to one * before the first pair in the %multimap. Iteration is done in * descending order according to the keys. */ const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return _M_t.rend(); } #if __cplusplus >= 201103L /** * Returns a read-only (constant) iterator that points to the first pair * in the %multimap. Iteration is done in ascending order according to * the keys. */ const_iterator cbegin() const noexcept { return _M_t.begin(); } /** * Returns a read-only (constant) iterator that points one past the last * pair in the %multimap. Iteration is done in ascending order according * to the keys. */ const_iterator cend() const noexcept { return _M_t.end(); } /** * Returns a read-only (constant) reverse iterator that points to the * last pair in the %multimap. Iteration is done in descending order * according to the keys. */ const_reverse_iterator crbegin() const noexcept { return _M_t.rbegin(); } /** * Returns a read-only (constant) reverse iterator that points to one * before the first pair in the %multimap. Iteration is done in * descending order according to the keys. */ const_reverse_iterator crend() const noexcept { return _M_t.rend(); } #endif // capacity /** Returns true if the %multimap is empty. */ bool empty() const _GLIBCXX_NOEXCEPT { return _M_t.empty(); } /** Returns the size of the %multimap. */ size_type size() const _GLIBCXX_NOEXCEPT { return _M_t.size(); } /** Returns the maximum size of the %multimap. */ size_type max_size() const _GLIBCXX_NOEXCEPT { return _M_t.max_size(); } // modifiers #if __cplusplus >= 201103L /** * @brief Build and insert a std::pair into the %multimap. * * @param __args Arguments used to generate a new pair instance (see * std::piecewise_contruct for passing arguments to each * part of the pair constructor). * * @return An iterator that points to the inserted (key,value) pair. * * This function builds and inserts a (key, value) %pair into the * %multimap. * Contrary to a std::map the %multimap does not rely on unique keys and * thus multiple pairs with the same key can be inserted. * * Insertion requires logarithmic time. */ template<typename... _Args> iterator emplace(_Args&&... __args) { return _M_t._M_emplace_equal(std::forward<_Args>(__args)...); } /** * @brief Builds and inserts a std::pair into the %multimap. * * @param __pos An iterator that serves as a hint as to where the pair * should be inserted. * @param __args Arguments used to generate a new pair instance (see * std::piecewise_contruct for passing arguments to each * part of the pair constructor). * @return An iterator that points to the inserted (key,value) pair. * * This function inserts a (key, value) pair into the %multimap. * Contrary to a std::map the %multimap does not rely on unique keys and * thus multiple pairs with the same key can be inserted. * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * For more on @a hinting, see: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * * Insertion requires logarithmic time (if the hint is not taken). */ template<typename... _Args> iterator emplace_hint(const_iterator __pos, _Args&&... __args) { return _M_t._M_emplace_hint_equal(__pos, std::forward<_Args>(__args)...); } #endif /** * @brief Inserts a std::pair into the %multimap. * @param __x Pair to be inserted (see std::make_pair for easy creation * of pairs). * @return An iterator that points to the inserted (key,value) pair. * * This function inserts a (key, value) pair into the %multimap. * Contrary to a std::map the %multimap does not rely on unique keys and * thus multiple pairs with the same key can be inserted. * * Insertion requires logarithmic time. * @{ */ iterator insert(const value_type& __x) { return _M_t._M_insert_equal(__x); } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2354. Unnecessary copying when inserting into maps with braced-init iterator insert(value_type&& __x) { return _M_t._M_insert_equal(std::move(__x)); } template<typename _Pair> __enable_if_t<is_constructible<value_type, _Pair>::value, iterator> insert(_Pair&& __x) { return _M_t._M_emplace_equal(std::forward<_Pair>(__x)); } #endif // @} /** * @brief Inserts a std::pair into the %multimap. * @param __position An iterator that serves as a hint as to where the * pair should be inserted. * @param __x Pair to be inserted (see std::make_pair for easy creation * of pairs). * @return An iterator that points to the inserted (key,value) pair. * * This function inserts a (key, value) pair into the %multimap. * Contrary to a std::map the %multimap does not rely on unique keys and * thus multiple pairs with the same key can be inserted. * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * For more on @a hinting, see: * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * * Insertion requires logarithmic time (if the hint is not taken). * @{ */ iterator #if __cplusplus >= 201103L insert(const_iterator __position, const value_type& __x) #else insert(iterator __position, const value_type& __x) #endif { return _M_t._M_insert_equal_(__position, __x); } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2354. Unnecessary copying when inserting into maps with braced-init iterator insert(const_iterator __position, value_type&& __x) { return _M_t._M_insert_equal_(__position, std::move(__x)); } template<typename _Pair> __enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator> insert(const_iterator __position, _Pair&& __x) { return _M_t._M_emplace_hint_equal(__position, std::forward<_Pair>(__x)); } #endif // @} /** * @brief A template function that attempts to insert a range * of elements. * @param __first Iterator pointing to the start of the range to be * inserted. * @param __last Iterator pointing to the end of the range. * * Complexity similar to that of the range constructor. */ template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_t._M_insert_equal(__first, __last); } #if __cplusplus >= 201103L /** * @brief Attempts to insert a list of std::pairs into the %multimap. * @param __l A std::initializer_list<value_type> of pairs to be * inserted. * * Complexity similar to that of the range constructor. */ void insert(initializer_list<value_type> __l) { this->insert(__l.begin(), __l.end()); } #endif #if __cplusplus > 201402L /// Extract a node. node_type extract(const_iterator __pos) { __glibcxx_assert(__pos != end()); return _M_t.extract(__pos); } /// Extract a node. node_type extract(const key_type& __x) { return _M_t.extract(__x); } /// Re-insert an extracted node. iterator insert(node_type&& __nh) { return _M_t._M_reinsert_node_equal(std::move(__nh)); } /// Re-insert an extracted node. iterator insert(const_iterator __hint, node_type&& __nh) { return _M_t._M_reinsert_node_hint_equal(__hint, std::move(__nh)); } template<typename, typename> friend class std::_Rb_tree_merge_helper; template<typename _C2> void merge(multimap<_Key, _Tp, _C2, _Alloc>& __source) { using _Merge_helper = _Rb_tree_merge_helper<multimap, _C2>; _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source)); } template<typename _C2> void merge(multimap<_Key, _Tp, _C2, _Alloc>&& __source) { merge(__source); } template<typename _C2> void merge(map<_Key, _Tp, _C2, _Alloc>& __source) { using _Merge_helper = _Rb_tree_merge_helper<multimap, _C2>; _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source)); } template<typename _C2> void merge(map<_Key, _Tp, _C2, _Alloc>&& __source) { merge(__source); } #endif // C++17 #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. /** * @brief Erases an element from a %multimap. * @param __position An iterator pointing to the element to be erased. * @return An iterator pointing to the element immediately following * @a position prior to the element being erased. If no such * element exists, end() is returned. * * This function erases an element, pointed to by the given iterator, * from a %multimap. Note that this function only erases the element, * and that if the element is itself a pointer, the pointed-to memory is * not touched in any way. Managing the pointer is the user's * responsibility. * * @{ */ iterator erase(const_iterator __position) { return _M_t.erase(__position); } // LWG 2059. _GLIBCXX_ABI_TAG_CXX11 iterator erase(iterator __position) { return _M_t.erase(__position); } // @} #else /** * @brief Erases an element from a %multimap. * @param __position An iterator pointing to the element to be erased. * * This function erases an element, pointed to by the given iterator, * from a %multimap. Note that this function only erases the element, * and that if the element is itself a pointer, the pointed-to memory is * not touched in any way. Managing the pointer is the user's * responsibility. */ void erase(iterator __position) { _M_t.erase(__position); } #endif /** * @brief Erases elements according to the provided key. * @param __x Key of element to be erased. * @return The number of elements erased. * * This function erases all elements located by the given key from a * %multimap. * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ size_type erase(const key_type& __x) { return _M_t.erase(__x); } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. /** * @brief Erases a [first,last) range of elements from a %multimap. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to be * erased . * @return The iterator @a __last. * * This function erases a sequence of elements from a %multimap. * Note that this function only erases the elements, and that if * the elements themselves are pointers, the pointed-to memory is not * touched in any way. Managing the pointer is the user's * responsibility. */ iterator erase(const_iterator __first, const_iterator __last) { return _M_t.erase(__first, __last); } #else // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. /** * @brief Erases a [first,last) range of elements from a %multimap. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to * be erased. * * This function erases a sequence of elements from a %multimap. * Note that this function only erases the elements, and that if * the elements themselves are pointers, the pointed-to memory is not * touched in any way. Managing the pointer is the user's * responsibility. */ void erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } #endif /** * @brief Swaps data with another %multimap. * @param __x A %multimap of the same element and allocator types. * * This exchanges the elements between two multimaps in constant time. * (It is only swapping a pointer, an integer, and an instance of * the @c Compare type (which itself is often stateless and empty), so it * should be quite fast.) * Note that the global std::swap() function is specialized such that * std::swap(m1,m2) will feed to this function. * * Whether the allocators are swapped depends on the allocator traits. */ void swap(multimap& __x) _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value) { _M_t.swap(__x._M_t); } /** * Erases all elements in a %multimap. Note that this function only * erases the elements, and that if the elements themselves are pointers, * the pointed-to memory is not touched in any way. Managing the pointer * is the user's responsibility. */ void clear() _GLIBCXX_NOEXCEPT { _M_t.clear(); } // observers /** * Returns the key comparison object out of which the %multimap * was constructed. */ key_compare key_comp() const { return _M_t.key_comp(); } /** * Returns a value comparison object, built from the key comparison * object out of which the %multimap was constructed. */ value_compare value_comp() const { return value_compare(_M_t.key_comp()); } // multimap operations //@{ /** * @brief Tries to locate an element in a %multimap. * @param __x Key of (key, value) pair to be located. * @return Iterator pointing to sought-after element, * or end() if not found. * * This function takes a key and tries to locate the element with which * the key matches. If successful the function returns an iterator * pointing to the sought after %pair. If unsuccessful it returns the * past-the-end ( @c end() ) iterator. */ iterator find(const key_type& __x) { return _M_t.find(__x); } #if __cplusplus > 201103L template<typename _Kt> auto find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x)) { return _M_t._M_find_tr(__x); } #endif //@} //@{ /** * @brief Tries to locate an element in a %multimap. * @param __x Key of (key, value) pair to be located. * @return Read-only (constant) iterator pointing to sought-after * element, or end() if not found. * * This function takes a key and tries to locate the element with which * the key matches. If successful the function returns a constant * iterator pointing to the sought after %pair. If unsuccessful it * returns the past-the-end ( @c end() ) iterator. */ const_iterator find(const key_type& __x) const { return _M_t.find(__x); } #if __cplusplus > 201103L template<typename _Kt> auto find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x)) { return _M_t._M_find_tr(__x); } #endif //@} //@{ /** * @brief Finds the number of elements with given key. * @param __x Key of (key, value) pairs to be located. * @return Number of elements with specified key. */ size_type count(const key_type& __x) const { return _M_t.count(__x); } #if __cplusplus > 201103L template<typename _Kt> auto count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x)) { return _M_t._M_count_tr(__x); } #endif //@} //@{ /** * @brief Finds the beginning of a subsequence matching given key. * @param __x Key of (key, value) pair to be located. * @return Iterator pointing to first element equal to or greater * than key, or end(). * * This function returns the first element of a subsequence of elements * that matches the given key. If unsuccessful it returns an iterator * pointing to the first element that has a greater value than given key * or end() if no such element exists. */ iterator lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto lower_bound(const _Kt& __x) -> decltype(iterator(_M_t._M_lower_bound_tr(__x))) { return iterator(_M_t._M_lower_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds the beginning of a subsequence matching given key. * @param __x Key of (key, value) pair to be located. * @return Read-only (constant) iterator pointing to first element * equal to or greater than key, or end(). * * This function returns the first element of a subsequence of * elements that matches the given key. If unsuccessful the * iterator will point to the next greatest element or, if no * such greater element exists, to end(). */ const_iterator lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto lower_bound(const _Kt& __x) const -> decltype(const_iterator(_M_t._M_lower_bound_tr(__x))) { return const_iterator(_M_t._M_lower_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds the end of a subsequence matching given key. * @param __x Key of (key, value) pair to be located. * @return Iterator pointing to the first element * greater than key, or end(). */ iterator upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto upper_bound(const _Kt& __x) -> decltype(iterator(_M_t._M_upper_bound_tr(__x))) { return iterator(_M_t._M_upper_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds the end of a subsequence matching given key. * @param __x Key of (key, value) pair to be located. * @return Read-only (constant) iterator pointing to first iterator * greater than key, or end(). */ const_iterator upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto upper_bound(const _Kt& __x) const -> decltype(const_iterator(_M_t._M_upper_bound_tr(__x))) { return const_iterator(_M_t._M_upper_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds a subsequence matching given key. * @param __x Key of (key, value) pairs to be located. * @return Pair of iterators that possibly points to the subsequence * matching given key. * * This function is equivalent to * @code * std::make_pair(c.lower_bound(val), * c.upper_bound(val)) * @endcode * (but is faster than making the calls separately). */ std::pair<iterator, iterator> equal_range(const key_type& __x) { return _M_t.equal_range(__x); } #if __cplusplus > 201103L template<typename _Kt> auto equal_range(const _Kt& __x) -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x))) { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); } #endif //@} //@{ /** * @brief Finds a subsequence matching given key. * @param __x Key of (key, value) pairs to be located. * @return Pair of read-only (constant) iterators that possibly points * to the subsequence matching given key. * * This function is equivalent to * @code * std::make_pair(c.lower_bound(val), * c.upper_bound(val)) * @endcode * (but is faster than making the calls separately). */ std::pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } #if __cplusplus > 201103L template<typename _Kt> auto equal_range(const _Kt& __x) const -> decltype(pair<const_iterator, const_iterator>( _M_t._M_equal_range_tr(__x))) { return pair<const_iterator, const_iterator>( _M_t._M_equal_range_tr(__x)); } #endif //@} template<typename _K1, typename _T1, typename _C1, typename _A1> friend bool operator==(const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); template<typename _K1, typename _T1, typename _C1, typename _A1> friend bool operator<(const multimap<_K1, _T1, _C1, _A1>&, const multimap<_K1, _T1, _C1, _A1>&); }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _Compare = less<__iter_key_t<_InputIterator>>, typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Compare, _Allocator>; template<typename _Key, typename _Tp, typename _Compare = less<_Key>, typename _Allocator = allocator<pair<const _Key, _Tp>>, typename = _RequireAllocator<_Allocator>> multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator()) -> multimap<_Key, _Tp, _Compare, _Allocator>; template<typename _InputIterator, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> multimap(_InputIterator, _InputIterator, _Allocator) -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, less<__iter_key_t<_InputIterator>>, _Allocator>; template<typename _Key, typename _Tp, typename _Allocator, typename = _RequireAllocator<_Allocator>> multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) -> multimap<_Key, _Tp, less<_Key>, _Allocator>; #endif /** * @brief Multimap equality comparison. * @param __x A %multimap. * @param __y A %multimap of the same type as @a __x. * @return True iff the size and elements of the maps are equal. * * This is an equivalence relation. It is linear in the size of the * multimaps. Multimaps are considered equivalent if their sizes are equal, * and if corresponding elements compare equal. */ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator==(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, const multimap<_Key, _Tp, _Compare, _Alloc>& __y) { return __x._M_t == __y._M_t; } /** * @brief Multimap ordering relation. * @param __x A %multimap. * @param __y A %multimap of the same type as @a __x. * @return True iff @a x is lexicographically less than @a y. * * This is a total ordering relation. It is linear in the size of the * multimaps. The elements must be comparable with @c <. * * See std::lexicographical_compare() for how the determination is made. */ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, const multimap<_Key, _Tp, _Compare, _Alloc>& __y) { return __x._M_t < __y._M_t; } /// Based on operator== template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator!=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, const multimap<_Key, _Tp, _Compare, _Alloc>& __y) { return !(__x == __y); } /// Based on operator< template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator>(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, const multimap<_Key, _Tp, _Compare, _Alloc>& __y) { return __y < __x; } /// Based on operator< template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator<=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, const multimap<_Key, _Tp, _Compare, _Alloc>& __y) { return !(__y < __x); } /// Based on operator< template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator>=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x, const multimap<_Key, _Tp, _Compare, _Alloc>& __y) { return !(__x < __y); } /// See std::multimap::swap(). template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline void swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x, multimap<_Key, _Tp, _Compare, _Alloc>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER #if __cplusplus > 201402L // Allow std::multimap access to internals of compatible maps. template<typename _Key, typename _Val, typename _Cmp1, typename _Alloc, typename _Cmp2> struct _Rb_tree_merge_helper<_GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp1, _Alloc>, _Cmp2> { private: friend class _GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp1, _Alloc>; static auto& _S_get_tree(_GLIBCXX_STD_C::map<_Key, _Val, _Cmp2, _Alloc>& __map) { return __map._M_t; } static auto& _S_get_tree(_GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp2, _Alloc>& __map) { return __map._M_t; } }; #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _STL_MULTIMAP_H */ c++/8/bits/regex_executor.tcc 0000644 00000044631 15146341150 0011757 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2013-2018 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/regex_executor.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_search() { if (_M_search_from_first()) return true; if (_M_flags & regex_constants::match_continuous) return false; _M_flags |= regex_constants::match_prev_avail; while (_M_begin != _M_end) { ++_M_begin; if (_M_search_from_first()) return true; } return false; } // The _M_main function operates in different modes, DFS mode or BFS mode, // indicated by template parameter __dfs_mode, and dispatches to one of the // _M_main_dispatch overloads. // // ------------------------------------------------------------ // // DFS mode: // // It applies a Depth-First-Search (aka backtracking) on given NFA and input // string. // At the very beginning the executor stands in the start state, then it // tries every possible state transition in current state recursively. Some // state transitions consume input string, say, a single-char-matcher or a // back-reference matcher; some don't, like assertion or other anchor nodes. // When the input is exhausted and/or the current state is an accepting // state, the whole executor returns true. // // TODO: This approach is exponentially slow for certain input. // Try to compile the NFA to a DFA. // // Time complexity: \Omega(match_length), O(2^(_M_nfa.size())) // Space complexity: \theta(match_results.size() + match_length) // template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_main_dispatch(_Match_mode __match_mode, __dfs) { _M_has_sol = false; *_M_states._M_get_sol_pos() = _BiIter(); _M_cur_results = _M_results; _M_dfs(__match_mode, _M_states._M_start); return _M_has_sol; } // ------------------------------------------------------------ // // BFS mode: // // Russ Cox's article (http://swtch.com/~rsc/regexp/regexp1.html) // explained this algorithm clearly. // // It first computes epsilon closure (states that can be achieved without // consuming characters) for every state that's still matching, // using the same DFS algorithm, but doesn't re-enter states (using // _M_states._M_visited to check), nor follow _S_opcode_match. // // Then apply DFS using every _S_opcode_match (in _M_states._M_match_queue) // as the start state. // // It significantly reduces potential duplicate states, so has a better // upper bound; but it requires more overhead. // // Time complexity: \Omega(match_length * match_results.size()) // O(match_length * _M_nfa.size() * match_results.size()) // Space complexity: \Omega(_M_nfa.size() + match_results.size()) // O(_M_nfa.size() * match_results.size()) template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_main_dispatch(_Match_mode __match_mode, __bfs) { _M_states._M_queue(_M_states._M_start, _M_results); bool __ret = false; while (1) { _M_has_sol = false; if (_M_states._M_match_queue.empty()) break; std::fill_n(_M_states._M_visited_states.get(), _M_nfa.size(), false); auto __old_queue = std::move(_M_states._M_match_queue); for (auto& __task : __old_queue) { _M_cur_results = std::move(__task.second); _M_dfs(__match_mode, __task.first); } if (__match_mode == _Match_mode::_Prefix) __ret |= _M_has_sol; if (_M_current == _M_end) break; ++_M_current; } if (__match_mode == _Match_mode::_Exact) __ret = _M_has_sol; _M_states._M_match_queue.clear(); return __ret; } // Return whether now match the given sub-NFA. template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_lookahead(_StateIdT __next) { // Backreferences may refer to captured content. // We may want to make this faster by not copying, // but let's not be clever prematurely. _ResultsVec __what(_M_cur_results); _Executor __sub(_M_current, _M_end, __what, _M_re, _M_flags); __sub._M_states._M_start = __next; if (__sub._M_search_from_first()) { for (size_t __i = 0; __i < __what.size(); __i++) if (__what[__i].matched) _M_cur_results[__i] = __what[__i]; return true; } return false; } // __rep_count records how many times (__rep_count.second) // this node is visited under certain input iterator // (__rep_count.first). This prevent the executor from entering // infinite loop by refusing to continue when it's already been // visited more than twice. It's `twice` instead of `once` because // we need to spare one more time for potential group capture. template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_rep_once_more(_Match_mode __match_mode, _StateIdT __i) { const auto& __state = _M_nfa[__i]; auto& __rep_count = _M_rep_count[__i]; if (__rep_count.second == 0 || __rep_count.first != _M_current) { auto __back = __rep_count; __rep_count.first = _M_current; __rep_count.second = 1; _M_dfs(__match_mode, __state._M_alt); __rep_count = __back; } else { if (__rep_count.second < 2) { __rep_count.second++; _M_dfs(__match_mode, __state._M_alt); __rep_count.second--; } } } // _M_alt branch is "match once more", while _M_next is "get me out // of this quantifier". Executing _M_next first or _M_alt first don't // mean the same thing, and we need to choose the correct order under // given greedy mode. template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_repeat(_Match_mode __match_mode, _StateIdT __i) { const auto& __state = _M_nfa[__i]; // Greedy. if (!__state._M_neg) { _M_rep_once_more(__match_mode, __i); // If it's DFS executor and already accepted, we're done. if (!__dfs_mode || !_M_has_sol) _M_dfs(__match_mode, __state._M_next); } else // Non-greedy mode { if (__dfs_mode) { // vice-versa. _M_dfs(__match_mode, __state._M_next); if (!_M_has_sol) _M_rep_once_more(__match_mode, __i); } else { // DON'T attempt anything, because there's already another // state with higher priority accepted. This state cannot // be better by attempting its next node. if (!_M_has_sol) { _M_dfs(__match_mode, __state._M_next); // DON'T attempt anything if it's already accepted. An // accepted state *must* be better than a solution that // matches a non-greedy quantifier one more time. if (!_M_has_sol) _M_rep_once_more(__match_mode, __i); } } } } template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_subexpr_begin(_Match_mode __match_mode, _StateIdT __i) { const auto& __state = _M_nfa[__i]; auto& __res = _M_cur_results[__state._M_subexpr]; auto __back = __res.first; __res.first = _M_current; _M_dfs(__match_mode, __state._M_next); __res.first = __back; } template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_subexpr_end(_Match_mode __match_mode, _StateIdT __i) { const auto& __state = _M_nfa[__i]; auto& __res = _M_cur_results[__state._M_subexpr]; auto __back = __res; __res.second = _M_current; __res.matched = true; _M_dfs(__match_mode, __state._M_next); __res = __back; } template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> inline void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_line_begin_assertion(_Match_mode __match_mode, _StateIdT __i) { const auto& __state = _M_nfa[__i]; if (_M_at_begin()) _M_dfs(__match_mode, __state._M_next); } template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> inline void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_line_end_assertion(_Match_mode __match_mode, _StateIdT __i) { const auto& __state = _M_nfa[__i]; if (_M_at_end()) _M_dfs(__match_mode, __state._M_next); } template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> inline void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_word_boundary(_Match_mode __match_mode, _StateIdT __i) { const auto& __state = _M_nfa[__i]; if (_M_word_boundary() == !__state._M_neg) _M_dfs(__match_mode, __state._M_next); } // Here __state._M_alt offers a single start node for a sub-NFA. // We recursively invoke our algorithm to match the sub-NFA. template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_subexpr_lookahead(_Match_mode __match_mode, _StateIdT __i) { const auto& __state = _M_nfa[__i]; if (_M_lookahead(__state._M_alt) == !__state._M_neg) _M_dfs(__match_mode, __state._M_next); } template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_match(_Match_mode __match_mode, _StateIdT __i) { const auto& __state = _M_nfa[__i]; if (_M_current == _M_end) return; if (__dfs_mode) { if (__state._M_matches(*_M_current)) { ++_M_current; _M_dfs(__match_mode, __state._M_next); --_M_current; } } else if (__state._M_matches(*_M_current)) _M_states._M_queue(__state._M_next, _M_cur_results); } template<typename _BiIter, typename _TraitsT> struct _Backref_matcher { _Backref_matcher(bool __icase, const _TraitsT& __traits) : _M_traits(__traits) { } bool _M_apply(_BiIter __expected_begin, _BiIter __expected_end, _BiIter __actual_begin, _BiIter __actual_end) { return _M_traits.transform(__expected_begin, __expected_end) == _M_traits.transform(__actual_begin, __actual_end); } const _TraitsT& _M_traits; }; template<typename _BiIter, typename _CharT> struct _Backref_matcher<_BiIter, std::regex_traits<_CharT>> { using _TraitsT = std::regex_traits<_CharT>; _Backref_matcher(bool __icase, const _TraitsT& __traits) : _M_icase(__icase), _M_traits(__traits) { } bool _M_apply(_BiIter __expected_begin, _BiIter __expected_end, _BiIter __actual_begin, _BiIter __actual_end) { if (!_M_icase) return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end, __actual_begin, __actual_end); typedef std::ctype<_CharT> __ctype_type; const auto& __fctyp = use_facet<__ctype_type>(_M_traits.getloc()); return _GLIBCXX_STD_A::__equal4(__expected_begin, __expected_end, __actual_begin, __actual_end, [this, &__fctyp](_CharT __lhs, _CharT __rhs) { return __fctyp.tolower(__lhs) == __fctyp.tolower(__rhs); }); } bool _M_icase; const _TraitsT& _M_traits; }; // First fetch the matched result from _M_cur_results as __submatch; // then compare it with // (_M_current, _M_current + (__submatch.second - __submatch.first)). // If matched, keep going; else just return and try another state. template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_backref(_Match_mode __match_mode, _StateIdT __i) { __glibcxx_assert(__dfs_mode); const auto& __state = _M_nfa[__i]; auto& __submatch = _M_cur_results[__state._M_backref_index]; if (!__submatch.matched) return; auto __last = _M_current; for (auto __tmp = __submatch.first; __last != _M_end && __tmp != __submatch.second; ++__tmp) ++__last; if (_Backref_matcher<_BiIter, _TraitsT>( _M_re.flags() & regex_constants::icase, _M_re._M_automaton->_M_traits)._M_apply( __submatch.first, __submatch.second, _M_current, __last)) { if (__last != _M_current) { auto __backup = _M_current; _M_current = __last; _M_dfs(__match_mode, __state._M_next); _M_current = __backup; } else _M_dfs(__match_mode, __state._M_next); } } template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_accept(_Match_mode __match_mode, _StateIdT __i) { if (__dfs_mode) { __glibcxx_assert(!_M_has_sol); if (__match_mode == _Match_mode::_Exact) _M_has_sol = _M_current == _M_end; else _M_has_sol = true; if (_M_current == _M_begin && (_M_flags & regex_constants::match_not_null)) _M_has_sol = false; if (_M_has_sol) { if (_M_nfa._M_flags & regex_constants::ECMAScript) _M_results = _M_cur_results; else // POSIX { __glibcxx_assert(_M_states._M_get_sol_pos()); // Here's POSIX's logic: match the longest one. However // we never know which one (lhs or rhs of "|") is longer // unless we try both of them and compare the results. // The member variable _M_sol_pos records the end // position of the last successful match. It's better // to be larger, because POSIX regex is always greedy. // TODO: This could be slow. if (*_M_states._M_get_sol_pos() == _BiIter() || std::distance(_M_begin, *_M_states._M_get_sol_pos()) < std::distance(_M_begin, _M_current)) { *_M_states._M_get_sol_pos() = _M_current; _M_results = _M_cur_results; } } } } else { if (_M_current == _M_begin && (_M_flags & regex_constants::match_not_null)) return; if (__match_mode == _Match_mode::_Prefix || _M_current == _M_end) if (!_M_has_sol) { _M_has_sol = true; _M_results = _M_cur_results; } } } template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_handle_alternative(_Match_mode __match_mode, _StateIdT __i) { const auto& __state = _M_nfa[__i]; if (_M_nfa._M_flags & regex_constants::ECMAScript) { // TODO: Fix BFS support. It is wrong. _M_dfs(__match_mode, __state._M_alt); // Pick lhs if it matches. Only try rhs if it doesn't. if (!_M_has_sol) _M_dfs(__match_mode, __state._M_next); } else { // Try both and compare the result. // See "case _S_opcode_accept:" handling above. _M_dfs(__match_mode, __state._M_alt); auto __has_sol = _M_has_sol; _M_has_sol = false; _M_dfs(__match_mode, __state._M_next); _M_has_sol |= __has_sol; } } template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_dfs(_Match_mode __match_mode, _StateIdT __i) { if (_M_states._M_visited(__i)) return; switch (_M_nfa[__i]._M_opcode()) { case _S_opcode_repeat: _M_handle_repeat(__match_mode, __i); break; case _S_opcode_subexpr_begin: _M_handle_subexpr_begin(__match_mode, __i); break; case _S_opcode_subexpr_end: _M_handle_subexpr_end(__match_mode, __i); break; case _S_opcode_line_begin_assertion: _M_handle_line_begin_assertion(__match_mode, __i); break; case _S_opcode_line_end_assertion: _M_handle_line_end_assertion(__match_mode, __i); break; case _S_opcode_word_boundary: _M_handle_word_boundary(__match_mode, __i); break; case _S_opcode_subexpr_lookahead: _M_handle_subexpr_lookahead(__match_mode, __i); break; case _S_opcode_match: _M_handle_match(__match_mode, __i); break; case _S_opcode_backref: _M_handle_backref(__match_mode, __i); break; case _S_opcode_accept: _M_handle_accept(__match_mode, __i); break; case _S_opcode_alternative: _M_handle_alternative(__match_mode, __i); break; default: __glibcxx_assert(false); } } // Return whether now is at some word boundary. template<typename _BiIter, typename _Alloc, typename _TraitsT, bool __dfs_mode> bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_word_boundary() const { if (_M_current == _M_begin && (_M_flags & regex_constants::match_not_bow)) return false; if (_M_current == _M_end && (_M_flags & regex_constants::match_not_eow)) return false; bool __left_is_word = false; if (_M_current != _M_begin || (_M_flags & regex_constants::match_prev_avail)) { auto __prev = _M_current; if (_M_is_word(*std::prev(__prev))) __left_is_word = true; } bool __right_is_word = _M_current != _M_end && _M_is_word(*_M_current); return __left_is_word != __right_is_word; } } // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/bits/functexcept.h 0000644 00000006266 15146341150 0010737 0 ustar 00 // Function-Based Exception Support -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/functexcept.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{exception} * * This header provides support for -fno-exceptions. */ // // ISO C++ 14882: 19.1 Exception classes // #ifndef _FUNCTEXCEPT_H #define _FUNCTEXCEPT_H 1 #include <bits/c++config.h> #include <bits/exception_defines.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Helper for exception objects in <except> void __throw_bad_exception(void) __attribute__((__noreturn__)); // Helper for exception objects in <new> void __throw_bad_alloc(void) __attribute__((__noreturn__)); // Helper for exception objects in <typeinfo> void __throw_bad_cast(void) __attribute__((__noreturn__)); void __throw_bad_typeid(void) __attribute__((__noreturn__)); // Helpers for exception objects in <stdexcept> void __throw_logic_error(const char*) __attribute__((__noreturn__)); void __throw_domain_error(const char*) __attribute__((__noreturn__)); void __throw_invalid_argument(const char*) __attribute__((__noreturn__)); void __throw_length_error(const char*) __attribute__((__noreturn__)); void __throw_out_of_range(const char*) __attribute__((__noreturn__)); void __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__)) __attribute__((__format__(__gnu_printf__, 1, 2))); void __throw_runtime_error(const char*) __attribute__((__noreturn__)); void __throw_range_error(const char*) __attribute__((__noreturn__)); void __throw_overflow_error(const char*) __attribute__((__noreturn__)); void __throw_underflow_error(const char*) __attribute__((__noreturn__)); // Helpers for exception objects in <ios> void __throw_ios_failure(const char*) __attribute__((__noreturn__)); void __throw_system_error(int) __attribute__((__noreturn__)); void __throw_future_error(int) __attribute__((__noreturn__)); // Helpers for exception objects in <functional> void __throw_bad_function_call() __attribute__((__noreturn__)); _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/bits/cxxabi_init_exception.h 0000644 00000004254 15146341150 0012761 0 ustar 00 // ABI Support -*- C++ -*- // Copyright (C) 2016-2018 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 c++/8/bits/ptr_traits.h 0000644 00000014742 15146341150 0010600 0 ustar 00 // Pointer Traits -*- C++ -*- // Copyright (C) 2011-2018 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/ptr_traits.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _PTR_TRAITS_H #define _PTR_TRAITS_H 1 #if __cplusplus >= 201103L #include <bits/move.h> #if __cplusplus > 201703L namespace __gnu_debug { struct _Safe_iterator_base; } #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION class __undefined; // Given Template<T, ...> return T, otherwise invalid. template<typename _Tp> struct __get_first_arg { using type = __undefined; }; template<template<typename, typename...> class _Template, typename _Tp, typename... _Types> struct __get_first_arg<_Template<_Tp, _Types...>> { using type = _Tp; }; template<typename _Tp> using __get_first_arg_t = typename __get_first_arg<_Tp>::type; // Given Template<T, ...> and U return Template<U, ...>, otherwise invalid. template<typename _Tp, typename _Up> struct __replace_first_arg { }; template<template<typename, typename...> class _Template, typename _Up, typename _Tp, typename... _Types> struct __replace_first_arg<_Template<_Tp, _Types...>, _Up> { using type = _Template<_Up, _Types...>; }; template<typename _Tp, typename _Up> using __replace_first_arg_t = typename __replace_first_arg<_Tp, _Up>::type; template<typename _Tp> using __make_not_void = typename conditional<is_void<_Tp>::value, __undefined, _Tp>::type; /** * @brief Uniform interface to all pointer-like types * @ingroup pointer_abstractions */ template<typename _Ptr> struct pointer_traits { private: template<typename _Tp> using __element_type = typename _Tp::element_type; template<typename _Tp> using __difference_type = typename _Tp::difference_type; template<typename _Tp, typename _Up, typename = void> struct __rebind : __replace_first_arg<_Tp, _Up> { }; template<typename _Tp, typename _Up> struct __rebind<_Tp, _Up, __void_t<typename _Tp::template rebind<_Up>>> { using type = typename _Tp::template rebind<_Up>; }; public: /// The pointer type. using pointer = _Ptr; /// The type pointed to. using element_type = __detected_or_t<__get_first_arg_t<_Ptr>, __element_type, _Ptr>; /// The type used to represent the difference between two pointers. using difference_type = __detected_or_t<ptrdiff_t, __difference_type, _Ptr>; /// A pointer to a different type. template<typename _Up> using rebind = typename __rebind<_Ptr, _Up>::type; static _Ptr pointer_to(__make_not_void<element_type>& __e) { return _Ptr::pointer_to(__e); } static_assert(!is_same<element_type, __undefined>::value, "pointer type defines element_type or is like SomePointer<T, Args>"); }; /** * @brief Partial specialization for built-in pointers. * @ingroup pointer_abstractions */ template<typename _Tp> struct pointer_traits<_Tp*> { /// The pointer type typedef _Tp* pointer; /// The type pointed to typedef _Tp element_type; /// Type used to represent the difference between two pointers typedef ptrdiff_t difference_type; template<typename _Up> using rebind = _Up*; /** * @brief Obtain a pointer to an object * @param __r A reference to an object of type @c element_type * @return @c addressof(__r) */ static pointer pointer_to(__make_not_void<element_type>& __r) noexcept { return std::addressof(__r); } }; /// Convenience alias for rebinding pointers. template<typename _Ptr, typename _Tp> using __ptr_rebind = typename pointer_traits<_Ptr>::template rebind<_Tp>; template<typename _Tp> constexpr _Tp* __to_address(_Tp* __ptr) noexcept { static_assert(!std::is_function<_Tp>::value, "not a function pointer"); return __ptr; } #if __cplusplus <= 201703L template<typename _Ptr> constexpr typename std::pointer_traits<_Ptr>::element_type* __to_address(const _Ptr& __ptr) { return std::__to_address(__ptr.operator->()); } #else template<typename _Ptr> constexpr auto __to_address(const _Ptr& __ptr) noexcept -> decltype(std::pointer_traits<_Ptr>::to_address(__ptr)) { return std::pointer_traits<_Ptr>::to_address(__ptr); } template<typename _Ptr, typename... _None> constexpr auto __to_address(const _Ptr& __ptr, _None...) noexcept { if constexpr (is_base_of_v<__gnu_debug::_Safe_iterator_base, _Ptr>) return std::__to_address(__ptr.base().operator->()); else return std::__to_address(__ptr.operator->()); } /** * @brief Obtain address referenced by a pointer to an object * @param __ptr A pointer to an object * @return @c __ptr * @ingroup pointer_abstractions */ template<typename _Tp> constexpr _Tp* to_address(_Tp* __ptr) noexcept { return std::__to_address(__ptr); } /** * @brief Obtain address referenced by a pointer to an object * @param __ptr A pointer to an object * @return @c pointer_traits<_Ptr>::to_address(__ptr) if that expression is well-formed, otherwise @c to_address(__ptr.operator->()) * @ingroup pointer_abstractions */ template<typename _Ptr> constexpr auto to_address(const _Ptr& __ptr) noexcept { return std::__to_address(__ptr); } #endif // C++2a _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif #endif c++/8/bits/stl_iterator_base_funcs.h 0000644 00000017762 15146341150 0013315 0 ustar 00 // Functions used by iterators -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_iterator_base_funcs.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iterator} * * This file contains all of the general iterator-related utility * functions, such as distance() and advance(). */ #ifndef _STL_ITERATOR_BASE_FUNCS_H #define _STL_ITERATOR_BASE_FUNCS_H 1 #pragma GCC system_header #include <bits/concept_check.h> #include <debug/assertions.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // Forward declaration for the overloads of __distance. template <typename> struct _List_iterator; template <typename> struct _List_const_iterator; _GLIBCXX_END_NAMESPACE_CONTAINER template<typename _InputIterator> inline _GLIBCXX14_CONSTEXPR typename iterator_traits<_InputIterator>::difference_type __distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) typename iterator_traits<_InputIterator>::difference_type __n = 0; while (__first != __last) { ++__first; ++__n; } return __n; } template<typename _RandomAccessIterator> inline _GLIBCXX14_CONSTEXPR typename iterator_traits<_RandomAccessIterator>::difference_type __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) return __last - __first; } #if _GLIBCXX_USE_CXX11_ABI // Forward declaration because of the qualified call in distance. template<typename _Tp> ptrdiff_t __distance(_GLIBCXX_STD_C::_List_iterator<_Tp>, _GLIBCXX_STD_C::_List_iterator<_Tp>, input_iterator_tag); template<typename _Tp> ptrdiff_t __distance(_GLIBCXX_STD_C::_List_const_iterator<_Tp>, _GLIBCXX_STD_C::_List_const_iterator<_Tp>, input_iterator_tag); #endif /** * @brief A generalization of pointer arithmetic. * @param __first An input iterator. * @param __last An input iterator. * @return The distance between them. * * Returns @c n such that __first + n == __last. This requires * that @p __last must be reachable from @p __first. Note that @c * n may be negative. * * For random access iterators, this uses their @c + and @c - operations * and are constant time. For other %iterator classes they are linear time. */ template<typename _InputIterator> inline _GLIBCXX17_CONSTEXPR typename iterator_traits<_InputIterator>::difference_type distance(_InputIterator __first, _InputIterator __last) { // concept requirements -- taken care of in __distance return std::__distance(__first, __last, std::__iterator_category(__first)); } template<typename _InputIterator, typename _Distance> inline _GLIBCXX14_CONSTEXPR void __advance(_InputIterator& __i, _Distance __n, input_iterator_tag) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_assert(__n >= 0); while (__n--) ++__i; } template<typename _BidirectionalIterator, typename _Distance> inline _GLIBCXX14_CONSTEXPR void __advance(_BidirectionalIterator& __i, _Distance __n, bidirectional_iterator_tag) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept< _BidirectionalIterator>) if (__n > 0) while (__n--) ++__i; else while (__n++) --__i; } template<typename _RandomAccessIterator, typename _Distance> inline _GLIBCXX14_CONSTEXPR void __advance(_RandomAccessIterator& __i, _Distance __n, random_access_iterator_tag) { // concept requirements __glibcxx_function_requires(_RandomAccessIteratorConcept< _RandomAccessIterator>) if (__builtin_constant_p(__n) && __n == 1) ++__i; else if (__builtin_constant_p(__n) && __n == -1) --__i; else __i += __n; } /** * @brief A generalization of pointer arithmetic. * @param __i An input iterator. * @param __n The @a delta by which to change @p __i. * @return Nothing. * * This increments @p i by @p n. For bidirectional and random access * iterators, @p __n may be negative, in which case @p __i is decremented. * * For random access iterators, this uses their @c + and @c - operations * and are constant time. For other %iterator classes they are linear time. */ template<typename _InputIterator, typename _Distance> inline _GLIBCXX17_CONSTEXPR void advance(_InputIterator& __i, _Distance __n) { // concept requirements -- taken care of in __advance typename iterator_traits<_InputIterator>::difference_type __d = __n; std::__advance(__i, __d, std::__iterator_category(__i)); } #if __cplusplus >= 201103L template<typename _InputIterator> inline _GLIBCXX17_CONSTEXPR _InputIterator next(_InputIterator __x, typename iterator_traits<_InputIterator>::difference_type __n = 1) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) std::advance(__x, __n); return __x; } template<typename _BidirectionalIterator> inline _GLIBCXX17_CONSTEXPR _BidirectionalIterator prev(_BidirectionalIterator __x, typename iterator_traits<_BidirectionalIterator>::difference_type __n = 1) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept< _BidirectionalIterator>) std::advance(__x, -__n); return __x; } #endif // C++11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _STL_ITERATOR_BASE_FUNCS_H */ c++/8/bits/stl_construct.h 0000644 00000016345 15146341150 0011314 0 ustar 00 // nonstandard construct and destroy functions -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_construct.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _STL_CONSTRUCT_H #define _STL_CONSTRUCT_H 1 #include <new> #include <bits/move.h> #include <ext/alloc_traits.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * Constructs an object in existing memory by invoking an allocated * object's constructor with an initializer. */ #if __cplusplus >= 201103L template<typename _T1, typename... _Args> inline void _Construct(_T1* __p, _Args&&... __args) { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); } #else template<typename _T1, typename _T2> inline void _Construct(_T1* __p, const _T2& __value) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_]allocator::construct ::new(static_cast<void*>(__p)) _T1(__value); } #endif template<typename _T1> inline void _Construct_novalue(_T1* __p) { ::new(static_cast<void*>(__p)) _T1; } /** * Destroy the object pointed to by a pointer type. */ template<typename _Tp> inline void _Destroy(_Tp* __pointer) { __pointer->~_Tp(); } template<bool> struct _Destroy_aux { template<typename _ForwardIterator> static void __destroy(_ForwardIterator __first, _ForwardIterator __last) { for (; __first != __last; ++__first) std::_Destroy(std::__addressof(*__first)); } }; template<> struct _Destroy_aux<true> { template<typename _ForwardIterator> static void __destroy(_ForwardIterator, _ForwardIterator) { } }; /** * Destroy a range of objects. If the value_type of the object has * a trivial destructor, the compiler should optimize all of this * away, otherwise the objects' destructors must be invoked. */ template<typename _ForwardIterator> inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last) { typedef typename iterator_traits<_ForwardIterator>::value_type _Value_type; #if __cplusplus >= 201103L // A deleted destructor is trivial, this ensures we reject such types: static_assert(is_destructible<_Value_type>::value, "value type is destructible"); #endif std::_Destroy_aux<__has_trivial_destructor(_Value_type)>:: __destroy(__first, __last); } template<bool> struct _Destroy_n_aux { template<typename _ForwardIterator, typename _Size> static _ForwardIterator __destroy_n(_ForwardIterator __first, _Size __count) { for (; __count > 0; (void)++__first, --__count) std::_Destroy(std::__addressof(*__first)); return __first; } }; template<> struct _Destroy_n_aux<true> { template<typename _ForwardIterator, typename _Size> static _ForwardIterator __destroy_n(_ForwardIterator __first, _Size __count) { std::advance(__first, __count); return __first; } }; /** * Destroy a range of objects. If the value_type of the object has * a trivial destructor, the compiler should optimize all of this * away, otherwise the objects' destructors must be invoked. */ template<typename _ForwardIterator, typename _Size> inline _ForwardIterator _Destroy_n(_ForwardIterator __first, _Size __count) { typedef typename iterator_traits<_ForwardIterator>::value_type _Value_type; #if __cplusplus >= 201103L // A deleted destructor is trivial, this ensures we reject such types: static_assert(is_destructible<_Value_type>::value, "value type is destructible"); #endif return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>:: __destroy_n(__first, __count); } /** * Destroy a range of objects using the supplied allocator. For * nondefault allocators we do not optimize away invocation of * destroy() even if _Tp has a trivial destructor. */ template<typename _ForwardIterator, typename _Allocator> void _Destroy(_ForwardIterator __first, _ForwardIterator __last, _Allocator& __alloc) { typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; for (; __first != __last; ++__first) __traits::destroy(__alloc, std::__addressof(*__first)); } template<typename _ForwardIterator, typename _Tp> inline void _Destroy(_ForwardIterator __first, _ForwardIterator __last, allocator<_Tp>&) { _Destroy(__first, __last); } #if __cplusplus > 201402L template <typename _Tp> inline void destroy_at(_Tp* __location) { std::_Destroy(__location); } template <typename _ForwardIterator> inline void destroy(_ForwardIterator __first, _ForwardIterator __last) { std::_Destroy(__first, __last); } template <typename _ForwardIterator, typename _Size> inline _ForwardIterator destroy_n(_ForwardIterator __first, _Size __count) { return std::_Destroy_n(__first, __count); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _STL_CONSTRUCT_H */ c++/8/bits/cxxabi_forced.h 0000644 00000003423 15146341150 0011177 0 ustar 00 // cxxabi.h subset for cancellation -*- C++ -*- // Copyright (C) 2007-2018 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 c++/8/bits/enable_special_members.h 0000644 00000030143 15146341150 0013036 0 ustar 00 // <bits/enable_special_members.h> -*- C++ -*- // Copyright (C) 2013-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/enable_special_members.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. */ #ifndef _ENABLE_SPECIAL_MEMBERS_H #define _ENABLE_SPECIAL_MEMBERS_H 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _Enable_default_constructor_tag { explicit constexpr _Enable_default_constructor_tag() = default; }; /** * @brief A mixin helper to conditionally enable or disable the default * constructor. * @sa _Enable_special_members */ template<bool _Switch, typename _Tag = void> struct _Enable_default_constructor { constexpr _Enable_default_constructor() noexcept = default; constexpr _Enable_default_constructor(_Enable_default_constructor const&) noexcept = default; constexpr _Enable_default_constructor(_Enable_default_constructor&&) noexcept = default; _Enable_default_constructor& operator=(_Enable_default_constructor const&) noexcept = default; _Enable_default_constructor& operator=(_Enable_default_constructor&&) noexcept = default; // Can be used in other ctors. constexpr explicit _Enable_default_constructor(_Enable_default_constructor_tag) { } }; /** * @brief A mixin helper to conditionally enable or disable the default * destructor. * @sa _Enable_special_members */ template<bool _Switch, typename _Tag = void> struct _Enable_destructor { }; /** * @brief A mixin helper to conditionally enable or disable the copy/move * special members. * @sa _Enable_special_members */ template<bool _Copy, bool _CopyAssignment, bool _Move, bool _MoveAssignment, typename _Tag = void> struct _Enable_copy_move { }; /** * @brief A mixin helper to conditionally enable or disable the special * members. * * The @c _Tag type parameter is to make mixin bases unique and thus avoid * ambiguities. */ template<bool _Default, bool _Destructor, bool _Copy, bool _CopyAssignment, bool _Move, bool _MoveAssignment, typename _Tag = void> struct _Enable_special_members : private _Enable_default_constructor<_Default, _Tag>, private _Enable_destructor<_Destructor, _Tag>, private _Enable_copy_move<_Copy, _CopyAssignment, _Move, _MoveAssignment, _Tag> { }; // Boilerplate follows. template<typename _Tag> struct _Enable_default_constructor<false, _Tag> { constexpr _Enable_default_constructor() noexcept = delete; constexpr _Enable_default_constructor(_Enable_default_constructor const&) noexcept = default; constexpr _Enable_default_constructor(_Enable_default_constructor&&) noexcept = default; _Enable_default_constructor& operator=(_Enable_default_constructor const&) noexcept = default; _Enable_default_constructor& operator=(_Enable_default_constructor&&) noexcept = default; // Can be used in other ctors. constexpr explicit _Enable_default_constructor(_Enable_default_constructor_tag) { } }; template<typename _Tag> struct _Enable_destructor<false, _Tag> { ~_Enable_destructor() noexcept = delete; }; template<typename _Tag> struct _Enable_copy_move<false, true, true, true, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = default; }; template<typename _Tag> struct _Enable_copy_move<true, false, true, true, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = default; }; template<typename _Tag> struct _Enable_copy_move<false, false, true, true, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = default; }; template<typename _Tag> struct _Enable_copy_move<true, true, false, true, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = default; }; template<typename _Tag> struct _Enable_copy_move<false, true, false, true, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = default; }; template<typename _Tag> struct _Enable_copy_move<true, false, false, true, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = default; }; template<typename _Tag> struct _Enable_copy_move<false, false, false, true, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = default; }; template<typename _Tag> struct _Enable_copy_move<true, true, true, false, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = delete; }; template<typename _Tag> struct _Enable_copy_move<false, true, true, false, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = delete; }; template<typename _Tag> struct _Enable_copy_move<true, false, true, false, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = delete; }; template<typename _Tag> struct _Enable_copy_move<false, false, true, false, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = delete; }; template<typename _Tag> struct _Enable_copy_move<true, true, false, false, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = delete; }; template<typename _Tag> struct _Enable_copy_move<false, true, false, false, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = default; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = delete; }; template<typename _Tag> struct _Enable_copy_move<true, false, false, false, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = delete; }; template<typename _Tag> struct _Enable_copy_move<false, false, false, false, _Tag> { constexpr _Enable_copy_move() noexcept = default; constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete; constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move const&) noexcept = delete; _Enable_copy_move& operator=(_Enable_copy_move&&) noexcept = delete; }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _ENABLE_SPECIAL_MEMBERS_H c++/8/bits/regex_error.h 0000644 00000011450 15146341150 0010721 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2010-2018 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/regex_error.h * @brief Error and exception objects for the std regex library. * * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup regex * @{ */ namespace regex_constants { /** * @name 5.3 Error Types */ //@{ enum error_type { _S_error_collate, _S_error_ctype, _S_error_escape, _S_error_backref, _S_error_brack, _S_error_paren, _S_error_brace, _S_error_badbrace, _S_error_range, _S_error_space, _S_error_badrepeat, _S_error_complexity, _S_error_stack, }; /** The expression contained an invalid collating element name. */ constexpr error_type error_collate(_S_error_collate); /** The expression contained an invalid character class name. */ constexpr error_type error_ctype(_S_error_ctype); /** * The expression contained an invalid escaped character, or a trailing * escape. */ constexpr error_type error_escape(_S_error_escape); /** The expression contained an invalid back reference. */ constexpr error_type error_backref(_S_error_backref); /** The expression contained mismatched [ and ]. */ constexpr error_type error_brack(_S_error_brack); /** The expression contained mismatched ( and ). */ constexpr error_type error_paren(_S_error_paren); /** The expression contained mismatched { and } */ constexpr error_type error_brace(_S_error_brace); /** The expression contained an invalid range in a {} expression. */ constexpr error_type error_badbrace(_S_error_badbrace); /** * The expression contained an invalid character range, * such as [b-a] in most encodings. */ constexpr error_type error_range(_S_error_range); /** * There was insufficient memory to convert the expression into a * finite state machine. */ constexpr error_type error_space(_S_error_space); /** * One of <em>*?+{</em> was not preceded by a valid regular expression. */ constexpr error_type error_badrepeat(_S_error_badrepeat); /** * The complexity of an attempted match against a regular expression * exceeded a pre-set level. */ constexpr error_type error_complexity(_S_error_complexity); /** * There was insufficient memory to determine whether the * regular expression could match the specified character sequence. */ constexpr error_type error_stack(_S_error_stack); //@} } // namespace regex_constants // [7.8] Class regex_error /** * @brief A regular expression exception class. * @ingroup exceptions * * The regular expression library throws objects of this class on error. */ class regex_error : public std::runtime_error { regex_constants::error_type _M_code; public: /** * @brief Constructs a regex_error object. * * @param __ecode the regex error code. */ explicit regex_error(regex_constants::error_type __ecode); virtual ~regex_error() throw(); /** * @brief Gets the regex error code. * * @returns the regex error code. */ regex_constants::error_type code() const { return _M_code; } private: regex_error(regex_constants::error_type __ecode, const char* __what) : std::runtime_error(__what), _M_code(__ecode) { } friend void __throw_regex_error(regex_constants::error_type, const char*); }; //@} // group regex void __throw_regex_error(regex_constants::error_type __ecode); inline void __throw_regex_error(regex_constants::error_type __ecode, const char* __what) { _GLIBCXX_THROW_OR_ABORT(regex_error(__ecode, __what)); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std c++/8/bits/char_traits.h 0000644 00000050663 15146341150 0010712 0 ustar 00 // Character Traits for use by standard string and iostream -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/char_traits.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{string} */ // // ISO C++ 14882: 21 Strings library // #ifndef _CHAR_TRAITS_H #define _CHAR_TRAITS_H 1 #pragma GCC system_header #include <bits/stl_algobase.h> // std::copy, std::fill_n #include <bits/postypes.h> // For streampos #include <cwchar> // For WEOF, wmemmove, wmemset, etc. #ifndef _GLIBCXX_ALWAYS_INLINE #define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__)) #endif namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Mapping from character type to associated types. * * @note This is an implementation class for the generic version * of char_traits. It defines int_type, off_type, pos_type, and * state_type. By default these are unsigned long, streamoff, * streampos, and mbstate_t. Users who need a different set of * types, but who don't need to change the definitions of any function * defined in char_traits, can specialize __gnu_cxx::_Char_types * while leaving __gnu_cxx::char_traits alone. */ template<typename _CharT> struct _Char_types { typedef unsigned long int_type; typedef std::streampos pos_type; typedef std::streamoff off_type; typedef std::mbstate_t state_type; }; /** * @brief Base class used to implement std::char_traits. * * @note For any given actual character type, this definition is * probably wrong. (Most of the member functions are likely to be * right, but the int_type and state_type typedefs, and the eof() * member function, are likely to be wrong.) The reason this class * exists is so users can specialize it. Classes in namespace std * may not be specialized for fundamental types, but classes in * namespace __gnu_cxx may be. * * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types * for advice on how to make use of this class for @a unusual character * types. Also, check out include/ext/pod_char_traits.h. */ template<typename _CharT> struct char_traits { typedef _CharT char_type; typedef typename _Char_types<_CharT>::int_type int_type; typedef typename _Char_types<_CharT>::pos_type pos_type; typedef typename _Char_types<_CharT>::off_type off_type; typedef typename _Char_types<_CharT>::state_type state_type; static _GLIBCXX14_CONSTEXPR void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } static _GLIBCXX_CONSTEXPR bool eq(const char_type& __c1, const char_type& __c2) { return __c1 == __c2; } static _GLIBCXX_CONSTEXPR bool lt(const char_type& __c1, const char_type& __c2) { return __c1 < __c2; } static _GLIBCXX14_CONSTEXPR int compare(const char_type* __s1, const char_type* __s2, std::size_t __n); static _GLIBCXX14_CONSTEXPR std::size_t length(const char_type* __s); static _GLIBCXX14_CONSTEXPR const char_type* find(const char_type* __s, std::size_t __n, const char_type& __a); static char_type* move(char_type* __s1, const char_type* __s2, std::size_t __n); static char_type* copy(char_type* __s1, const char_type* __s2, std::size_t __n); static char_type* assign(char_type* __s, std::size_t __n, char_type __a); static _GLIBCXX_CONSTEXPR char_type to_char_type(const int_type& __c) { return static_cast<char_type>(__c); } static _GLIBCXX_CONSTEXPR int_type to_int_type(const char_type& __c) { return static_cast<int_type>(__c); } static _GLIBCXX_CONSTEXPR bool eq_int_type(const int_type& __c1, const int_type& __c2) { return __c1 == __c2; } static _GLIBCXX_CONSTEXPR int_type eof() { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } static _GLIBCXX_CONSTEXPR int_type not_eof(const int_type& __c) { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); } }; template<typename _CharT> _GLIBCXX14_CONSTEXPR int char_traits<_CharT>:: compare(const char_type* __s1, const char_type* __s2, std::size_t __n) { for (std::size_t __i = 0; __i < __n; ++__i) if (lt(__s1[__i], __s2[__i])) return -1; else if (lt(__s2[__i], __s1[__i])) return 1; return 0; } template<typename _CharT> _GLIBCXX14_CONSTEXPR std::size_t char_traits<_CharT>:: length(const char_type* __p) { std::size_t __i = 0; while (!eq(__p[__i], char_type())) ++__i; return __i; } template<typename _CharT> _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type* char_traits<_CharT>:: find(const char_type* __s, std::size_t __n, const char_type& __a) { for (std::size_t __i = 0; __i < __n; ++__i) if (eq(__s[__i], __a)) return __s + __i; return 0; } template<typename _CharT> typename char_traits<_CharT>::char_type* char_traits<_CharT>:: move(char_type* __s1, const char_type* __s2, std::size_t __n) { if (__n == 0) return __s1; return static_cast<_CharT*>(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))); } template<typename _CharT> typename char_traits<_CharT>::char_type* char_traits<_CharT>:: copy(char_type* __s1, const char_type* __s2, std::size_t __n) { // NB: Inline std::copy so no recursive dependencies. std::copy(__s2, __s2 + __n, __s1); return __s1; } template<typename _CharT> typename char_traits<_CharT>::char_type* char_traits<_CharT>:: assign(char_type* __s, std::size_t __n, char_type __a) { // NB: Inline std::fill_n so no recursive dependencies. std::fill_n(__s, __n, __a); return __s; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus > 201402 #define __cpp_lib_constexpr_char_traits 201611 /** * @brief Determine whether the characters of a NULL-terminated * string are known at compile time. * @param __s The string. * * Assumes that _CharT is a built-in character type. */ template<typename _CharT> static _GLIBCXX_ALWAYS_INLINE constexpr bool __constant_string_p(const _CharT* __s) { while (__builtin_constant_p(*__s) && *__s) __s++; return __builtin_constant_p(*__s); } /** * @brief Determine whether the characters of a character array are * known at compile time. * @param __a The character array. * @param __n Number of characters. * * Assumes that _CharT is a built-in character type. */ template<typename _CharT> static _GLIBCXX_ALWAYS_INLINE constexpr bool __constant_char_array_p(const _CharT* __a, size_t __n) { size_t __i = 0; while (__i < __n && __builtin_constant_p(__a[__i])) __i++; return __i == __n; } #endif // 21.1 /** * @brief Basis for explicit traits specializations. * * @note For any given actual character type, this definition is * probably wrong. Since this is just a thin wrapper around * __gnu_cxx::char_traits, it is possible to achieve a more * appropriate definition by specializing __gnu_cxx::char_traits. * * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types * for advice on how to make use of this class for @a unusual character * types. Also, check out include/ext/pod_char_traits.h. */ template<class _CharT> struct char_traits : public __gnu_cxx::char_traits<_CharT> { }; /// 21.1.3.1 char_traits specializations template<> struct char_traits<char> { typedef char char_type; typedef int int_type; typedef streampos pos_type; typedef streamoff off_type; typedef mbstate_t state_type; static _GLIBCXX17_CONSTEXPR void assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT { __c1 = __c2; } static _GLIBCXX_CONSTEXPR bool eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT { return __c1 == __c2; } static _GLIBCXX_CONSTEXPR bool lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT { // LWG 467. return (static_cast<unsigned char>(__c1) < static_cast<unsigned char>(__c2)); } static _GLIBCXX17_CONSTEXPR int compare(const char_type* __s1, const char_type* __s2, size_t __n) { #if __cplusplus > 201402 if (__builtin_constant_p(__n) && __constant_char_array_p(__s1, __n) && __constant_char_array_p(__s2, __n)) { for (size_t __i = 0; __i < __n; ++__i) if (lt(__s1[__i], __s2[__i])) return -1; else if (lt(__s2[__i], __s1[__i])) return 1; return 0; } #endif if (__n == 0) return 0; return __builtin_memcmp(__s1, __s2, __n); } static _GLIBCXX17_CONSTEXPR size_t length(const char_type* __s) { #if __cplusplus > 201402 if (__constant_string_p(__s)) return __gnu_cxx::char_traits<char_type>::length(__s); #endif return __builtin_strlen(__s); } static _GLIBCXX17_CONSTEXPR const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { #if __cplusplus > 201402 if (__builtin_constant_p(__n) && __builtin_constant_p(__a) && __constant_char_array_p(__s, __n)) return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); #endif if (__n == 0) return 0; return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n)); } static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n)); } static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n)); } static char_type* assign(char_type* __s, size_t __n, char_type __a) { if (__n == 0) return __s; return static_cast<char_type*>(__builtin_memset(__s, __a, __n)); } static _GLIBCXX_CONSTEXPR char_type to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT { return static_cast<char_type>(__c); } // To keep both the byte 0xff and the eof symbol 0xffffffff // from ending up as 0xffffffff. static _GLIBCXX_CONSTEXPR int_type to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT { return static_cast<int_type>(static_cast<unsigned char>(__c)); } static _GLIBCXX_CONSTEXPR bool eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT { return __c1 == __c2; } static _GLIBCXX_CONSTEXPR int_type eof() _GLIBCXX_NOEXCEPT { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); } static _GLIBCXX_CONSTEXPR int_type not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT { return (__c == eof()) ? 0 : __c; } }; #ifdef _GLIBCXX_USE_WCHAR_T /// 21.1.3.2 char_traits specializations template<> struct char_traits<wchar_t> { typedef wchar_t char_type; typedef wint_t int_type; typedef streamoff off_type; typedef wstreampos pos_type; typedef mbstate_t state_type; static _GLIBCXX17_CONSTEXPR void assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT { __c1 = __c2; } static _GLIBCXX_CONSTEXPR bool eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT { return __c1 == __c2; } static _GLIBCXX_CONSTEXPR bool lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT { return __c1 < __c2; } static _GLIBCXX17_CONSTEXPR int compare(const char_type* __s1, const char_type* __s2, size_t __n) { #if __cplusplus > 201402 if (__builtin_constant_p(__n) && __constant_char_array_p(__s1, __n) && __constant_char_array_p(__s2, __n)) return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); #endif if (__n == 0) return 0; else return wmemcmp(__s1, __s2, __n); } static _GLIBCXX17_CONSTEXPR size_t length(const char_type* __s) { #if __cplusplus > 201402 if (__constant_string_p(__s)) return __gnu_cxx::char_traits<char_type>::length(__s); else #endif return wcslen(__s); } static _GLIBCXX17_CONSTEXPR const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { #if __cplusplus > 201402 if (__builtin_constant_p(__n) && __builtin_constant_p(__a) && __constant_char_array_p(__s, __n)) return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); #endif if (__n == 0) return 0; else return wmemchr(__s, __a, __n); } static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; return wmemmove(__s1, __s2, __n); } static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; return wmemcpy(__s1, __s2, __n); } static char_type* assign(char_type* __s, size_t __n, char_type __a) { if (__n == 0) return __s; return wmemset(__s, __a, __n); } static _GLIBCXX_CONSTEXPR char_type to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT { return char_type(__c); } static _GLIBCXX_CONSTEXPR int_type to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT { return int_type(__c); } static _GLIBCXX_CONSTEXPR bool eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT { return __c1 == __c2; } static _GLIBCXX_CONSTEXPR int_type eof() _GLIBCXX_NOEXCEPT { return static_cast<int_type>(WEOF); } static _GLIBCXX_CONSTEXPR int_type not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT { return eq_int_type(__c, eof()) ? 0 : __c; } }; #endif //_GLIBCXX_USE_WCHAR_T _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if ((__cplusplus >= 201103L) \ && defined(_GLIBCXX_USE_C99_STDINT_TR1)) #include <cstdint> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<> struct char_traits<char16_t> { typedef char16_t char_type; typedef uint_least16_t int_type; typedef streamoff off_type; typedef u16streampos pos_type; typedef mbstate_t state_type; static _GLIBCXX17_CONSTEXPR void assign(char_type& __c1, const char_type& __c2) noexcept { __c1 = __c2; } static constexpr bool eq(const char_type& __c1, const char_type& __c2) noexcept { return __c1 == __c2; } static constexpr bool lt(const char_type& __c1, const char_type& __c2) noexcept { return __c1 < __c2; } static _GLIBCXX17_CONSTEXPR int compare(const char_type* __s1, const char_type* __s2, size_t __n) { for (size_t __i = 0; __i < __n; ++__i) if (lt(__s1[__i], __s2[__i])) return -1; else if (lt(__s2[__i], __s1[__i])) return 1; return 0; } static _GLIBCXX17_CONSTEXPR size_t length(const char_type* __s) { size_t __i = 0; while (!eq(__s[__i], char_type())) ++__i; return __i; } static _GLIBCXX17_CONSTEXPR const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { for (size_t __i = 0; __i < __n; ++__i) if (eq(__s[__i], __a)) return __s + __i; return 0; } static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; return (static_cast<char_type*> (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); } static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; return (static_cast<char_type*> (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); } static char_type* assign(char_type* __s, size_t __n, char_type __a) { for (size_t __i = 0; __i < __n; ++__i) assign(__s[__i], __a); return __s; } static constexpr char_type to_char_type(const int_type& __c) noexcept { return char_type(__c); } static constexpr int_type to_int_type(const char_type& __c) noexcept { return __c == eof() ? int_type(0xfffd) : int_type(__c); } static constexpr bool eq_int_type(const int_type& __c1, const int_type& __c2) noexcept { return __c1 == __c2; } static constexpr int_type eof() noexcept { return static_cast<int_type>(-1); } static constexpr int_type not_eof(const int_type& __c) noexcept { return eq_int_type(__c, eof()) ? 0 : __c; } }; template<> struct char_traits<char32_t> { typedef char32_t char_type; typedef uint_least32_t int_type; typedef streamoff off_type; typedef u32streampos pos_type; typedef mbstate_t state_type; static _GLIBCXX17_CONSTEXPR void assign(char_type& __c1, const char_type& __c2) noexcept { __c1 = __c2; } static constexpr bool eq(const char_type& __c1, const char_type& __c2) noexcept { return __c1 == __c2; } static constexpr bool lt(const char_type& __c1, const char_type& __c2) noexcept { return __c1 < __c2; } static _GLIBCXX17_CONSTEXPR int compare(const char_type* __s1, const char_type* __s2, size_t __n) { for (size_t __i = 0; __i < __n; ++__i) if (lt(__s1[__i], __s2[__i])) return -1; else if (lt(__s2[__i], __s1[__i])) return 1; return 0; } static _GLIBCXX17_CONSTEXPR size_t length(const char_type* __s) { size_t __i = 0; while (!eq(__s[__i], char_type())) ++__i; return __i; } static _GLIBCXX17_CONSTEXPR const char_type* find(const char_type* __s, size_t __n, const char_type& __a) { for (size_t __i = 0; __i < __n; ++__i) if (eq(__s[__i], __a)) return __s + __i; return 0; } static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; return (static_cast<char_type*> (__builtin_memmove(__s1, __s2, __n * sizeof(char_type)))); } static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { if (__n == 0) return __s1; return (static_cast<char_type*> (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type)))); } static char_type* assign(char_type* __s, size_t __n, char_type __a) { for (size_t __i = 0; __i < __n; ++__i) assign(__s[__i], __a); return __s; } static constexpr char_type to_char_type(const int_type& __c) noexcept { return char_type(__c); } static constexpr int_type to_int_type(const char_type& __c) noexcept { return int_type(__c); } static constexpr bool eq_int_type(const int_type& __c1, const int_type& __c2) noexcept { return __c1 == __c2; } static constexpr int_type eof() noexcept { return static_cast<int_type>(-1); } static constexpr int_type not_eof(const int_type& __c) noexcept { return eq_int_type(__c, eof()) ? 0 : __c; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif #endif // _CHAR_TRAITS_H c++/8/bits/ostream_insert.h 0000644 00000007642 15146341150 0011444 0 ustar 00 // Helpers for ostream inserters -*- C++ -*- // Copyright (C) 2007-2018 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/ostream_insert.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ostream} */ #ifndef _OSTREAM_INSERT_H #define _OSTREAM_INSERT_H 1 #pragma GCC system_header #include <iosfwd> #include <bits/cxxabi_forced.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits> inline void __ostream_write(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s, streamsize __n) { typedef basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const streamsize __put = __out.rdbuf()->sputn(__s, __n); if (__put != __n) __out.setstate(__ios_base::badbit); } template<typename _CharT, typename _Traits> inline void __ostream_fill(basic_ostream<_CharT, _Traits>& __out, streamsize __n) { typedef basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; const _CharT __c = __out.fill(); for (; __n > 0; --__n) { const typename _Traits::int_type __put = __out.rdbuf()->sputc(__c); if (_Traits::eq_int_type(__put, _Traits::eof())) { __out.setstate(__ios_base::badbit); break; } } } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& __ostream_insert(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s, streamsize __n) { typedef basic_ostream<_CharT, _Traits> __ostream_type; typedef typename __ostream_type::ios_base __ios_base; typename __ostream_type::sentry __cerb(__out); if (__cerb) { __try { const streamsize __w = __out.width(); if (__w > __n) { const bool __left = ((__out.flags() & __ios_base::adjustfield) == __ios_base::left); if (!__left) __ostream_fill(__out, __w - __n); if (__out.good()) __ostream_write(__out, __s, __n); if (__left && __out.good()) __ostream_fill(__out, __w - __n); } else __ostream_write(__out, __s, __n); __out.width(0); } __catch(__cxxabiv1::__forced_unwind&) { __out._M_setstate(__ios_base::badbit); __throw_exception_again; } __catch(...) { __out._M_setstate(__ios_base::badbit); } } return __out; } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template ostream& __ostream_insert(ostream&, const char*, streamsize); #ifdef _GLIBCXX_USE_WCHAR_T extern template wostream& __ostream_insert(wostream&, const wchar_t*, streamsize); #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _OSTREAM_INSERT_H */ c++/8/bits/alloc_traits.h 0000644 00000047142 15146341150 0011065 0 ustar 00 // Allocator traits -*- C++ -*- // Copyright (C) 2011-2018 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 #if __cplusplus >= 201103L #include <bits/memoryfwd.h> #include <bits/ptr_traits.h> #include <ext/numeric_traits.h> #define __cpp_lib_allocator_traits_is_always_equal 201411 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __allocator_traits_base { template<typename _Tp, typename _Up, typename = void> struct __rebind : __replace_first_arg<_Tp, _Up> { }; template<typename _Tp, typename _Up> struct __rebind<_Tp, _Up, __void_t<typename _Tp::template rebind<_Up>::other>> { using type = typename _Tp::template rebind<_Up>::other; }; protected: template<typename _Tp> using __pointer = typename _Tp::pointer; template<typename _Tp> using __c_pointer = typename _Tp::const_pointer; template<typename _Tp> using __v_pointer = typename _Tp::void_pointer; template<typename _Tp> using __cv_pointer = typename _Tp::const_void_pointer; template<typename _Tp> using __pocca = typename _Tp::propagate_on_container_copy_assignment; template<typename _Tp> using __pocma = typename _Tp::propagate_on_container_move_assignment; template<typename _Tp> using __pocs = typename _Tp::propagate_on_container_swap; template<typename _Tp> using __equal = typename _Tp::is_always_equal; }; template<typename _Alloc, typename _Up> using __alloc_rebind = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type; /** * @brief Uniform interface to all allocator types. * @ingroup allocators */ template<typename _Alloc> struct allocator_traits : __allocator_traits_base { /// The allocator type typedef _Alloc allocator_type; /// The allocated type typedef typename _Alloc::value_type value_type; /** * @brief The allocator's pointer type. * * @c Alloc::pointer if that type exists, otherwise @c value_type* */ using pointer = __detected_or_t<value_type*, __pointer, _Alloc>; private: // Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp> template<template<typename> class _Func, typename _Tp, typename = void> struct _Ptr { using type = typename pointer_traits<pointer>::template rebind<_Tp>; }; template<template<typename> class _Func, typename _Tp> struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>> { using type = _Func<_Alloc>; }; // Select _A2::difference_type or pointer_traits<_Ptr>::difference_type template<typename _A2, typename _PtrT, typename = void> struct _Diff { using type = typename pointer_traits<_PtrT>::difference_type; }; template<typename _A2, typename _PtrT> struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>> { using type = typename _A2::difference_type; }; // Select _A2::size_type or make_unsigned<_DiffT>::type template<typename _A2, typename _DiffT, typename = void> struct _Size : make_unsigned<_DiffT> { }; template<typename _A2, typename _DiffT> struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>> { using type = typename _A2::size_type; }; public: /** * @brief The allocator's const pointer type. * * @c Alloc::const_pointer if that type exists, otherwise * <tt> pointer_traits<pointer>::rebind<const value_type> </tt> */ using const_pointer = typename _Ptr<__c_pointer, const value_type>::type; /** * @brief The allocator's void pointer type. * * @c Alloc::void_pointer if that type exists, otherwise * <tt> pointer_traits<pointer>::rebind<void> </tt> */ using void_pointer = typename _Ptr<__v_pointer, void>::type; /** * @brief The allocator's const void pointer type. * * @c Alloc::const_void_pointer if that type exists, otherwise * <tt> pointer_traits<pointer>::rebind<const void> </tt> */ using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type; /** * @brief The allocator's difference type * * @c Alloc::difference_type if that type exists, otherwise * <tt> pointer_traits<pointer>::difference_type </tt> */ using difference_type = typename _Diff<_Alloc, pointer>::type; /** * @brief The allocator's size type * * @c Alloc::size_type if that type exists, otherwise * <tt> make_unsigned<difference_type>::type </tt> */ using size_type = typename _Size<_Alloc, difference_type>::type; /** * @brief How the allocator is propagated on copy assignment * * @c Alloc::propagate_on_container_copy_assignment if that type exists, * otherwise @c false_type */ using propagate_on_container_copy_assignment = __detected_or_t<false_type, __pocca, _Alloc>; /** * @brief How the allocator is propagated on move assignment * * @c Alloc::propagate_on_container_move_assignment if that type exists, * otherwise @c false_type */ using propagate_on_container_move_assignment = __detected_or_t<false_type, __pocma, _Alloc>; /** * @brief How the allocator is propagated on swap * * @c Alloc::propagate_on_container_swap if that type exists, * otherwise @c false_type */ using propagate_on_container_swap = __detected_or_t<false_type, __pocs, _Alloc>; /** * @brief Whether all instances of the allocator type compare equal. * * @c Alloc::is_always_equal if that type exists, * otherwise @c is_empty<Alloc>::type */ using is_always_equal = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>; template<typename _Tp> using rebind_alloc = __alloc_rebind<_Alloc, _Tp>; template<typename _Tp> using rebind_traits = allocator_traits<rebind_alloc<_Tp>>; private: template<typename _Alloc2> static 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 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 _Require<__has_construct<_Tp, _Args...>> _S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args) { __a.construct(__p, std::forward<_Args>(__args)...); } template<typename _Tp, typename... _Args> static _Require<__and_<__not_<__has_construct<_Tp, _Args...>>, is_constructible<_Tp, _Args...>>> _S_construct(_Alloc&, _Tp* __p, _Args&&... __args) { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); } template<typename _Alloc2, typename _Tp> static auto _S_destroy(_Alloc2& __a, _Tp* __p, int) -> decltype(__a.destroy(__p)) { __a.destroy(__p); } template<typename _Alloc2, typename _Tp> static void _S_destroy(_Alloc2&, _Tp* __p, ...) { __p->~_Tp(); } template<typename _Alloc2> static auto _S_max_size(_Alloc2& __a, int) -> decltype(__a.max_size()) { return __a.max_size(); } template<typename _Alloc2> static 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 auto _S_select(_Alloc2& __a, int) -> decltype(__a.select_on_container_copy_construction()) { return __a.select_on_container_copy_construction(); } template<typename _Alloc2> static _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) */ static 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) */ static 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 void deallocate(_Alloc& __a, pointer __p, size_type __n) { __a.deallocate(__p, __n); } /** * @brief Construct an object of type @a _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 auto construct(_Alloc& __a, _Tp* __p, _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 void destroy(_Alloc& __a, _Tp* __p) { _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 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 _Alloc select_on_container_copy_construction(const _Alloc& __rhs) { return _S_select(__rhs, 0); } }; /// 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) */ static 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> */ static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint) { return __a.allocate(__n, __hint); } /** * @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 void deallocate(allocator_type& __a, pointer __p, size_type __n) { __a.deallocate(__p, __n); } /** * @brief Construct an object of type @a _Up * @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> */ template<typename _Up, typename... _Args> static void construct(allocator_type& __a, _Up* __p, _Args&&... __args) { __a.construct(__p, std::forward<_Args>(__args)...); } /** * @brief Destroy an object of type @a _Up * @param __a An allocator. * @param __p Pointer to the object to destroy * * Calls @c __a.destroy(__p). */ template<typename _Up> static void destroy(allocator_type& __a, _Up* __p) { __a.destroy(__p); } /** * @brief The maximum supported allocation size * @param __a An allocator. * @return @c __a.max_size() */ static size_type max_size(const allocator_type& __a) noexcept { return __a.max_size(); } /** * @brief Obtain an allocator to use when copying a container. * @param __rhs An allocator. * @return @c __rhs */ static allocator_type select_on_container_copy_construction(const allocator_type& __rhs) { return __rhs; } }; template<typename _Alloc> inline void __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type) { __one = __two; } template<typename _Alloc> inline void __do_alloc_on_copy(_Alloc&, const _Alloc&, false_type) { } template<typename _Alloc> inline void __alloc_on_copy(_Alloc& __one, const _Alloc& __two) { typedef allocator_traits<_Alloc> __traits; typedef typename __traits::propagate_on_container_copy_assignment __pocca; __do_alloc_on_copy(__one, __two, __pocca()); } template<typename _Alloc> inline _Alloc __alloc_on_copy(const _Alloc& __a) { typedef allocator_traits<_Alloc> __traits; return __traits::select_on_container_copy_construction(__a); } template<typename _Alloc> inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type) { __one = std::move(__two); } template<typename _Alloc> inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type) { } template<typename _Alloc> inline void __alloc_on_move(_Alloc& __one, _Alloc& __two) { typedef allocator_traits<_Alloc> __traits; typedef typename __traits::propagate_on_container_move_assignment __pocma; __do_alloc_on_move(__one, __two, __pocma()); } template<typename _Alloc> inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type) { using std::swap; swap(__one, __two); } template<typename _Alloc> inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type) { } template<typename _Alloc> inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two) { typedef allocator_traits<_Alloc> __traits; typedef typename __traits::propagate_on_container_swap __pocs; __do_alloc_on_swap(__one, __two, __pocs()); } template<typename _Alloc> class __is_copy_insertable_impl { typedef allocator_traits<_Alloc> _Traits; template<typename _Up, typename = decltype(_Traits::construct(std::declval<_Alloc&>(), std::declval<_Up*>(), std::declval<const _Up&>()))> static true_type _M_select(int); template<typename _Up> static false_type _M_select(...); public: typedef decltype(_M_select<typename _Alloc::value_type>(0)) type; }; // true if _Alloc::value_type is CopyInsertable into containers using _Alloc template<typename _Alloc> struct __is_copy_insertable : __is_copy_insertable_impl<_Alloc>::type { }; // std::allocator<_Tp> just requires CopyConstructible template<typename _Tp> struct __is_copy_insertable<allocator<_Tp>> : is_copy_constructible<_Tp> { }; // Trait to detect Allocator-like types. template<typename _Alloc, typename = void> struct __is_allocator : false_type { }; template<typename _Alloc> struct __is_allocator<_Alloc, __void_t<typename _Alloc::value_type, decltype(std::declval<_Alloc&>().allocate(size_t{}))>> : true_type { }; template<typename _Alloc> using _RequireAllocator = typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _ALLOC_TRAITS_H c++/8/bits/stl_function.h 0000644 00000121421 15146341150 0011105 0 ustar 00 // Functor implementations -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_function.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{functional} */ #ifndef _STL_FUNCTION_H #define _STL_FUNCTION_H 1 #if __cplusplus > 201103L #include <bits/move.h> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // 20.3.1 base classes /** @defgroup functors Function Objects * @ingroup utilities * * Function objects, or @e functors, are objects with an @c operator() * defined and accessible. They can be passed as arguments to algorithm * templates and used in place of a function pointer. Not only is the * resulting expressiveness of the library increased, but the generated * code can be more efficient than what you might write by hand. When we * refer to @a functors, then, generally we include function pointers in * the description as well. * * Often, functors are only created as temporaries passed to algorithm * calls, rather than being created as named variables. * * Two examples taken from the standard itself follow. To perform a * by-element addition of two vectors @c a and @c b containing @c double, * and put the result in @c a, use * \code * transform (a.begin(), a.end(), b.begin(), a.begin(), plus<double>()); * \endcode * To negate every element in @c a, use * \code * transform(a.begin(), a.end(), a.begin(), negate<double>()); * \endcode * The addition and negation functions will be inlined directly. * * The standard functors are derived from structs named @c unary_function * and @c binary_function. These two classes contain nothing but typedefs, * to aid in generic (template) programming. If you write your own * functors, you might consider doing the same. * * @{ */ /** * This is one of the @link functors functor base classes@endlink. */ template<typename _Arg, typename _Result> struct unary_function { /// @c argument_type is the type of the argument typedef _Arg argument_type; /// @c result_type is the return type typedef _Result result_type; }; /** * This is one of the @link functors functor base classes@endlink. */ template<typename _Arg1, typename _Arg2, typename _Result> struct binary_function { /// @c first_argument_type is the type of the first argument typedef _Arg1 first_argument_type; /// @c second_argument_type is the type of the second argument typedef _Arg2 second_argument_type; /// @c result_type is the return type typedef _Result result_type; }; /** @} */ // 20.3.2 arithmetic /** @defgroup arithmetic_functors Arithmetic Classes * @ingroup functors * * Because basic math often needs to be done during an algorithm, * the library provides functors for those operations. See the * documentation for @link functors the base classes@endlink * for examples of their use. * * @{ */ #if __cplusplus > 201103L struct __is_transparent; // undefined template<typename _Tp = void> struct plus; template<typename _Tp = void> struct minus; template<typename _Tp = void> struct multiplies; template<typename _Tp = void> struct divides; template<typename _Tp = void> struct modulus; template<typename _Tp = void> struct negate; #endif /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct plus : public binary_function<_Tp, _Tp, _Tp> { _GLIBCXX14_CONSTEXPR _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } }; /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct minus : public binary_function<_Tp, _Tp, _Tp> { _GLIBCXX14_CONSTEXPR _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } }; /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct multiplies : public binary_function<_Tp, _Tp, _Tp> { _GLIBCXX14_CONSTEXPR _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } }; /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct divides : public binary_function<_Tp, _Tp, _Tp> { _GLIBCXX14_CONSTEXPR _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } }; /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct modulus : public binary_function<_Tp, _Tp, _Tp> { _GLIBCXX14_CONSTEXPR _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } }; /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct negate : public unary_function<_Tp, _Tp> { _GLIBCXX14_CONSTEXPR _Tp operator()(const _Tp& __x) const { return -__x; } }; #if __cplusplus > 201103L #define __cpp_lib_transparent_operators 201510 template<> struct plus<void> { template <typename _Tp, typename _Up> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) + std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) + std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) + std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link arithmetic_functors math functors@endlink. template<> struct minus<void> { template <typename _Tp, typename _Up> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) - std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) - std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) - std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link arithmetic_functors math functors@endlink. template<> struct multiplies<void> { template <typename _Tp, typename _Up> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) * std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) * std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) * std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link arithmetic_functors math functors@endlink. template<> struct divides<void> { template <typename _Tp, typename _Up> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) / std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) / std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) / std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link arithmetic_functors math functors@endlink. template<> struct modulus<void> { template <typename _Tp, typename _Up> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) % std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) % std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) % std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link arithmetic_functors math functors@endlink. template<> struct negate<void> { template <typename _Tp> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t) const noexcept(noexcept(-std::forward<_Tp>(__t))) -> decltype(-std::forward<_Tp>(__t)) { return -std::forward<_Tp>(__t); } typedef __is_transparent is_transparent; }; #endif /** @} */ // 20.3.3 comparisons /** @defgroup comparison_functors Comparison Classes * @ingroup functors * * The library provides six wrapper functors for all the basic comparisons * in C++, like @c <. * * @{ */ #if __cplusplus > 201103L template<typename _Tp = void> struct equal_to; template<typename _Tp = void> struct not_equal_to; template<typename _Tp = void> struct greater; template<typename _Tp = void> struct less; template<typename _Tp = void> struct greater_equal; template<typename _Tp = void> struct less_equal; #endif /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct equal_to : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } }; /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct not_equal_to : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } }; /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct greater : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct less : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } }; /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct greater_equal : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } }; /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct less_equal : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } }; // Partial specialization of std::greater for pointers. template<typename _Tp> struct greater<_Tp*> : public binary_function<_Tp*, _Tp*, bool> { _GLIBCXX14_CONSTEXPR bool operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW { if (__builtin_constant_p (__x > __y)) return __x > __y; return (__UINTPTR_TYPE__)__x > (__UINTPTR_TYPE__)__y; } }; // Partial specialization of std::less for pointers. template<typename _Tp> struct less<_Tp*> : public binary_function<_Tp*, _Tp*, bool> { _GLIBCXX14_CONSTEXPR bool operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW { if (__builtin_constant_p (__x < __y)) return __x < __y; return (__UINTPTR_TYPE__)__x < (__UINTPTR_TYPE__)__y; } }; // Partial specialization of std::greater_equal for pointers. template<typename _Tp> struct greater_equal<_Tp*> : public binary_function<_Tp*, _Tp*, bool> { _GLIBCXX14_CONSTEXPR bool operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW { if (__builtin_constant_p (__x >= __y)) return __x >= __y; return (__UINTPTR_TYPE__)__x >= (__UINTPTR_TYPE__)__y; } }; // Partial specialization of std::less_equal for pointers. template<typename _Tp> struct less_equal<_Tp*> : public binary_function<_Tp*, _Tp*, bool> { _GLIBCXX14_CONSTEXPR bool operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW { if (__builtin_constant_p (__x <= __y)) return __x <= __y; return (__UINTPTR_TYPE__)__x <= (__UINTPTR_TYPE__)__y; } }; #if __cplusplus >= 201402L /// One of the @link comparison_functors comparison functors@endlink. template<> struct equal_to<void> { template <typename _Tp, typename _Up> constexpr auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) == std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) == std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link comparison_functors comparison functors@endlink. template<> struct not_equal_to<void> { template <typename _Tp, typename _Up> constexpr auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) != std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) != std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) != std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link comparison_functors comparison functors@endlink. template<> struct greater<void> { template <typename _Tp, typename _Up> constexpr auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) > std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) > std::forward<_Up>(__u)) { return _S_cmp(std::forward<_Tp>(__t), std::forward<_Up>(__u), __ptr_cmp<_Tp, _Up>{}); } template<typename _Tp, typename _Up> constexpr bool operator()(_Tp* __t, _Up* __u) const noexcept { return greater<common_type_t<_Tp*, _Up*>>{}(__t, __u); } typedef __is_transparent is_transparent; private: template <typename _Tp, typename _Up> static constexpr decltype(auto) _S_cmp(_Tp&& __t, _Up&& __u, false_type) { return std::forward<_Tp>(__t) > std::forward<_Up>(__u); } template <typename _Tp, typename _Up> static constexpr bool _S_cmp(_Tp&& __t, _Up&& __u, true_type) noexcept { return greater<const volatile void*>{}( static_cast<const volatile void*>(std::forward<_Tp>(__t)), static_cast<const volatile void*>(std::forward<_Up>(__u))); } // True if there is no viable operator> member function. template<typename _Tp, typename _Up, typename = void> struct __not_overloaded2 : true_type { }; // False if we can call T.operator>(U) template<typename _Tp, typename _Up> struct __not_overloaded2<_Tp, _Up, __void_t< decltype(std::declval<_Tp>().operator>(std::declval<_Up>()))>> : false_type { }; // True if there is no overloaded operator> for these operands. template<typename _Tp, typename _Up, typename = void> struct __not_overloaded : __not_overloaded2<_Tp, _Up> { }; // False if we can call operator>(T,U) template<typename _Tp, typename _Up> struct __not_overloaded<_Tp, _Up, __void_t< decltype(operator>(std::declval<_Tp>(), std::declval<_Up>()))>> : false_type { }; template<typename _Tp, typename _Up> using __ptr_cmp = __and_<__not_overloaded<_Tp, _Up>, is_convertible<_Tp, const volatile void*>, is_convertible<_Up, const volatile void*>>; }; /// One of the @link comparison_functors comparison functors@endlink. template<> struct less<void> { template <typename _Tp, typename _Up> constexpr auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) < std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) < std::forward<_Up>(__u)) { return _S_cmp(std::forward<_Tp>(__t), std::forward<_Up>(__u), __ptr_cmp<_Tp, _Up>{}); } template<typename _Tp, typename _Up> constexpr bool operator()(_Tp* __t, _Up* __u) const noexcept { return less<common_type_t<_Tp*, _Up*>>{}(__t, __u); } typedef __is_transparent is_transparent; private: template <typename _Tp, typename _Up> static constexpr decltype(auto) _S_cmp(_Tp&& __t, _Up&& __u, false_type) { return std::forward<_Tp>(__t) < std::forward<_Up>(__u); } template <typename _Tp, typename _Up> static constexpr bool _S_cmp(_Tp&& __t, _Up&& __u, true_type) noexcept { return less<const volatile void*>{}( static_cast<const volatile void*>(std::forward<_Tp>(__t)), static_cast<const volatile void*>(std::forward<_Up>(__u))); } // True if there is no viable operator< member function. template<typename _Tp, typename _Up, typename = void> struct __not_overloaded2 : true_type { }; // False if we can call T.operator<(U) template<typename _Tp, typename _Up> struct __not_overloaded2<_Tp, _Up, __void_t< decltype(std::declval<_Tp>().operator<(std::declval<_Up>()))>> : false_type { }; // True if there is no overloaded operator< for these operands. template<typename _Tp, typename _Up, typename = void> struct __not_overloaded : __not_overloaded2<_Tp, _Up> { }; // False if we can call operator<(T,U) template<typename _Tp, typename _Up> struct __not_overloaded<_Tp, _Up, __void_t< decltype(operator<(std::declval<_Tp>(), std::declval<_Up>()))>> : false_type { }; template<typename _Tp, typename _Up> using __ptr_cmp = __and_<__not_overloaded<_Tp, _Up>, is_convertible<_Tp, const volatile void*>, is_convertible<_Up, const volatile void*>>; }; /// One of the @link comparison_functors comparison functors@endlink. template<> struct greater_equal<void> { template <typename _Tp, typename _Up> constexpr auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) >= std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) >= std::forward<_Up>(__u)) { return _S_cmp(std::forward<_Tp>(__t), std::forward<_Up>(__u), __ptr_cmp<_Tp, _Up>{}); } template<typename _Tp, typename _Up> constexpr bool operator()(_Tp* __t, _Up* __u) const noexcept { return greater_equal<common_type_t<_Tp*, _Up*>>{}(__t, __u); } typedef __is_transparent is_transparent; private: template <typename _Tp, typename _Up> static constexpr decltype(auto) _S_cmp(_Tp&& __t, _Up&& __u, false_type) { return std::forward<_Tp>(__t) >= std::forward<_Up>(__u); } template <typename _Tp, typename _Up> static constexpr bool _S_cmp(_Tp&& __t, _Up&& __u, true_type) noexcept { return greater_equal<const volatile void*>{}( static_cast<const volatile void*>(std::forward<_Tp>(__t)), static_cast<const volatile void*>(std::forward<_Up>(__u))); } // True if there is no viable operator>= member function. template<typename _Tp, typename _Up, typename = void> struct __not_overloaded2 : true_type { }; // False if we can call T.operator>=(U) template<typename _Tp, typename _Up> struct __not_overloaded2<_Tp, _Up, __void_t< decltype(std::declval<_Tp>().operator>=(std::declval<_Up>()))>> : false_type { }; // True if there is no overloaded operator>= for these operands. template<typename _Tp, typename _Up, typename = void> struct __not_overloaded : __not_overloaded2<_Tp, _Up> { }; // False if we can call operator>=(T,U) template<typename _Tp, typename _Up> struct __not_overloaded<_Tp, _Up, __void_t< decltype(operator>=(std::declval<_Tp>(), std::declval<_Up>()))>> : false_type { }; template<typename _Tp, typename _Up> using __ptr_cmp = __and_<__not_overloaded<_Tp, _Up>, is_convertible<_Tp, const volatile void*>, is_convertible<_Up, const volatile void*>>; }; /// One of the @link comparison_functors comparison functors@endlink. template<> struct less_equal<void> { template <typename _Tp, typename _Up> constexpr auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) <= std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) <= std::forward<_Up>(__u)) { return _S_cmp(std::forward<_Tp>(__t), std::forward<_Up>(__u), __ptr_cmp<_Tp, _Up>{}); } template<typename _Tp, typename _Up> constexpr bool operator()(_Tp* __t, _Up* __u) const noexcept { return less_equal<common_type_t<_Tp*, _Up*>>{}(__t, __u); } typedef __is_transparent is_transparent; private: template <typename _Tp, typename _Up> static constexpr decltype(auto) _S_cmp(_Tp&& __t, _Up&& __u, false_type) { return std::forward<_Tp>(__t) <= std::forward<_Up>(__u); } template <typename _Tp, typename _Up> static constexpr bool _S_cmp(_Tp&& __t, _Up&& __u, true_type) noexcept { return less_equal<const volatile void*>{}( static_cast<const volatile void*>(std::forward<_Tp>(__t)), static_cast<const volatile void*>(std::forward<_Up>(__u))); } // True if there is no viable operator<= member function. template<typename _Tp, typename _Up, typename = void> struct __not_overloaded2 : true_type { }; // False if we can call T.operator<=(U) template<typename _Tp, typename _Up> struct __not_overloaded2<_Tp, _Up, __void_t< decltype(std::declval<_Tp>().operator<=(std::declval<_Up>()))>> : false_type { }; // True if there is no overloaded operator<= for these operands. template<typename _Tp, typename _Up, typename = void> struct __not_overloaded : __not_overloaded2<_Tp, _Up> { }; // False if we can call operator<=(T,U) template<typename _Tp, typename _Up> struct __not_overloaded<_Tp, _Up, __void_t< decltype(operator<=(std::declval<_Tp>(), std::declval<_Up>()))>> : false_type { }; template<typename _Tp, typename _Up> using __ptr_cmp = __and_<__not_overloaded<_Tp, _Up>, is_convertible<_Tp, const volatile void*>, is_convertible<_Up, const volatile void*>>; }; #endif // C++14 /** @} */ // 20.3.4 logical operations /** @defgroup logical_functors Boolean Operations Classes * @ingroup functors * * Here are wrapper functors for Boolean operations: @c &&, @c ||, * and @c !. * * @{ */ #if __cplusplus > 201103L template<typename _Tp = void> struct logical_and; template<typename _Tp = void> struct logical_or; template<typename _Tp = void> struct logical_not; #endif /// One of the @link logical_functors Boolean operations functors@endlink. template<typename _Tp> struct logical_and : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } }; /// One of the @link logical_functors Boolean operations functors@endlink. template<typename _Tp> struct logical_or : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } }; /// One of the @link logical_functors Boolean operations functors@endlink. template<typename _Tp> struct logical_not : public unary_function<_Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x) const { return !__x; } }; #if __cplusplus > 201103L /// One of the @link logical_functors Boolean operations functors@endlink. template<> struct logical_and<void> { template <typename _Tp, typename _Up> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) && std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) && std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) && std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link logical_functors Boolean operations functors@endlink. template<> struct logical_or<void> { template <typename _Tp, typename _Up> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) || std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) || std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) || std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link logical_functors Boolean operations functors@endlink. template<> struct logical_not<void> { template <typename _Tp> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t) const noexcept(noexcept(!std::forward<_Tp>(__t))) -> decltype(!std::forward<_Tp>(__t)) { return !std::forward<_Tp>(__t); } typedef __is_transparent is_transparent; }; #endif /** @} */ #if __cplusplus > 201103L template<typename _Tp = void> struct bit_and; template<typename _Tp = void> struct bit_or; template<typename _Tp = void> struct bit_xor; template<typename _Tp = void> struct bit_not; #endif // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 660. Missing Bitwise Operations. template<typename _Tp> struct bit_and : public binary_function<_Tp, _Tp, _Tp> { _GLIBCXX14_CONSTEXPR _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x & __y; } }; template<typename _Tp> struct bit_or : public binary_function<_Tp, _Tp, _Tp> { _GLIBCXX14_CONSTEXPR _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x | __y; } }; template<typename _Tp> struct bit_xor : public binary_function<_Tp, _Tp, _Tp> { _GLIBCXX14_CONSTEXPR _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x ^ __y; } }; template<typename _Tp> struct bit_not : public unary_function<_Tp, _Tp> { _GLIBCXX14_CONSTEXPR _Tp operator()(const _Tp& __x) const { return ~__x; } }; #if __cplusplus > 201103L template <> struct bit_and<void> { template <typename _Tp, typename _Up> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) & std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) & std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) & std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; template <> struct bit_or<void> { template <typename _Tp, typename _Up> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) | std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) | std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) | std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; template <> struct bit_xor<void> { template <typename _Tp, typename _Up> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) ^ std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) ^ std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) ^ std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; template <> struct bit_not<void> { template <typename _Tp> _GLIBCXX14_CONSTEXPR auto operator()(_Tp&& __t) const noexcept(noexcept(~std::forward<_Tp>(__t))) -> decltype(~std::forward<_Tp>(__t)) { return ~std::forward<_Tp>(__t); } typedef __is_transparent is_transparent; }; #endif // 20.3.5 negators /** @defgroup negators Negators * @ingroup functors * * The functions @c not1 and @c not2 each take a predicate functor * and return an instance of @c unary_negate or * @c binary_negate, respectively. These classes are functors whose * @c operator() performs the stored predicate function and then returns * the negation of the result. * * For example, given a vector of integers and a trivial predicate, * \code * struct IntGreaterThanThree * : public std::unary_function<int, bool> * { * bool operator() (int x) { return x > 3; } * }; * * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); * \endcode * The call to @c find_if will locate the first index (i) of @c v for which * <code>!(v[i] > 3)</code> is true. * * The not1/unary_negate combination works on predicates taking a single * argument. The not2/binary_negate combination works on predicates which * take two arguments. * * @{ */ /// One of the @link negators negation functors@endlink. template<typename _Predicate> class unary_negate : public unary_function<typename _Predicate::argument_type, bool> { protected: _Predicate _M_pred; public: _GLIBCXX14_CONSTEXPR explicit unary_negate(const _Predicate& __x) : _M_pred(__x) { } _GLIBCXX14_CONSTEXPR bool operator()(const typename _Predicate::argument_type& __x) const { return !_M_pred(__x); } }; /// One of the @link negators negation functors@endlink. template<typename _Predicate> _GLIBCXX14_CONSTEXPR inline unary_negate<_Predicate> not1(const _Predicate& __pred) { return unary_negate<_Predicate>(__pred); } /// One of the @link negators negation functors@endlink. template<typename _Predicate> class binary_negate : public binary_function<typename _Predicate::first_argument_type, typename _Predicate::second_argument_type, bool> { protected: _Predicate _M_pred; public: _GLIBCXX14_CONSTEXPR explicit binary_negate(const _Predicate& __x) : _M_pred(__x) { } _GLIBCXX14_CONSTEXPR bool operator()(const typename _Predicate::first_argument_type& __x, const typename _Predicate::second_argument_type& __y) const { return !_M_pred(__x, __y); } }; /// One of the @link negators negation functors@endlink. template<typename _Predicate> _GLIBCXX14_CONSTEXPR inline binary_negate<_Predicate> not2(const _Predicate& __pred) { return binary_negate<_Predicate>(__pred); } /** @} */ // 20.3.7 adaptors pointers functions /** @defgroup pointer_adaptors Adaptors for pointers to functions * @ingroup functors * * The advantage of function objects over pointers to functions is that * the objects in the standard library declare nested typedefs describing * their argument and result types with uniform names (e.g., @c result_type * from the base classes @c unary_function and @c binary_function). * Sometimes those typedefs are required, not just optional. * * Adaptors are provided to turn pointers to unary (single-argument) and * binary (double-argument) functions into function objects. The * long-winded functor @c pointer_to_unary_function is constructed with a * function pointer @c f, and its @c operator() called with argument @c x * returns @c f(x). The functor @c pointer_to_binary_function does the same * thing, but with a double-argument @c f and @c operator(). * * The function @c ptr_fun takes a pointer-to-function @c f and constructs * an instance of the appropriate functor. * * @{ */ /// One of the @link pointer_adaptors adaptors for function pointers@endlink. template<typename _Arg, typename _Result> class pointer_to_unary_function : public unary_function<_Arg, _Result> { protected: _Result (*_M_ptr)(_Arg); public: pointer_to_unary_function() { } explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) { } _Result operator()(_Arg __x) const { return _M_ptr(__x); } }; /// One of the @link pointer_adaptors adaptors for function pointers@endlink. template<typename _Arg, typename _Result> inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg)) { return pointer_to_unary_function<_Arg, _Result>(__x); } /// One of the @link pointer_adaptors adaptors for function pointers@endlink. template<typename _Arg1, typename _Arg2, typename _Result> class pointer_to_binary_function : public binary_function<_Arg1, _Arg2, _Result> { protected: _Result (*_M_ptr)(_Arg1, _Arg2); public: pointer_to_binary_function() { } explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) : _M_ptr(__x) { } _Result operator()(_Arg1 __x, _Arg2 __y) const { return _M_ptr(__x, __y); } }; /// One of the @link pointer_adaptors adaptors for function pointers@endlink. template<typename _Arg1, typename _Arg2, typename _Result> inline pointer_to_binary_function<_Arg1, _Arg2, _Result> ptr_fun(_Result (*__x)(_Arg1, _Arg2)) { return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); } /** @} */ template<typename _Tp> struct _Identity : public unary_function<_Tp, _Tp> { _Tp& operator()(_Tp& __x) const { return __x; } const _Tp& operator()(const _Tp& __x) const { return __x; } }; // Partial specialization, avoids confusing errors in e.g. std::set<const T>. template<typename _Tp> struct _Identity<const _Tp> : _Identity<_Tp> { }; template<typename _Pair> struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { typename _Pair::first_type& operator()(_Pair& __x) const { return __x.first; } const typename _Pair::first_type& operator()(const _Pair& __x) const { return __x.first; } #if __cplusplus >= 201103L template<typename _Pair2> typename _Pair2::first_type& operator()(_Pair2& __x) const { return __x.first; } template<typename _Pair2> const typename _Pair2::first_type& operator()(const _Pair2& __x) const { return __x.first; } #endif }; template<typename _Pair> struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> { typename _Pair::second_type& operator()(_Pair& __x) const { return __x.second; } const typename _Pair::second_type& operator()(const _Pair& __x) const { return __x.second; } }; // 20.3.8 adaptors pointers members /** @defgroup memory_adaptors Adaptors for pointers to members * @ingroup functors * * There are a total of 8 = 2^3 function objects in this family. * (1) Member functions taking no arguments vs member functions taking * one argument. * (2) Call through pointer vs call through reference. * (3) Const vs non-const member function. * * All of this complexity is in the function objects themselves. You can * ignore it by using the helper function mem_fun and mem_fun_ref, * which create whichever type of adaptor is appropriate. * * @{ */ /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp> class mem_fun_t : public unary_function<_Tp*, _Ret> { public: explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) { } _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } private: _Ret (_Tp::*_M_f)(); }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp> class const_mem_fun_t : public unary_function<const _Tp*, _Ret> { public: explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) { } _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); } private: _Ret (_Tp::*_M_f)() const; }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp> class mem_fun_ref_t : public unary_function<_Tp, _Ret> { public: explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) { } _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); } private: _Ret (_Tp::*_M_f)(); }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp> class const_mem_fun_ref_t : public unary_function<_Tp, _Ret> { public: explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) { } _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); } private: _Ret (_Tp::*_M_f)() const; }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp, typename _Arg> class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret> { public: explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) { } _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } private: _Ret (_Tp::*_M_f)(_Arg); }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp, typename _Arg> class const_mem_fun1_t : public binary_function<const _Tp*, _Arg, _Ret> { public: explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) { } _Ret operator()(const _Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } private: _Ret (_Tp::*_M_f)(_Arg) const; }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp, typename _Arg> class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> { public: explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) { } _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } private: _Ret (_Tp::*_M_f)(_Arg); }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp, typename _Arg> class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> { public: explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) { } _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } private: _Ret (_Tp::*_M_f)(_Arg) const; }; // Mem_fun adaptor helper functions. There are only two: // mem_fun and mem_fun_ref. template<typename _Ret, typename _Tp> inline mem_fun_t<_Ret, _Tp> mem_fun(_Ret (_Tp::*__f)()) { return mem_fun_t<_Ret, _Tp>(__f); } template<typename _Ret, typename _Tp> inline const_mem_fun_t<_Ret, _Tp> mem_fun(_Ret (_Tp::*__f)() const) { return const_mem_fun_t<_Ret, _Tp>(__f); } template<typename _Ret, typename _Tp> inline mem_fun_ref_t<_Ret, _Tp> mem_fun_ref(_Ret (_Tp::*__f)()) { return mem_fun_ref_t<_Ret, _Tp>(__f); } template<typename _Ret, typename _Tp> inline const_mem_fun_ref_t<_Ret, _Tp> mem_fun_ref(_Ret (_Tp::*__f)() const) { return const_mem_fun_ref_t<_Ret, _Tp>(__f); } template<typename _Ret, typename _Tp, typename _Arg> inline mem_fun1_t<_Ret, _Tp, _Arg> mem_fun(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } template<typename _Ret, typename _Tp, typename _Arg> inline const_mem_fun1_t<_Ret, _Tp, _Arg> mem_fun(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } template<typename _Ret, typename _Tp, typename _Arg> inline mem_fun1_ref_t<_Ret, _Tp, _Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } template<typename _Ret, typename _Tp, typename _Arg> inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } /** @} */ _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED # include <backward/binders.h> #endif #endif /* _STL_FUNCTION_H */ c++/8/bits/regex.tcc 0000644 00000040265 15146341150 0010040 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2013-2018 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/regex.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { // Result of merging regex_match and regex_search. // // __policy now can be _S_auto (auto dispatch) and _S_alternate (use // the other one if possible, for test purpose). // // That __match_mode is true means regex_match, else regex_search. template<typename _BiIter, typename _Alloc, typename _CharT, typename _TraitsT, _RegexExecutorPolicy __policy, bool __match_mode> bool __regex_algo_impl(_BiIter __s, _BiIter __e, match_results<_BiIter, _Alloc>& __m, const basic_regex<_CharT, _TraitsT>& __re, regex_constants::match_flag_type __flags) { if (__re._M_automaton == nullptr) return false; typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m; __m._M_begin = __s; __m._M_resize(__re._M_automaton->_M_sub_count()); for (auto& __it : __res) __it.matched = false; bool __ret; if ((__re.flags() & regex_constants::__polynomial) || (__policy == _RegexExecutorPolicy::_S_alternate && !__re._M_automaton->_M_has_backref)) { _Executor<_BiIter, _Alloc, _TraitsT, false> __executor(__s, __e, __m, __re, __flags); if (__match_mode) __ret = __executor._M_match(); else __ret = __executor._M_search(); } else { _Executor<_BiIter, _Alloc, _TraitsT, true> __executor(__s, __e, __m, __re, __flags); if (__match_mode) __ret = __executor._M_match(); else __ret = __executor._M_search(); } if (__ret) { for (auto& __it : __res) if (!__it.matched) __it.first = __it.second = __e; auto& __pre = __m._M_prefix(); auto& __suf = __m._M_suffix(); if (__match_mode) { __pre.matched = false; __pre.first = __s; __pre.second = __s; __suf.matched = false; __suf.first = __e; __suf.second = __e; } else { __pre.first = __s; __pre.second = __res[0].first; __pre.matched = (__pre.first != __pre.second); __suf.first = __res[0].second; __suf.second = __e; __suf.matched = (__suf.first != __suf.second); } } else { __m._M_resize(0); for (auto& __it : __res) { __it.matched = false; __it.first = __it.second = __e; } } return __ret; } } template<typename _Ch_type> template<typename _Fwd_iter> typename regex_traits<_Ch_type>::string_type regex_traits<_Ch_type>:: lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const { typedef std::ctype<char_type> __ctype_type; const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); static const char* __collatenames[] = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "alert", "backspace", "tab", "newline", "vertical-tab", "form-feed", "carriage-return", "SO", "SI", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "IS4", "IS3", "IS2", "IS1", "space", "exclamation-mark", "quotation-mark", "number-sign", "dollar-sign", "percent-sign", "ampersand", "apostrophe", "left-parenthesis", "right-parenthesis", "asterisk", "plus-sign", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less-than-sign", "equals-sign", "greater-than-sign", "question-mark", "commercial-at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "left-square-bracket", "backslash", "right-square-bracket", "circumflex", "underscore", "grave-accent", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "left-curly-bracket", "vertical-line", "right-curly-bracket", "tilde", "DEL", }; string __s; for (; __first != __last; ++__first) __s += __fctyp.narrow(*__first, 0); for (const auto& __it : __collatenames) if (__s == __it) return string_type(1, __fctyp.widen( static_cast<char>(&__it - __collatenames))); // TODO Add digraph support: // http://boost.sourceforge.net/libs/regex/doc/collating_names.html return string_type(); } template<typename _Ch_type> template<typename _Fwd_iter> typename regex_traits<_Ch_type>::char_class_type regex_traits<_Ch_type>:: lookup_classname(_Fwd_iter __first, _Fwd_iter __last, bool __icase) const { typedef std::ctype<char_type> __ctype_type; const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); // Mappings from class name to class mask. static const pair<const char*, char_class_type> __classnames[] = { {"d", ctype_base::digit}, {"w", {ctype_base::alnum, _RegexMask::_S_under}}, {"s", ctype_base::space}, {"alnum", ctype_base::alnum}, {"alpha", ctype_base::alpha}, {"blank", ctype_base::blank}, {"cntrl", ctype_base::cntrl}, {"digit", ctype_base::digit}, {"graph", ctype_base::graph}, {"lower", ctype_base::lower}, {"print", ctype_base::print}, {"punct", ctype_base::punct}, {"space", ctype_base::space}, {"upper", ctype_base::upper}, {"xdigit", ctype_base::xdigit}, }; string __s; for (; __first != __last; ++__first) __s += __fctyp.narrow(__fctyp.tolower(*__first), 0); for (const auto& __it : __classnames) if (__s == __it.first) { if (__icase && ((__it.second & (ctype_base::lower | ctype_base::upper)) != 0)) return ctype_base::alpha; return __it.second; } return 0; } template<typename _Ch_type> bool regex_traits<_Ch_type>:: isctype(_Ch_type __c, char_class_type __f) const { typedef std::ctype<char_type> __ctype_type; const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale)); return __fctyp.is(__f._M_base, __c) // [[:w:]] || ((__f._M_extended & _RegexMask::_S_under) && __c == __fctyp.widen('_')); } template<typename _Ch_type> int regex_traits<_Ch_type>:: value(_Ch_type __ch, int __radix) const { std::basic_istringstream<char_type> __is(string_type(1, __ch)); long __v; if (__radix == 8) __is >> std::oct; else if (__radix == 16) __is >> std::hex; __is >> __v; return __is.fail() ? -1 : __v; } template<typename _Bi_iter, typename _Alloc> template<typename _Out_iter> _Out_iter match_results<_Bi_iter, _Alloc>:: format(_Out_iter __out, const match_results<_Bi_iter, _Alloc>::char_type* __fmt_first, const match_results<_Bi_iter, _Alloc>::char_type* __fmt_last, match_flag_type __flags) const { __glibcxx_assert( ready() ); regex_traits<char_type> __traits; typedef std::ctype<char_type> __ctype_type; const __ctype_type& __fctyp(use_facet<__ctype_type>(__traits.getloc())); auto __output = [&](size_t __idx) { auto& __sub = (*this)[__idx]; if (__sub.matched) __out = std::copy(__sub.first, __sub.second, __out); }; if (__flags & regex_constants::format_sed) { bool __escaping = false; for (; __fmt_first != __fmt_last; __fmt_first++) { if (__escaping) { __escaping = false; if (__fctyp.is(__ctype_type::digit, *__fmt_first)) __output(__traits.value(*__fmt_first, 10)); else *__out++ = *__fmt_first; continue; } if (*__fmt_first == '\\') { __escaping = true; continue; } if (*__fmt_first == '&') { __output(0); continue; } *__out++ = *__fmt_first; } if (__escaping) *__out++ = '\\'; } else { while (1) { auto __next = std::find(__fmt_first, __fmt_last, '$'); if (__next == __fmt_last) break; __out = std::copy(__fmt_first, __next, __out); auto __eat = [&](char __ch) -> bool { if (*__next == __ch) { ++__next; return true; } return false; }; if (++__next == __fmt_last) *__out++ = '$'; else if (__eat('$')) *__out++ = '$'; else if (__eat('&')) __output(0); else if (__eat('`')) { auto& __sub = _M_prefix(); if (__sub.matched) __out = std::copy(__sub.first, __sub.second, __out); } else if (__eat('\'')) { auto& __sub = _M_suffix(); if (__sub.matched) __out = std::copy(__sub.first, __sub.second, __out); } else if (__fctyp.is(__ctype_type::digit, *__next)) { long __num = __traits.value(*__next, 10); if (++__next != __fmt_last && __fctyp.is(__ctype_type::digit, *__next)) { __num *= 10; __num += __traits.value(*__next++, 10); } if (0 <= __num && __num < this->size()) __output(__num); } else *__out++ = '$'; __fmt_first = __next; } __out = std::copy(__fmt_first, __fmt_last, __out); } return __out; } template<typename _Out_iter, typename _Bi_iter, typename _Rx_traits, typename _Ch_type> _Out_iter regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last, const basic_regex<_Ch_type, _Rx_traits>& __e, const _Ch_type* __fmt, regex_constants::match_flag_type __flags) { typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> _IterT; _IterT __i(__first, __last, __e, __flags); _IterT __end; if (__i == __end) { if (!(__flags & regex_constants::format_no_copy)) __out = std::copy(__first, __last, __out); } else { sub_match<_Bi_iter> __last; auto __len = char_traits<_Ch_type>::length(__fmt); for (; __i != __end; ++__i) { if (!(__flags & regex_constants::format_no_copy)) __out = std::copy(__i->prefix().first, __i->prefix().second, __out); __out = __i->format(__out, __fmt, __fmt + __len, __flags); __last = __i->suffix(); if (__flags & regex_constants::format_first_only) break; } if (!(__flags & regex_constants::format_no_copy)) __out = std::copy(__last.first, __last.second, __out); } return __out; } template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> bool regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: operator==(const regex_iterator& __rhs) const { if (_M_pregex == nullptr && __rhs._M_pregex == nullptr) return true; return _M_pregex == __rhs._M_pregex && _M_begin == __rhs._M_begin && _M_end == __rhs._M_end && _M_flags == __rhs._M_flags && _M_match[0] == __rhs._M_match[0]; } template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>& regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: operator++() { // In all cases in which the call to regex_search returns true, // match.prefix().first shall be equal to the previous value of // match[0].second, and for each index i in the half-open range // [0, match.size()) for which match[i].matched is true, // match[i].position() shall return distance(begin, match[i].first). // [28.12.1.4.5] if (_M_match[0].matched) { auto __start = _M_match[0].second; auto __prefix_first = _M_match[0].second; if (_M_match[0].first == _M_match[0].second) { if (__start == _M_end) { _M_pregex = nullptr; return *this; } else { if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags | regex_constants::match_not_null | regex_constants::match_continuous)) { __glibcxx_assert(_M_match[0].matched); auto& __prefix = _M_match._M_prefix(); __prefix.first = __prefix_first; __prefix.matched = __prefix.first != __prefix.second; // [28.12.1.4.5] _M_match._M_begin = _M_begin; return *this; } else ++__start; } } _M_flags |= regex_constants::match_prev_avail; if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags)) { __glibcxx_assert(_M_match[0].matched); auto& __prefix = _M_match._M_prefix(); __prefix.first = __prefix_first; __prefix.matched = __prefix.first != __prefix.second; // [28.12.1.4.5] _M_match._M_begin = _M_begin; } else _M_pregex = nullptr; } return *this; } template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>& regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: operator=(const regex_token_iterator& __rhs) { _M_position = __rhs._M_position; _M_subs = __rhs._M_subs; _M_n = __rhs._M_n; _M_suffix = __rhs._M_suffix; _M_has_m1 = __rhs._M_has_m1; _M_normalize_result(); return *this; } template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> bool regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: operator==(const regex_token_iterator& __rhs) const { if (_M_end_of_seq() && __rhs._M_end_of_seq()) return true; if (_M_suffix.matched && __rhs._M_suffix.matched && _M_suffix == __rhs._M_suffix) return true; if (_M_end_of_seq() || _M_suffix.matched || __rhs._M_end_of_seq() || __rhs._M_suffix.matched) return false; return _M_position == __rhs._M_position && _M_n == __rhs._M_n && _M_subs == __rhs._M_subs; } template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>& regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: operator++() { _Position __prev = _M_position; if (_M_suffix.matched) *this = regex_token_iterator(); else if (_M_n + 1 < _M_subs.size()) { _M_n++; _M_result = &_M_current_match(); } else { _M_n = 0; ++_M_position; if (_M_position != _Position()) _M_result = &_M_current_match(); else if (_M_has_m1 && __prev->suffix().length() != 0) { _M_suffix.matched = true; _M_suffix.first = __prev->suffix().first; _M_suffix.second = __prev->suffix().second; _M_result = &_M_suffix; } else *this = regex_token_iterator(); } return *this; } template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> void regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>:: _M_init(_Bi_iter __a, _Bi_iter __b) { _M_has_m1 = false; for (auto __it : _M_subs) if (__it == -1) { _M_has_m1 = true; break; } if (_M_position != _Position()) _M_result = &_M_current_match(); else if (_M_has_m1) { _M_suffix.matched = true; _M_suffix.first = __a; _M_suffix.second = __b; _M_result = &_M_suffix; } else _M_result = nullptr; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/bits/memoryfwd.h 0000644 00000004625 15146341150 0010415 0 ustar 00 // <memory> Forward declarations -*- C++ -*- // Copyright (C) 2001-2018 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/memoryfwd.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _MEMORYFWD_H #define _MEMORYFWD_H 1 #pragma GCC system_header #include <bits/c++config.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup allocators Allocators * @ingroup memory * * Classes encapsulating memory operations. * * @{ */ template<typename> class allocator; template<> class allocator<void>; #if __cplusplus >= 201103L /// Declare uses_allocator so it can be specialized in \<queue\> etc. template<typename, typename> struct uses_allocator; #endif /// @} group memory _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/fs_path.h 0000644 00000100176 15146341150 0010026 0 ustar 00 // Class filesystem::path -*- C++ -*- // Copyright (C) 2014-2018 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_path.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{filesystem} */ #ifndef _GLIBCXX_FS_PATH_H #define _GLIBCXX_FS_PATH_H 1 #if __cplusplus >= 201703L #include <utility> #include <type_traits> #include <vector> #include <locale> #include <iosfwd> #include <codecvt> #include <string_view> #include <system_error> #include <bits/stl_algobase.h> #include <bits/quoted_string.h> #include <bits/locale_conv.h> #if defined(_WIN32) && !defined(__CYGWIN__) # define _GLIBCXX_FILESYSTEM_IS_WINDOWS 1 # include <algorithm> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace filesystem { _GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * @ingroup filesystem * @{ */ /// A filesystem path. class path { template<typename _CharT> struct __is_encoded_char : std::false_type { }; template<typename _Iter, typename _Iter_traits = std::iterator_traits<_Iter>> using __is_path_iter_src = __and_<__is_encoded_char<typename _Iter_traits::value_type>, std::is_base_of<std::input_iterator_tag, typename _Iter_traits::iterator_category>>; template<typename _Iter> static __is_path_iter_src<_Iter> __is_path_src(_Iter, int); template<typename _CharT, typename _Traits, typename _Alloc> static __is_encoded_char<_CharT> __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int); template<typename _CharT, typename _Traits> static __is_encoded_char<_CharT> __is_path_src(const basic_string_view<_CharT, _Traits>&, int); template<typename _Unknown> static std::false_type __is_path_src(const _Unknown&, ...); template<typename _Tp1, typename _Tp2> struct __constructible_from; template<typename _Iter> struct __constructible_from<_Iter, _Iter> : __is_path_iter_src<_Iter> { }; template<typename _Source> struct __constructible_from<_Source, void> : decltype(__is_path_src(std::declval<_Source>(), 0)) { }; template<typename _Tp1, typename _Tp2 = void> using _Path = typename std::enable_if<__and_<__not_<is_same<remove_cv_t<_Tp1>, path>>, __not_<is_void<remove_pointer_t<_Tp1>>>, __constructible_from<_Tp1, _Tp2>>::value, path>::type; template<typename _Source> static _Source _S_range_begin(_Source __begin) { return __begin; } struct __null_terminated { }; template<typename _Source> static __null_terminated _S_range_end(_Source) { return {}; } template<typename _CharT, typename _Traits, typename _Alloc> static const _CharT* _S_range_begin(const basic_string<_CharT, _Traits, _Alloc>& __str) { return __str.data(); } template<typename _CharT, typename _Traits, typename _Alloc> static const _CharT* _S_range_end(const basic_string<_CharT, _Traits, _Alloc>& __str) { return __str.data() + __str.size(); } template<typename _CharT, typename _Traits> static const _CharT* _S_range_begin(const basic_string_view<_CharT, _Traits>& __str) { return __str.data(); } template<typename _CharT, typename _Traits> static const _CharT* _S_range_end(const basic_string_view<_CharT, _Traits>& __str) { return __str.data() + __str.size(); } template<typename _Tp, typename _Iter = decltype(_S_range_begin(std::declval<_Tp>())), typename _Val = typename std::iterator_traits<_Iter>::value_type> using __value_type_is_char = typename std::enable_if<std::is_same<_Val, char>::value>::type; public: #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS typedef wchar_t value_type; static constexpr value_type preferred_separator = L'\\'; #else typedef char value_type; static constexpr value_type preferred_separator = '/'; #endif typedef std::basic_string<value_type> string_type; enum format { native_format, generic_format, auto_format }; // constructors and destructor path() noexcept { } path(const path& __p) = default; path(path&& __p) noexcept : _M_pathname(std::move(__p._M_pathname)), _M_type(__p._M_type) { if (_M_type == _Type::_Multi) _M_split_cmpts(); __p.clear(); } path(string_type&& __source, format = auto_format) : _M_pathname(std::move(__source)) { _M_split_cmpts(); } template<typename _Source, typename _Require = _Path<_Source>> path(_Source const& __source, format = auto_format) : _M_pathname(_S_convert(_S_range_begin(__source), _S_range_end(__source))) { _M_split_cmpts(); } template<typename _InputIterator, typename _Require = _Path<_InputIterator, _InputIterator>> path(_InputIterator __first, _InputIterator __last, format = auto_format) : _M_pathname(_S_convert(__first, __last)) { _M_split_cmpts(); } template<typename _Source, typename _Require = _Path<_Source>, typename _Require2 = __value_type_is_char<_Source>> path(_Source const& __source, const locale& __loc, format = auto_format) : _M_pathname(_S_convert_loc(_S_range_begin(__source), _S_range_end(__source), __loc)) { _M_split_cmpts(); } template<typename _InputIterator, typename _Require = _Path<_InputIterator, _InputIterator>, typename _Require2 = __value_type_is_char<_InputIterator>> path(_InputIterator __first, _InputIterator __last, const locale& __loc, format = auto_format) : _M_pathname(_S_convert_loc(__first, __last, __loc)) { _M_split_cmpts(); } ~path() = default; // assignments path& operator=(const path& __p) = default; path& operator=(path&& __p) noexcept; path& operator=(string_type&& __source); path& assign(string_type&& __source); template<typename _Source> _Path<_Source>& operator=(_Source const& __source) { return *this = path(__source); } template<typename _Source> _Path<_Source>& assign(_Source const& __source) { return *this = path(__source); } template<typename _InputIterator> _Path<_InputIterator, _InputIterator>& assign(_InputIterator __first, _InputIterator __last) { return *this = path(__first, __last); } // appends path& operator/=(const path& __p) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS if (__p.is_absolute() || (__p.has_root_name() && __p.root_name() != root_name())) operator=(__p); else { string_type __pathname; if (__p.has_root_directory()) __pathname = root_name().native(); else if (has_filename() || (!has_root_directory() && is_absolute())) __pathname = _M_pathname + preferred_separator; __pathname += __p.relative_path().native(); // XXX is this right? _M_pathname.swap(__pathname); _M_split_cmpts(); } #else // Much simpler, as any path with root-name or root-dir is absolute. if (__p.is_absolute()) operator=(__p); else { if (has_filename() || (_M_type == _Type::_Root_name)) _M_pathname += preferred_separator; _M_pathname += __p.native(); _M_split_cmpts(); } #endif return *this; } template <class _Source> _Path<_Source>& operator/=(_Source const& __source) { return _M_append(path(__source)); } template<typename _Source> _Path<_Source>& append(_Source const& __source) { return _M_append(path(__source)); } template<typename _InputIterator> _Path<_InputIterator, _InputIterator>& append(_InputIterator __first, _InputIterator __last) { return _M_append(path(__first, __last)); } // concatenation path& operator+=(const path& __x); path& operator+=(const string_type& __x); path& operator+=(const value_type* __x); path& operator+=(value_type __x); path& operator+=(basic_string_view<value_type> __x); template<typename _Source> _Path<_Source>& operator+=(_Source const& __x) { return concat(__x); } template<typename _CharT> _Path<_CharT*, _CharT*>& operator+=(_CharT __x); template<typename _Source> _Path<_Source>& concat(_Source const& __x) { return *this += _S_convert(_S_range_begin(__x), _S_range_end(__x)); } template<typename _InputIterator> _Path<_InputIterator, _InputIterator>& concat(_InputIterator __first, _InputIterator __last) { return *this += _S_convert(__first, __last); } // modifiers void clear() noexcept { _M_pathname.clear(); _M_split_cmpts(); } path& make_preferred(); path& remove_filename(); path& replace_filename(const path& __replacement); path& replace_extension(const path& __replacement = path()); void swap(path& __rhs) noexcept; // native format observers const string_type& native() const noexcept { return _M_pathname; } const value_type* c_str() const noexcept { return _M_pathname.c_str(); } operator string_type() const { return _M_pathname; } template<typename _CharT, typename _Traits = std::char_traits<_CharT>, typename _Allocator = std::allocator<_CharT>> std::basic_string<_CharT, _Traits, _Allocator> string(const _Allocator& __a = _Allocator()) const; std::string string() const; #if _GLIBCXX_USE_WCHAR_T std::wstring wstring() const; #endif std::string u8string() const; std::u16string u16string() const; std::u32string u32string() const; // generic format observers template<typename _CharT, typename _Traits = std::char_traits<_CharT>, typename _Allocator = std::allocator<_CharT>> std::basic_string<_CharT, _Traits, _Allocator> generic_string(const _Allocator& __a = _Allocator()) const; std::string generic_string() const; #if _GLIBCXX_USE_WCHAR_T std::wstring generic_wstring() const; #endif std::string generic_u8string() const; std::u16string generic_u16string() const; std::u32string generic_u32string() const; // compare int compare(const path& __p) const noexcept; int compare(const string_type& __s) const; int compare(const value_type* __s) const; int compare(const basic_string_view<value_type> __s) const; // decomposition path root_name() const; path root_directory() const; path root_path() const; path relative_path() const; path parent_path() const; path filename() const; path stem() const; path extension() const; // query [[nodiscard]] bool empty() const noexcept { return _M_pathname.empty(); } bool has_root_name() const; bool has_root_directory() const; bool has_root_path() const; bool has_relative_path() const; bool has_parent_path() const; bool has_filename() const; bool has_stem() const; bool has_extension() const; bool is_absolute() const { return has_root_directory(); } bool is_relative() const { return !is_absolute(); } // generation path lexically_normal() const; path lexically_relative(const path& base) const; path lexically_proximate(const path& base) const; // iterators class iterator; typedef iterator const_iterator; iterator begin() const; iterator end() const; private: enum class _Type : unsigned char { _Multi, _Root_name, _Root_dir, _Filename }; path(string_type __str, _Type __type) : _M_pathname(__str), _M_type(__type) { __glibcxx_assert(_M_type != _Type::_Multi); } enum class _Split { _Stem, _Extension }; path& _M_append(path __p) { if (__p.is_absolute()) operator=(std::move(__p)); #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS else if (__p.has_root_name() && __p.root_name() != root_name()) operator=(std::move(__p)); #endif else operator/=(const_cast<const path&>(__p)); return *this; } pair<const string_type*, size_t> _M_find_extension() const; template<typename _CharT> struct _Cvt; static string_type _S_convert(value_type* __src, __null_terminated) { return string_type(__src); } static string_type _S_convert(const value_type* __src, __null_terminated) { return string_type(__src); } template<typename _Iter> static string_type _S_convert(_Iter __first, _Iter __last) { using __value_type = typename std::iterator_traits<_Iter>::value_type; return _Cvt<typename remove_cv<__value_type>::type>:: _S_convert(__first, __last); } template<typename _InputIterator> static string_type _S_convert(_InputIterator __src, __null_terminated) { using _Tp = typename std::iterator_traits<_InputIterator>::value_type; std::basic_string<typename remove_cv<_Tp>::type> __tmp; for (; *__src != _Tp{}; ++__src) __tmp.push_back(*__src); return _S_convert(__tmp.c_str(), __tmp.c_str() + __tmp.size()); } static string_type _S_convert_loc(const char* __first, const char* __last, const std::locale& __loc); template<typename _Iter> static string_type _S_convert_loc(_Iter __first, _Iter __last, const std::locale& __loc) { const std::string __str(__first, __last); return _S_convert_loc(__str.data(), __str.data()+__str.size(), __loc); } template<typename _InputIterator> static string_type _S_convert_loc(_InputIterator __src, __null_terminated, const std::locale& __loc) { std::string __tmp; while (*__src != '\0') __tmp.push_back(*__src++); return _S_convert_loc(__tmp.data(), __tmp.data()+__tmp.size(), __loc); } template<typename _CharT, typename _Traits, typename _Allocator> static basic_string<_CharT, _Traits, _Allocator> _S_str_convert(basic_string_view<value_type>, const _Allocator&); static bool _S_is_dir_sep(value_type __ch) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS return __ch == L'/' || __ch == preferred_separator; #else return __ch == '/'; #endif } void _M_split_cmpts(); void _M_trim(); void _M_add_root_name(size_t __n); void _M_add_root_dir(size_t __pos); void _M_add_filename(size_t __pos, size_t __n); string_type _M_pathname; struct _Cmpt; using _List = _GLIBCXX_STD_C::vector<_Cmpt>; _List _M_cmpts; // empty unless _M_type == _Type::_Multi _Type _M_type = _Type::_Filename; }; template<> struct path::__is_encoded_char<char> : std::true_type { using value_type = char; }; template<> struct path::__is_encoded_char<wchar_t> : std::true_type { using value_type = wchar_t; }; template<> struct path::__is_encoded_char<char16_t> : std::true_type { using value_type = char16_t; }; template<> struct path::__is_encoded_char<char32_t> : std::true_type { using value_type = char32_t; }; template<typename _Tp> struct path::__is_encoded_char<const _Tp> : __is_encoded_char<_Tp> { }; inline void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); } size_t hash_value(const path& __p) noexcept; /// Compare paths inline bool operator<(const path& __lhs, const path& __rhs) noexcept { return __lhs.compare(__rhs) < 0; } /// Compare paths inline bool operator<=(const path& __lhs, const path& __rhs) noexcept { return !(__rhs < __lhs); } /// Compare paths inline bool operator>(const path& __lhs, const path& __rhs) noexcept { return __rhs < __lhs; } /// Compare paths inline bool operator>=(const path& __lhs, const path& __rhs) noexcept { return !(__lhs < __rhs); } /// Compare paths inline bool operator==(const path& __lhs, const path& __rhs) noexcept { return __lhs.compare(__rhs) == 0; } /// Compare paths inline bool operator!=(const path& __lhs, const path& __rhs) noexcept { return !(__lhs == __rhs); } /// Append one path to another inline path operator/(const path& __lhs, const path& __rhs) { path __result(__lhs); __result /= __rhs; return __result; } /// Write a path to a stream template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { auto __tmp = __p.string<_CharT, _Traits>(); using __quoted_string = std::__detail::_Quoted_string<decltype(__tmp)&, _CharT>; __os << __quoted_string{__tmp, '"', '\\'}; return __os; } /// Read a path from a stream template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { basic_string<_CharT, _Traits> __tmp; using __quoted_string = std::__detail::_Quoted_string<decltype(__tmp)&, _CharT>; if (__is >> __quoted_string{ __tmp, '"', '\\' }) __p = std::move(__tmp); return __is; } template<typename _Source> inline auto u8path(const _Source& __source) -> decltype(filesystem::path(__source, std::locale::classic())) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS const std::string __u8str{__source}; return std::filesystem::u8path(__u8str.begin(), __u8str.end()); #else return path{ __source }; #endif } template<typename _InputIterator> inline auto u8path(_InputIterator __first, _InputIterator __last) -> decltype(filesystem::path(__first, __last, std::locale::classic())) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS codecvt_utf8<value_type> __cvt; string_type __tmp; if (__str_codecvt_in(__first, __last, __tmp, __cvt)) return path{ __tmp }; else return {}; #else return path{ __first, __last }; #endif } class filesystem_error : public std::system_error { public: filesystem_error(const string& __what_arg, error_code __ec) : system_error(__ec, __what_arg) { } filesystem_error(const string& __what_arg, const path& __p1, error_code __ec) : system_error(__ec, __what_arg), _M_path1(__p1) { } filesystem_error(const string& __what_arg, const path& __p1, const path& __p2, error_code __ec) : system_error(__ec, __what_arg), _M_path1(__p1), _M_path2(__p2) { } ~filesystem_error(); const path& path1() const noexcept { return _M_path1; } const path& path2() const noexcept { return _M_path2; } const char* what() const noexcept { return _M_what.c_str(); } private: std::string _M_gen_what(); path _M_path1; path _M_path2; std::string _M_what = _M_gen_what(); }; struct path::_Cmpt : path { _Cmpt(string_type __s, _Type __t, size_t __pos) : path(std::move(__s), __t), _M_pos(__pos) { } _Cmpt() : _M_pos(-1) { } size_t _M_pos; }; // specialize _Cvt for degenerate 'noconv' case template<> struct path::_Cvt<path::value_type> { template<typename _Iter> static string_type _S_convert(_Iter __first, _Iter __last) { return string_type{__first, __last}; } }; template<typename _CharT> struct path::_Cvt { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS static string_type _S_wconvert(const char* __f, const char* __l, true_type) { using _Cvt = std::codecvt<wchar_t, char, mbstate_t>; const auto& __cvt = std::use_facet<_Cvt>(std::locale{}); std::wstring __wstr; if (__str_codecvt_in(__f, __l, __wstr, __cvt)) return __wstr; _GLIBCXX_THROW_OR_ABORT(filesystem_error( "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); } static string_type _S_wconvert(const _CharT* __f, const _CharT* __l, false_type) { std::codecvt_utf8<_CharT> __cvt; std::string __str; if (__str_codecvt_out(__f, __l, __str, __cvt)) { const char* __f2 = __str.data(); const char* __l2 = __f2 + __str.size(); std::codecvt_utf8<wchar_t> __wcvt; std::wstring __wstr; if (__str_codecvt_in(__f2, __l2, __wstr, __wcvt)) return __wstr; } _GLIBCXX_THROW_OR_ABORT(filesystem_error( "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); } static string_type _S_convert(const _CharT* __f, const _CharT* __l) { return _S_wconvert(__f, __l, is_same<_CharT, char>{}); } #else static string_type _S_convert(const _CharT* __f, const _CharT* __l) { std::codecvt_utf8<_CharT> __cvt; std::string __str; if (__str_codecvt_out(__f, __l, __str, __cvt)) return __str; _GLIBCXX_THROW_OR_ABORT(filesystem_error( "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); } #endif static string_type _S_convert(_CharT* __f, _CharT* __l) { return _S_convert(const_cast<const _CharT*>(__f), const_cast<const _CharT*>(__l)); } template<typename _Iter> static string_type _S_convert(_Iter __first, _Iter __last) { const std::basic_string<_CharT> __str(__first, __last); return _S_convert(__str.data(), __str.data() + __str.size()); } template<typename _Iter, typename _Cont> static string_type _S_convert(__gnu_cxx::__normal_iterator<_Iter, _Cont> __first, __gnu_cxx::__normal_iterator<_Iter, _Cont> __last) { return _S_convert(__first.base(), __last.base()); } }; /// An iterator for the components of a path class path::iterator { public: using difference_type = std::ptrdiff_t; using value_type = path; using reference = const path&; using pointer = const path*; using iterator_category = std::bidirectional_iterator_tag; iterator() : _M_path(nullptr), _M_cur(), _M_at_end() { } iterator(const iterator&) = default; iterator& operator=(const iterator&) = default; reference operator*() const; pointer operator->() const { return std::__addressof(**this); } iterator& operator++(); iterator operator++(int) { auto __tmp = *this; ++*this; return __tmp; } iterator& operator--(); iterator operator--(int) { auto __tmp = *this; --*this; return __tmp; } friend bool operator==(const iterator& __lhs, const iterator& __rhs) { return __lhs._M_equals(__rhs); } friend bool operator!=(const iterator& __lhs, const iterator& __rhs) { return !__lhs._M_equals(__rhs); } private: friend class path; iterator(const path* __path, path::_List::const_iterator __iter) : _M_path(__path), _M_cur(__iter), _M_at_end() { } iterator(const path* __path, bool __at_end) : _M_path(__path), _M_cur(), _M_at_end(__at_end) { } bool _M_equals(iterator) const; const path* _M_path; path::_List::const_iterator _M_cur; bool _M_at_end; // only used when type != _Multi }; inline path& path::operator=(path&& __p) noexcept { if (&__p == this) return *this; _M_pathname = std::move(__p._M_pathname); _M_cmpts = std::move(__p._M_cmpts); _M_type = __p._M_type; __p.clear(); return *this; } inline path& path::operator=(string_type&& __source) { return *this = path(std::move(__source)); } inline path& path::assign(string_type&& __source) { return *this = path(std::move(__source)); } inline path& path::operator+=(const path& __p) { return operator+=(__p.native()); } inline path& path::operator+=(const string_type& __x) { _M_pathname += __x; _M_split_cmpts(); return *this; } inline path& path::operator+=(const value_type* __x) { _M_pathname += __x; _M_split_cmpts(); return *this; } inline path& path::operator+=(value_type __x) { _M_pathname += __x; _M_split_cmpts(); return *this; } inline path& path::operator+=(basic_string_view<value_type> __x) { _M_pathname.append(__x.data(), __x.size()); _M_split_cmpts(); return *this; } template<typename _CharT> inline path::_Path<_CharT*, _CharT*>& path::operator+=(_CharT __x) { auto* __addr = std::__addressof(__x); return concat(__addr, __addr + 1); } inline path& path::make_preferred() { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS std::replace(_M_pathname.begin(), _M_pathname.end(), L'/', preferred_separator); #endif return *this; } inline void path::swap(path& __rhs) noexcept { _M_pathname.swap(__rhs._M_pathname); _M_cmpts.swap(__rhs._M_cmpts); std::swap(_M_type, __rhs._M_type); } template<typename _CharT, typename _Traits, typename _Allocator> std::basic_string<_CharT, _Traits, _Allocator> path::_S_str_convert(basic_string_view<value_type> __str, const _Allocator& __a) { if (__str.size() == 0) return std::basic_string<_CharT, _Traits, _Allocator>(__a); const value_type* __first = __str.data(); const value_type* __last = __first + __str.size(); #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS using _CharAlloc = __alloc_rebind<_Allocator, char>; using _String = basic_string<char, char_traits<char>, _CharAlloc>; using _WString = basic_string<_CharT, _Traits, _Allocator>; // use codecvt_utf8<wchar_t> to convert native string to UTF-8 codecvt_utf8<value_type> __cvt; _String __u8str{_CharAlloc{__a}}; if (__str_codecvt_out(__first, __last, __u8str, __cvt)) { if constexpr (is_same_v<_CharT, char>) return __u8str; else { _WString __wstr; // use codecvt_utf8<_CharT> to convert UTF-8 to wide string codecvt_utf8<_CharT> __cvt; const char* __f = __u8str.data(); const char* __l = __f + __u8str.size(); if (__str_codecvt_in(__f, __l, __wstr, __cvt)) return __wstr; } } #else codecvt_utf8<_CharT> __cvt; basic_string<_CharT, _Traits, _Allocator> __wstr{__a}; if (__str_codecvt_in(__first, __last, __wstr, __cvt)) return __wstr; #endif _GLIBCXX_THROW_OR_ABORT(filesystem_error( "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); } template<typename _CharT, typename _Traits, typename _Allocator> inline basic_string<_CharT, _Traits, _Allocator> path::string(const _Allocator& __a) const { if constexpr (is_same_v<_CharT, value_type>) #if _GLIBCXX_USE_CXX11_ABI return { _M_pathname, __a }; #else return { _M_pathname, string_type::size_type(0), __a }; #endif else return _S_str_convert<_CharT, _Traits>(_M_pathname, __a); } inline std::string path::string() const { return string<char>(); } #if _GLIBCXX_USE_WCHAR_T inline std::wstring path::wstring() const { return string<wchar_t>(); } #endif inline std::string path::u8string() const { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS std::string __str; // convert from native encoding to UTF-8 codecvt_utf8<value_type> __cvt; const value_type* __first = _M_pathname.data(); const value_type* __last = __first + _M_pathname.size(); if (__str_codecvt_out(__first, __last, __str, __cvt)) return __str; _GLIBCXX_THROW_OR_ABORT(filesystem_error( "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); #else return _M_pathname; #endif } inline std::u16string path::u16string() const { return string<char16_t>(); } inline std::u32string path::u32string() const { return string<char32_t>(); } template<typename _CharT, typename _Traits, typename _Allocator> inline std::basic_string<_CharT, _Traits, _Allocator> path::generic_string(const _Allocator& __a) const { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS const value_type __slash = L'/'; #else const value_type __slash = '/'; #endif using _Alloc2 = typename allocator_traits<_Allocator>::template rebind_alloc<value_type>; basic_string<value_type, char_traits<value_type>, _Alloc2> __str(__a); if (_M_type == _Type::_Root_dir) __str.assign(1, __slash); else { __str.reserve(_M_pathname.size()); bool __add_slash = false; for (auto& __elem : *this) { if (__add_slash) __str += __slash; __str += basic_string_view<value_type>(__elem._M_pathname); __add_slash = __elem._M_type == _Type::_Filename; } } if constexpr (is_same_v<_CharT, value_type>) return __str; else return _S_str_convert<_CharT, _Traits>(__str, __a); } inline std::string path::generic_string() const { return generic_string<char>(); } #if _GLIBCXX_USE_WCHAR_T inline std::wstring path::generic_wstring() const { return generic_string<wchar_t>(); } #endif inline std::string path::generic_u8string() const { return generic_string(); } inline std::u16string path::generic_u16string() const { return generic_string<char16_t>(); } inline std::u32string path::generic_u32string() const { return generic_string<char32_t>(); } inline int path::compare(const string_type& __s) const { return compare(path(__s)); } inline int path::compare(const value_type* __s) const { return compare(path(__s)); } inline int path::compare(basic_string_view<value_type> __s) const { return compare(path(__s)); } inline path path::filename() const { if (empty()) return {}; else if (_M_type == _Type::_Filename) return *this; else if (_M_type == _Type::_Multi) { if (_M_pathname.back() == preferred_separator) return {}; auto& __last = *--end(); if (__last._M_type == _Type::_Filename) return __last; } return {}; } inline path path::stem() const { auto ext = _M_find_extension(); if (ext.first && ext.second != 0) return path{ext.first->substr(0, ext.second)}; return {}; } inline path path::extension() const { auto ext = _M_find_extension(); if (ext.first && ext.second != string_type::npos) return path{ext.first->substr(ext.second)}; return {}; } inline bool path::has_stem() const { auto ext = _M_find_extension(); return ext.first && ext.second != 0; } inline bool path::has_extension() const { auto ext = _M_find_extension(); return ext.first && ext.second != string_type::npos; } inline path::iterator path::begin() const { if (_M_type == _Type::_Multi) return iterator(this, _M_cmpts.begin()); return iterator(this, empty()); } inline path::iterator path::end() const { if (_M_type == _Type::_Multi) return iterator(this, _M_cmpts.end()); return iterator(this, true); } inline path::iterator& path::iterator::operator++() { __glibcxx_assert(_M_path != nullptr); if (_M_path->_M_type == _Type::_Multi) { __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end()); ++_M_cur; } else { __glibcxx_assert(!_M_at_end); _M_at_end = true; } return *this; } inline path::iterator& path::iterator::operator--() { __glibcxx_assert(_M_path != nullptr); if (_M_path->_M_type == _Type::_Multi) { __glibcxx_assert(_M_cur != _M_path->_M_cmpts.begin()); --_M_cur; } else { __glibcxx_assert(_M_at_end); _M_at_end = false; } return *this; } inline path::iterator::reference path::iterator::operator*() const { __glibcxx_assert(_M_path != nullptr); if (_M_path->_M_type == _Type::_Multi) { __glibcxx_assert(_M_cur != _M_path->_M_cmpts.end()); return *_M_cur; } return *_M_path; } inline bool path::iterator::_M_equals(iterator __rhs) const { if (_M_path != __rhs._M_path) return false; if (_M_path == nullptr) return true; if (_M_path->_M_type == path::_Type::_Multi) return _M_cur == __rhs._M_cur; return _M_at_end == __rhs._M_at_end; } // @} group filesystem _GLIBCXX_END_NAMESPACE_CXX11 } // namespace filesystem _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++17 #endif // _GLIBCXX_FS_PATH_H c++/8/bits/move.h 0000644 00000014601 15146341150 0007345 0 ustar 00 // Move, forward and identity for C++11 + swap -*- C++ -*- // Copyright (C) 2007-2018 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/move.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{utility} */ #ifndef _MOVE_H #define _MOVE_H 1 #include <bits/c++config.h> #include <bits/concept_check.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Used, in C++03 mode too, by allocators, etc. /** * @brief Same as C++11 std::addressof * @ingroup utilities */ template<typename _Tp> inline _GLIBCXX_CONSTEXPR _Tp* __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT { return __builtin_addressof(__r); } #if __cplusplus >= 201103L _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include <type_traits> // Brings in std::declval too. namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup utilities * @{ */ /** * @brief Forward an lvalue. * @return The parameter cast to the specified type. * * This function is used to implement "perfect forwarding". */ template<typename _Tp> constexpr _Tp&& forward(typename std::remove_reference<_Tp>::type& __t) noexcept { return static_cast<_Tp&&>(__t); } /** * @brief Forward an rvalue. * @return The parameter cast to the specified type. * * This function is used to implement "perfect forwarding". */ template<typename _Tp> constexpr _Tp&& forward(typename std::remove_reference<_Tp>::type&& __t) noexcept { static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument" " substituting _Tp is an lvalue reference type"); return static_cast<_Tp&&>(__t); } /** * @brief Convert a value to an rvalue. * @param __t A thing of arbitrary type. * @return The parameter cast to an rvalue-reference to allow moving it. */ template<typename _Tp> constexpr typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) noexcept { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); } template<typename _Tp> struct __move_if_noexcept_cond : public __and_<__not_<is_nothrow_move_constructible<_Tp>>, is_copy_constructible<_Tp>>::type { }; /** * @brief Conditionally convert a value to an rvalue. * @param __x A thing of arbitrary type. * @return The parameter, possibly cast to an rvalue-reference. * * Same as std::move unless the type's move constructor could throw and the * type is copyable, in which case an lvalue-reference is returned instead. */ template<typename _Tp> constexpr typename conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type move_if_noexcept(_Tp& __x) noexcept { return std::move(__x); } // declval, from type_traits. #if __cplusplus > 201402L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2296. std::addressof should be constexpr # define __cpp_lib_addressof_constexpr 201603 #endif /** * @brief Returns the actual address of the object or function * referenced by r, even in the presence of an overloaded * operator&. * @param __r Reference to an object or function. * @return The actual address. */ template<typename _Tp> inline _GLIBCXX17_CONSTEXPR _Tp* addressof(_Tp& __r) noexcept { return std::__addressof(__r); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2598. addressof works on temporaries template<typename _Tp> const _Tp* addressof(const _Tp&&) = delete; // C++11 version of std::exchange for internal use. template <typename _Tp, typename _Up = _Tp> inline _Tp __exchange(_Tp& __obj, _Up&& __new_val) { _Tp __old_val = std::move(__obj); __obj = std::forward<_Up>(__new_val); return __old_val; } /// @} group utilities #define _GLIBCXX_MOVE(__val) std::move(__val) #define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val) #else #define _GLIBCXX_MOVE(__val) (__val) #define _GLIBCXX_FORWARD(_Tp, __val) (__val) #endif /** * @addtogroup utilities * @{ */ /** * @brief Swaps two values. * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @return Nothing. */ template<typename _Tp> inline #if __cplusplus >= 201103L typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>, is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value>::type swap(_Tp& __a, _Tp& __b) noexcept(__and_<is_nothrow_move_constructible<_Tp>, is_nothrow_move_assignable<_Tp>>::value) #else void swap(_Tp& __a, _Tp& __b) #endif { // concept requirements __glibcxx_function_requires(_SGIAssignableConcept<_Tp>) _Tp __tmp = _GLIBCXX_MOVE(__a); __a = _GLIBCXX_MOVE(__b); __b = _GLIBCXX_MOVE(__tmp); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 809. std::swap should be overloaded for array types. /// Swap the contents of two arrays. template<typename _Tp, size_t _Nm> inline #if __cplusplus >= 201103L typename enable_if<__is_swappable<_Tp>::value>::type swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) noexcept(__is_nothrow_swappable<_Tp>::value) #else void swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) #endif { for (size_t __n = 0; __n < _Nm; ++__n) swap(__a[__n], __b[__n]); } /// @} group utilities _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _MOVE_H */ c++/8/bits/mask_array.h 0000644 00000016653 15146341150 0010541 0 ustar 00 // The template and inlines for the -*- C++ -*- mask_array class. // Copyright (C) 1997-2018 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/mask_array.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{valarray} */ // Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr> #ifndef _MASK_ARRAY_H #define _MASK_ARRAY_H 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup numeric_arrays * @{ */ /** * @brief Reference to selected subset of an array. * * A mask_array is a reference to the actual elements of an array specified * by a bitmask in the form of an array of bool. The way to get a * mask_array is to call operator[](valarray<bool>) on a valarray. The * returned mask_array then permits carrying operations out on the * referenced subset of elements in the original valarray. * * For example, if a mask_array is obtained using the array (false, true, * false, true) as an argument, the mask array has two elements referring * to array[1] and array[3] in the underlying array. * * @param Tp Element type. */ template <class _Tp> class mask_array { public: typedef _Tp value_type; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 253. valarray helper functions are almost entirely useless /// Copy constructor. Both slices refer to the same underlying array. mask_array (const mask_array&); /// Assignment operator. Assigns elements to corresponding elements /// of @a a. mask_array& operator=(const mask_array&); void operator=(const valarray<_Tp>&) const; /// Multiply slice elements by corresponding elements of @a v. void operator*=(const valarray<_Tp>&) const; /// Divide slice elements by corresponding elements of @a v. void operator/=(const valarray<_Tp>&) const; /// Modulo slice elements by corresponding elements of @a v. void operator%=(const valarray<_Tp>&) const; /// Add corresponding elements of @a v to slice elements. void operator+=(const valarray<_Tp>&) const; /// Subtract corresponding elements of @a v from slice elements. void operator-=(const valarray<_Tp>&) const; /// Logical xor slice elements with corresponding elements of @a v. void operator^=(const valarray<_Tp>&) const; /// Logical and slice elements with corresponding elements of @a v. void operator&=(const valarray<_Tp>&) const; /// Logical or slice elements with corresponding elements of @a v. void operator|=(const valarray<_Tp>&) const; /// Left shift slice elements by corresponding elements of @a v. void operator<<=(const valarray<_Tp>&) const; /// Right shift slice elements by corresponding elements of @a v. void operator>>=(const valarray<_Tp>&) const; /// Assign all slice elements to @a t. void operator=(const _Tp&) const; // ~mask_array (); template<class _Dom> void operator=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> void operator*=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> void operator/=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> void operator%=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> void operator+=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> void operator-=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> void operator^=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> void operator&=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> void operator|=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> void operator<<=(const _Expr<_Dom,_Tp>&) const; template<class _Dom> void operator>>=(const _Expr<_Dom,_Tp>&) const; private: mask_array(_Array<_Tp>, size_t, _Array<bool>); friend class valarray<_Tp>; const size_t _M_sz; const _Array<bool> _M_mask; const _Array<_Tp> _M_array; // not implemented mask_array(); }; template<typename _Tp> inline mask_array<_Tp>::mask_array(const mask_array<_Tp>& __a) : _M_sz(__a._M_sz), _M_mask(__a._M_mask), _M_array(__a._M_array) {} template<typename _Tp> inline mask_array<_Tp>::mask_array(_Array<_Tp> __a, size_t __s, _Array<bool> __m) : _M_sz(__s), _M_mask(__m), _M_array(__a) {} template<typename _Tp> inline mask_array<_Tp>& mask_array<_Tp>::operator=(const mask_array<_Tp>& __a) { std::__valarray_copy(__a._M_array, __a._M_mask, _M_sz, _M_array, _M_mask); return *this; } template<typename _Tp> inline void mask_array<_Tp>::operator=(const _Tp& __t) const { std::__valarray_fill(_M_array, _M_sz, _M_mask, __t); } template<typename _Tp> inline void mask_array<_Tp>::operator=(const valarray<_Tp>& __v) const { std::__valarray_copy(_Array<_Tp>(__v), __v.size(), _M_array, _M_mask); } template<typename _Tp> template<class _Ex> inline void mask_array<_Tp>::operator=(const _Expr<_Ex, _Tp>& __e) const { std::__valarray_copy(__e, __e.size(), _M_array, _M_mask); } #undef _DEFINE_VALARRAY_OPERATOR #define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \ template<typename _Tp> \ inline void \ mask_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \ { \ _Array_augmented_##_Name(_M_array, _M_mask, \ _Array<_Tp>(__v), __v.size()); \ } \ \ template<typename _Tp> \ template<class _Dom> \ inline void \ mask_array<_Tp>::operator _Op##=(const _Expr<_Dom, _Tp>& __e) const\ { \ _Array_augmented_##_Name(_M_array, _M_mask, __e, __e.size()); \ } _DEFINE_VALARRAY_OPERATOR(*, __multiplies) _DEFINE_VALARRAY_OPERATOR(/, __divides) _DEFINE_VALARRAY_OPERATOR(%, __modulus) _DEFINE_VALARRAY_OPERATOR(+, __plus) _DEFINE_VALARRAY_OPERATOR(-, __minus) _DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor) _DEFINE_VALARRAY_OPERATOR(&, __bitwise_and) _DEFINE_VALARRAY_OPERATOR(|, __bitwise_or) _DEFINE_VALARRAY_OPERATOR(<<, __shift_left) _DEFINE_VALARRAY_OPERATOR(>>, __shift_right) #undef _DEFINE_VALARRAY_OPERATOR // @} group numeric_arrays _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _MASK_ARRAY_H */ c++/8/bits/regex_automaton.h 0000644 00000024742 15146341150 0011607 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2013-2018 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/regex_automaton.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ // This macro defines the maximal state number a NFA can have. #ifndef _GLIBCXX_REGEX_STATE_LIMIT #define _GLIBCXX_REGEX_STATE_LIMIT 100000 #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { /** * @defgroup regex-detail Base and Implementation Classes * @ingroup regex * @{ */ typedef long _StateIdT; static const _StateIdT _S_invalid_state_id = -1; template<typename _CharT> using _Matcher = std::function<bool (_CharT)>; /// Operation codes that define the type of transitions within the base NFA /// that represents the regular expression. enum _Opcode : int { _S_opcode_unknown, _S_opcode_alternative, _S_opcode_repeat, _S_opcode_backref, _S_opcode_line_begin_assertion, _S_opcode_line_end_assertion, _S_opcode_word_boundary, _S_opcode_subexpr_lookahead, _S_opcode_subexpr_begin, _S_opcode_subexpr_end, _S_opcode_dummy, _S_opcode_match, _S_opcode_accept, }; struct _State_base { protected: _Opcode _M_opcode; // type of outgoing transition public: _StateIdT _M_next; // outgoing transition union // Since they are mutually exclusive. { size_t _M_subexpr; // for _S_opcode_subexpr_* size_t _M_backref_index; // for _S_opcode_backref struct { // for _S_opcode_alternative, _S_opcode_repeat and // _S_opcode_subexpr_lookahead _StateIdT _M_alt; // for _S_opcode_word_boundary or _S_opcode_subexpr_lookahead or // quantifiers (ungreedy if set true) bool _M_neg; }; // For _S_opcode_match __gnu_cxx::__aligned_membuf<_Matcher<char>> _M_matcher_storage; }; protected: explicit _State_base(_Opcode __opcode) : _M_opcode(__opcode), _M_next(_S_invalid_state_id) { } public: bool _M_has_alt() { return _M_opcode == _S_opcode_alternative || _M_opcode == _S_opcode_repeat || _M_opcode == _S_opcode_subexpr_lookahead; } #ifdef _GLIBCXX_DEBUG std::ostream& _M_print(std::ostream& ostr) const; // Prints graphviz dot commands for state. std::ostream& _M_dot(std::ostream& __ostr, _StateIdT __id) const; #endif }; template<typename _Char_type> struct _State : _State_base { typedef _Matcher<_Char_type> _MatcherT; static_assert(sizeof(_MatcherT) == sizeof(_Matcher<char>), "std::function<bool(T)> has the same size as " "std::function<bool(char)>"); static_assert(alignof(_MatcherT) == alignof(_Matcher<char>), "std::function<bool(T)> has the same alignment as " "std::function<bool(char)>"); explicit _State(_Opcode __opcode) : _State_base(__opcode) { if (_M_opcode() == _S_opcode_match) new (this->_M_matcher_storage._M_addr()) _MatcherT(); } _State(const _State& __rhs) : _State_base(__rhs) { if (__rhs._M_opcode() == _S_opcode_match) new (this->_M_matcher_storage._M_addr()) _MatcherT(__rhs._M_get_matcher()); } _State(_State&& __rhs) : _State_base(__rhs) { if (__rhs._M_opcode() == _S_opcode_match) new (this->_M_matcher_storage._M_addr()) _MatcherT(std::move(__rhs._M_get_matcher())); } _State& operator=(const _State&) = delete; ~_State() { if (_M_opcode() == _S_opcode_match) _M_get_matcher().~_MatcherT(); } // Since correct ctor and dtor rely on _M_opcode, it's better not to // change it over time. _Opcode _M_opcode() const { return _State_base::_M_opcode; } bool _M_matches(_Char_type __char) const { return _M_get_matcher()(__char); } _MatcherT& _M_get_matcher() { return *static_cast<_MatcherT*>(this->_M_matcher_storage._M_addr()); } const _MatcherT& _M_get_matcher() const { return *static_cast<const _MatcherT*>( this->_M_matcher_storage._M_addr()); } }; struct _NFA_base { typedef size_t _SizeT; typedef regex_constants::syntax_option_type _FlagT; explicit _NFA_base(_FlagT __f) : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0), _M_has_backref(false) { } _NFA_base(_NFA_base&&) = default; protected: ~_NFA_base() = default; public: _FlagT _M_options() const { return _M_flags; } _StateIdT _M_start() const { return _M_start_state; } _SizeT _M_sub_count() const { return _M_subexpr_count; } std::vector<size_t> _M_paren_stack; _FlagT _M_flags; _StateIdT _M_start_state; _SizeT _M_subexpr_count; bool _M_has_backref; }; template<typename _TraitsT> struct _NFA : _NFA_base, std::vector<_State<typename _TraitsT::char_type>> { typedef typename _TraitsT::char_type _Char_type; typedef _State<_Char_type> _StateT; typedef _Matcher<_Char_type> _MatcherT; _NFA(const typename _TraitsT::locale_type& __loc, _FlagT __flags) : _NFA_base(__flags) { _M_traits.imbue(__loc); } // for performance reasons _NFA objects should only be moved not copied _NFA(const _NFA&) = delete; _NFA(_NFA&&) = default; _StateIdT _M_insert_accept() { auto __ret = _M_insert_state(_StateT(_S_opcode_accept)); return __ret; } _StateIdT _M_insert_alt(_StateIdT __next, _StateIdT __alt, bool __neg __attribute__((__unused__))) { _StateT __tmp(_S_opcode_alternative); // It labels every quantifier to make greedy comparison easier in BFS // approach. __tmp._M_next = __next; __tmp._M_alt = __alt; return _M_insert_state(std::move(__tmp)); } _StateIdT _M_insert_repeat(_StateIdT __next, _StateIdT __alt, bool __neg) { _StateT __tmp(_S_opcode_repeat); // It labels every quantifier to make greedy comparison easier in BFS // approach. __tmp._M_next = __next; __tmp._M_alt = __alt; __tmp._M_neg = __neg; return _M_insert_state(std::move(__tmp)); } _StateIdT _M_insert_matcher(_MatcherT __m) { _StateT __tmp(_S_opcode_match); __tmp._M_get_matcher() = std::move(__m); return _M_insert_state(std::move(__tmp)); } _StateIdT _M_insert_subexpr_begin() { auto __id = this->_M_subexpr_count++; this->_M_paren_stack.push_back(__id); _StateT __tmp(_S_opcode_subexpr_begin); __tmp._M_subexpr = __id; return _M_insert_state(std::move(__tmp)); } _StateIdT _M_insert_subexpr_end() { _StateT __tmp(_S_opcode_subexpr_end); __tmp._M_subexpr = this->_M_paren_stack.back(); this->_M_paren_stack.pop_back(); return _M_insert_state(std::move(__tmp)); } _StateIdT _M_insert_backref(size_t __index); _StateIdT _M_insert_line_begin() { return _M_insert_state(_StateT(_S_opcode_line_begin_assertion)); } _StateIdT _M_insert_line_end() { return _M_insert_state(_StateT(_S_opcode_line_end_assertion)); } _StateIdT _M_insert_word_bound(bool __neg) { _StateT __tmp(_S_opcode_word_boundary); __tmp._M_neg = __neg; return _M_insert_state(std::move(__tmp)); } _StateIdT _M_insert_lookahead(_StateIdT __alt, bool __neg) { _StateT __tmp(_S_opcode_subexpr_lookahead); __tmp._M_alt = __alt; __tmp._M_neg = __neg; return _M_insert_state(std::move(__tmp)); } _StateIdT _M_insert_dummy() { return _M_insert_state(_StateT(_S_opcode_dummy)); } _StateIdT _M_insert_state(_StateT __s) { this->push_back(std::move(__s)); if (this->size() > _GLIBCXX_REGEX_STATE_LIMIT) __throw_regex_error( regex_constants::error_space, "Number of NFA states exceeds limit. Please use shorter regex " "string, or use smaller brace expression, or make " "_GLIBCXX_REGEX_STATE_LIMIT larger."); return this->size() - 1; } // Eliminate dummy node in this NFA to make it compact. void _M_eliminate_dummy(); #ifdef _GLIBCXX_DEBUG std::ostream& _M_dot(std::ostream& __ostr) const; #endif public: _TraitsT _M_traits; }; /// Describes a sequence of one or more %_State, its current start /// and end(s). This structure contains fragments of an NFA during /// construction. template<typename _TraitsT> class _StateSeq { public: typedef _NFA<_TraitsT> _RegexT; public: _StateSeq(_RegexT& __nfa, _StateIdT __s) : _M_nfa(__nfa), _M_start(__s), _M_end(__s) { } _StateSeq(_RegexT& __nfa, _StateIdT __s, _StateIdT __end) : _M_nfa(__nfa), _M_start(__s), _M_end(__end) { } // Append a state on *this and change *this to the new sequence. void _M_append(_StateIdT __id) { _M_nfa[_M_end]._M_next = __id; _M_end = __id; } // Append a sequence on *this and change *this to the new sequence. void _M_append(const _StateSeq& __s) { _M_nfa[_M_end]._M_next = __s._M_start; _M_end = __s._M_end; } // Clones an entire sequence. _StateSeq _M_clone(); public: _RegexT& _M_nfa; _StateIdT _M_start; _StateIdT _M_end; }; //@} regex-detail } // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #include <bits/regex_automaton.tcc> c++/8/bits/locale_facets.h 0000644 00000264250 15146341150 0011172 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 1997-2018 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/locale_facets.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.1 Locales // #ifndef _LOCALE_FACETS_H #define _LOCALE_FACETS_H 1 #pragma GCC system_header #include <cwctype> // For wctype_t #include <cctype> #include <bits/ctype_base.h> #include <iosfwd> #include <bits/ios_base.h> // For ios_base, ios_base::iostate #include <streambuf> #include <bits/cpp_type_traits.h> #include <ext/type_traits.h> #include <ext/numeric_traits.h> #include <bits/streambuf_iterator.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // NB: Don't instantiate required wchar_t facets if no wchar_t support. #ifdef _GLIBCXX_USE_WCHAR_T # define _GLIBCXX_NUM_FACETS 28 # define _GLIBCXX_NUM_CXX11_FACETS 16 #else # define _GLIBCXX_NUM_FACETS 14 # define _GLIBCXX_NUM_CXX11_FACETS 8 #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 # define _GLIBCXX_NUM_UNICODE_FACETS 2 #else # define _GLIBCXX_NUM_UNICODE_FACETS 0 #endif // Convert string to numeric value of type _Tp and store results. // NB: This is specialized for all required types, there is no // generic definition. template<typename _Tp> void __convert_to_v(const char*, _Tp&, ios_base::iostate&, const __c_locale&) throw(); // Explicit specializations for required types. template<> void __convert_to_v(const char*, float&, ios_base::iostate&, const __c_locale&) throw(); template<> void __convert_to_v(const char*, double&, ios_base::iostate&, const __c_locale&) throw(); template<> void __convert_to_v(const char*, long double&, ios_base::iostate&, const __c_locale&) throw(); // NB: __pad is a struct, rather than a function, so it can be // partially-specialized. template<typename _CharT, typename _Traits> struct __pad { static void _S_pad(ios_base& __io, _CharT __fill, _CharT* __news, const _CharT* __olds, streamsize __newlen, streamsize __oldlen); }; // Used by both numeric and monetary facets. // Inserts "group separator" characters into an array of characters. // It's recursive, one iteration per group. It moves the characters // in the buffer this way: "xxxx12345" -> "12,345xxx". Call this // only with __gsize != 0. template<typename _CharT> _CharT* __add_grouping(_CharT* __s, _CharT __sep, const char* __gbeg, size_t __gsize, const _CharT* __first, const _CharT* __last); // This template permits specializing facet output code for // ostreambuf_iterator. For ostreambuf_iterator, sputn is // significantly more efficient than incrementing iterators. template<typename _CharT> inline ostreambuf_iterator<_CharT> __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len) { __s._M_put(__ws, __len); return __s; } // This is the unspecialized form of the template. template<typename _CharT, typename _OutIter> inline _OutIter __write(_OutIter __s, const _CharT* __ws, int __len) { for (int __j = 0; __j < __len; __j++, ++__s) *__s = __ws[__j]; return __s; } // 22.2.1.1 Template class ctype // Include host and configuration specific ctype enums for ctype_base. /** * @brief Common base for ctype facet * * 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 _CharT> class __ctype_abstract_base : public locale::facet, public ctype_base { public: // Types: /// Typedef for the template parameter typedef _CharT char_type; /** * @brief Test char_type classification. * * This function finds a mask M for @a __c and compares it to * mask @a __m. It does so by returning the value of * ctype<char_type>::do_is(). * * @param __c The char_type to compare the mask of. * @param __m The mask to compare against. * @return (M & __m) != 0. */ bool is(mask __m, char_type __c) const { return this->do_is(__m, __c); } /** * @brief Return a mask array. * * This function finds the mask for each char_type in the range [lo,hi) * and successively writes it to vec. vec must have as many elements * as the char array. It does so by returning the value of * ctype<char_type>::do_is(). * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __vec Pointer to an array of mask storage. * @return @a __hi. */ const char_type* is(const char_type *__lo, const char_type *__hi, mask *__vec) const { return this->do_is(__lo, __hi, __vec); } /** * @brief Find char_type matching a mask * * This function searches for and returns the first char_type c in * [lo,hi) for which is(m,c) is true. It does so by returning * ctype<char_type>::do_scan_is(). * * @param __m The mask to compare against. * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return Pointer to matching char_type if found, else @a __hi. */ const char_type* scan_is(mask __m, const char_type* __lo, const char_type* __hi) const { return this->do_scan_is(__m, __lo, __hi); } /** * @brief Find char_type not matching a mask * * This function searches for and returns the first char_type c in * [lo,hi) for which is(m,c) is false. It does so by returning * ctype<char_type>::do_scan_not(). * * @param __m The mask to compare against. * @param __lo Pointer to first char in range. * @param __hi Pointer to end of range. * @return Pointer to non-matching char if found, else @a __hi. */ const char_type* scan_not(mask __m, const char_type* __lo, const char_type* __hi) const { return this->do_scan_not(__m, __lo, __hi); } /** * @brief Convert to uppercase. * * This function converts the argument to uppercase if possible. * If not possible (for example, '2'), returns the argument. It does * so by returning ctype<char_type>::do_toupper(). * * @param __c The char_type to convert. * @return The uppercase char_type if convertible, else @a __c. */ char_type toupper(char_type __c) const { return this->do_toupper(__c); } /** * @brief Convert array to uppercase. * * This function converts each char_type in the range [lo,hi) to * uppercase if possible. Other elements remain untouched. It does so * by returning ctype<char_type>:: do_toupper(lo, hi). * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return @a __hi. */ const char_type* toupper(char_type *__lo, const char_type* __hi) const { return this->do_toupper(__lo, __hi); } /** * @brief Convert to lowercase. * * This function converts the argument to lowercase if possible. If * not possible (for example, '2'), returns the argument. It does so * by returning ctype<char_type>::do_tolower(c). * * @param __c The char_type to convert. * @return The lowercase char_type if convertible, else @a __c. */ char_type tolower(char_type __c) const { return this->do_tolower(__c); } /** * @brief Convert array to lowercase. * * This function converts each char_type in the range [__lo,__hi) to * lowercase if possible. Other elements remain untouched. It does so * by returning ctype<char_type>:: do_tolower(__lo, __hi). * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return @a __hi. */ const char_type* tolower(char_type* __lo, const char_type* __hi) const { return this->do_tolower(__lo, __hi); } /** * @brief Widen char to char_type * * This function converts the char argument to char_type using the * simplest reasonable transformation. It does so by returning * ctype<char_type>::do_widen(c). * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __c The char to convert. * @return The converted char_type. */ char_type widen(char __c) const { return this->do_widen(__c); } /** * @brief Widen array to char_type * * This function converts each char in the input to char_type using the * simplest reasonable transformation. It does so by returning * ctype<char_type>::do_widen(c). * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __to Pointer to the destination array. * @return @a __hi. */ const char* widen(const char* __lo, const char* __hi, char_type* __to) const { return this->do_widen(__lo, __hi, __to); } /** * @brief Narrow char_type to char * * This function converts the char_type to char using the simplest * reasonable transformation. If the conversion fails, dfault is * returned instead. It does so by returning * ctype<char_type>::do_narrow(__c). * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __c The char_type to convert. * @param __dfault Char to return if conversion fails. * @return The converted char. */ char narrow(char_type __c, char __dfault) const { return this->do_narrow(__c, __dfault); } /** * @brief Narrow array to char array * * This function converts each char_type in the input to char using the * simplest reasonable transformation and writes the results to the * destination array. For any char_type in the input that cannot be * converted, @a dfault is used instead. It does so by returning * ctype<char_type>::do_narrow(__lo, __hi, __dfault, __to). * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __dfault Char to use if conversion fails. * @param __to Pointer to the destination array. * @return @a __hi. */ const char_type* narrow(const char_type* __lo, const char_type* __hi, char __dfault, char* __to) const { return this->do_narrow(__lo, __hi, __dfault, __to); } protected: explicit __ctype_abstract_base(size_t __refs = 0): facet(__refs) { } virtual ~__ctype_abstract_base() { } /** * @brief Test char_type classification. * * This function finds a mask M for @a c and compares it to mask @a m. * * do_is() is a hook for a derived facet to change the behavior of * classifying. do_is() must always return the same result for the * same input. * * @param __c The char_type to find the mask of. * @param __m The mask to compare against. * @return (M & __m) != 0. */ virtual bool do_is(mask __m, char_type __c) const = 0; /** * @brief Return a mask array. * * This function finds the mask for each char_type in the range [lo,hi) * and successively writes it to vec. vec must have as many elements * as the input. * * do_is() is a hook for a derived facet to change the behavior of * classifying. do_is() must always return the same result for the * same input. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __vec Pointer to an array of mask storage. * @return @a __hi. */ virtual const char_type* do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const = 0; /** * @brief Find char_type matching mask * * This function searches for and returns the first char_type c in * [__lo,__hi) for which is(__m,c) is true. * * do_scan_is() is a hook for a derived facet to change the behavior of * match searching. do_is() must always return the same result for the * same input. * * @param __m The mask to compare against. * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return Pointer to a matching char_type if found, else @a __hi. */ virtual const char_type* do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const = 0; /** * @brief Find char_type not matching mask * * This function searches for and returns a pointer to the first * char_type c of [lo,hi) for which is(m,c) is false. * * do_scan_is() is a hook for a derived facet to change the behavior of * match searching. do_is() must always return the same result for the * same input. * * @param __m The mask to compare against. * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return Pointer to a non-matching char_type if found, else @a __hi. */ virtual const char_type* do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const = 0; /** * @brief Convert to uppercase. * * This virtual function converts the char_type argument to uppercase * if possible. If not possible (for example, '2'), returns the * argument. * * do_toupper() is a hook for a derived facet to change the behavior of * uppercasing. do_toupper() must always return the same result for * the same input. * * @param __c The char_type to convert. * @return The uppercase char_type if convertible, else @a __c. */ virtual char_type do_toupper(char_type __c) const = 0; /** * @brief Convert array to uppercase. * * This virtual function converts each char_type in the range [__lo,__hi) * to uppercase if possible. Other elements remain untouched. * * do_toupper() is a hook for a derived facet to change the behavior of * uppercasing. do_toupper() must always return the same result for * the same input. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return @a __hi. */ virtual const char_type* do_toupper(char_type* __lo, const char_type* __hi) const = 0; /** * @brief Convert to lowercase. * * This virtual function converts the argument to lowercase if * possible. If not possible (for example, '2'), returns the argument. * * do_tolower() is a hook for a derived facet to change the behavior of * lowercasing. do_tolower() must always return the same result for * the same input. * * @param __c The char_type to convert. * @return The lowercase char_type if convertible, else @a __c. */ virtual char_type do_tolower(char_type __c) const = 0; /** * @brief Convert array to lowercase. * * This virtual function converts each char_type in the range [__lo,__hi) * to lowercase if possible. Other elements remain untouched. * * do_tolower() is a hook for a derived facet to change the behavior of * lowercasing. do_tolower() must always return the same result for * the same input. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return @a __hi. */ virtual const char_type* do_tolower(char_type* __lo, const char_type* __hi) const = 0; /** * @brief Widen char * * This virtual function converts the char to char_type using the * simplest reasonable transformation. * * do_widen() is a hook for a derived facet to change the behavior of * widening. do_widen() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __c The char to convert. * @return The converted char_type */ virtual char_type do_widen(char __c) const = 0; /** * @brief Widen char array * * This function converts each char in the input to char_type using the * simplest reasonable transformation. * * do_widen() is a hook for a derived facet to change the behavior of * widening. do_widen() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __lo Pointer to start range. * @param __hi Pointer to end of range. * @param __to Pointer to the destination array. * @return @a __hi. */ virtual const char* do_widen(const char* __lo, const char* __hi, char_type* __to) const = 0; /** * @brief Narrow char_type to char * * This virtual function converts the argument to char using the * simplest reasonable transformation. If the conversion fails, dfault * is returned instead. * * do_narrow() is a hook for a derived facet to change the behavior of * narrowing. do_narrow() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __c The char_type to convert. * @param __dfault Char to return if conversion fails. * @return The converted char. */ virtual char do_narrow(char_type __c, char __dfault) const = 0; /** * @brief Narrow char_type array to char * * This virtual function converts each char_type in the range * [__lo,__hi) to char using the simplest reasonable * transformation and writes the results to the destination * array. For any element in the input that cannot be * converted, @a __dfault is used instead. * * do_narrow() is a hook for a derived facet to change the behavior of * narrowing. do_narrow() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __dfault Char to use if conversion fails. * @param __to Pointer to the destination array. * @return @a __hi. */ virtual const char_type* do_narrow(const char_type* __lo, const char_type* __hi, char __dfault, char* __to) const = 0; }; /** * @brief Primary class template ctype facet. * @ingroup locales * * This template class defines classification and conversion functions for * character sets. It wraps cctype functionality. Ctype gets used by * streams for many I/O operations. * * This template provides the protected virtual functions the developer * will have to replace in a derived class or specialization to make a * working facet. The public functions that access them are defined in * __ctype_abstract_base, to allow for implementation flexibility. See * ctype<wchar_t> for an example. The functions are documented in * __ctype_abstract_base. * * Note: implementations are provided for all the protected virtual * functions, but will likely not be useful. */ template<typename _CharT> class ctype : public __ctype_abstract_base<_CharT> { public: // Types: typedef _CharT char_type; typedef typename __ctype_abstract_base<_CharT>::mask mask; /// The facet id for ctype<char_type> static locale::id id; explicit ctype(size_t __refs = 0) : __ctype_abstract_base<_CharT>(__refs) { } protected: virtual ~ctype(); virtual bool do_is(mask __m, char_type __c) const; virtual const char_type* do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; virtual const char_type* do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; virtual const char_type* do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const; virtual char_type do_toupper(char_type __c) const; virtual const char_type* do_toupper(char_type* __lo, const char_type* __hi) const; virtual char_type do_tolower(char_type __c) const; virtual const char_type* do_tolower(char_type* __lo, const char_type* __hi) const; virtual char_type do_widen(char __c) const; virtual const char* do_widen(const char* __lo, const char* __hi, char_type* __dest) const; virtual char do_narrow(char_type, char __dfault) const; virtual const char_type* do_narrow(const char_type* __lo, const char_type* __hi, char __dfault, char* __to) const; }; template<typename _CharT> locale::id ctype<_CharT>::id; /** * @brief The ctype<char> specialization. * @ingroup locales * * This class defines classification and conversion functions for * the char type. It gets used by char streams for many I/O * operations. The char specialization provides a number of * optimizations as well. */ template<> class ctype<char> : public locale::facet, public ctype_base { public: // Types: /// Typedef for the template parameter char. typedef char char_type; protected: // Data Members: __c_locale _M_c_locale_ctype; bool _M_del; __to_type _M_toupper; __to_type _M_tolower; const mask* _M_table; mutable char _M_widen_ok; mutable char _M_widen[1 + static_cast<unsigned char>(-1)]; mutable char _M_narrow[1 + static_cast<unsigned char>(-1)]; mutable char _M_narrow_ok; // 0 uninitialized, 1 init, // 2 memcpy can't be used public: /// The facet id for ctype<char> static locale::id id; /// The size of the mask table. It is SCHAR_MAX + 1. static const size_t table_size = 1 + static_cast<unsigned char>(-1); /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __table If non-zero, table is used as the per-char mask. * Else classic_table() is used. * @param __del If true, passes ownership of table to this facet. * @param __refs Passed to the base facet class. */ explicit ctype(const mask* __table = 0, bool __del = false, size_t __refs = 0); /** * @brief Constructor performs static initialization. * * This constructor is used to construct the initial C locale facet. * * @param __cloc Handle to C locale data. * @param __table If non-zero, table is used as the per-char mask. * @param __del If true, passes ownership of table to this facet. * @param __refs Passed to the base facet class. */ explicit ctype(__c_locale __cloc, const mask* __table = 0, bool __del = false, size_t __refs = 0); /** * @brief Test char classification. * * This function compares the mask table[c] to @a __m. * * @param __c The char to compare the mask of. * @param __m The mask to compare against. * @return True if __m & table[__c] is true, false otherwise. */ inline bool is(mask __m, char __c) const; /** * @brief Return a mask array. * * This function finds the mask for each char in the range [lo, hi) and * successively writes it to vec. vec must have as many elements as * the char array. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __vec Pointer to an array of mask storage. * @return @a __hi. */ inline const char* is(const char* __lo, const char* __hi, mask* __vec) const; /** * @brief Find char matching a mask * * This function searches for and returns the first char in [lo,hi) for * which is(m,char) is true. * * @param __m The mask to compare against. * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return Pointer to a matching char if found, else @a __hi. */ inline const char* scan_is(mask __m, const char* __lo, const char* __hi) const; /** * @brief Find char not matching a mask * * This function searches for and returns a pointer to the first char * in [__lo,__hi) for which is(m,char) is false. * * @param __m The mask to compare against. * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return Pointer to a non-matching char if found, else @a __hi. */ inline const char* scan_not(mask __m, const char* __lo, const char* __hi) const; /** * @brief Convert to uppercase. * * This function converts the char argument to uppercase if possible. * If not possible (for example, '2'), returns the argument. * * toupper() acts as if it returns ctype<char>::do_toupper(c). * do_toupper() must always return the same result for the same input. * * @param __c The char to convert. * @return The uppercase char if convertible, else @a __c. */ char_type toupper(char_type __c) const { return this->do_toupper(__c); } /** * @brief Convert array to uppercase. * * This function converts each char in the range [__lo,__hi) to uppercase * if possible. Other chars remain untouched. * * toupper() acts as if it returns ctype<char>:: do_toupper(__lo, __hi). * do_toupper() must always return the same result for the same input. * * @param __lo Pointer to first char in range. * @param __hi Pointer to end of range. * @return @a __hi. */ const char_type* toupper(char_type *__lo, const char_type* __hi) const { return this->do_toupper(__lo, __hi); } /** * @brief Convert to lowercase. * * This function converts the char argument to lowercase if possible. * If not possible (for example, '2'), returns the argument. * * tolower() acts as if it returns ctype<char>::do_tolower(__c). * do_tolower() must always return the same result for the same input. * * @param __c The char to convert. * @return The lowercase char if convertible, else @a __c. */ char_type tolower(char_type __c) const { return this->do_tolower(__c); } /** * @brief Convert array to lowercase. * * This function converts each char in the range [lo,hi) to lowercase * if possible. Other chars remain untouched. * * tolower() acts as if it returns ctype<char>:: do_tolower(__lo, __hi). * do_tolower() must always return the same result for the same input. * * @param __lo Pointer to first char in range. * @param __hi Pointer to end of range. * @return @a __hi. */ const char_type* tolower(char_type* __lo, const char_type* __hi) const { return this->do_tolower(__lo, __hi); } /** * @brief Widen char * * This function converts the char to char_type using the simplest * reasonable transformation. For an underived ctype<char> facet, the * argument will be returned unchanged. * * This function works as if it returns ctype<char>::do_widen(c). * do_widen() must always return the same result for the same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __c The char to convert. * @return The converted character. */ char_type widen(char __c) const { if (_M_widen_ok) return _M_widen[static_cast<unsigned char>(__c)]; this->_M_widen_init(); return this->do_widen(__c); } /** * @brief Widen char array * * This function converts each char in the input to char using the * simplest reasonable transformation. For an underived ctype<char> * facet, the argument will be copied unchanged. * * This function works as if it returns ctype<char>::do_widen(c). * do_widen() must always return the same result for the same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __lo Pointer to first char in range. * @param __hi Pointer to end of range. * @param __to Pointer to the destination array. * @return @a __hi. */ const char* widen(const char* __lo, const char* __hi, char_type* __to) const { if (_M_widen_ok == 1) { if (__builtin_expect(__hi != __lo, true)) __builtin_memcpy(__to, __lo, __hi - __lo); return __hi; } if (!_M_widen_ok) _M_widen_init(); return this->do_widen(__lo, __hi, __to); } /** * @brief Narrow char * * This function converts the char to char using the simplest * reasonable transformation. If the conversion fails, dfault is * returned instead. For an underived ctype<char> facet, @a c * will be returned unchanged. * * This function works as if it returns ctype<char>::do_narrow(c). * do_narrow() must always return the same result for the same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __c The char to convert. * @param __dfault Char to return if conversion fails. * @return The converted character. */ char narrow(char_type __c, char __dfault) const { if (_M_narrow[static_cast<unsigned char>(__c)]) return _M_narrow[static_cast<unsigned char>(__c)]; const char __t = do_narrow(__c, __dfault); if (__t != __dfault) _M_narrow[static_cast<unsigned char>(__c)] = __t; return __t; } /** * @brief Narrow char array * * This function converts each char in the input to char using the * simplest reasonable transformation and writes the results to the * destination array. For any char in the input that cannot be * converted, @a dfault is used instead. For an underived ctype<char> * facet, the argument will be copied unchanged. * * This function works as if it returns ctype<char>::do_narrow(lo, hi, * dfault, to). do_narrow() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __dfault Char to use if conversion fails. * @param __to Pointer to the destination array. * @return @a __hi. */ const char_type* narrow(const char_type* __lo, const char_type* __hi, char __dfault, char* __to) const { if (__builtin_expect(_M_narrow_ok == 1, true)) { if (__builtin_expect(__hi != __lo, true)) __builtin_memcpy(__to, __lo, __hi - __lo); return __hi; } if (!_M_narrow_ok) _M_narrow_init(); return this->do_narrow(__lo, __hi, __dfault, __to); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 695. ctype<char>::classic_table() not accessible. /// Returns a pointer to the mask table provided to the constructor, or /// the default from classic_table() if none was provided. const mask* table() const throw() { return _M_table; } /// Returns a pointer to the C locale mask table. static const mask* classic_table() throw(); protected: /** * @brief Destructor. * * This function deletes table() if @a del was true in the * constructor. */ virtual ~ctype(); /** * @brief Convert to uppercase. * * This virtual function converts the char argument to uppercase if * possible. If not possible (for example, '2'), returns the argument. * * do_toupper() is a hook for a derived facet to change the behavior of * uppercasing. do_toupper() must always return the same result for * the same input. * * @param __c The char to convert. * @return The uppercase char if convertible, else @a __c. */ virtual char_type do_toupper(char_type __c) const; /** * @brief Convert array to uppercase. * * This virtual function converts each char in the range [lo,hi) to * uppercase if possible. Other chars remain untouched. * * do_toupper() is a hook for a derived facet to change the behavior of * uppercasing. do_toupper() must always return the same result for * the same input. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return @a __hi. */ virtual const char_type* do_toupper(char_type* __lo, const char_type* __hi) const; /** * @brief Convert to lowercase. * * This virtual function converts the char argument to lowercase if * possible. If not possible (for example, '2'), returns the argument. * * do_tolower() is a hook for a derived facet to change the behavior of * lowercasing. do_tolower() must always return the same result for * the same input. * * @param __c The char to convert. * @return The lowercase char if convertible, else @a __c. */ virtual char_type do_tolower(char_type __c) const; /** * @brief Convert array to lowercase. * * This virtual function converts each char in the range [lo,hi) to * lowercase if possible. Other chars remain untouched. * * do_tolower() is a hook for a derived facet to change the behavior of * lowercasing. do_tolower() must always return the same result for * the same input. * * @param __lo Pointer to first char in range. * @param __hi Pointer to end of range. * @return @a __hi. */ virtual const char_type* do_tolower(char_type* __lo, const char_type* __hi) const; /** * @brief Widen char * * This virtual function converts the char to char using the simplest * reasonable transformation. For an underived ctype<char> facet, the * argument will be returned unchanged. * * do_widen() is a hook for a derived facet to change the behavior of * widening. do_widen() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __c The char to convert. * @return The converted character. */ virtual char_type do_widen(char __c) const { return __c; } /** * @brief Widen char array * * This function converts each char in the range [lo,hi) to char using * the simplest reasonable transformation. For an underived * ctype<char> facet, the argument will be copied unchanged. * * do_widen() is a hook for a derived facet to change the behavior of * widening. do_widen() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __to Pointer to the destination array. * @return @a __hi. */ virtual const char* do_widen(const char* __lo, const char* __hi, char_type* __to) const { if (__builtin_expect(__hi != __lo, true)) __builtin_memcpy(__to, __lo, __hi - __lo); return __hi; } /** * @brief Narrow char * * This virtual function converts the char to char using the simplest * reasonable transformation. If the conversion fails, dfault is * returned instead. For an underived ctype<char> facet, @a c will be * returned unchanged. * * do_narrow() is a hook for a derived facet to change the behavior of * narrowing. do_narrow() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __c The char to convert. * @param __dfault Char to return if conversion fails. * @return The converted char. */ virtual char do_narrow(char_type __c, char __dfault __attribute__((__unused__))) const { return __c; } /** * @brief Narrow char array to char array * * This virtual function converts each char in the range [lo,hi) to * char using the simplest reasonable transformation and writes the * results to the destination array. For any char in the input that * cannot be converted, @a dfault is used instead. For an underived * ctype<char> facet, the argument will be copied unchanged. * * do_narrow() is a hook for a derived facet to change the behavior of * narrowing. do_narrow() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __dfault Char to use if conversion fails. * @param __to Pointer to the destination array. * @return @a __hi. */ virtual const char_type* do_narrow(const char_type* __lo, const char_type* __hi, char __dfault __attribute__((__unused__)), char* __to) const { if (__builtin_expect(__hi != __lo, true)) __builtin_memcpy(__to, __lo, __hi - __lo); return __hi; } private: void _M_narrow_init() const; void _M_widen_init() const; }; #ifdef _GLIBCXX_USE_WCHAR_T /** * @brief The ctype<wchar_t> specialization. * @ingroup locales * * This class defines classification and conversion functions for the * wchar_t type. It gets used by wchar_t streams for many I/O operations. * The wchar_t specialization provides a number of optimizations as well. * * ctype<wchar_t> inherits its public methods from * __ctype_abstract_base<wchar_t>. */ template<> class ctype<wchar_t> : public __ctype_abstract_base<wchar_t> { public: // Types: /// Typedef for the template parameter wchar_t. typedef wchar_t char_type; typedef wctype_t __wmask_type; protected: __c_locale _M_c_locale_ctype; // Pre-computed narrowed and widened chars. bool _M_narrow_ok; char _M_narrow[128]; wint_t _M_widen[1 + static_cast<unsigned char>(-1)]; // Pre-computed elements for do_is. mask _M_bit[16]; __wmask_type _M_wmask[16]; public: // Data Members: /// The facet id for ctype<wchar_t> static locale::id id; /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __refs Passed to the base facet class. */ explicit ctype(size_t __refs = 0); /** * @brief Constructor performs static initialization. * * This constructor is used to construct the initial C locale facet. * * @param __cloc Handle to C locale data. * @param __refs Passed to the base facet class. */ explicit ctype(__c_locale __cloc, size_t __refs = 0); protected: __wmask_type _M_convert_to_wmask(const mask __m) const throw(); /// Destructor virtual ~ctype(); /** * @brief Test wchar_t classification. * * This function finds a mask M for @a c and compares it to mask @a m. * * do_is() is a hook for a derived facet to change the behavior of * classifying. do_is() must always return the same result for the * same input. * * @param __c The wchar_t to find the mask of. * @param __m The mask to compare against. * @return (M & __m) != 0. */ virtual bool do_is(mask __m, char_type __c) const; /** * @brief Return a mask array. * * This function finds the mask for each wchar_t in the range [lo,hi) * and successively writes it to vec. vec must have as many elements * as the input. * * do_is() is a hook for a derived facet to change the behavior of * classifying. do_is() must always return the same result for the * same input. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __vec Pointer to an array of mask storage. * @return @a __hi. */ virtual const char_type* do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const; /** * @brief Find wchar_t matching mask * * This function searches for and returns the first wchar_t c in * [__lo,__hi) for which is(__m,c) is true. * * do_scan_is() is a hook for a derived facet to change the behavior of * match searching. do_is() must always return the same result for the * same input. * * @param __m The mask to compare against. * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return Pointer to a matching wchar_t if found, else @a __hi. */ virtual const char_type* do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const; /** * @brief Find wchar_t not matching mask * * This function searches for and returns a pointer to the first * wchar_t c of [__lo,__hi) for which is(__m,c) is false. * * do_scan_is() is a hook for a derived facet to change the behavior of * match searching. do_is() must always return the same result for the * same input. * * @param __m The mask to compare against. * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return Pointer to a non-matching wchar_t if found, else @a __hi. */ virtual const char_type* do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const; /** * @brief Convert to uppercase. * * This virtual function converts the wchar_t argument to uppercase if * possible. If not possible (for example, '2'), returns the argument. * * do_toupper() is a hook for a derived facet to change the behavior of * uppercasing. do_toupper() must always return the same result for * the same input. * * @param __c The wchar_t to convert. * @return The uppercase wchar_t if convertible, else @a __c. */ virtual char_type do_toupper(char_type __c) const; /** * @brief Convert array to uppercase. * * This virtual function converts each wchar_t in the range [lo,hi) to * uppercase if possible. Other elements remain untouched. * * do_toupper() is a hook for a derived facet to change the behavior of * uppercasing. do_toupper() must always return the same result for * the same input. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return @a __hi. */ virtual const char_type* do_toupper(char_type* __lo, const char_type* __hi) const; /** * @brief Convert to lowercase. * * This virtual function converts the argument to lowercase if * possible. If not possible (for example, '2'), returns the argument. * * do_tolower() is a hook for a derived facet to change the behavior of * lowercasing. do_tolower() must always return the same result for * the same input. * * @param __c The wchar_t to convert. * @return The lowercase wchar_t if convertible, else @a __c. */ virtual char_type do_tolower(char_type __c) const; /** * @brief Convert array to lowercase. * * This virtual function converts each wchar_t in the range [lo,hi) to * lowercase if possible. Other elements remain untouched. * * do_tolower() is a hook for a derived facet to change the behavior of * lowercasing. do_tolower() must always return the same result for * the same input. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @return @a __hi. */ virtual const char_type* do_tolower(char_type* __lo, const char_type* __hi) const; /** * @brief Widen char to wchar_t * * This virtual function converts the char to wchar_t using the * simplest reasonable transformation. For an underived ctype<wchar_t> * facet, the argument will be cast to wchar_t. * * do_widen() is a hook for a derived facet to change the behavior of * widening. do_widen() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __c The char to convert. * @return The converted wchar_t. */ virtual char_type do_widen(char __c) const; /** * @brief Widen char array to wchar_t array * * This function converts each char in the input to wchar_t using the * simplest reasonable transformation. For an underived ctype<wchar_t> * facet, the argument will be copied, casting each element to wchar_t. * * do_widen() is a hook for a derived facet to change the behavior of * widening. do_widen() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __lo Pointer to start range. * @param __hi Pointer to end of range. * @param __to Pointer to the destination array. * @return @a __hi. */ virtual const char* do_widen(const char* __lo, const char* __hi, char_type* __to) const; /** * @brief Narrow wchar_t to char * * This virtual function converts the argument to char using * the simplest reasonable transformation. If the conversion * fails, dfault is returned instead. For an underived * ctype<wchar_t> facet, @a c will be cast to char and * returned. * * do_narrow() is a hook for a derived facet to change the * behavior of narrowing. do_narrow() must always return the * same result for the same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __c The wchar_t to convert. * @param __dfault Char to return if conversion fails. * @return The converted char. */ virtual char do_narrow(char_type __c, char __dfault) const; /** * @brief Narrow wchar_t array to char array * * This virtual function converts each wchar_t in the range [lo,hi) to * char using the simplest reasonable transformation and writes the * results to the destination array. For any wchar_t in the input that * cannot be converted, @a dfault is used instead. For an underived * ctype<wchar_t> facet, the argument will be copied, casting each * element to char. * * do_narrow() is a hook for a derived facet to change the behavior of * narrowing. do_narrow() must always return the same result for the * same input. * * Note: this is not what you want for codepage conversions. See * codecvt for that. * * @param __lo Pointer to start of range. * @param __hi Pointer to end of range. * @param __dfault Char to use if conversion fails. * @param __to Pointer to the destination array. * @return @a __hi. */ virtual const char_type* do_narrow(const char_type* __lo, const char_type* __hi, char __dfault, char* __to) const; // For use at construction time only. void _M_initialize_ctype() throw(); }; #endif //_GLIBCXX_USE_WCHAR_T /// class ctype_byname [22.2.1.2]. template<typename _CharT> class ctype_byname : public ctype<_CharT> { public: typedef typename ctype<_CharT>::mask mask; explicit ctype_byname(const char* __s, size_t __refs = 0); #if __cplusplus >= 201103L explicit ctype_byname(const string& __s, size_t __refs = 0) : ctype_byname(__s.c_str(), __refs) { } #endif protected: virtual ~ctype_byname() { } }; /// 22.2.1.4 Class ctype_byname specializations. template<> class ctype_byname<char> : public ctype<char> { public: explicit ctype_byname(const char* __s, size_t __refs = 0); #if __cplusplus >= 201103L explicit ctype_byname(const string& __s, size_t __refs = 0); #endif protected: virtual ~ctype_byname(); }; #ifdef _GLIBCXX_USE_WCHAR_T template<> class ctype_byname<wchar_t> : public ctype<wchar_t> { public: explicit ctype_byname(const char* __s, size_t __refs = 0); #if __cplusplus >= 201103L explicit ctype_byname(const string& __s, size_t __refs = 0); #endif protected: virtual ~ctype_byname(); }; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace // Include host and configuration specific ctype inlines. #include <bits/ctype_inline.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // 22.2.2 The numeric category. class __num_base { public: // NB: Code depends on the order of _S_atoms_out elements. // Below are the indices into _S_atoms_out. enum { _S_ominus, _S_oplus, _S_ox, _S_oX, _S_odigits, _S_odigits_end = _S_odigits + 16, _S_oudigits = _S_odigits_end, _S_oudigits_end = _S_oudigits + 16, _S_oe = _S_odigits + 14, // For scientific notation, 'e' _S_oE = _S_oudigits + 14, // For scientific notation, 'E' _S_oend = _S_oudigits_end }; // A list of valid numeric literals for output. This array // contains chars that will be passed through the current locale's // ctype<_CharT>.widen() and then used to render numbers. // For the standard "C" locale, this is // "-+xX0123456789abcdef0123456789ABCDEF". static const char* _S_atoms_out; // String literal of acceptable (narrow) input, for num_get. // "-+xX0123456789abcdefABCDEF" static const char* _S_atoms_in; enum { _S_iminus, _S_iplus, _S_ix, _S_iX, _S_izero, _S_ie = _S_izero + 14, _S_iE = _S_izero + 20, _S_iend = 26 }; // num_put // Construct and return valid scanf format for floating point types. static void _S_format_float(const ios_base& __io, char* __fptr, char __mod) throw(); }; template<typename _CharT> struct __numpunct_cache : public locale::facet { const char* _M_grouping; size_t _M_grouping_size; bool _M_use_grouping; const _CharT* _M_truename; size_t _M_truename_size; const _CharT* _M_falsename; size_t _M_falsename_size; _CharT _M_decimal_point; _CharT _M_thousands_sep; // A list of valid numeric literals for output: in the standard // "C" locale, this is "-+xX0123456789abcdef0123456789ABCDEF". // This array contains the chars after having been passed // through the current locale's ctype<_CharT>.widen(). _CharT _M_atoms_out[__num_base::_S_oend]; // A list of valid numeric literals for input: in the standard // "C" locale, this is "-+xX0123456789abcdefABCDEF" // This array contains the chars after having been passed // through the current locale's ctype<_CharT>.widen(). _CharT _M_atoms_in[__num_base::_S_iend]; bool _M_allocated; __numpunct_cache(size_t __refs = 0) : facet(__refs), _M_grouping(0), _M_grouping_size(0), _M_use_grouping(false), _M_truename(0), _M_truename_size(0), _M_falsename(0), _M_falsename_size(0), _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()), _M_allocated(false) { } ~__numpunct_cache(); void _M_cache(const locale& __loc); private: __numpunct_cache& operator=(const __numpunct_cache&); explicit __numpunct_cache(const __numpunct_cache&); }; template<typename _CharT> __numpunct_cache<_CharT>::~__numpunct_cache() { if (_M_allocated) { delete [] _M_grouping; delete [] _M_truename; delete [] _M_falsename; } } _GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * @brief Primary class template numpunct. * @ingroup locales * * This facet stores several pieces of information related to printing and * scanning numbers, such as the decimal point character. It takes a * template parameter specifying the char type. The numpunct facet is * used by streams for many I/O operations involving numbers. * * The numpunct template uses protected virtual functions to provide the * actual results. The public accessors forward the call to the virtual * functions. These virtual functions are hooks for developers to * implement the behavior they require from a numpunct facet. */ template<typename _CharT> class numpunct : public locale::facet { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef basic_string<_CharT> string_type; //@} typedef __numpunct_cache<_CharT> __cache_type; protected: __cache_type* _M_data; public: /// Numpunct facet id. static locale::id id; /** * @brief Numpunct constructor. * * @param __refs Refcount to pass to the base class. */ explicit numpunct(size_t __refs = 0) : facet(__refs), _M_data(0) { _M_initialize_numpunct(); } /** * @brief Internal constructor. Not for general use. * * This is a constructor for use by the library itself to set up the * predefined locale facets. * * @param __cache __numpunct_cache object. * @param __refs Refcount to pass to the base class. */ explicit numpunct(__cache_type* __cache, size_t __refs = 0) : facet(__refs), _M_data(__cache) { _M_initialize_numpunct(); } /** * @brief Internal constructor. Not for general use. * * This is a constructor for use by the library itself to set up new * locales. * * @param __cloc The C locale. * @param __refs Refcount to pass to the base class. */ explicit numpunct(__c_locale __cloc, size_t __refs = 0) : facet(__refs), _M_data(0) { _M_initialize_numpunct(__cloc); } /** * @brief Return decimal point character. * * This function returns a char_type to use as a decimal point. It * does so by returning returning * numpunct<char_type>::do_decimal_point(). * * @return @a char_type representing a decimal point. */ char_type decimal_point() const { return this->do_decimal_point(); } /** * @brief Return thousands separator character. * * This function returns a char_type to use as a thousands * separator. It does so by returning returning * numpunct<char_type>::do_thousands_sep(). * * @return char_type representing a thousands separator. */ char_type thousands_sep() const { return this->do_thousands_sep(); } /** * @brief Return grouping specification. * * This function returns a string representing groupings for the * integer part of a number. Groupings indicate where thousands * separators should be inserted in the integer part of a number. * * Each char in the return string is interpret as an integer * rather than a character. These numbers represent the number * of digits in a group. The first char in the string * represents the number of digits in the least significant * group. If a char is negative, it indicates an unlimited * number of digits for the group. If more chars from the * string are required to group a number, the last char is used * repeatedly. * * For example, if the grouping() returns "\003\002" and is * applied to the number 123456789, this corresponds to * 12,34,56,789. Note that if the string was "32", this would * put more than 50 digits into the least significant group if * the character set is ASCII. * * The string is returned by calling * numpunct<char_type>::do_grouping(). * * @return string representing grouping specification. */ string grouping() const { return this->do_grouping(); } /** * @brief Return string representation of bool true. * * This function returns a string_type containing the text * representation for true bool variables. It does so by calling * numpunct<char_type>::do_truename(). * * @return string_type representing printed form of true. */ string_type truename() const { return this->do_truename(); } /** * @brief Return string representation of bool false. * * This function returns a string_type containing the text * representation for false bool variables. It does so by calling * numpunct<char_type>::do_falsename(). * * @return string_type representing printed form of false. */ string_type falsename() const { return this->do_falsename(); } protected: /// Destructor. virtual ~numpunct(); /** * @brief Return decimal point character. * * Returns a char_type to use as a decimal point. This function is a * hook for derived classes to change the value returned. * * @return @a char_type representing a decimal point. */ virtual char_type do_decimal_point() const { return _M_data->_M_decimal_point; } /** * @brief Return thousands separator character. * * Returns a char_type to use as a thousands separator. This function * is a hook for derived classes to change the value returned. * * @return @a char_type representing a thousands separator. */ virtual char_type do_thousands_sep() const { return _M_data->_M_thousands_sep; } /** * @brief Return grouping specification. * * Returns a string representing groupings for the integer part of a * number. This function is a hook for derived classes to change the * value returned. @see grouping() for details. * * @return String representing grouping specification. */ virtual string do_grouping() const { return _M_data->_M_grouping; } /** * @brief Return string representation of bool true. * * Returns a string_type containing the text representation for true * bool variables. This function is a hook for derived classes to * change the value returned. * * @return string_type representing printed form of true. */ virtual string_type do_truename() const { return _M_data->_M_truename; } /** * @brief Return string representation of bool false. * * Returns a string_type containing the text representation for false * bool variables. This function is a hook for derived classes to * change the value returned. * * @return string_type representing printed form of false. */ virtual string_type do_falsename() const { return _M_data->_M_falsename; } // For use at construction time only. void _M_initialize_numpunct(__c_locale __cloc = 0); }; template<typename _CharT> locale::id numpunct<_CharT>::id; template<> numpunct<char>::~numpunct(); template<> void numpunct<char>::_M_initialize_numpunct(__c_locale __cloc); #ifdef _GLIBCXX_USE_WCHAR_T template<> numpunct<wchar_t>::~numpunct(); template<> void numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc); #endif /// class numpunct_byname [22.2.3.2]. template<typename _CharT> class numpunct_byname : public numpunct<_CharT> { public: typedef _CharT char_type; typedef basic_string<_CharT> string_type; explicit numpunct_byname(const char* __s, size_t __refs = 0) : numpunct<_CharT>(__refs) { if (__builtin_strcmp(__s, "C") != 0 && __builtin_strcmp(__s, "POSIX") != 0) { __c_locale __tmp; this->_S_create_c_locale(__tmp, __s); this->_M_initialize_numpunct(__tmp); this->_S_destroy_c_locale(__tmp); } } #if __cplusplus >= 201103L explicit numpunct_byname(const string& __s, size_t __refs = 0) : numpunct_byname(__s.c_str(), __refs) { } #endif protected: virtual ~numpunct_byname() { } }; _GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_BEGIN_NAMESPACE_LDBL /** * @brief Primary class template num_get. * @ingroup locales * * This facet encapsulates the code to parse and return a number * from a string. It is used by the istream numeric extraction * operators. * * The num_get template uses protected virtual functions to provide the * actual results. The public accessors forward the call to the virtual * functions. These virtual functions are hooks for developers to * implement the behavior they require from the num_get facet. */ template<typename _CharT, typename _InIter> class num_get : public locale::facet { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef _InIter iter_type; //@} /// Numpunct facet id. static locale::id id; /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __refs Passed to the base facet class. */ explicit num_get(size_t __refs = 0) : facet(__refs) { } /** * @brief Numeric parsing. * * Parses the input stream into the bool @a v. It does so by calling * num_get::do_get(). * * If ios_base::boolalpha is set, attempts to read * ctype<CharT>::truename() or ctype<CharT>::falsename(). Sets * @a v to true or false if successful. Sets err to * ios_base::failbit if reading the string fails. Sets err to * ios_base::eofbit if the stream is emptied. * * If ios_base::boolalpha is not set, proceeds as with reading a long, * except if the value is 1, sets @a v to true, if the value is 0, sets * @a v to false, and otherwise set err to ios_base::failbit. * * @param __in Start of input stream. * @param __end End of input stream. * @param __io Source of locale and flags. * @param __err Error flags to set. * @param __v Value to format and insert. * @return Iterator after reading. */ iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, bool& __v) const { return this->do_get(__in, __end, __io, __err, __v); } //@{ /** * @brief Numeric parsing. * * Parses the input stream into the integral variable @a v. It does so * by calling num_get::do_get(). * * Parsing is affected by the flag settings in @a io. * * The basic parse is affected by the value of io.flags() & * ios_base::basefield. If equal to ios_base::oct, parses like the * scanf %o specifier. Else if equal to ios_base::hex, parses like %X * specifier. Else if basefield equal to 0, parses like the %i * specifier. Otherwise, parses like %d for signed and %u for unsigned * types. The matching type length modifier is also used. * * Digit grouping is interpreted according to * numpunct::grouping() and numpunct::thousands_sep(). If the * pattern of digit groups isn't consistent, sets err to * ios_base::failbit. * * If parsing the string yields a valid value for @a v, @a v is set. * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. * Sets err to ios_base::eofbit if the stream is emptied. * * @param __in Start of input stream. * @param __end End of input stream. * @param __io Source of locale and flags. * @param __err Error flags to set. * @param __v Value to format and insert. * @return Iterator after reading. */ iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned short& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned int& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } #ifdef _GLIBCXX_USE_LONG_LONG iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, long long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long long& __v) const { return this->do_get(__in, __end, __io, __err, __v); } #endif //@} //@{ /** * @brief Numeric parsing. * * Parses the input stream into the integral variable @a v. It does so * by calling num_get::do_get(). * * The input characters are parsed like the scanf %g specifier. The * matching type length modifier is also used. * * The decimal point character used is numpunct::decimal_point(). * Digit grouping is interpreted according to * numpunct::grouping() and numpunct::thousands_sep(). If the * pattern of digit groups isn't consistent, sets err to * ios_base::failbit. * * If parsing the string yields a valid value for @a v, @a v is set. * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. * Sets err to ios_base::eofbit if the stream is emptied. * * @param __in Start of input stream. * @param __end End of input stream. * @param __io Source of locale and flags. * @param __err Error flags to set. * @param __v Value to format and insert. * @return Iterator after reading. */ iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, float& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, double& __v) const { return this->do_get(__in, __end, __io, __err, __v); } iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, long double& __v) const { return this->do_get(__in, __end, __io, __err, __v); } //@} /** * @brief Numeric parsing. * * Parses the input stream into the pointer variable @a v. It does so * by calling num_get::do_get(). * * The input characters are parsed like the scanf %p specifier. * * Digit grouping is interpreted according to * numpunct::grouping() and numpunct::thousands_sep(). If the * pattern of digit groups isn't consistent, sets err to * ios_base::failbit. * * Note that the digit grouping effect for pointers is a bit ambiguous * in the standard and shouldn't be relied on. See DR 344. * * If parsing the string yields a valid value for @a v, @a v is set. * Otherwise, sets err to ios_base::failbit and leaves @a v unaltered. * Sets err to ios_base::eofbit if the stream is emptied. * * @param __in Start of input stream. * @param __end End of input stream. * @param __io Source of locale and flags. * @param __err Error flags to set. * @param __v Value to format and insert. * @return Iterator after reading. */ iter_type get(iter_type __in, iter_type __end, ios_base& __io, ios_base::iostate& __err, void*& __v) const { return this->do_get(__in, __end, __io, __err, __v); } protected: /// Destructor. virtual ~num_get() { } _GLIBCXX_DEFAULT_ABI_TAG iter_type _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, string&) const; template<typename _ValueT> _GLIBCXX_DEFAULT_ABI_TAG iter_type _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, _ValueT&) const; template<typename _CharT2> typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, int>::__type _M_find(const _CharT2*, size_t __len, _CharT2 __c) const { int __ret = -1; if (__len <= 10) { if (__c >= _CharT2('0') && __c < _CharT2(_CharT2('0') + __len)) __ret = __c - _CharT2('0'); } else { if (__c >= _CharT2('0') && __c <= _CharT2('9')) __ret = __c - _CharT2('0'); else if (__c >= _CharT2('a') && __c <= _CharT2('f')) __ret = 10 + (__c - _CharT2('a')); else if (__c >= _CharT2('A') && __c <= _CharT2('F')) __ret = 10 + (__c - _CharT2('A')); } return __ret; } template<typename _CharT2> typename __gnu_cxx::__enable_if<!__is_char<_CharT2>::__value, int>::__type _M_find(const _CharT2* __zero, size_t __len, _CharT2 __c) const { int __ret = -1; const char_type* __q = char_traits<_CharT2>::find(__zero, __len, __c); if (__q) { __ret = __q - __zero; if (__ret > 15) __ret -= 6; } return __ret; } //@{ /** * @brief Numeric parsing. * * Parses the input stream into the variable @a v. This function is a * hook for derived classes to change the value returned. @see get() * for more details. * * @param __beg Start of input stream. * @param __end End of input stream. * @param __io Source of locale and flags. * @param __err Error flags to set. * @param __v Value to format and insert. * @return Iterator after reading. */ virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const; virtual iter_type do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, long& __v) const { return _M_extract_int(__beg, __end, __io, __err, __v); } virtual iter_type do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned short& __v) const { return _M_extract_int(__beg, __end, __io, __err, __v); } virtual iter_type do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned int& __v) const { return _M_extract_int(__beg, __end, __io, __err, __v); } virtual iter_type do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long& __v) const { return _M_extract_int(__beg, __end, __io, __err, __v); } #ifdef _GLIBCXX_USE_LONG_LONG virtual iter_type do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, long long& __v) const { return _M_extract_int(__beg, __end, __io, __err, __v); } virtual iter_type do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, unsigned long long& __v) const { return _M_extract_int(__beg, __end, __io, __err, __v); } #endif virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, float&) const; virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, double&) const; // XXX GLIBCXX_ABI Deprecated #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ virtual iter_type __do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, double&) const; #else virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long double&) const; #endif virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, void*&) const; // XXX GLIBCXX_ABI Deprecated #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ virtual iter_type do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, long double&) const; #endif //@} }; template<typename _CharT, typename _InIter> locale::id num_get<_CharT, _InIter>::id; /** * @brief Primary class template num_put. * @ingroup locales * * This facet encapsulates the code to convert a number to a string. It is * used by the ostream numeric insertion operators. * * The num_put template uses protected virtual functions to provide the * actual results. The public accessors forward the call to the virtual * functions. These virtual functions are hooks for developers to * implement the behavior they require from the num_put facet. */ template<typename _CharT, typename _OutIter> class num_put : public locale::facet { public: // Types: //@{ /// Public typedefs typedef _CharT char_type; typedef _OutIter iter_type; //@} /// Numpunct facet id. static locale::id id; /** * @brief Constructor performs initialization. * * This is the constructor provided by the standard. * * @param __refs Passed to the base facet class. */ explicit num_put(size_t __refs = 0) : facet(__refs) { } /** * @brief Numeric formatting. * * Formats the boolean @a v and inserts it into a stream. It does so * by calling num_put::do_put(). * * If ios_base::boolalpha is set, writes ctype<CharT>::truename() or * ctype<CharT>::falsename(). Otherwise formats @a v as an int. * * @param __s Stream to write to. * @param __io Source of locale and flags. * @param __fill Char_type to use for filling. * @param __v Value to format and insert. * @return Iterator after writing. */ iter_type put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const { return this->do_put(__s, __io, __fill, __v); } //@{ /** * @brief Numeric formatting. * * Formats the integral value @a v and inserts it into a * stream. It does so by calling num_put::do_put(). * * Formatting is affected by the flag settings in @a io. * * The basic format is affected by the value of io.flags() & * ios_base::basefield. If equal to ios_base::oct, formats like the * printf %o specifier. Else if equal to ios_base::hex, formats like * %x or %X with ios_base::uppercase unset or set respectively. * Otherwise, formats like %d, %ld, %lld for signed and %u, %lu, %llu * for unsigned values. Note that if both oct and hex are set, neither * will take effect. * * If ios_base::showpos is set, '+' is output before positive values. * If ios_base::showbase is set, '0' precedes octal values (except 0) * and '0[xX]' precedes hex values. * * The decimal point character used is numpunct::decimal_point(). * Thousands separators are inserted according to * numpunct::grouping() and numpunct::thousands_sep(). * * If io.width() is non-zero, enough @a fill characters are inserted to * make the result at least that wide. If * (io.flags() & ios_base::adjustfield) == ios_base::left, result is * padded at the end. If ios_base::internal, then padding occurs * immediately after either a '+' or '-' or after '0x' or '0X'. * Otherwise, padding occurs at the beginning. * * @param __s Stream to write to. * @param __io Source of locale and flags. * @param __fill Char_type to use for filling. * @param __v Value to format and insert. * @return Iterator after writing. */ iter_type put(iter_type __s, ios_base& __io, char_type __fill, long __v) const { return this->do_put(__s, __io, __fill, __v); } iter_type put(iter_type __s, ios_base& __io, char_type __fill, unsigned long __v) const { return this->do_put(__s, __io, __fill, __v); } #ifdef _GLIBCXX_USE_LONG_LONG iter_type put(iter_type __s, ios_base& __io, char_type __fill, long long __v) const { return this->do_put(__s, __io, __fill, __v); } iter_type put(iter_type __s, ios_base& __io, char_type __fill, unsigned long long __v) const { return this->do_put(__s, __io, __fill, __v); } #endif //@} //@{ /** * @brief Numeric formatting. * * Formats the floating point value @a v and inserts it into a stream. * It does so by calling num_put::do_put(). * * Formatting is affected by the flag settings in @a io. * * The basic format is affected by the value of io.flags() & * ios_base::floatfield. If equal to ios_base::fixed, formats like the * printf %f specifier. Else if equal to ios_base::scientific, formats * like %e or %E with ios_base::uppercase unset or set respectively. * Otherwise, formats like %g or %G depending on uppercase. Note that * if both fixed and scientific are set, the effect will also be like * %g or %G. * * The output precision is given by io.precision(). This precision is * capped at numeric_limits::digits10 + 2 (different for double and * long double). The default precision is 6. * * If ios_base::showpos is set, '+' is output before positive values. * If ios_base::showpoint is set, a decimal point will always be * output. * * The decimal point character used is numpunct::decimal_point(). * Thousands separators are inserted according to * numpunct::grouping() and numpunct::thousands_sep(). * * If io.width() is non-zero, enough @a fill characters are inserted to * make the result at least that wide. If * (io.flags() & ios_base::adjustfield) == ios_base::left, result is * padded at the end. If ios_base::internal, then padding occurs * immediately after either a '+' or '-' or after '0x' or '0X'. * Otherwise, padding occurs at the beginning. * * @param __s Stream to write to. * @param __io Source of locale and flags. * @param __fill Char_type to use for filling. * @param __v Value to format and insert. * @return Iterator after writing. */ iter_type put(iter_type __s, ios_base& __io, char_type __fill, double __v) const { return this->do_put(__s, __io, __fill, __v); } iter_type put(iter_type __s, ios_base& __io, char_type __fill, long double __v) const { return this->do_put(__s, __io, __fill, __v); } //@} /** * @brief Numeric formatting. * * Formats the pointer value @a v and inserts it into a stream. It * does so by calling num_put::do_put(). * * This function formats @a v as an unsigned long with ios_base::hex * and ios_base::showbase set. * * @param __s Stream to write to. * @param __io Source of locale and flags. * @param __fill Char_type to use for filling. * @param __v Value to format and insert. * @return Iterator after writing. */ iter_type put(iter_type __s, ios_base& __io, char_type __fill, const void* __v) const { return this->do_put(__s, __io, __fill, __v); } protected: template<typename _ValueT> iter_type _M_insert_float(iter_type, ios_base& __io, char_type __fill, char __mod, _ValueT __v) const; void _M_group_float(const char* __grouping, size_t __grouping_size, char_type __sep, const char_type* __p, char_type* __new, char_type* __cs, int& __len) const; template<typename _ValueT> iter_type _M_insert_int(iter_type, ios_base& __io, char_type __fill, _ValueT __v) const; void _M_group_int(const char* __grouping, size_t __grouping_size, char_type __sep, ios_base& __io, char_type* __new, char_type* __cs, int& __len) const; void _M_pad(char_type __fill, streamsize __w, ios_base& __io, char_type* __new, const char_type* __cs, int& __len) const; /// Destructor. virtual ~num_put() { } //@{ /** * @brief Numeric formatting. * * These functions do the work of formatting numeric values and * inserting them into a stream. This function is a hook for derived * classes to change the value returned. * * @param __s Stream to write to. * @param __io Source of locale and flags. * @param __fill Char_type to use for filling. * @param __v Value to format and insert. * @return Iterator after writing. */ virtual iter_type do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const; virtual iter_type do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const { return _M_insert_int(__s, __io, __fill, __v); } virtual iter_type do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long __v) const { return _M_insert_int(__s, __io, __fill, __v); } #ifdef _GLIBCXX_USE_LONG_LONG virtual iter_type do_put(iter_type __s, ios_base& __io, char_type __fill, long long __v) const { return _M_insert_int(__s, __io, __fill, __v); } virtual iter_type do_put(iter_type __s, ios_base& __io, char_type __fill, unsigned long long __v) const { return _M_insert_int(__s, __io, __fill, __v); } #endif virtual iter_type do_put(iter_type, ios_base&, char_type, double) const; // XXX GLIBCXX_ABI Deprecated #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ virtual iter_type __do_put(iter_type, ios_base&, char_type, double) const; #else virtual iter_type do_put(iter_type, ios_base&, char_type, long double) const; #endif virtual iter_type do_put(iter_type, ios_base&, char_type, const void*) const; // XXX GLIBCXX_ABI Deprecated #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ virtual iter_type do_put(iter_type, ios_base&, char_type, long double) const; #endif //@} }; template <typename _CharT, typename _OutIter> locale::id num_put<_CharT, _OutIter>::id; _GLIBCXX_END_NAMESPACE_LDBL // Subclause convenience interfaces, inlines. // NB: These are inline because, when used in a loop, some compilers // can hoist the body out of the loop; then it's just as fast as the // C is*() function. /// Convenience interface to ctype.is(ctype_base::space, __c). template<typename _CharT> inline bool isspace(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); } /// Convenience interface to ctype.is(ctype_base::print, __c). template<typename _CharT> inline bool isprint(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); } /// Convenience interface to ctype.is(ctype_base::cntrl, __c). template<typename _CharT> inline bool iscntrl(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); } /// Convenience interface to ctype.is(ctype_base::upper, __c). template<typename _CharT> inline bool isupper(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); } /// Convenience interface to ctype.is(ctype_base::lower, __c). template<typename _CharT> inline bool islower(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); } /// Convenience interface to ctype.is(ctype_base::alpha, __c). template<typename _CharT> inline bool isalpha(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); } /// Convenience interface to ctype.is(ctype_base::digit, __c). template<typename _CharT> inline bool isdigit(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); } /// Convenience interface to ctype.is(ctype_base::punct, __c). template<typename _CharT> inline bool ispunct(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); } /// Convenience interface to ctype.is(ctype_base::xdigit, __c). template<typename _CharT> inline bool isxdigit(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); } /// Convenience interface to ctype.is(ctype_base::alnum, __c). template<typename _CharT> inline bool isalnum(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); } /// Convenience interface to ctype.is(ctype_base::graph, __c). template<typename _CharT> inline bool isgraph(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); } #if __cplusplus >= 201103L /// Convenience interface to ctype.is(ctype_base::blank, __c). template<typename _CharT> inline bool isblank(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::blank, __c); } #endif /// Convenience interface to ctype.toupper(__c). template<typename _CharT> inline _CharT toupper(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).toupper(__c); } /// Convenience interface to ctype.tolower(__c). template<typename _CharT> inline _CharT tolower(_CharT __c, const locale& __loc) { return use_facet<ctype<_CharT> >(__loc).tolower(__c); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std # include <bits/locale_facets.tcc> #endif c++/8/bits/refwrap.h 0000644 00000027154 15146341150 0010054 0 ustar 00 // Implementation of std::reference_wrapper -*- C++ -*- // Copyright (C) 2004-2018 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/refwrap.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{functional} */ #ifndef _GLIBCXX_REFWRAP_H #define _GLIBCXX_REFWRAP_H 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <bits/move.h> #include <bits/invoke.h> #include <bits/stl_function.h> // for unary_function and binary_function namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * Derives from @c unary_function or @c binary_function, or perhaps * nothing, depending on the number of arguments provided. The * primary template is the basis case, which derives nothing. */ template<typename _Res, typename... _ArgTypes> struct _Maybe_unary_or_binary_function { }; /// Derives from @c unary_function, as appropriate. template<typename _Res, typename _T1> struct _Maybe_unary_or_binary_function<_Res, _T1> : std::unary_function<_T1, _Res> { }; /// Derives from @c binary_function, as appropriate. template<typename _Res, typename _T1, typename _T2> struct _Maybe_unary_or_binary_function<_Res, _T1, _T2> : std::binary_function<_T1, _T2, _Res> { }; template<typename _Signature> struct _Mem_fn_traits; template<typename _Res, typename _Class, typename... _ArgTypes> struct _Mem_fn_traits_base { using __result_type = _Res; using __maybe_type = _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>; using __arity = integral_constant<size_t, sizeof...(_ArgTypes)>; }; #define _GLIBCXX_MEM_FN_TRAITS2(_CV, _REF, _LVAL, _RVAL) \ template<typename _Res, typename _Class, typename... _ArgTypes> \ struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) _CV _REF> \ : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \ { \ using __vararg = false_type; \ }; \ template<typename _Res, typename _Class, typename... _ArgTypes> \ struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes... ...) _CV _REF> \ : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \ { \ using __vararg = true_type; \ }; #define _GLIBCXX_MEM_FN_TRAITS(_REF, _LVAL, _RVAL) \ _GLIBCXX_MEM_FN_TRAITS2( , _REF, _LVAL, _RVAL) \ _GLIBCXX_MEM_FN_TRAITS2(const , _REF, _LVAL, _RVAL) \ _GLIBCXX_MEM_FN_TRAITS2(volatile , _REF, _LVAL, _RVAL) \ _GLIBCXX_MEM_FN_TRAITS2(const volatile, _REF, _LVAL, _RVAL) _GLIBCXX_MEM_FN_TRAITS( , true_type, true_type) _GLIBCXX_MEM_FN_TRAITS(&, true_type, false_type) _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) #if __cplusplus > 201402L _GLIBCXX_MEM_FN_TRAITS(noexcept, true_type, true_type) _GLIBCXX_MEM_FN_TRAITS(& noexcept, true_type, false_type) _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type) #endif #undef _GLIBCXX_MEM_FN_TRAITS #undef _GLIBCXX_MEM_FN_TRAITS2 /// If we have found a result_type, extract it. template<typename _Functor, typename = __void_t<>> struct _Maybe_get_result_type { }; template<typename _Functor> struct _Maybe_get_result_type<_Functor, __void_t<typename _Functor::result_type>> { typedef typename _Functor::result_type result_type; }; /** * Base class for any function object that has a weak result type, as * defined in 20.8.2 [func.require] of C++11. */ template<typename _Functor> struct _Weak_result_type_impl : _Maybe_get_result_type<_Functor> { }; /// Retrieve the result type for a function type. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct _Weak_result_type_impl<_Res(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL> { typedef _Res result_type; }; /// Retrieve the result type for a varargs function type. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct _Weak_result_type_impl<_Res(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL> { typedef _Res result_type; }; /// Retrieve the result type for a function pointer. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct _Weak_result_type_impl<_Res(*)(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL> { typedef _Res result_type; }; /// Retrieve the result type for a varargs function pointer. template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> struct _Weak_result_type_impl<_Res(*)(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL> { typedef _Res result_type; }; // Let _Weak_result_type_impl perform the real work. template<typename _Functor, bool = is_member_function_pointer<_Functor>::value> struct _Weak_result_type_memfun : _Weak_result_type_impl<_Functor> { }; // A pointer to member function has a weak result type. template<typename _MemFunPtr> struct _Weak_result_type_memfun<_MemFunPtr, true> { using result_type = typename _Mem_fn_traits<_MemFunPtr>::__result_type; }; // A pointer to data member doesn't have a weak result type. template<typename _Func, typename _Class> struct _Weak_result_type_memfun<_Func _Class::*, false> { }; /** * Strip top-level cv-qualifiers from the function object and let * _Weak_result_type_memfun perform the real work. */ template<typename _Functor> struct _Weak_result_type : _Weak_result_type_memfun<typename remove_cv<_Functor>::type> { }; // Detect nested argument_type. template<typename _Tp, typename = __void_t<>> struct _Refwrap_base_arg1 { }; // Nested argument_type. template<typename _Tp> struct _Refwrap_base_arg1<_Tp, __void_t<typename _Tp::argument_type>> { typedef typename _Tp::argument_type argument_type; }; // Detect nested first_argument_type and second_argument_type. template<typename _Tp, typename = __void_t<>> struct _Refwrap_base_arg2 { }; // Nested first_argument_type and second_argument_type. template<typename _Tp> struct _Refwrap_base_arg2<_Tp, __void_t<typename _Tp::first_argument_type, typename _Tp::second_argument_type>> { typedef typename _Tp::first_argument_type first_argument_type; typedef typename _Tp::second_argument_type second_argument_type; }; /** * Derives from unary_function or binary_function when it * can. Specializations handle all of the easy cases. The primary * template determines what to do with a class type, which may * derive from both unary_function and binary_function. */ template<typename _Tp> struct _Reference_wrapper_base : _Weak_result_type<_Tp>, _Refwrap_base_arg1<_Tp>, _Refwrap_base_arg2<_Tp> { }; // - a function type (unary) template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM> struct _Reference_wrapper_base<_Res(_T1) _GLIBCXX_NOEXCEPT_QUAL> : unary_function<_T1, _Res> { }; template<typename _Res, typename _T1> struct _Reference_wrapper_base<_Res(_T1) const> : unary_function<_T1, _Res> { }; template<typename _Res, typename _T1> struct _Reference_wrapper_base<_Res(_T1) volatile> : unary_function<_T1, _Res> { }; template<typename _Res, typename _T1> struct _Reference_wrapper_base<_Res(_T1) const volatile> : unary_function<_T1, _Res> { }; // - a function type (binary) template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM> struct _Reference_wrapper_base<_Res(_T1, _T2) _GLIBCXX_NOEXCEPT_QUAL> : binary_function<_T1, _T2, _Res> { }; template<typename _Res, typename _T1, typename _T2> struct _Reference_wrapper_base<_Res(_T1, _T2) const> : binary_function<_T1, _T2, _Res> { }; template<typename _Res, typename _T1, typename _T2> struct _Reference_wrapper_base<_Res(_T1, _T2) volatile> : binary_function<_T1, _T2, _Res> { }; template<typename _Res, typename _T1, typename _T2> struct _Reference_wrapper_base<_Res(_T1, _T2) const volatile> : binary_function<_T1, _T2, _Res> { }; // - a function pointer type (unary) template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM> struct _Reference_wrapper_base<_Res(*)(_T1) _GLIBCXX_NOEXCEPT_QUAL> : unary_function<_T1, _Res> { }; // - a function pointer type (binary) template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM> struct _Reference_wrapper_base<_Res(*)(_T1, _T2) _GLIBCXX_NOEXCEPT_QUAL> : binary_function<_T1, _T2, _Res> { }; template<typename _Tp, bool = is_member_function_pointer<_Tp>::value> struct _Reference_wrapper_base_memfun : _Reference_wrapper_base<_Tp> { }; template<typename _MemFunPtr> struct _Reference_wrapper_base_memfun<_MemFunPtr, true> : _Mem_fn_traits<_MemFunPtr>::__maybe_type { using result_type = typename _Mem_fn_traits<_MemFunPtr>::__result_type; }; /** * @brief Primary class template for reference_wrapper. * @ingroup functors * @{ */ template<typename _Tp> class reference_wrapper : public _Reference_wrapper_base_memfun<typename remove_cv<_Tp>::type> { _Tp* _M_data; public: typedef _Tp type; reference_wrapper(_Tp& __indata) noexcept : _M_data(std::__addressof(__indata)) { } reference_wrapper(_Tp&&) = delete; reference_wrapper(const reference_wrapper&) = default; reference_wrapper& operator=(const reference_wrapper&) = default; operator _Tp&() const noexcept { return this->get(); } _Tp& get() const noexcept { return *_M_data; } template<typename... _Args> typename result_of<_Tp&(_Args&&...)>::type operator()(_Args&&... __args) const { return std::__invoke(get(), std::forward<_Args>(__args)...); } }; /// Denotes a reference should be taken to a variable. template<typename _Tp> inline reference_wrapper<_Tp> ref(_Tp& __t) noexcept { return reference_wrapper<_Tp>(__t); } /// Denotes a const reference should be taken to a variable. template<typename _Tp> inline reference_wrapper<const _Tp> cref(const _Tp& __t) noexcept { return reference_wrapper<const _Tp>(__t); } template<typename _Tp> void ref(const _Tp&&) = delete; template<typename _Tp> void cref(const _Tp&&) = delete; /// std::ref overload to prevent wrapping a reference_wrapper template<typename _Tp> inline reference_wrapper<_Tp> ref(reference_wrapper<_Tp> __t) noexcept { return __t; } /// std::cref overload to prevent wrapping a reference_wrapper template<typename _Tp> inline reference_wrapper<const _Tp> cref(reference_wrapper<_Tp> __t) noexcept { return { __t.get() }; } // @} group functors _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_REFWRAP_H c++/8/bits/std_abs.h 0000644 00000006302 15146341150 0010015 0 ustar 00 // -*- C++ -*- C library enhancements header. // Copyright (C) 2016-2018 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/std_abs.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{cmath, cstdlib} */ #ifndef _GLIBCXX_BITS_STD_ABS_H #define _GLIBCXX_BITS_STD_ABS_H #pragma GCC system_header #include <bits/c++config.h> #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include_next <stdlib.h> #ifdef __CORRECT_ISO_CPP_MATH_H_PROTO # include_next <math.h> #endif #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS #undef abs extern "C++" { namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::abs; #ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO inline long abs(long __i) { return __builtin_labs(__i); } #endif #ifdef _GLIBCXX_USE_LONG_LONG inline long long abs(long long __x) { return __builtin_llabs (__x); } #endif // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2192. Validity and return type of std::abs(0u) is unclear // 2294. <cstdlib> should declare abs(double) #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO inline _GLIBCXX_CONSTEXPR double abs(double __x) { return __builtin_fabs(__x); } inline _GLIBCXX_CONSTEXPR float abs(float __x) { return __builtin_fabsf(__x); } inline _GLIBCXX_CONSTEXPR long double abs(long double __x) { return __builtin_fabsl(__x); } #endif #if defined(__GLIBCXX_TYPE_INT_N_0) inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_0 abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; } #endif #if defined(__GLIBCXX_TYPE_INT_N_1) inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_1 abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; } #endif #if defined(__GLIBCXX_TYPE_INT_N_2) inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_2 abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; } #endif #if defined(__GLIBCXX_TYPE_INT_N_3) inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_3 abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; } #endif #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) inline _GLIBCXX_CONSTEXPR __float128 abs(__float128 __x) { return __x < 0 ? -__x : __x; } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace } #endif // _GLIBCXX_BITS_STD_ABS_H c++/8/bits/stl_tempbuf.h 0000644 00000020230 15146341150 0010716 0 ustar 00 // Temporary buffer implementation -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_tempbuf.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _STL_TEMPBUF_H #define _STL_TEMPBUF_H 1 #include <bits/stl_algobase.h> #include <bits/stl_construct.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Allocates a temporary buffer. * @param __len The number of objects of type Tp. * @return See full description. * * Reinventing the wheel, but this time with prettier spokes! * * This function tries to obtain storage for @c __len adjacent Tp * objects. The objects themselves are not constructed, of course. * A pair<> is returned containing <em>the buffer s address and * capacity (in the units of sizeof(_Tp)), or a pair of 0 values if * no storage can be obtained.</em> Note that the capacity obtained * may be less than that requested if the memory is unavailable; * you should compare len with the .second return value. * * Provides the nothrow exception guarantee. */ template<typename _Tp> pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) _GLIBCXX_NOEXCEPT { const ptrdiff_t __max = __gnu_cxx::__numeric_traits<ptrdiff_t>::__max / sizeof(_Tp); if (__len > __max) __len = __max; while (__len > 0) { _Tp* __tmp = static_cast<_Tp*>(::operator new(__len * sizeof(_Tp), std::nothrow)); if (__tmp != 0) return std::pair<_Tp*, ptrdiff_t>(__tmp, __len); __len /= 2; } return std::pair<_Tp*, ptrdiff_t>(static_cast<_Tp*>(0), 0); } /** * @brief The companion to get_temporary_buffer(). * @param __p A buffer previously allocated by get_temporary_buffer. * @return None. * * Frees the memory pointed to by __p. */ template<typename _Tp> inline void return_temporary_buffer(_Tp* __p) { ::operator delete(__p, std::nothrow); } /** * This class is used in two places: stl_algo.h and ext/memory, * where it is wrapped as the temporary_buffer class. See * temporary_buffer docs for more notes. */ template<typename _ForwardIterator, typename _Tp> class _Temporary_buffer { // concept requirements __glibcxx_class_requires(_ForwardIterator, _ForwardIteratorConcept) public: typedef _Tp value_type; typedef value_type* pointer; typedef pointer iterator; typedef ptrdiff_t size_type; protected: size_type _M_original_len; size_type _M_len; pointer _M_buffer; public: /// As per Table mumble. size_type size() const { return _M_len; } /// Returns the size requested by the constructor; may be >size(). size_type requested_size() const { return _M_original_len; } /// As per Table mumble. iterator begin() { return _M_buffer; } /// As per Table mumble. iterator end() { return _M_buffer + _M_len; } /** * Constructs a temporary buffer of a size somewhere between * zero and the size of the given range. */ _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last); ~_Temporary_buffer() { std::_Destroy(_M_buffer, _M_buffer + _M_len); std::return_temporary_buffer(_M_buffer); } private: // Disable copy constructor and assignment operator. _Temporary_buffer(const _Temporary_buffer&); void operator=(const _Temporary_buffer&); }; template<bool> struct __uninitialized_construct_buf_dispatch { template<typename _Pointer, typename _ForwardIterator> static void __ucr(_Pointer __first, _Pointer __last, _ForwardIterator __seed) { if(__first == __last) return; _Pointer __cur = __first; __try { std::_Construct(std::__addressof(*__first), _GLIBCXX_MOVE(*__seed)); _Pointer __prev = __cur; ++__cur; for(; __cur != __last; ++__cur, ++__prev) std::_Construct(std::__addressof(*__cur), _GLIBCXX_MOVE(*__prev)); *__seed = _GLIBCXX_MOVE(*__prev); } __catch(...) { std::_Destroy(__first, __cur); __throw_exception_again; } } }; template<> struct __uninitialized_construct_buf_dispatch<true> { template<typename _Pointer, typename _ForwardIterator> static void __ucr(_Pointer, _Pointer, _ForwardIterator) { } }; // Constructs objects in the range [first, last). // Note that while these new objects will take valid values, // their exact value is not defined. In particular they may // be 'moved from'. // // While *__seed may be altered during this algorithm, it will have // the same value when the algorithm finishes, unless one of the // constructions throws. // // Requirements: _Pointer::value_type(_Tp&&) is valid. template<typename _Pointer, typename _ForwardIterator> inline void __uninitialized_construct_buf(_Pointer __first, _Pointer __last, _ForwardIterator __seed) { typedef typename std::iterator_traits<_Pointer>::value_type _ValueType; std::__uninitialized_construct_buf_dispatch< __has_trivial_constructor(_ValueType)>:: __ucr(__first, __last, __seed); } template<typename _ForwardIterator, typename _Tp> _Temporary_buffer<_ForwardIterator, _Tp>:: _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) : _M_original_len(std::distance(__first, __last)), _M_len(0), _M_buffer(0) { __try { std::pair<pointer, size_type> __p(std::get_temporary_buffer< value_type>(_M_original_len)); _M_buffer = __p.first; _M_len = __p.second; if (_M_buffer) std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len, __first); } __catch(...) { std::return_temporary_buffer(_M_buffer); _M_buffer = 0; _M_len = 0; __throw_exception_again; } } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _STL_TEMPBUF_H */ c++/8/bits/specfun.h 0000644 00000133713 15146341150 0010050 0 ustar 00 // Mathematical Special Functions for -*- C++ -*- // Copyright (C) 2006-2018 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/specfun.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{cmath} */ #ifndef _GLIBCXX_BITS_SPECFUN_H #define _GLIBCXX_BITS_SPECFUN_H 1 #pragma GCC visibility push(default) #include <bits/c++config.h> #define __STDCPP_MATH_SPEC_FUNCS__ 201003L #define __cpp_lib_math_special_functions 201603L #if __cplusplus <= 201403L && __STDCPP_WANT_MATH_SPEC_FUNCS__ == 0 # error include <cmath> and define __STDCPP_WANT_MATH_SPEC_FUNCS__ #endif #include <bits/stl_algobase.h> #include <limits> #include <type_traits> #include <tr1/gamma.tcc> #include <tr1/bessel_function.tcc> #include <tr1/beta_function.tcc> #include <tr1/ell_integral.tcc> #include <tr1/exp_integral.tcc> #include <tr1/hypergeometric.tcc> #include <tr1/legendre_function.tcc> #include <tr1/modified_bessel_func.tcc> #include <tr1/poly_hermite.tcc> #include <tr1/poly_laguerre.tcc> #include <tr1/riemann_zeta.tcc> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup mathsf Mathematical Special Functions * @ingroup numerics * * A collection of advanced mathematical special functions, * defined by ISO/IEC IS 29124. * @{ */ /** * @mainpage Mathematical Special Functions * * @section intro Introduction and History * The first significant library upgrade on the road to C++2011, * <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1836.pdf"> * TR1</a>, included a set of 23 mathematical functions that significantly * extended the standard transcendental functions inherited from C and declared * in @<cmath@>. * * Although most components from TR1 were eventually adopted for C++11 these * math functions were left behind out of concern for implementability. * The math functions were published as a separate international standard * <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3060.pdf"> * IS 29124 - Extensions to the C++ Library to Support Mathematical Special * Functions</a>. * * For C++17 these functions were incorporated into the main standard. * * @section contents Contents * The following functions are implemented in namespace @c std: * - @ref assoc_laguerre "assoc_laguerre - Associated Laguerre functions" * - @ref assoc_legendre "assoc_legendre - Associated Legendre functions" * - @ref beta "beta - Beta functions" * - @ref comp_ellint_1 "comp_ellint_1 - Complete elliptic functions of the first kind" * - @ref comp_ellint_2 "comp_ellint_2 - Complete elliptic functions of the second kind" * - @ref comp_ellint_3 "comp_ellint_3 - Complete elliptic functions of the third kind" * - @ref cyl_bessel_i "cyl_bessel_i - Regular modified cylindrical Bessel functions" * - @ref cyl_bessel_j "cyl_bessel_j - Cylindrical Bessel functions of the first kind" * - @ref cyl_bessel_k "cyl_bessel_k - Irregular modified cylindrical Bessel functions" * - @ref cyl_neumann "cyl_neumann - Cylindrical Neumann functions or Cylindrical Bessel functions of the second kind" * - @ref ellint_1 "ellint_1 - Incomplete elliptic functions of the first kind" * - @ref ellint_2 "ellint_2 - Incomplete elliptic functions of the second kind" * - @ref ellint_3 "ellint_3 - Incomplete elliptic functions of the third kind" * - @ref expint "expint - The exponential integral" * - @ref hermite "hermite - Hermite polynomials" * - @ref laguerre "laguerre - Laguerre functions" * - @ref legendre "legendre - Legendre polynomials" * - @ref riemann_zeta "riemann_zeta - The Riemann zeta function" * - @ref sph_bessel "sph_bessel - Spherical Bessel functions" * - @ref sph_legendre "sph_legendre - Spherical Legendre functions" * - @ref sph_neumann "sph_neumann - Spherical Neumann functions" * * The hypergeometric functions were stricken from the TR29124 and C++17 * versions of this math library because of implementation concerns. * However, since they were in the TR1 version and since they are popular * we kept them as an extension in namespace @c __gnu_cxx: * - @ref __gnu_cxx::conf_hyperg "conf_hyperg - Confluent hypergeometric functions" * - @ref __gnu_cxx::hyperg "hyperg - Hypergeometric functions" * * @section general General Features * * @subsection promotion Argument Promotion * The arguments suppled to the non-suffixed functions will be promoted * according to the following rules: * 1. If any argument intended to be floating point is given an integral value * That integral value is promoted to double. * 2. All floating point arguments are promoted up to the largest floating * point precision among them. * * @subsection NaN NaN Arguments * If any of the floating point arguments supplied to these functions is * invalid or NaN (std::numeric_limits<Tp>::quiet_NaN), * the value NaN is returned. * * @section impl Implementation * * We strive to implement the underlying math with type generic algorithms * to the greatest extent possible. In practice, the functions are thin * wrappers that dispatch to function templates. Type dependence is * controlled with std::numeric_limits and functions thereof. * * We don't promote @c float to @c double or @c double to <tt>long double</tt> * reflexively. The goal is for @c float functions to operate more quickly, * at the cost of @c float accuracy and possibly a smaller domain of validity. * Similaryly, <tt>long double</tt> should give you more dynamic range * and slightly more pecision than @c double on many systems. * * @section testing Testing * * These functions have been tested against equivalent implementations * from the <a href="http://www.gnu.org/software/gsl"> * Gnu Scientific Library, GSL</a> and * <a href="http://www.boost.org/doc/libs/1_60_0/libs/math/doc/html/index.html>Boost</a> * and the ratio * @f[ * \frac{|f - f_{test}|}{|f_{test}|} * @f] * is generally found to be within 10^-15 for 64-bit double on linux-x86_64 systems * over most of the ranges of validity. * * @todo Provide accuracy comparisons on a per-function basis for a small * number of targets. * * @section bibliography General Bibliography * * @see Abramowitz and Stegun: Handbook of Mathematical Functions, * with Formulas, Graphs, and Mathematical Tables * Edited by Milton Abramowitz and Irene A. Stegun, * National Bureau of Standards Applied Mathematics Series - 55 * Issued June 1964, Tenth Printing, December 1972, with corrections * Electronic versions of A&S abound including both pdf and navigable html. * @see for example http://people.math.sfu.ca/~cbm/aands/ * * @see The old A&S has been redone as the * NIST Digital Library of Mathematical Functions: http://dlmf.nist.gov/ * This version is far more navigable and includes more recent work. * * @see An Atlas of Functions: with Equator, the Atlas Function Calculator * 2nd Edition, by Oldham, Keith B., Myland, Jan, Spanier, Jerome * * @see Asymptotics and Special Functions by Frank W. J. Olver, * Academic Press, 1974 * * @see Numerical Recipes in C, The Art of Scientific Computing, * by William H. Press, Second Ed., Saul A. Teukolsky, * William T. Vetterling, and Brian P. Flannery, * Cambridge University Press, 1992 * * @see The Special Functions and Their Approximations: Volumes 1 and 2, * by Yudell L. Luke, Academic Press, 1969 */ // Associated Laguerre polynomials /** * Return the associated Laguerre polynomial of order @c n, * degree @c m: @f$ L_n^m(x) @f$ for @c float argument. * * @see assoc_laguerre for more details. */ inline float assoc_laguerref(unsigned int __n, unsigned int __m, float __x) { return __detail::__assoc_laguerre<float>(__n, __m, __x); } /** * Return the associated Laguerre polynomial of order @c n, * degree @c m: @f$ L_n^m(x) @f$. * * @see assoc_laguerre for more details. */ inline long double assoc_laguerrel(unsigned int __n, unsigned int __m, long double __x) { return __detail::__assoc_laguerre<long double>(__n, __m, __x); } /** * Return the associated Laguerre polynomial of nonnegative order @c n, * nonnegative degree @c m and real argument @c x: @f$ L_n^m(x) @f$. * * The associated Laguerre function of real degree @f$ \alpha @f$, * @f$ L_n^\alpha(x) @f$, is defined by * @f[ * L_n^\alpha(x) = \frac{(\alpha + 1)_n}{n!} * {}_1F_1(-n; \alpha + 1; x) * @f] * where @f$ (\alpha)_n @f$ is the Pochhammer symbol and * @f$ {}_1F_1(a; c; x) @f$ is the confluent hypergeometric function. * * The associated Laguerre polynomial is defined for integral * degree @f$ \alpha = m @f$ by: * @f[ * L_n^m(x) = (-1)^m \frac{d^m}{dx^m} L_{n + m}(x) * @f] * where the Laguerre polynomial is defined by: * @f[ * L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x}) * @f] * and @f$ x >= 0 @f$. * @see laguerre for details of the Laguerre function of degree @c n * * @tparam _Tp The floating-point type of the argument @c __x. * @param __n The order of the Laguerre function, <tt>__n >= 0</tt>. * @param __m The degree of the Laguerre function, <tt>__m >= 0</tt>. * @param __x The argument of the Laguerre function, <tt>__x >= 0</tt>. * @throw std::domain_error if <tt>__x < 0</tt>. */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type assoc_laguerre(unsigned int __n, unsigned int __m, _Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__assoc_laguerre<__type>(__n, __m, __x); } // Associated Legendre functions /** * Return the associated Legendre function of degree @c l and order @c m * for @c float argument. * * @see assoc_legendre for more details. */ inline float assoc_legendref(unsigned int __l, unsigned int __m, float __x) { return __detail::__assoc_legendre_p<float>(__l, __m, __x); } /** * Return the associated Legendre function of degree @c l and order @c m. * * @see assoc_legendre for more details. */ inline long double assoc_legendrel(unsigned int __l, unsigned int __m, long double __x) { return __detail::__assoc_legendre_p<long double>(__l, __m, __x); } /** * Return the associated Legendre function of degree @c l and order @c m. * * The associated Legendre function is derived from the Legendre function * @f$ P_l(x) @f$ by the Rodrigues formula: * @f[ * P_l^m(x) = (1 - x^2)^{m/2}\frac{d^m}{dx^m}P_l(x) * @f] * @see legendre for details of the Legendre function of degree @c l * * @tparam _Tp The floating-point type of the argument @c __x. * @param __l The degree <tt>__l >= 0</tt>. * @param __m The order <tt>__m <= l</tt>. * @param __x The argument, <tt>abs(__x) <= 1</tt>. * @throw std::domain_error if <tt>abs(__x) > 1</tt>. */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type assoc_legendre(unsigned int __l, unsigned int __m, _Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__assoc_legendre_p<__type>(__l, __m, __x); } // Beta functions /** * Return the beta function, @f$ B(a,b) @f$, for @c float parameters @c a, @c b. * * @see beta for more details. */ inline float betaf(float __a, float __b) { return __detail::__beta<float>(__a, __b); } /** * Return the beta function, @f$B(a,b)@f$, for long double * parameters @c a, @c b. * * @see beta for more details. */ inline long double betal(long double __a, long double __b) { return __detail::__beta<long double>(__a, __b); } /** * Return the beta function, @f$B(a,b)@f$, for real parameters @c a, @c b. * * The beta function is defined by * @f[ * B(a,b) = \int_0^1 t^{a - 1} (1 - t)^{b - 1} dt * = \frac{\Gamma(a)\Gamma(b)}{\Gamma(a+b)} * @f] * where @f$ a > 0 @f$ and @f$ b > 0 @f$ * * @tparam _Tpa The floating-point type of the parameter @c __a. * @tparam _Tpb The floating-point type of the parameter @c __b. * @param __a The first argument of the beta function, <tt> __a > 0 </tt>. * @param __b The second argument of the beta function, <tt> __b > 0 </tt>. * @throw std::domain_error if <tt> __a < 0 </tt> or <tt> __b < 0 </tt>. */ template<typename _Tpa, typename _Tpb> inline typename __gnu_cxx::__promote_2<_Tpa, _Tpb>::__type beta(_Tpa __a, _Tpb __b) { typedef typename __gnu_cxx::__promote_2<_Tpa, _Tpb>::__type __type; return __detail::__beta<__type>(__a, __b); } // Complete elliptic integrals of the first kind /** * Return the complete elliptic integral of the first kind @f$ E(k) @f$ * for @c float modulus @c k. * * @see comp_ellint_1 for details. */ inline float comp_ellint_1f(float __k) { return __detail::__comp_ellint_1<float>(__k); } /** * Return the complete elliptic integral of the first kind @f$ E(k) @f$ * for long double modulus @c k. * * @see comp_ellint_1 for details. */ inline long double comp_ellint_1l(long double __k) { return __detail::__comp_ellint_1<long double>(__k); } /** * Return the complete elliptic integral of the first kind * @f$ K(k) @f$ for real modulus @c k. * * The complete elliptic integral of the first kind is defined as * @f[ * K(k) = F(k,\pi/2) = \int_0^{\pi/2}\frac{d\theta} * {\sqrt{1 - k^2 sin^2\theta}} * @f] * where @f$ F(k,\phi) @f$ is the incomplete elliptic integral of the * first kind and the modulus @f$ |k| <= 1 @f$. * @see ellint_1 for details of the incomplete elliptic function * of the first kind. * * @tparam _Tp The floating-point type of the modulus @c __k. * @param __k The modulus, <tt> abs(__k) <= 1 </tt> * @throw std::domain_error if <tt> abs(__k) > 1 </tt>. */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type comp_ellint_1(_Tp __k) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__comp_ellint_1<__type>(__k); } // Complete elliptic integrals of the second kind /** * Return the complete elliptic integral of the second kind @f$ E(k) @f$ * for @c float modulus @c k. * * @see comp_ellint_2 for details. */ inline float comp_ellint_2f(float __k) { return __detail::__comp_ellint_2<float>(__k); } /** * Return the complete elliptic integral of the second kind @f$ E(k) @f$ * for long double modulus @c k. * * @see comp_ellint_2 for details. */ inline long double comp_ellint_2l(long double __k) { return __detail::__comp_ellint_2<long double>(__k); } /** * Return the complete elliptic integral of the second kind @f$ E(k) @f$ * for real modulus @c k. * * The complete elliptic integral of the second kind is defined as * @f[ * E(k) = E(k,\pi/2) = \int_0^{\pi/2}\sqrt{1 - k^2 sin^2\theta} * @f] * where @f$ E(k,\phi) @f$ is the incomplete elliptic integral of the * second kind and the modulus @f$ |k| <= 1 @f$. * @see ellint_2 for details of the incomplete elliptic function * of the second kind. * * @tparam _Tp The floating-point type of the modulus @c __k. * @param __k The modulus, @c abs(__k) <= 1 * @throw std::domain_error if @c abs(__k) > 1. */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type comp_ellint_2(_Tp __k) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__comp_ellint_2<__type>(__k); } // Complete elliptic integrals of the third kind /** * @brief Return the complete elliptic integral of the third kind * @f$ \Pi(k,\nu) @f$ for @c float modulus @c k. * * @see comp_ellint_3 for details. */ inline float comp_ellint_3f(float __k, float __nu) { return __detail::__comp_ellint_3<float>(__k, __nu); } /** * @brief Return the complete elliptic integral of the third kind * @f$ \Pi(k,\nu) @f$ for <tt>long double</tt> modulus @c k. * * @see comp_ellint_3 for details. */ inline long double comp_ellint_3l(long double __k, long double __nu) { return __detail::__comp_ellint_3<long double>(__k, __nu); } /** * Return the complete elliptic integral of the third kind * @f$ \Pi(k,\nu) = \Pi(k,\nu,\pi/2) @f$ for real modulus @c k. * * The complete elliptic integral of the third kind is defined as * @f[ * \Pi(k,\nu) = \Pi(k,\nu,\pi/2) = \int_0^{\pi/2} * \frac{d\theta} * {(1 - \nu \sin^2\theta)\sqrt{1 - k^2 \sin^2\theta}} * @f] * where @f$ \Pi(k,\nu,\phi) @f$ is the incomplete elliptic integral of the * second kind and the modulus @f$ |k| <= 1 @f$. * @see ellint_3 for details of the incomplete elliptic function * of the third kind. * * @tparam _Tp The floating-point type of the modulus @c __k. * @tparam _Tpn The floating-point type of the argument @c __nu. * @param __k The modulus, @c abs(__k) <= 1 * @param __nu The argument * @throw std::domain_error if @c abs(__k) > 1. */ template<typename _Tp, typename _Tpn> inline typename __gnu_cxx::__promote_2<_Tp, _Tpn>::__type comp_ellint_3(_Tp __k, _Tpn __nu) { typedef typename __gnu_cxx::__promote_2<_Tp, _Tpn>::__type __type; return __detail::__comp_ellint_3<__type>(__k, __nu); } // Regular modified cylindrical Bessel functions /** * Return the regular modified Bessel function @f$ I_{\nu}(x) @f$ * for @c float order @f$ \nu @f$ and argument @f$ x >= 0 @f$. * * @see cyl_bessel_i for setails. */ inline float cyl_bessel_if(float __nu, float __x) { return __detail::__cyl_bessel_i<float>(__nu, __x); } /** * Return the regular modified Bessel function @f$ I_{\nu}(x) @f$ * for <tt>long double</tt> order @f$ \nu @f$ and argument @f$ x >= 0 @f$. * * @see cyl_bessel_i for setails. */ inline long double cyl_bessel_il(long double __nu, long double __x) { return __detail::__cyl_bessel_i<long double>(__nu, __x); } /** * Return the regular modified Bessel function @f$ I_{\nu}(x) @f$ * for real order @f$ \nu @f$ and argument @f$ x >= 0 @f$. * * The regular modified cylindrical Bessel function is: * @f[ * I_{\nu}(x) = i^{-\nu}J_\nu(ix) = \sum_{k=0}^{\infty} * \frac{(x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)} * @f] * * @tparam _Tpnu The floating-point type of the order @c __nu. * @tparam _Tp The floating-point type of the argument @c __x. * @param __nu The order * @param __x The argument, <tt> __x >= 0 </tt> * @throw std::domain_error if <tt> __x < 0 </tt>. */ template<typename _Tpnu, typename _Tp> inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type cyl_bessel_i(_Tpnu __nu, _Tp __x) { typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type; return __detail::__cyl_bessel_i<__type>(__nu, __x); } // Cylindrical Bessel functions (of the first kind) /** * Return the Bessel function of the first kind @f$ J_{\nu}(x) @f$ * for @c float order @f$ \nu @f$ and argument @f$ x >= 0 @f$. * * @see cyl_bessel_j for setails. */ inline float cyl_bessel_jf(float __nu, float __x) { return __detail::__cyl_bessel_j<float>(__nu, __x); } /** * Return the Bessel function of the first kind @f$ J_{\nu}(x) @f$ * for <tt>long double</tt> order @f$ \nu @f$ and argument @f$ x >= 0 @f$. * * @see cyl_bessel_j for setails. */ inline long double cyl_bessel_jl(long double __nu, long double __x) { return __detail::__cyl_bessel_j<long double>(__nu, __x); } /** * Return the Bessel function @f$ J_{\nu}(x) @f$ of real order @f$ \nu @f$ * and argument @f$ x >= 0 @f$. * * The cylindrical Bessel function is: * @f[ * J_{\nu}(x) = \sum_{k=0}^{\infty} * \frac{(-1)^k (x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)} * @f] * * @tparam _Tpnu The floating-point type of the order @c __nu. * @tparam _Tp The floating-point type of the argument @c __x. * @param __nu The order * @param __x The argument, <tt> __x >= 0 </tt> * @throw std::domain_error if <tt> __x < 0 </tt>. */ template<typename _Tpnu, typename _Tp> inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type cyl_bessel_j(_Tpnu __nu, _Tp __x) { typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type; return __detail::__cyl_bessel_j<__type>(__nu, __x); } // Irregular modified cylindrical Bessel functions /** * Return the irregular modified Bessel function @f$ K_{\nu}(x) @f$ * for @c float order @f$ \nu @f$ and argument @f$ x >= 0 @f$. * * @see cyl_bessel_k for setails. */ inline float cyl_bessel_kf(float __nu, float __x) { return __detail::__cyl_bessel_k<float>(__nu, __x); } /** * Return the irregular modified Bessel function @f$ K_{\nu}(x) @f$ * for <tt>long double</tt> order @f$ \nu @f$ and argument @f$ x >= 0 @f$. * * @see cyl_bessel_k for setails. */ inline long double cyl_bessel_kl(long double __nu, long double __x) { return __detail::__cyl_bessel_k<long double>(__nu, __x); } /** * Return the irregular modified Bessel function @f$ K_{\nu}(x) @f$ * of real order @f$ \nu @f$ and argument @f$ x @f$. * * The irregular modified Bessel function is defined by: * @f[ * K_{\nu}(x) = \frac{\pi}{2} * \frac{I_{-\nu}(x) - I_{\nu}(x)}{\sin \nu\pi} * @f] * where for integral @f$ \nu = n @f$ a limit is taken: * @f$ lim_{\nu \to n} @f$. * For negative argument we have simply: * @f[ * K_{-\nu}(x) = K_{\nu}(x) * @f] * * @tparam _Tpnu The floating-point type of the order @c __nu. * @tparam _Tp The floating-point type of the argument @c __x. * @param __nu The order * @param __x The argument, <tt> __x >= 0 </tt> * @throw std::domain_error if <tt> __x < 0 </tt>. */ template<typename _Tpnu, typename _Tp> inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type cyl_bessel_k(_Tpnu __nu, _Tp __x) { typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type; return __detail::__cyl_bessel_k<__type>(__nu, __x); } // Cylindrical Neumann functions /** * Return the Neumann function @f$ N_{\nu}(x) @f$ * of @c float order @f$ \nu @f$ and argument @f$ x @f$. * * @see cyl_neumann for setails. */ inline float cyl_neumannf(float __nu, float __x) { return __detail::__cyl_neumann_n<float>(__nu, __x); } /** * Return the Neumann function @f$ N_{\nu}(x) @f$ * of <tt>long double</tt> order @f$ \nu @f$ and argument @f$ x @f$. * * @see cyl_neumann for setails. */ inline long double cyl_neumannl(long double __nu, long double __x) { return __detail::__cyl_neumann_n<long double>(__nu, __x); } /** * Return the Neumann function @f$ N_{\nu}(x) @f$ * of real order @f$ \nu @f$ and argument @f$ x >= 0 @f$. * * The Neumann function is defined by: * @f[ * N_{\nu}(x) = \frac{J_{\nu}(x) \cos \nu\pi - J_{-\nu}(x)} * {\sin \nu\pi} * @f] * where @f$ x >= 0 @f$ and for integral order @f$ \nu = n @f$ * a limit is taken: @f$ lim_{\nu \to n} @f$. * * @tparam _Tpnu The floating-point type of the order @c __nu. * @tparam _Tp The floating-point type of the argument @c __x. * @param __nu The order * @param __x The argument, <tt> __x >= 0 </tt> * @throw std::domain_error if <tt> __x < 0 </tt>. */ template<typename _Tpnu, typename _Tp> inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type cyl_neumann(_Tpnu __nu, _Tp __x) { typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type; return __detail::__cyl_neumann_n<__type>(__nu, __x); } // Incomplete elliptic integrals of the first kind /** * Return the incomplete elliptic integral of the first kind @f$ E(k,\phi) @f$ * for @c float modulus @f$ k @f$ and angle @f$ \phi @f$. * * @see ellint_1 for details. */ inline float ellint_1f(float __k, float __phi) { return __detail::__ellint_1<float>(__k, __phi); } /** * Return the incomplete elliptic integral of the first kind @f$ E(k,\phi) @f$ * for <tt>long double</tt> modulus @f$ k @f$ and angle @f$ \phi @f$. * * @see ellint_1 for details. */ inline long double ellint_1l(long double __k, long double __phi) { return __detail::__ellint_1<long double>(__k, __phi); } /** * Return the incomplete elliptic integral of the first kind @f$ F(k,\phi) @f$ * for @c real modulus @f$ k @f$ and angle @f$ \phi @f$. * * The incomplete elliptic integral of the first kind is defined as * @f[ * F(k,\phi) = \int_0^{\phi}\frac{d\theta} * {\sqrt{1 - k^2 sin^2\theta}} * @f] * For @f$ \phi= \pi/2 @f$ this becomes the complete elliptic integral of * the first kind, @f$ K(k) @f$. @see comp_ellint_1. * * @tparam _Tp The floating-point type of the modulus @c __k. * @tparam _Tpp The floating-point type of the angle @c __phi. * @param __k The modulus, <tt> abs(__k) <= 1 </tt> * @param __phi The integral limit argument in radians * @throw std::domain_error if <tt> abs(__k) > 1 </tt>. */ template<typename _Tp, typename _Tpp> inline typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type ellint_1(_Tp __k, _Tpp __phi) { typedef typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type __type; return __detail::__ellint_1<__type>(__k, __phi); } // Incomplete elliptic integrals of the second kind /** * @brief Return the incomplete elliptic integral of the second kind * @f$ E(k,\phi) @f$ for @c float argument. * * @see ellint_2 for details. */ inline float ellint_2f(float __k, float __phi) { return __detail::__ellint_2<float>(__k, __phi); } /** * @brief Return the incomplete elliptic integral of the second kind * @f$ E(k,\phi) @f$. * * @see ellint_2 for details. */ inline long double ellint_2l(long double __k, long double __phi) { return __detail::__ellint_2<long double>(__k, __phi); } /** * Return the incomplete elliptic integral of the second kind * @f$ E(k,\phi) @f$. * * The incomplete elliptic integral of the second kind is defined as * @f[ * E(k,\phi) = \int_0^{\phi} \sqrt{1 - k^2 sin^2\theta} * @f] * For @f$ \phi= \pi/2 @f$ this becomes the complete elliptic integral of * the second kind, @f$ E(k) @f$. @see comp_ellint_2. * * @tparam _Tp The floating-point type of the modulus @c __k. * @tparam _Tpp The floating-point type of the angle @c __phi. * @param __k The modulus, <tt> abs(__k) <= 1 </tt> * @param __phi The integral limit argument in radians * @return The elliptic function of the second kind. * @throw std::domain_error if <tt> abs(__k) > 1 </tt>. */ template<typename _Tp, typename _Tpp> inline typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type ellint_2(_Tp __k, _Tpp __phi) { typedef typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type __type; return __detail::__ellint_2<__type>(__k, __phi); } // Incomplete elliptic integrals of the third kind /** * @brief Return the incomplete elliptic integral of the third kind * @f$ \Pi(k,\nu,\phi) @f$ for @c float argument. * * @see ellint_3 for details. */ inline float ellint_3f(float __k, float __nu, float __phi) { return __detail::__ellint_3<float>(__k, __nu, __phi); } /** * @brief Return the incomplete elliptic integral of the third kind * @f$ \Pi(k,\nu,\phi) @f$. * * @see ellint_3 for details. */ inline long double ellint_3l(long double __k, long double __nu, long double __phi) { return __detail::__ellint_3<long double>(__k, __nu, __phi); } /** * @brief Return the incomplete elliptic integral of the third kind * @f$ \Pi(k,\nu,\phi) @f$. * * The incomplete elliptic integral of the third kind is defined by: * @f[ * \Pi(k,\nu,\phi) = \int_0^{\phi} * \frac{d\theta} * {(1 - \nu \sin^2\theta) * \sqrt{1 - k^2 \sin^2\theta}} * @f] * For @f$ \phi= \pi/2 @f$ this becomes the complete elliptic integral of * the third kind, @f$ \Pi(k,\nu) @f$. @see comp_ellint_3. * * @tparam _Tp The floating-point type of the modulus @c __k. * @tparam _Tpn The floating-point type of the argument @c __nu. * @tparam _Tpp The floating-point type of the angle @c __phi. * @param __k The modulus, <tt> abs(__k) <= 1 </tt> * @param __nu The second argument * @param __phi The integral limit argument in radians * @return The elliptic function of the third kind. * @throw std::domain_error if <tt> abs(__k) > 1 </tt>. */ template<typename _Tp, typename _Tpn, typename _Tpp> inline typename __gnu_cxx::__promote_3<_Tp, _Tpn, _Tpp>::__type ellint_3(_Tp __k, _Tpn __nu, _Tpp __phi) { typedef typename __gnu_cxx::__promote_3<_Tp, _Tpn, _Tpp>::__type __type; return __detail::__ellint_3<__type>(__k, __nu, __phi); } // Exponential integrals /** * Return the exponential integral @f$ Ei(x) @f$ for @c float argument @c x. * * @see expint for details. */ inline float expintf(float __x) { return __detail::__expint<float>(__x); } /** * Return the exponential integral @f$ Ei(x) @f$ * for <tt>long double</tt> argument @c x. * * @see expint for details. */ inline long double expintl(long double __x) { return __detail::__expint<long double>(__x); } /** * Return the exponential integral @f$ Ei(x) @f$ for @c real argument @c x. * * The exponential integral is given by * \f[ * Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt * \f] * * @tparam _Tp The floating-point type of the argument @c __x. * @param __x The argument of the exponential integral function. */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type expint(_Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__expint<__type>(__x); } // Hermite polynomials /** * Return the Hermite polynomial @f$ H_n(x) @f$ of nonnegative order n * and float argument @c x. * * @see hermite for details. */ inline float hermitef(unsigned int __n, float __x) { return __detail::__poly_hermite<float>(__n, __x); } /** * Return the Hermite polynomial @f$ H_n(x) @f$ of nonnegative order n * and <tt>long double</tt> argument @c x. * * @see hermite for details. */ inline long double hermitel(unsigned int __n, long double __x) { return __detail::__poly_hermite<long double>(__n, __x); } /** * Return the Hermite polynomial @f$ H_n(x) @f$ of order n * and @c real argument @c x. * * The Hermite polynomial is defined by: * @f[ * H_n(x) = (-1)^n e^{x^2} \frac{d^n}{dx^n} e^{-x^2} * @f] * * The Hermite polynomial obeys a reflection formula: * @f[ * H_n(-x) = (-1)^n H_n(x) * @f] * * @tparam _Tp The floating-point type of the argument @c __x. * @param __n The order * @param __x The argument */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type hermite(unsigned int __n, _Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__poly_hermite<__type>(__n, __x); } // Laguerre polynomials /** * Returns the Laguerre polynomial @f$ L_n(x) @f$ of nonnegative degree @c n * and @c float argument @f$ x >= 0 @f$. * * @see laguerre for more details. */ inline float laguerref(unsigned int __n, float __x) { return __detail::__laguerre<float>(__n, __x); } /** * Returns the Laguerre polynomial @f$ L_n(x) @f$ of nonnegative degree @c n * and <tt>long double</tt> argument @f$ x >= 0 @f$. * * @see laguerre for more details. */ inline long double laguerrel(unsigned int __n, long double __x) { return __detail::__laguerre<long double>(__n, __x); } /** * Returns the Laguerre polynomial @f$ L_n(x) @f$ * of nonnegative degree @c n and real argument @f$ x >= 0 @f$. * * The Laguerre polynomial is defined by: * @f[ * L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x}) * @f] * * @tparam _Tp The floating-point type of the argument @c __x. * @param __n The nonnegative order * @param __x The argument <tt> __x >= 0 </tt> * @throw std::domain_error if <tt> __x < 0 </tt>. */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type laguerre(unsigned int __n, _Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__laguerre<__type>(__n, __x); } // Legendre polynomials /** * Return the Legendre polynomial @f$ P_l(x) @f$ of nonnegative * degree @f$ l @f$ and @c float argument @f$ |x| <= 0 @f$. * * @see legendre for more details. */ inline float legendref(unsigned int __l, float __x) { return __detail::__poly_legendre_p<float>(__l, __x); } /** * Return the Legendre polynomial @f$ P_l(x) @f$ of nonnegative * degree @f$ l @f$ and <tt>long double</tt> argument @f$ |x| <= 0 @f$. * * @see legendre for more details. */ inline long double legendrel(unsigned int __l, long double __x) { return __detail::__poly_legendre_p<long double>(__l, __x); } /** * Return the Legendre polynomial @f$ P_l(x) @f$ of nonnegative * degree @f$ l @f$ and real argument @f$ |x| <= 0 @f$. * * The Legendre function of order @f$ l @f$ and argument @f$ x @f$, * @f$ P_l(x) @f$, is defined by: * @f[ * P_l(x) = \frac{1}{2^l l!}\frac{d^l}{dx^l}(x^2 - 1)^{l} * @f] * * @tparam _Tp The floating-point type of the argument @c __x. * @param __l The degree @f$ l >= 0 @f$ * @param __x The argument @c abs(__x) <= 1 * @throw std::domain_error if @c abs(__x) > 1 */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type legendre(unsigned int __l, _Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__poly_legendre_p<__type>(__l, __x); } // Riemann zeta functions /** * Return the Riemann zeta function @f$ \zeta(s) @f$ * for @c float argument @f$ s @f$. * * @see riemann_zeta for more details. */ inline float riemann_zetaf(float __s) { return __detail::__riemann_zeta<float>(__s); } /** * Return the Riemann zeta function @f$ \zeta(s) @f$ * for <tt>long double</tt> argument @f$ s @f$. * * @see riemann_zeta for more details. */ inline long double riemann_zetal(long double __s) { return __detail::__riemann_zeta<long double>(__s); } /** * Return the Riemann zeta function @f$ \zeta(s) @f$ * for real argument @f$ s @f$. * * The Riemann zeta function is defined by: * @f[ * \zeta(s) = \sum_{k=1}^{\infty} k^{-s} \hbox{ for } s > 1 * @f] * and * @f[ * \zeta(s) = \frac{1}{1-2^{1-s}}\sum_{k=1}^{\infty}(-1)^{k-1}k^{-s} * \hbox{ for } 0 <= s <= 1 * @f] * For s < 1 use the reflection formula: * @f[ * \zeta(s) = 2^s \pi^{s-1} \sin(\frac{\pi s}{2}) \Gamma(1-s) \zeta(1-s) * @f] * * @tparam _Tp The floating-point type of the argument @c __s. * @param __s The argument <tt> s != 1 </tt> */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type riemann_zeta(_Tp __s) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__riemann_zeta<__type>(__s); } // Spherical Bessel functions /** * Return the spherical Bessel function @f$ j_n(x) @f$ of nonnegative order n * and @c float argument @f$ x >= 0 @f$. * * @see sph_bessel for more details. */ inline float sph_besself(unsigned int __n, float __x) { return __detail::__sph_bessel<float>(__n, __x); } /** * Return the spherical Bessel function @f$ j_n(x) @f$ of nonnegative order n * and <tt>long double</tt> argument @f$ x >= 0 @f$. * * @see sph_bessel for more details. */ inline long double sph_bessell(unsigned int __n, long double __x) { return __detail::__sph_bessel<long double>(__n, __x); } /** * Return the spherical Bessel function @f$ j_n(x) @f$ of nonnegative order n * and real argument @f$ x >= 0 @f$. * * The spherical Bessel function is defined by: * @f[ * j_n(x) = \left(\frac{\pi}{2x} \right) ^{1/2} J_{n+1/2}(x) * @f] * * @tparam _Tp The floating-point type of the argument @c __x. * @param __n The integral order <tt> n >= 0 </tt> * @param __x The real argument <tt> x >= 0 </tt> * @throw std::domain_error if <tt> __x < 0 </tt>. */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type sph_bessel(unsigned int __n, _Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__sph_bessel<__type>(__n, __x); } // Spherical associated Legendre functions /** * Return the spherical Legendre function of nonnegative integral * degree @c l and order @c m and float angle @f$ \theta @f$ in radians. * * @see sph_legendre for details. */ inline float sph_legendref(unsigned int __l, unsigned int __m, float __theta) { return __detail::__sph_legendre<float>(__l, __m, __theta); } /** * Return the spherical Legendre function of nonnegative integral * degree @c l and order @c m and <tt>long double</tt> angle @f$ \theta @f$ * in radians. * * @see sph_legendre for details. */ inline long double sph_legendrel(unsigned int __l, unsigned int __m, long double __theta) { return __detail::__sph_legendre<long double>(__l, __m, __theta); } /** * Return the spherical Legendre function of nonnegative integral * degree @c l and order @c m and real angle @f$ \theta @f$ in radians. * * The spherical Legendre function is defined by * @f[ * Y_l^m(\theta,\phi) = (-1)^m[\frac{(2l+1)}{4\pi} * \frac{(l-m)!}{(l+m)!}] * P_l^m(\cos\theta) \exp^{im\phi} * @f] * * @tparam _Tp The floating-point type of the angle @c __theta. * @param __l The order <tt> __l >= 0 </tt> * @param __m The degree <tt> __m >= 0 </tt> and <tt> __m <= __l </tt> * @param __theta The radian polar angle argument */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type sph_legendre(unsigned int __l, unsigned int __m, _Tp __theta) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__sph_legendre<__type>(__l, __m, __theta); } // Spherical Neumann functions /** * Return the spherical Neumann function of integral order @f$ n >= 0 @f$ * and @c float argument @f$ x >= 0 @f$. * * @see sph_neumann for details. */ inline float sph_neumannf(unsigned int __n, float __x) { return __detail::__sph_neumann<float>(__n, __x); } /** * Return the spherical Neumann function of integral order @f$ n >= 0 @f$ * and <tt>long double</tt> @f$ x >= 0 @f$. * * @see sph_neumann for details. */ inline long double sph_neumannl(unsigned int __n, long double __x) { return __detail::__sph_neumann<long double>(__n, __x); } /** * Return the spherical Neumann function of integral order @f$ n >= 0 @f$ * and real argument @f$ x >= 0 @f$. * * The spherical Neumann function is defined by * @f[ * n_n(x) = \left(\frac{\pi}{2x} \right) ^{1/2} N_{n+1/2}(x) * @f] * * @tparam _Tp The floating-point type of the argument @c __x. * @param __n The integral order <tt> n >= 0 </tt> * @param __x The real argument <tt> __x >= 0 </tt> * @throw std::domain_error if <tt> __x < 0 </tt>. */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type sph_neumann(unsigned int __n, _Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; return __detail::__sph_neumann<__type>(__n, __x); } // @} group mathsf _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #ifndef __STRICT_ANSI__ namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Airy functions /** * Return the Airy function @f$ Ai(x) @f$ of @c float argument x. */ inline float airy_aif(float __x) { float __Ai, __Bi, __Aip, __Bip; std::__detail::__airy<float>(__x, __Ai, __Bi, __Aip, __Bip); return __Ai; } /** * Return the Airy function @f$ Ai(x) @f$ of <tt>long double</tt> argument x. */ inline long double airy_ail(long double __x) { long double __Ai, __Bi, __Aip, __Bip; std::__detail::__airy<long double>(__x, __Ai, __Bi, __Aip, __Bip); return __Ai; } /** * Return the Airy function @f$ Ai(x) @f$ of real argument x. */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type airy_ai(_Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; __type __Ai, __Bi, __Aip, __Bip; std::__detail::__airy<__type>(__x, __Ai, __Bi, __Aip, __Bip); return __Ai; } /** * Return the Airy function @f$ Bi(x) @f$ of @c float argument x. */ inline float airy_bif(float __x) { float __Ai, __Bi, __Aip, __Bip; std::__detail::__airy<float>(__x, __Ai, __Bi, __Aip, __Bip); return __Bi; } /** * Return the Airy function @f$ Bi(x) @f$ of <tt>long double</tt> argument x. */ inline long double airy_bil(long double __x) { long double __Ai, __Bi, __Aip, __Bip; std::__detail::__airy<long double>(__x, __Ai, __Bi, __Aip, __Bip); return __Bi; } /** * Return the Airy function @f$ Bi(x) @f$ of real argument x. */ template<typename _Tp> inline typename __gnu_cxx::__promote<_Tp>::__type airy_bi(_Tp __x) { typedef typename __gnu_cxx::__promote<_Tp>::__type __type; __type __Ai, __Bi, __Aip, __Bip; std::__detail::__airy<__type>(__x, __Ai, __Bi, __Aip, __Bip); return __Bi; } // Confluent hypergeometric functions /** * Return the confluent hypergeometric function @f$ {}_1F_1(a;c;x) @f$ * of @c float numeratorial parameter @c a, denominatorial parameter @c c, * and argument @c x. * * @see conf_hyperg for details. */ inline float conf_hypergf(float __a, float __c, float __x) { return std::__detail::__conf_hyperg<float>(__a, __c, __x); } /** * Return the confluent hypergeometric function @f$ {}_1F_1(a;c;x) @f$ * of <tt>long double</tt> numeratorial parameter @c a, * denominatorial parameter @c c, and argument @c x. * * @see conf_hyperg for details. */ inline long double conf_hypergl(long double __a, long double __c, long double __x) { return std::__detail::__conf_hyperg<long double>(__a, __c, __x); } /** * Return the confluent hypergeometric function @f$ {}_1F_1(a;c;x) @f$ * of real numeratorial parameter @c a, denominatorial parameter @c c, * and argument @c x. * * The confluent hypergeometric function is defined by * @f[ * {}_1F_1(a;c;x) = \sum_{n=0}^{\infty} \frac{(a)_n x^n}{(c)_n n!} * @f] * where the Pochhammer symbol is @f$ (x)_k = (x)(x+1)...(x+k-1) @f$, * @f$ (x)_0 = 1 @f$ * * @param __a The numeratorial parameter * @param __c The denominatorial parameter * @param __x The argument */ template<typename _Tpa, typename _Tpc, typename _Tp> inline typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type conf_hyperg(_Tpa __a, _Tpc __c, _Tp __x) { typedef typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type __type; return std::__detail::__conf_hyperg<__type>(__a, __c, __x); } // Hypergeometric functions /** * Return the hypergeometric function @f$ {}_2F_1(a,b;c;x) @f$ * of @ float numeratorial parameters @c a and @c b, * denominatorial parameter @c c, and argument @c x. * * @see hyperg for details. */ inline float hypergf(float __a, float __b, float __c, float __x) { return std::__detail::__hyperg<float>(__a, __b, __c, __x); } /** * Return the hypergeometric function @f$ {}_2F_1(a,b;c;x) @f$ * of <tt>long double</tt> numeratorial parameters @c a and @c b, * denominatorial parameter @c c, and argument @c x. * * @see hyperg for details. */ inline long double hypergl(long double __a, long double __b, long double __c, long double __x) { return std::__detail::__hyperg<long double>(__a, __b, __c, __x); } /** * Return the hypergeometric function @f$ {}_2F_1(a,b;c;x) @f$ * of real numeratorial parameters @c a and @c b, * denominatorial parameter @c c, and argument @c x. * * The hypergeometric function is defined by * @f[ * {}_2F_1(a;c;x) = \sum_{n=0}^{\infty} \frac{(a)_n (b)_n x^n}{(c)_n n!} * @f] * where the Pochhammer symbol is @f$ (x)_k = (x)(x+1)...(x+k-1) @f$, * @f$ (x)_0 = 1 @f$ * * @param __a The first numeratorial parameter * @param __b The second numeratorial parameter * @param __c The denominatorial parameter * @param __x The argument */ template<typename _Tpa, typename _Tpb, typename _Tpc, typename _Tp> inline typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type hyperg(_Tpa __a, _Tpb __b, _Tpc __c, _Tp __x) { typedef typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp> ::__type __type; return std::__detail::__hyperg<__type>(__a, __b, __c, __x); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx #endif // __STRICT_ANSI__ #pragma GCC visibility pop #endif // _GLIBCXX_BITS_SPECFUN_H c++/8/bits/algorithmfwd.h 0000644 00000052350 15146341150 0011071 0 ustar 00 // <algorithm> Forward declarations -*- C++ -*- // Copyright (C) 2007-2018 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 Operation * @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 >= 201103L template<typename _IIter, typename _Predicate> bool all_of(_IIter, _IIter, _Predicate); template<typename _IIter, typename _Predicate> bool any_of(_IIter, _IIter, _Predicate); #endif template<typename _FIter, typename _Tp> bool binary_search(_FIter, _FIter, const _Tp&); template<typename _FIter, typename _Tp, typename _Compare> 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> _OIter copy(_IIter, _IIter, _OIter); template<typename _BIter1, typename _BIter2> _BIter2 copy_backward(_BIter1, _BIter1, _BIter2); #if __cplusplus >= 201103L template<typename _IIter, typename _OIter, typename _Predicate> _OIter copy_if(_IIter, _IIter, _OIter, _Predicate); template<typename _IIter, typename _Size, typename _OIter> _OIter copy_n(_IIter, _Size, _OIter); #endif // count // count_if template<typename _FIter, typename _Tp> pair<_FIter, _FIter> equal_range(_FIter, _FIter, const _Tp&); template<typename _FIter, typename _Tp, typename _Compare> pair<_FIter, _FIter> equal_range(_FIter, _FIter, const _Tp&, _Compare); template<typename _FIter, typename _Tp> void fill(_FIter, _FIter, const _Tp&); template<typename _OIter, typename _Size, typename _Tp> _OIter fill_n(_OIter, _Size, const _Tp&); // find template<typename _FIter1, typename _FIter2> _FIter1 find_end(_FIter1, _FIter1, _FIter2, _FIter2); template<typename _FIter1, typename _FIter2, typename _BinaryPredicate> _FIter1 find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate); // find_first_of // find_if #if __cplusplus >= 201103L template<typename _IIter, typename _Predicate> _IIter find_if_not(_IIter, _IIter, _Predicate); #endif // for_each // generate // generate_n template<typename _IIter1, typename _IIter2> bool includes(_IIter1, _IIter1, _IIter2, _IIter2); template<typename _IIter1, typename _IIter2, typename _Compare> 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> bool is_heap(_RAIter, _RAIter); template<typename _RAIter, typename _Compare> bool is_heap(_RAIter, _RAIter, _Compare); template<typename _RAIter> _RAIter is_heap_until(_RAIter, _RAIter); template<typename _RAIter, typename _Compare> _RAIter is_heap_until(_RAIter, _RAIter, _Compare); template<typename _IIter, typename _Predicate> bool is_partitioned(_IIter, _IIter, _Predicate); template<typename _FIter1, typename _FIter2> bool is_permutation(_FIter1, _FIter1, _FIter2); template<typename _FIter1, typename _FIter2, typename _BinaryPredicate> bool is_permutation(_FIter1, _FIter1, _FIter2, _BinaryPredicate); template<typename _FIter> bool is_sorted(_FIter, _FIter); template<typename _FIter, typename _Compare> bool is_sorted(_FIter, _FIter, _Compare); template<typename _FIter> _FIter is_sorted_until(_FIter, _FIter); template<typename _FIter, typename _Compare> _FIter is_sorted_until(_FIter, _FIter, _Compare); #endif template<typename _FIter1, typename _FIter2> void iter_swap(_FIter1, _FIter2); template<typename _FIter, typename _Tp> _FIter lower_bound(_FIter, _FIter, const _Tp&); template<typename _FIter, typename _Tp, typename _Compare> _FIter lower_bound(_FIter, _FIter, const _Tp&, _Compare); template<typename _RAIter> void make_heap(_RAIter, _RAIter); template<typename _RAIter, typename _Compare> 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> bool next_permutation(_BIter, _BIter); template<typename _BIter, typename _Compare> bool next_permutation(_BIter, _BIter, _Compare); #if __cplusplus >= 201103L template<typename _IIter, typename _Predicate> bool none_of(_IIter, _IIter, _Predicate); #endif // nth_element // partial_sort template<typename _IIter, typename _RAIter> _RAIter partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter); template<typename _IIter, typename _RAIter, typename _Compare> _RAIter partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter, _Compare); // partition #if __cplusplus >= 201103L template<typename _IIter, typename _OIter1, typename _OIter2, typename _Predicate> pair<_OIter1, _OIter2> partition_copy(_IIter, _IIter, _OIter1, _OIter2, _Predicate); template<typename _FIter, typename _Predicate> _FIter partition_point(_FIter, _FIter, _Predicate); #endif template<typename _RAIter> void pop_heap(_RAIter, _RAIter); template<typename _RAIter, typename _Compare> void pop_heap(_RAIter, _RAIter, _Compare); template<typename _BIter> bool prev_permutation(_BIter, _BIter); template<typename _BIter, typename _Compare> bool prev_permutation(_BIter, _BIter, _Compare); template<typename _RAIter> void push_heap(_RAIter, _RAIter); template<typename _RAIter, typename _Compare> void push_heap(_RAIter, _RAIter, _Compare); // random_shuffle template<typename _FIter, typename _Tp> _FIter remove(_FIter, _FIter, const _Tp&); template<typename _FIter, typename _Predicate> _FIter remove_if(_FIter, _FIter, _Predicate); template<typename _IIter, typename _OIter, typename _Tp> _OIter remove_copy(_IIter, _IIter, _OIter, const _Tp&); template<typename _IIter, typename _OIter, typename _Predicate> _OIter remove_copy_if(_IIter, _IIter, _OIter, _Predicate); // replace template<typename _IIter, typename _OIter, typename _Tp> _OIter replace_copy(_IIter, _IIter, _OIter, const _Tp&, const _Tp&); template<typename _Iter, typename _OIter, typename _Predicate, typename _Tp> _OIter replace_copy_if(_Iter, _Iter, _OIter, _Predicate, const _Tp&); // replace_if template<typename _BIter> void reverse(_BIter, _BIter); template<typename _BIter, typename _OIter> _OIter reverse_copy(_BIter, _BIter, _OIter); inline namespace _V2 { template<typename _FIter> _FIter rotate(_FIter, _FIter, _FIter); } template<typename _FIter, typename _OIter> _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> void sort_heap(_RAIter, _RAIter); template<typename _RAIter, typename _Compare> void sort_heap(_RAIter, _RAIter, _Compare); template<typename _BIter, typename _Predicate> _BIter stable_partition(_BIter, _BIter, _Predicate); #if __cplusplus < 201103L // For C++11 swap() is declared in <type_traits>. template<typename _Tp, size_t _Nm> inline void swap(_Tp& __a, _Tp& __b); template<typename _Tp, size_t _Nm> inline void swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]); #endif template<typename _FIter1, typename _FIter2> _FIter2 swap_ranges(_FIter1, _FIter1, _FIter2); // transform template<typename _FIter> _FIter unique(_FIter, _FIter); template<typename _FIter, typename _BinaryPredicate> _FIter unique(_FIter, _FIter, _BinaryPredicate); // unique_copy template<typename _FIter, typename _Tp> _FIter upper_bound(_FIter, _FIter, const _Tp&); template<typename _FIter, typename _Tp, typename _Compare> _FIter upper_bound(_FIter, _FIter, const _Tp&, _Compare); _GLIBCXX_BEGIN_NAMESPACE_ALGO template<typename _FIter> _FIter adjacent_find(_FIter, _FIter); template<typename _FIter, typename _BinaryPredicate> _FIter adjacent_find(_FIter, _FIter, _BinaryPredicate); template<typename _IIter, typename _Tp> typename iterator_traits<_IIter>::difference_type count(_IIter, _IIter, const _Tp&); template<typename _IIter, typename _Predicate> typename iterator_traits<_IIter>::difference_type count_if(_IIter, _IIter, _Predicate); template<typename _IIter1, typename _IIter2> bool equal(_IIter1, _IIter1, _IIter2); template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> bool equal(_IIter1, _IIter1, _IIter2, _BinaryPredicate); template<typename _IIter, typename _Tp> _IIter find(_IIter, _IIter, const _Tp&); template<typename _FIter1, typename _FIter2> _FIter1 find_first_of(_FIter1, _FIter1, _FIter2, _FIter2); template<typename _FIter1, typename _FIter2, typename _BinaryPredicate> _FIter1 find_first_of(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate); template<typename _IIter, typename _Predicate> _IIter find_if(_IIter, _IIter, _Predicate); template<typename _IIter, typename _Funct> _Funct for_each(_IIter, _IIter, _Funct); template<typename _FIter, typename _Generator> void generate(_FIter, _FIter, _Generator); template<typename _OIter, typename _Size, typename _Generator> _OIter generate_n(_OIter, _Size, _Generator); template<typename _IIter1, typename _IIter2> bool lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2); template<typename _IIter1, typename _IIter2, typename _Compare> 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> _OIter merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare> _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> pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2); template<typename _IIter1, typename _IIter2, typename _BinaryPredicate> pair<_IIter1, _IIter2> mismatch(_IIter1, _IIter1, _IIter2, _BinaryPredicate); template<typename _RAIter> void nth_element(_RAIter, _RAIter, _RAIter); template<typename _RAIter, typename _Compare> void nth_element(_RAIter, _RAIter, _RAIter, _Compare); template<typename _RAIter> void partial_sort(_RAIter, _RAIter, _RAIter); template<typename _RAIter, typename _Compare> void partial_sort(_RAIter, _RAIter, _RAIter, _Compare); template<typename _BIter, typename _Predicate> _BIter partition(_BIter, _BIter, _Predicate); template<typename _RAIter> void random_shuffle(_RAIter, _RAIter); template<typename _RAIter, typename _Generator> void random_shuffle(_RAIter, _RAIter, #if __cplusplus >= 201103L _Generator&&); #else _Generator&); #endif template<typename _FIter, typename _Tp> void replace(_FIter, _FIter, const _Tp&, const _Tp&); template<typename _FIter, typename _Predicate, typename _Tp> void replace_if(_FIter, _FIter, _Predicate, const _Tp&); template<typename _FIter1, typename _FIter2> _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2); template<typename _FIter1, typename _FIter2, typename _BinaryPredicate> _FIter1 search(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate); template<typename _FIter, typename _Size, typename _Tp> _FIter search_n(_FIter, _FIter, _Size, const _Tp&); template<typename _FIter, typename _Size, typename _Tp, typename _BinaryPredicate> _FIter search_n(_FIter, _FIter, _Size, const _Tp&, _BinaryPredicate); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare> _OIter set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare> _OIter set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare> _OIter set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare); template<typename _IIter1, typename _IIter2, typename _OIter> _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter); template<typename _IIter1, typename _IIter2, typename _OIter, typename _Compare> _OIter set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare); template<typename _RAIter> void sort(_RAIter, _RAIter); template<typename _RAIter, typename _Compare> 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> _OIter transform(_IIter, _IIter, _OIter, _UnaryOperation); template<typename _IIter1, typename _IIter2, typename _OIter, typename _BinaryOperation> _OIter transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation); template<typename _IIter, typename _OIter> _OIter unique_copy(_IIter, _IIter, _OIter); template<typename _IIter, typename _OIter, typename _BinaryPredicate> _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 c++/8/bits/fstream.tcc 0000644 00000100037 15146341150 0010361 0 ustar 00 // File based streams -*- C++ -*- // Copyright (C) 1997-2018 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/fstream.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{fstream} */ // // ISO C++ 14882: 27.8 File-based streams // #ifndef _FSTREAM_TCC #define _FSTREAM_TCC 1 #pragma GCC system_header #include <bits/cxxabi_forced.h> #include <bits/move.h> // for swap namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: _M_allocate_internal_buffer() { // Allocate internal buffer only if one doesn't already exist // (either allocated or provided by the user via setbuf). if (!_M_buf_allocated && !_M_buf) { _M_buf = new char_type[_M_buf_size]; _M_buf_allocated = true; } } template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: _M_destroy_internal_buffer() throw() { if (_M_buf_allocated) { delete [] _M_buf; _M_buf = 0; _M_buf_allocated = false; } delete [] _M_ext_buf; _M_ext_buf = 0; _M_ext_buf_size = 0; _M_ext_next = 0; _M_ext_end = 0; } template<typename _CharT, typename _Traits> basic_filebuf<_CharT, _Traits>:: basic_filebuf() : __streambuf_type(), _M_lock(), _M_file(&_M_lock), _M_mode(ios_base::openmode(0)), _M_state_beg(), _M_state_cur(), _M_state_last(), _M_buf(0), _M_buf_size(BUFSIZ), _M_buf_allocated(false), _M_reading(false), _M_writing(false), _M_pback(), _M_pback_cur_save(0), _M_pback_end_save(0), _M_pback_init(false), _M_codecvt(0), _M_ext_buf(0), _M_ext_buf_size(0), _M_ext_next(0), _M_ext_end(0) { if (has_facet<__codecvt_type>(this->_M_buf_locale)) _M_codecvt = &use_facet<__codecvt_type>(this->_M_buf_locale); } #if __cplusplus >= 201103L template<typename _CharT, typename _Traits> basic_filebuf<_CharT, _Traits>:: basic_filebuf(basic_filebuf&& __rhs) : __streambuf_type(__rhs), _M_lock(), _M_file(std::move(__rhs._M_file), &_M_lock), _M_mode(std::__exchange(__rhs._M_mode, ios_base::openmode(0))), _M_state_beg(std::move(__rhs._M_state_beg)), _M_state_cur(std::move(__rhs._M_state_cur)), _M_state_last(std::move(__rhs._M_state_last)), _M_buf(std::__exchange(__rhs._M_buf, nullptr)), _M_buf_size(std::__exchange(__rhs._M_buf_size, 1)), _M_buf_allocated(std::__exchange(__rhs._M_buf_allocated, false)), _M_reading(std::__exchange(__rhs._M_reading, false)), _M_writing(std::__exchange(__rhs._M_writing, false)), _M_pback(__rhs._M_pback), _M_pback_cur_save(std::__exchange(__rhs._M_pback_cur_save, nullptr)), _M_pback_end_save(std::__exchange(__rhs._M_pback_end_save, nullptr)), _M_pback_init(std::__exchange(__rhs._M_pback_init, false)), _M_codecvt(__rhs._M_codecvt), _M_ext_buf(std::__exchange(__rhs._M_ext_buf, nullptr)), _M_ext_buf_size(std::__exchange(__rhs._M_ext_buf_size, 0)), _M_ext_next(std::__exchange(__rhs._M_ext_next, nullptr)), _M_ext_end(std::__exchange(__rhs._M_ext_end, nullptr)) { __rhs._M_set_buffer(-1); __rhs._M_state_last = __rhs._M_state_cur = __rhs._M_state_beg; } template<typename _CharT, typename _Traits> basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>:: operator=(basic_filebuf&& __rhs) { this->close(); __streambuf_type::operator=(__rhs); _M_file.swap(__rhs._M_file); _M_mode = std::__exchange(__rhs._M_mode, ios_base::openmode(0)); _M_state_beg = std::move(__rhs._M_state_beg); _M_state_cur = std::move(__rhs._M_state_cur); _M_state_last = std::move(__rhs._M_state_last); _M_buf = std::__exchange(__rhs._M_buf, nullptr); _M_buf_size = std::__exchange(__rhs._M_buf_size, 1); _M_buf_allocated = std::__exchange(__rhs._M_buf_allocated, false); _M_ext_buf = std::__exchange(__rhs._M_ext_buf, nullptr); _M_ext_buf_size = std::__exchange(__rhs._M_ext_buf_size, 0); _M_ext_next = std::__exchange(__rhs._M_ext_next, nullptr); _M_ext_end = std::__exchange(__rhs._M_ext_end, nullptr); _M_reading = std::__exchange(__rhs._M_reading, false); _M_writing = std::__exchange(__rhs._M_writing, false); _M_pback_cur_save = std::__exchange(__rhs._M_pback_cur_save, nullptr); _M_pback_end_save = std::__exchange(__rhs._M_pback_end_save, nullptr); _M_pback_init = std::__exchange(__rhs._M_pback_init, false); __rhs._M_set_buffer(-1); __rhs._M_state_last = __rhs._M_state_cur = __rhs._M_state_beg; return *this; } template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: swap(basic_filebuf& __rhs) { __streambuf_type::swap(__rhs); _M_file.swap(__rhs._M_file); std::swap(_M_mode, __rhs._M_mode); std::swap(_M_state_beg, __rhs._M_state_beg); std::swap(_M_state_cur, __rhs._M_state_cur); std::swap(_M_state_last, __rhs._M_state_last); std::swap(_M_buf, __rhs._M_buf); std::swap(_M_buf_size, __rhs._M_buf_size); std::swap(_M_buf_allocated, __rhs._M_buf_allocated); std::swap(_M_ext_buf, __rhs._M_ext_buf); std::swap(_M_ext_buf_size, __rhs._M_ext_buf_size); std::swap(_M_ext_next, __rhs._M_ext_next); std::swap(_M_ext_end, __rhs._M_ext_end); std::swap(_M_reading, __rhs._M_reading); std::swap(_M_writing, __rhs._M_writing); std::swap(_M_pback_cur_save, __rhs._M_pback_cur_save); std::swap(_M_pback_end_save, __rhs._M_pback_end_save); std::swap(_M_pback_init, __rhs._M_pback_init); } #endif template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::__filebuf_type* basic_filebuf<_CharT, _Traits>:: open(const char* __s, ios_base::openmode __mode) { __filebuf_type *__ret = 0; if (!this->is_open()) { _M_file.open(__s, __mode); if (this->is_open()) { _M_allocate_internal_buffer(); _M_mode = __mode; // Setup initial buffer to 'uncommitted' mode. _M_reading = false; _M_writing = false; _M_set_buffer(-1); // Reset to initial state. _M_state_last = _M_state_cur = _M_state_beg; // 27.8.1.3,4 if ((__mode & ios_base::ate) && this->seekoff(0, ios_base::end, __mode) == pos_type(off_type(-1))) this->close(); else __ret = this; } } return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::__filebuf_type* basic_filebuf<_CharT, _Traits>:: close() { if (!this->is_open()) return 0; bool __testfail = false; { // NB: Do this here so that re-opened filebufs will be cool... struct __close_sentry { basic_filebuf *__fb; __close_sentry (basic_filebuf *__fbi): __fb(__fbi) { } ~__close_sentry () { __fb->_M_mode = ios_base::openmode(0); __fb->_M_pback_init = false; __fb->_M_destroy_internal_buffer(); __fb->_M_reading = false; __fb->_M_writing = false; __fb->_M_set_buffer(-1); __fb->_M_state_last = __fb->_M_state_cur = __fb->_M_state_beg; } } __cs (this); __try { if (!_M_terminate_output()) __testfail = true; } __catch(__cxxabiv1::__forced_unwind&) { _M_file.close(); __throw_exception_again; } __catch(...) { __testfail = true; } } if (!_M_file.close()) __testfail = true; if (__testfail) return 0; else return this; } template<typename _CharT, typename _Traits> streamsize basic_filebuf<_CharT, _Traits>:: showmanyc() { streamsize __ret = -1; const bool __testin = _M_mode & ios_base::in; if (__testin && this->is_open()) { // For a stateful encoding (-1) the pending sequence might be just // shift and unshift prefixes with no actual character. __ret = this->egptr() - this->gptr(); #if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM // About this workaround, see libstdc++/20806. const bool __testbinary = _M_mode & ios_base::binary; if (__check_facet(_M_codecvt).encoding() >= 0 && __testbinary) #else if (__check_facet(_M_codecvt).encoding() >= 0) #endif __ret += _M_file.showmanyc() / _M_codecvt->max_length(); } return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>:: underflow() { int_type __ret = traits_type::eof(); const bool __testin = _M_mode & ios_base::in; if (__testin) { if (_M_writing) { if (overflow() == traits_type::eof()) return __ret; _M_set_buffer(-1); _M_writing = false; } // Check for pback madness, and if so switch back to the // normal buffers and jet outta here before expensive // fileops happen... _M_destroy_pback(); if (this->gptr() < this->egptr()) return traits_type::to_int_type(*this->gptr()); // Get and convert input sequence. const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; // Will be set to true if ::read() returns 0 indicating EOF. bool __got_eof = false; // Number of internal characters produced. streamsize __ilen = 0; codecvt_base::result __r = codecvt_base::ok; if (__check_facet(_M_codecvt).always_noconv()) { __ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()), __buflen); if (__ilen == 0) __got_eof = true; } else { // Worst-case number of external bytes. // XXX Not done encoding() == -1. const int __enc = _M_codecvt->encoding(); streamsize __blen; // Minimum buffer size. streamsize __rlen; // Number of chars to read. if (__enc > 0) __blen = __rlen = __buflen * __enc; else { __blen = __buflen + _M_codecvt->max_length() - 1; __rlen = __buflen; } const streamsize __remainder = _M_ext_end - _M_ext_next; __rlen = __rlen > __remainder ? __rlen - __remainder : 0; // An imbue in 'read' mode implies first converting the external // chars already present. if (_M_reading && this->egptr() == this->eback() && __remainder) __rlen = 0; // Allocate buffer if necessary and move unconverted // bytes to front. if (_M_ext_buf_size < __blen) { char* __buf = new char[__blen]; if (__remainder) __builtin_memcpy(__buf, _M_ext_next, __remainder); delete [] _M_ext_buf; _M_ext_buf = __buf; _M_ext_buf_size = __blen; } else if (__remainder) __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder); _M_ext_next = _M_ext_buf; _M_ext_end = _M_ext_buf + __remainder; _M_state_last = _M_state_cur; do { if (__rlen > 0) { // Sanity check! // This may fail if the return value of // codecvt::max_length() is bogus. if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size) { __throw_ios_failure(__N("basic_filebuf::underflow " "codecvt::max_length() " "is not valid")); } streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen); if (__elen == 0) __got_eof = true; else if (__elen == -1) break; _M_ext_end += __elen; } char_type* __iend = this->eback(); if (_M_ext_next < _M_ext_end) __r = _M_codecvt->in(_M_state_cur, _M_ext_next, _M_ext_end, _M_ext_next, this->eback(), this->eback() + __buflen, __iend); if (__r == codecvt_base::noconv) { size_t __avail = _M_ext_end - _M_ext_buf; __ilen = std::min(__avail, __buflen); traits_type::copy(this->eback(), reinterpret_cast<char_type*> (_M_ext_buf), __ilen); _M_ext_next = _M_ext_buf + __ilen; } else __ilen = __iend - this->eback(); // _M_codecvt->in may return error while __ilen > 0: this is // ok, and actually occurs in case of mixed encodings (e.g., // XML files). if (__r == codecvt_base::error) break; __rlen = 1; } while (__ilen == 0 && !__got_eof); } if (__ilen > 0) { _M_set_buffer(__ilen); _M_reading = true; __ret = traits_type::to_int_type(*this->gptr()); } else if (__got_eof) { // If the actual end of file is reached, set 'uncommitted' // mode, thus allowing an immediate write without an // intervening seek. _M_set_buffer(-1); _M_reading = false; // However, reaching it while looping on partial means that // the file has got an incomplete character. if (__r == codecvt_base::partial) __throw_ios_failure(__N("basic_filebuf::underflow " "incomplete character in file")); } else if (__r == codecvt_base::error) __throw_ios_failure(__N("basic_filebuf::underflow " "invalid byte sequence in file")); else __throw_ios_failure(__N("basic_filebuf::underflow " "error reading the file")); } return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>:: pbackfail(int_type __i) { int_type __ret = traits_type::eof(); const bool __testin = _M_mode & ios_base::in; if (__testin) { if (_M_writing) { if (overflow() == traits_type::eof()) return __ret; _M_set_buffer(-1); _M_writing = false; } // Remember whether the pback buffer is active, otherwise below // we may try to store in it a second char (libstdc++/9761). const bool __testpb = _M_pback_init; const bool __testeof = traits_type::eq_int_type(__i, __ret); int_type __tmp; if (this->eback() < this->gptr()) { this->gbump(-1); __tmp = traits_type::to_int_type(*this->gptr()); } else if (this->seekoff(-1, ios_base::cur) != pos_type(off_type(-1))) { __tmp = this->underflow(); if (traits_type::eq_int_type(__tmp, __ret)) return __ret; } else { // At the beginning of the buffer, need to make a // putback position available. But the seek may fail // (f.i., at the beginning of a file, see // libstdc++/9439) and in that case we return // traits_type::eof(). return __ret; } // Try to put back __i into input sequence in one of three ways. // Order these tests done in is unspecified by the standard. if (!__testeof && traits_type::eq_int_type(__i, __tmp)) __ret = __i; else if (__testeof) __ret = traits_type::not_eof(__i); else if (!__testpb) { _M_create_pback(); _M_reading = true; *this->gptr() = traits_type::to_char_type(__i); __ret = __i; } } return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>:: overflow(int_type __c) { int_type __ret = traits_type::eof(); const bool __testeof = traits_type::eq_int_type(__c, __ret); const bool __testout = (_M_mode & ios_base::out || _M_mode & ios_base::app); if (__testout) { if (_M_reading) { _M_destroy_pback(); const int __gptr_off = _M_get_ext_pos(_M_state_last); if (_M_seek(__gptr_off, ios_base::cur, _M_state_last) == pos_type(off_type(-1))) return __ret; } if (this->pbase() < this->pptr()) { // If appropriate, append the overflow char. if (!__testeof) { *this->pptr() = traits_type::to_char_type(__c); this->pbump(1); } // Convert pending sequence to external representation, // and output. if (_M_convert_to_external(this->pbase(), this->pptr() - this->pbase())) { _M_set_buffer(0); __ret = traits_type::not_eof(__c); } } else if (_M_buf_size > 1) { // Overflow in 'uncommitted' mode: set _M_writing, set // the buffer to the initial 'write' mode, and put __c // into the buffer. _M_set_buffer(0); _M_writing = true; if (!__testeof) { *this->pptr() = traits_type::to_char_type(__c); this->pbump(1); } __ret = traits_type::not_eof(__c); } else { // Unbuffered. char_type __conv = traits_type::to_char_type(__c); if (__testeof || _M_convert_to_external(&__conv, 1)) { _M_writing = true; __ret = traits_type::not_eof(__c); } } } return __ret; } template<typename _CharT, typename _Traits> bool basic_filebuf<_CharT, _Traits>:: _M_convert_to_external(_CharT* __ibuf, streamsize __ilen) { // Sizes of external and pending output. streamsize __elen; streamsize __plen; if (__check_facet(_M_codecvt).always_noconv()) { __elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen); __plen = __ilen; } else { // Worst-case number of external bytes needed. // XXX Not done encoding() == -1. streamsize __blen = __ilen * _M_codecvt->max_length(); char* __buf = static_cast<char*>(__builtin_alloca(__blen)); char* __bend; const char_type* __iend; codecvt_base::result __r; __r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen, __iend, __buf, __buf + __blen, __bend); if (__r == codecvt_base::ok || __r == codecvt_base::partial) __blen = __bend - __buf; else if (__r == codecvt_base::noconv) { // Same as the always_noconv case above. __buf = reinterpret_cast<char*>(__ibuf); __blen = __ilen; } else __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " "conversion error")); __elen = _M_file.xsputn(__buf, __blen); __plen = __blen; // Try once more for partial conversions. if (__r == codecvt_base::partial && __elen == __plen) { const char_type* __iresume = __iend; streamsize __rlen = this->pptr() - __iend; __r = _M_codecvt->out(_M_state_cur, __iresume, __iresume + __rlen, __iend, __buf, __buf + __blen, __bend); if (__r != codecvt_base::error) { __rlen = __bend - __buf; __elen = _M_file.xsputn(__buf, __rlen); __plen = __rlen; } else __throw_ios_failure(__N("basic_filebuf::_M_convert_to_external " "conversion error")); } } return __elen == __plen; } template<typename _CharT, typename _Traits> streamsize basic_filebuf<_CharT, _Traits>:: xsgetn(_CharT* __s, streamsize __n) { // Clear out pback buffer before going on to the real deal... streamsize __ret = 0; if (_M_pback_init) { if (__n > 0 && this->gptr() == this->eback()) { *__s++ = *this->gptr(); // emulate non-underflowing sbumpc this->gbump(1); __ret = 1; --__n; } _M_destroy_pback(); } else if (_M_writing) { if (overflow() == traits_type::eof()) return __ret; _M_set_buffer(-1); _M_writing = false; } // Optimization in the always_noconv() case, to be generalized in the // future: when __n > __buflen we read directly instead of using the // buffer repeatedly. const bool __testin = _M_mode & ios_base::in; const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1; if (__n > __buflen && __check_facet(_M_codecvt).always_noconv() && __testin) { // First, copy the chars already present in the buffer. const streamsize __avail = this->egptr() - this->gptr(); if (__avail != 0) { traits_type::copy(__s, this->gptr(), __avail); __s += __avail; this->setg(this->eback(), this->gptr() + __avail, this->egptr()); __ret += __avail; __n -= __avail; } // Need to loop in case of short reads (relatively common // with pipes). streamsize __len; for (;;) { __len = _M_file.xsgetn(reinterpret_cast<char*>(__s), __n); if (__len == -1) __throw_ios_failure(__N("basic_filebuf::xsgetn " "error reading the file")); if (__len == 0) break; __n -= __len; __ret += __len; if (__n == 0) break; __s += __len; } if (__n == 0) { // Set _M_reading. Buffer is already in initial 'read' mode. _M_reading = true; } else if (__len == 0) { // If end of file is reached, set 'uncommitted' // mode, thus allowing an immediate write without // an intervening seek. _M_set_buffer(-1); _M_reading = false; } } else __ret += __streambuf_type::xsgetn(__s, __n); return __ret; } template<typename _CharT, typename _Traits> streamsize basic_filebuf<_CharT, _Traits>:: xsputn(const _CharT* __s, streamsize __n) { streamsize __ret = 0; // Optimization in the always_noconv() case, to be generalized in the // future: when __n is sufficiently large we write directly instead of // using the buffer. const bool __testout = (_M_mode & ios_base::out || _M_mode & ios_base::app); if (__check_facet(_M_codecvt).always_noconv() && __testout && !_M_reading) { // Measurement would reveal the best choice. const streamsize __chunk = 1ul << 10; streamsize __bufavail = this->epptr() - this->pptr(); // Don't mistake 'uncommitted' mode buffered with unbuffered. if (!_M_writing && _M_buf_size > 1) __bufavail = _M_buf_size - 1; const streamsize __limit = std::min(__chunk, __bufavail); if (__n >= __limit) { const streamsize __buffill = this->pptr() - this->pbase(); const char* __buf = reinterpret_cast<const char*>(this->pbase()); __ret = _M_file.xsputn_2(__buf, __buffill, reinterpret_cast<const char*>(__s), __n); if (__ret == __buffill + __n) { _M_set_buffer(0); _M_writing = true; } if (__ret > __buffill) __ret -= __buffill; else __ret = 0; } else __ret = __streambuf_type::xsputn(__s, __n); } else __ret = __streambuf_type::xsputn(__s, __n); return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::__streambuf_type* basic_filebuf<_CharT, _Traits>:: setbuf(char_type* __s, streamsize __n) { if (!this->is_open()) { if (__s == 0 && __n == 0) _M_buf_size = 1; else if (__s && __n > 0) { // This is implementation-defined behavior, and assumes that // an external char_type array of length __n exists and has // been pre-allocated. If this is not the case, things will // quickly blow up. When __n > 1, __n - 1 positions will be // used for the get area, __n - 1 for the put area and 1 // position to host the overflow char of a full put area. // When __n == 1, 1 position will be used for the get area // and 0 for the put area, as in the unbuffered case above. _M_buf = __s; _M_buf_size = __n; } } return this; } // According to 27.8.1.4 p11 - 13, seekoff should ignore the last // argument (of type openmode). template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>:: seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) { int __width = 0; if (_M_codecvt) __width = _M_codecvt->encoding(); if (__width < 0) __width = 0; pos_type __ret = pos_type(off_type(-1)); const bool __testfail = __off != 0 && __width <= 0; if (this->is_open() && !__testfail) { // tellg and tellp queries do not affect any state, unless // ! always_noconv and the put sequence is not empty. // In that case, determining the position requires converting the // put sequence. That doesn't use ext_buf, so requires a flush. bool __no_movement = __way == ios_base::cur && __off == 0 && (!_M_writing || _M_codecvt->always_noconv()); // Ditch any pback buffers to avoid confusion. if (!__no_movement) _M_destroy_pback(); // Correct state at destination. Note that this is the correct // state for the current position during output, because // codecvt::unshift() returns the state to the initial state. // This is also the correct state at the end of the file because // an unshift sequence should have been written at the end. __state_type __state = _M_state_beg; off_type __computed_off = __off * __width; if (_M_reading && __way == ios_base::cur) { __state = _M_state_last; __computed_off += _M_get_ext_pos(__state); } if (!__no_movement) __ret = _M_seek(__computed_off, __way, __state); else { if (_M_writing) __computed_off = this->pptr() - this->pbase(); off_type __file_off = _M_file.seekoff(0, ios_base::cur); if (__file_off != off_type(-1)) { __ret = __file_off + __computed_off; __ret.state(__state); } } } return __ret; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 171. Strange seekpos() semantics due to joint position // According to the resolution of DR 171, seekpos should ignore the last // argument (of type openmode). template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>:: seekpos(pos_type __pos, ios_base::openmode) { pos_type __ret = pos_type(off_type(-1)); if (this->is_open()) { // Ditch any pback buffers to avoid confusion. _M_destroy_pback(); __ret = _M_seek(off_type(__pos), ios_base::beg, __pos.state()); } return __ret; } template<typename _CharT, typename _Traits> typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>:: _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state) { pos_type __ret = pos_type(off_type(-1)); if (_M_terminate_output()) { off_type __file_off = _M_file.seekoff(__off, __way); if (__file_off != off_type(-1)) { _M_reading = false; _M_writing = false; _M_ext_next = _M_ext_end = _M_ext_buf; _M_set_buffer(-1); _M_state_cur = __state; __ret = __file_off; __ret.state(_M_state_cur); } } return __ret; } // Returns the distance from the end of the ext buffer to the point // corresponding to gptr(). This is a negative value. Updates __state // from eback() correspondence to gptr(). template<typename _CharT, typename _Traits> int basic_filebuf<_CharT, _Traits>:: _M_get_ext_pos(__state_type& __state) { if (_M_codecvt->always_noconv()) return this->gptr() - this->egptr(); else { // Calculate offset from _M_ext_buf that corresponds to // gptr(). Precondition: __state == _M_state_last, which // corresponds to eback(). const int __gptr_off = _M_codecvt->length(__state, _M_ext_buf, _M_ext_next, this->gptr() - this->eback()); return _M_ext_buf + __gptr_off - _M_ext_end; } } template<typename _CharT, typename _Traits> bool basic_filebuf<_CharT, _Traits>:: _M_terminate_output() { // Part one: update the output sequence. bool __testvalid = true; if (this->pbase() < this->pptr()) { const int_type __tmp = this->overflow(); if (traits_type::eq_int_type(__tmp, traits_type::eof())) __testvalid = false; } // Part two: output unshift sequence. if (_M_writing && !__check_facet(_M_codecvt).always_noconv() && __testvalid) { // Note: this value is arbitrary, since there is no way to // get the length of the unshift sequence from codecvt, // without calling unshift. const size_t __blen = 128; char __buf[__blen]; codecvt_base::result __r; streamsize __ilen = 0; do { char* __next; __r = _M_codecvt->unshift(_M_state_cur, __buf, __buf + __blen, __next); if (__r == codecvt_base::error) __testvalid = false; else if (__r == codecvt_base::ok || __r == codecvt_base::partial) { __ilen = __next - __buf; if (__ilen > 0) { const streamsize __elen = _M_file.xsputn(__buf, __ilen); if (__elen != __ilen) __testvalid = false; } } } while (__r == codecvt_base::partial && __ilen > 0 && __testvalid); if (__testvalid) { // This second call to overflow() is required by the standard, // but it's not clear why it's needed, since the output buffer // should be empty by this point (it should have been emptied // in the first call to overflow()). const int_type __tmp = this->overflow(); if (traits_type::eq_int_type(__tmp, traits_type::eof())) __testvalid = false; } } return __testvalid; } template<typename _CharT, typename _Traits> int basic_filebuf<_CharT, _Traits>:: sync() { // Make sure that the internal buffer resyncs its idea of // the file position with the external file. int __ret = 0; if (this->pbase() < this->pptr()) { const int_type __tmp = this->overflow(); if (traits_type::eq_int_type(__tmp, traits_type::eof())) __ret = -1; } return __ret; } template<typename _CharT, typename _Traits> void basic_filebuf<_CharT, _Traits>:: imbue(const locale& __loc) { bool __testvalid = true; const __codecvt_type* _M_codecvt_tmp = 0; if (__builtin_expect(has_facet<__codecvt_type>(__loc), true)) _M_codecvt_tmp = &use_facet<__codecvt_type>(__loc); if (this->is_open()) { // encoding() == -1 is ok only at the beginning. if ((_M_reading || _M_writing) && __check_facet(_M_codecvt).encoding() == -1) __testvalid = false; else { if (_M_reading) { if (__check_facet(_M_codecvt).always_noconv()) { if (_M_codecvt_tmp && !__check_facet(_M_codecvt_tmp).always_noconv()) __testvalid = this->seekoff(0, ios_base::cur, _M_mode) != pos_type(off_type(-1)); } else { // External position corresponding to gptr(). _M_ext_next = _M_ext_buf + _M_codecvt->length(_M_state_last, _M_ext_buf, _M_ext_next, this->gptr() - this->eback()); const streamsize __remainder = _M_ext_end - _M_ext_next; if (__remainder) __builtin_memmove(_M_ext_buf, _M_ext_next, __remainder); _M_ext_next = _M_ext_buf; _M_ext_end = _M_ext_buf + __remainder; _M_set_buffer(-1); _M_state_last = _M_state_cur = _M_state_beg; } } else if (_M_writing && (__testvalid = _M_terminate_output())) _M_set_buffer(-1); } } if (__testvalid) _M_codecvt = _M_codecvt_tmp; else _M_codecvt = 0; } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_filebuf<char>; extern template class basic_ifstream<char>; extern template class basic_ofstream<char>; extern template class basic_fstream<char>; #ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_filebuf<wchar_t>; extern template class basic_ifstream<wchar_t>; extern template class basic_ofstream<wchar_t>; extern template class basic_fstream<wchar_t>; #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/stl_pair.h 0000644 00000044322 15146341150 0010217 0 ustar 00 // Pair implementation -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_pair.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{utility} */ #ifndef _STL_PAIR_H #define _STL_PAIR_H 1 #include <bits/move.h> // for std::move / std::forward, and std::swap #if __cplusplus >= 201103L #include <type_traits> // for std::__decay_and_strip too #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup utilities * @{ */ #if __cplusplus >= 201103L /// piecewise_construct_t struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; /// piecewise_construct _GLIBCXX17_INLINE constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); // Forward declarations. template<typename...> class tuple; template<std::size_t...> struct _Index_tuple; // Concept utility functions, reused in conditionally-explicit // constructors. // See PR 70437, don't look at is_constructible or // is_convertible if the types are the same to // avoid querying those properties for incomplete types. template <bool, typename _T1, typename _T2> struct _PCC { template <typename _U1, typename _U2> static constexpr bool _ConstructiblePair() { return __and_<is_constructible<_T1, const _U1&>, is_constructible<_T2, const _U2&>>::value; } template <typename _U1, typename _U2> static constexpr bool _ImplicitlyConvertiblePair() { return __and_<is_convertible<const _U1&, _T1>, is_convertible<const _U2&, _T2>>::value; } template <typename _U1, typename _U2> static constexpr bool _MoveConstructiblePair() { return __and_<is_constructible<_T1, _U1&&>, is_constructible<_T2, _U2&&>>::value; } template <typename _U1, typename _U2> static constexpr bool _ImplicitlyMoveConvertiblePair() { return __and_<is_convertible<_U1&&, _T1>, is_convertible<_U2&&, _T2>>::value; } template <bool __implicit, typename _U1, typename _U2> static constexpr bool _CopyMovePair() { using __do_converts = __and_<is_convertible<const _U1&, _T1>, is_convertible<_U2&&, _T2>>; using __converts = typename conditional<__implicit, __do_converts, __not_<__do_converts>>::type; return __and_<is_constructible<_T1, const _U1&>, is_constructible<_T2, _U2&&>, __converts >::value; } template <bool __implicit, typename _U1, typename _U2> static constexpr bool _MoveCopyPair() { using __do_converts = __and_<is_convertible<_U1&&, _T1>, is_convertible<const _U2&, _T2>>; using __converts = typename conditional<__implicit, __do_converts, __not_<__do_converts>>::type; return __and_<is_constructible<_T1, _U1&&>, is_constructible<_T2, const _U2&&>, __converts >::value; } }; template <typename _T1, typename _T2> struct _PCC<false, _T1, _T2> { template <typename _U1, typename _U2> static constexpr bool _ConstructiblePair() { return false; } template <typename _U1, typename _U2> static constexpr bool _ImplicitlyConvertiblePair() { return false; } template <typename _U1, typename _U2> static constexpr bool _MoveConstructiblePair() { return false; } template <typename _U1, typename _U2> static constexpr bool _ImplicitlyMoveConvertiblePair() { return false; } }; // PR libstdc++/79141, a utility type for preventing // initialization of an argument of a disabled assignment // operator from a pair of empty braces. struct __nonesuch_no_braces : std::__nonesuch { explicit __nonesuch_no_braces(const __nonesuch&) = delete; }; #endif // C++11 template<typename _U1, typename _U2> class __pair_base { #if __cplusplus >= 201103L template<typename _T1, typename _T2> friend struct pair; __pair_base() = default; ~__pair_base() = default; __pair_base(const __pair_base&) = default; __pair_base& operator=(const __pair_base&) = delete; #endif // C++11 }; /** * @brief Struct holding two objects of arbitrary type. * * @tparam _T1 Type of first object. * @tparam _T2 Type of second object. */ template<typename _T1, typename _T2> struct pair : private __pair_base<_T1, _T2> { typedef _T1 first_type; /// @c first_type is the first bound type typedef _T2 second_type; /// @c second_type is the second bound type _T1 first; /// @c first is a copy of the first object _T2 second; /// @c second is a copy of the second object // _GLIBCXX_RESOLVE_LIB_DEFECTS // 265. std::pair::pair() effects overly restrictive /** The default constructor creates @c first and @c second using their * respective default constructors. */ #if __cplusplus >= 201103L template <typename _U1 = _T1, typename _U2 = _T2, typename enable_if<__and_< __is_implicitly_default_constructible<_U1>, __is_implicitly_default_constructible<_U2>> ::value, bool>::type = true> #endif _GLIBCXX_CONSTEXPR pair() : first(), second() { } #if __cplusplus >= 201103L template <typename _U1 = _T1, typename _U2 = _T2, typename enable_if<__and_< is_default_constructible<_U1>, is_default_constructible<_U2>, __not_< __and_<__is_implicitly_default_constructible<_U1>, __is_implicitly_default_constructible<_U2>>>> ::value, bool>::type = false> explicit constexpr pair() : first(), second() { } #endif /** Two objects may be passed to a @c pair constructor to be copied. */ #if __cplusplus < 201103L pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) { } #else // Shortcut for constraining the templates that don't take pairs. using _PCCP = _PCC<true, _T1, _T2>; template<typename _U1 = _T1, typename _U2=_T2, typename enable_if<_PCCP::template _ConstructiblePair<_U1, _U2>() && _PCCP::template _ImplicitlyConvertiblePair<_U1, _U2>(), bool>::type=true> constexpr pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) { } template<typename _U1 = _T1, typename _U2=_T2, typename enable_if<_PCCP::template _ConstructiblePair<_U1, _U2>() && !_PCCP::template _ImplicitlyConvertiblePair<_U1, _U2>(), bool>::type=false> explicit constexpr pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) { } #endif /** There is also a templated copy ctor for the @c pair class itself. */ #if __cplusplus < 201103L template<typename _U1, typename _U2> pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) { } #else // Shortcut for constraining the templates that take pairs. template <typename _U1, typename _U2> using _PCCFP = _PCC<!is_same<_T1, _U1>::value || !is_same<_T2, _U2>::value, _T1, _T2>; template<typename _U1, typename _U2, typename enable_if<_PCCFP<_U1, _U2>::template _ConstructiblePair<_U1, _U2>() && _PCCFP<_U1, _U2>::template _ImplicitlyConvertiblePair<_U1, _U2>(), bool>::type=true> constexpr pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) { } template<typename _U1, typename _U2, typename enable_if<_PCCFP<_U1, _U2>::template _ConstructiblePair<_U1, _U2>() && !_PCCFP<_U1, _U2>::template _ImplicitlyConvertiblePair<_U1, _U2>(), bool>::type=false> explicit constexpr pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) { } constexpr pair(const pair&) = default; constexpr pair(pair&&) = default; // DR 811. template<typename _U1, typename enable_if<_PCCP::template _MoveCopyPair<true, _U1, _T2>(), bool>::type=true> constexpr pair(_U1&& __x, const _T2& __y) : first(std::forward<_U1>(__x)), second(__y) { } template<typename _U1, typename enable_if<_PCCP::template _MoveCopyPair<false, _U1, _T2>(), bool>::type=false> explicit constexpr pair(_U1&& __x, const _T2& __y) : first(std::forward<_U1>(__x)), second(__y) { } template<typename _U2, typename enable_if<_PCCP::template _CopyMovePair<true, _T1, _U2>(), bool>::type=true> constexpr pair(const _T1& __x, _U2&& __y) : first(__x), second(std::forward<_U2>(__y)) { } template<typename _U2, typename enable_if<_PCCP::template _CopyMovePair<false, _T1, _U2>(), bool>::type=false> explicit pair(const _T1& __x, _U2&& __y) : first(__x), second(std::forward<_U2>(__y)) { } template<typename _U1, typename _U2, typename enable_if<_PCCP::template _MoveConstructiblePair<_U1, _U2>() && _PCCP::template _ImplicitlyMoveConvertiblePair<_U1, _U2>(), bool>::type=true> constexpr pair(_U1&& __x, _U2&& __y) : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { } template<typename _U1, typename _U2, typename enable_if<_PCCP::template _MoveConstructiblePair<_U1, _U2>() && !_PCCP::template _ImplicitlyMoveConvertiblePair<_U1, _U2>(), bool>::type=false> explicit constexpr pair(_U1&& __x, _U2&& __y) : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { } template<typename _U1, typename _U2, typename enable_if<_PCCFP<_U1, _U2>::template _MoveConstructiblePair<_U1, _U2>() && _PCCFP<_U1, _U2>::template _ImplicitlyMoveConvertiblePair<_U1, _U2>(), bool>::type=true> constexpr pair(pair<_U1, _U2>&& __p) : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) { } template<typename _U1, typename _U2, typename enable_if<_PCCFP<_U1, _U2>::template _MoveConstructiblePair<_U1, _U2>() && !_PCCFP<_U1, _U2>::template _ImplicitlyMoveConvertiblePair<_U1, _U2>(), bool>::type=false> explicit constexpr pair(pair<_U1, _U2>&& __p) : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) { } template<typename... _Args1, typename... _Args2> pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>); pair& operator=(typename conditional< __and_<is_copy_assignable<_T1>, is_copy_assignable<_T2>>::value, const pair&, const __nonesuch_no_braces&>::type __p) { first = __p.first; second = __p.second; return *this; } pair& operator=(typename conditional< __and_<is_move_assignable<_T1>, is_move_assignable<_T2>>::value, pair&&, __nonesuch_no_braces&&>::type __p) noexcept(__and_<is_nothrow_move_assignable<_T1>, is_nothrow_move_assignable<_T2>>::value) { first = std::forward<first_type>(__p.first); second = std::forward<second_type>(__p.second); return *this; } template<typename _U1, typename _U2> typename enable_if<__and_<is_assignable<_T1&, const _U1&>, is_assignable<_T2&, const _U2&>>::value, pair&>::type operator=(const pair<_U1, _U2>& __p) { first = __p.first; second = __p.second; return *this; } template<typename _U1, typename _U2> typename enable_if<__and_<is_assignable<_T1&, _U1&&>, is_assignable<_T2&, _U2&&>>::value, pair&>::type operator=(pair<_U1, _U2>&& __p) { first = std::forward<_U1>(__p.first); second = std::forward<_U2>(__p.second); return *this; } void swap(pair& __p) noexcept(__and_<__is_nothrow_swappable<_T1>, __is_nothrow_swappable<_T2>>::value) { using std::swap; swap(first, __p.first); swap(second, __p.second); } private: template<typename... _Args1, std::size_t... _Indexes1, typename... _Args2, std::size_t... _Indexes2> pair(tuple<_Args1...>&, tuple<_Args2...>&, _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>); #endif }; #if __cpp_deduction_guides >= 201606 template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>; #endif /// Two pairs of the same type are equal iff their members are equal. template<typename _T1, typename _T2> inline _GLIBCXX_CONSTEXPR bool operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return __x.first == __y.first && __x.second == __y.second; } /// <http://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html> template<typename _T1, typename _T2> inline _GLIBCXX_CONSTEXPR bool operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second); } /// Uses @c operator== to find the result. template<typename _T1, typename _T2> inline _GLIBCXX_CONSTEXPR bool operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return !(__x == __y); } /// Uses @c operator< to find the result. template<typename _T1, typename _T2> inline _GLIBCXX_CONSTEXPR bool operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return __y < __x; } /// Uses @c operator< to find the result. template<typename _T1, typename _T2> inline _GLIBCXX_CONSTEXPR bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return !(__y < __x); } /// Uses @c operator< to find the result. template<typename _T1, typename _T2> inline _GLIBCXX_CONSTEXPR bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return !(__x < __y); } #if __cplusplus >= 201103L /// See std::pair::swap(). // Note: no std::swap overloads in C++03 mode, this has performance // implications, see, eg, libstdc++/38466. template<typename _T1, typename _T2> inline #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 // Constrained free swap overload, see p0185r1 typename enable_if<__and_<__is_swappable<_T1>, __is_swappable<_T2>>::value>::type #else void #endif swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 template<typename _T1, typename _T2> typename enable_if<!__and_<__is_swappable<_T1>, __is_swappable<_T2>>::value>::type swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete; #endif #endif // __cplusplus >= 201103L /** * @brief A convenience wrapper for creating a pair from two objects. * @param __x The first object. * @param __y The second object. * @return A newly-constructed pair<> object of the appropriate type. * * The standard requires that the objects be passed by reference-to-const, * but LWG issue #181 says they should be passed by const value. We follow * the LWG by default. */ // _GLIBCXX_RESOLVE_LIB_DEFECTS // 181. make_pair() unintended behavior #if __cplusplus >= 201103L // NB: DR 706. template<typename _T1, typename _T2> constexpr pair<typename __decay_and_strip<_T1>::__type, typename __decay_and_strip<_T2>::__type> make_pair(_T1&& __x, _T2&& __y) { typedef typename __decay_and_strip<_T1>::__type __ds_type1; typedef typename __decay_and_strip<_T2>::__type __ds_type2; typedef pair<__ds_type1, __ds_type2> __pair_type; return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y)); } #else template<typename _T1, typename _T2> inline pair<_T1, _T2> make_pair(_T1 __x, _T2 __y) { return pair<_T1, _T2>(__x, __y); } #endif /// @} _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _STL_PAIR_H */ c++/8/bits/stl_uninitialized.h 0000644 00000066075 15146341150 0012145 0 ustar 00 // Raw memory manipulators -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_uninitialized.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _STL_UNINITIALIZED_H #define _STL_UNINITIALIZED_H 1 #if __cplusplus > 201402L #include <utility> #endif #if __cplusplus >= 201103L #include <type_traits> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<bool _TrivialValueTypes> struct __uninitialized_copy { template<typename _InputIterator, typename _ForwardIterator> static _ForwardIterator __uninit_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result) { _ForwardIterator __cur = __result; __try { for (; __first != __last; ++__first, (void)++__cur) std::_Construct(std::__addressof(*__cur), *__first); return __cur; } __catch(...) { std::_Destroy(__result, __cur); __throw_exception_again; } } }; template<> struct __uninitialized_copy<true> { template<typename _InputIterator, typename _ForwardIterator> static _ForwardIterator __uninit_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result) { return std::copy(__first, __last, __result); } }; /** * @brief Copies the range [first,last) into result. * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @return __result + (__first - __last) * * Like copy(), but does not require an initialized output range. */ template<typename _InputIterator, typename _ForwardIterator> inline _ForwardIterator uninitialized_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result) { typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; #if __cplusplus < 201103L const bool __assignable = true; #else // trivial types can have deleted assignment typedef typename iterator_traits<_InputIterator>::reference _RefType1; typedef typename iterator_traits<_ForwardIterator>::reference _RefType2; const bool __assignable = is_assignable<_RefType2, _RefType1>::value; #endif return std::__uninitialized_copy<__is_trivial(_ValueType1) && __is_trivial(_ValueType2) && __assignable>:: __uninit_copy(__first, __last, __result); } template<bool _TrivialValueType> struct __uninitialized_fill { template<typename _ForwardIterator, typename _Tp> static void __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __x) { _ForwardIterator __cur = __first; __try { for (; __cur != __last; ++__cur) std::_Construct(std::__addressof(*__cur), __x); } __catch(...) { std::_Destroy(__first, __cur); __throw_exception_again; } } }; template<> struct __uninitialized_fill<true> { template<typename _ForwardIterator, typename _Tp> static void __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __x) { std::fill(__first, __last, __x); } }; /** * @brief Copies the value x into the range [first,last). * @param __first An input iterator. * @param __last An input iterator. * @param __x The source value. * @return Nothing. * * Like fill(), but does not require an initialized output range. */ template<typename _ForwardIterator, typename _Tp> inline void uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __x) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; #if __cplusplus < 201103L const bool __assignable = true; #else // trivial types can have deleted assignment const bool __assignable = is_copy_assignable<_ValueType>::value; #endif std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>:: __uninit_fill(__first, __last, __x); } template<bool _TrivialValueType> struct __uninitialized_fill_n { template<typename _ForwardIterator, typename _Size, typename _Tp> static _ForwardIterator __uninit_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) { _ForwardIterator __cur = __first; __try { for (; __n > 0; --__n, (void) ++__cur) std::_Construct(std::__addressof(*__cur), __x); return __cur; } __catch(...) { std::_Destroy(__first, __cur); __throw_exception_again; } } }; template<> struct __uninitialized_fill_n<true> { template<typename _ForwardIterator, typename _Size, typename _Tp> static _ForwardIterator __uninit_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) { return std::fill_n(__first, __n, __x); } }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 1339. uninitialized_fill_n should return the end of its range /** * @brief Copies the value x into the range [first,first+n). * @param __first An input iterator. * @param __n The number of copies to make. * @param __x The source value. * @return Nothing. * * Like fill_n(), but does not require an initialized output range. */ template<typename _ForwardIterator, typename _Size, typename _Tp> inline _ForwardIterator uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; #if __cplusplus < 201103L const bool __assignable = true; #else // trivial types can have deleted assignment const bool __assignable = is_copy_assignable<_ValueType>::value; #endif return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>:: __uninit_fill_n(__first, __n, __x); } // Extensions: versions of uninitialized_copy, uninitialized_fill, // and uninitialized_fill_n that take an allocator parameter. // We dispatch back to the standard versions when we're given the // default allocator. For nondefault allocators we do not use // any of the POD optimizations. template<typename _InputIterator, typename _ForwardIterator, typename _Allocator> _ForwardIterator __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _Allocator& __alloc) { _ForwardIterator __cur = __result; __try { typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; for (; __first != __last; ++__first, (void)++__cur) __traits::construct(__alloc, std::__addressof(*__cur), *__first); return __cur; } __catch(...) { std::_Destroy(__result, __cur, __alloc); __throw_exception_again; } } template<typename _InputIterator, typename _ForwardIterator, typename _Tp> inline _ForwardIterator __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, allocator<_Tp>&) { return std::uninitialized_copy(__first, __last, __result); } template<typename _InputIterator, typename _ForwardIterator, typename _Allocator> inline _ForwardIterator __uninitialized_move_a(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _Allocator& __alloc) { return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result, __alloc); } template<typename _InputIterator, typename _ForwardIterator, typename _Allocator> inline _ForwardIterator __uninitialized_move_if_noexcept_a(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _Allocator& __alloc) { return std::__uninitialized_copy_a (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); } template<typename _ForwardIterator, typename _Tp, typename _Allocator> void __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __x, _Allocator& __alloc) { _ForwardIterator __cur = __first; __try { typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; for (; __cur != __last; ++__cur) __traits::construct(__alloc, std::__addressof(*__cur), __x); } __catch(...) { std::_Destroy(__first, __cur, __alloc); __throw_exception_again; } } template<typename _ForwardIterator, typename _Tp, typename _Tp2> inline void __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __x, allocator<_Tp2>&) { std::uninitialized_fill(__first, __last, __x); } template<typename _ForwardIterator, typename _Size, typename _Tp, typename _Allocator> _ForwardIterator __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, const _Tp& __x, _Allocator& __alloc) { _ForwardIterator __cur = __first; __try { typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; for (; __n > 0; --__n, (void) ++__cur) __traits::construct(__alloc, std::__addressof(*__cur), __x); return __cur; } __catch(...) { std::_Destroy(__first, __cur, __alloc); __throw_exception_again; } } template<typename _ForwardIterator, typename _Size, typename _Tp, typename _Tp2> inline _ForwardIterator __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, const _Tp& __x, allocator<_Tp2>&) { return std::uninitialized_fill_n(__first, __n, __x); } // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, // __uninitialized_fill_move, __uninitialized_move_fill. // All of these algorithms take a user-supplied allocator, which is used // for construction and destruction. // __uninitialized_copy_move // Copies [first1, last1) into [result, result + (last1 - first1)), and // move [first2, last2) into // [result, result + (last1 - first1) + (last2 - first2)). template<typename _InputIterator1, typename _InputIterator2, typename _ForwardIterator, typename _Allocator> inline _ForwardIterator __uninitialized_copy_move(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _ForwardIterator __result, _Allocator& __alloc) { _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, __result, __alloc); __try { return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); } __catch(...) { std::_Destroy(__result, __mid, __alloc); __throw_exception_again; } } // __uninitialized_move_copy // Moves [first1, last1) into [result, result + (last1 - first1)), and // copies [first2, last2) into // [result, result + (last1 - first1) + (last2 - first2)). template<typename _InputIterator1, typename _InputIterator2, typename _ForwardIterator, typename _Allocator> inline _ForwardIterator __uninitialized_move_copy(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _ForwardIterator __result, _Allocator& __alloc) { _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, __result, __alloc); __try { return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); } __catch(...) { std::_Destroy(__result, __mid, __alloc); __throw_exception_again; } } // __uninitialized_fill_move // Fills [result, mid) with x, and moves [first, last) into // [mid, mid + (last - first)). template<typename _ForwardIterator, typename _Tp, typename _InputIterator, typename _Allocator> inline _ForwardIterator __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, const _Tp& __x, _InputIterator __first, _InputIterator __last, _Allocator& __alloc) { std::__uninitialized_fill_a(__result, __mid, __x, __alloc); __try { return std::__uninitialized_move_a(__first, __last, __mid, __alloc); } __catch(...) { std::_Destroy(__result, __mid, __alloc); __throw_exception_again; } } // __uninitialized_move_fill // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and // fills [first2 + (last1 - first1), last2) with x. template<typename _InputIterator, typename _ForwardIterator, typename _Tp, typename _Allocator> inline void __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, _ForwardIterator __first2, _ForwardIterator __last2, const _Tp& __x, _Allocator& __alloc) { _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, __first2, __alloc); __try { std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); } __catch(...) { std::_Destroy(__first2, __mid2, __alloc); __throw_exception_again; } } #if __cplusplus >= 201103L // Extensions: __uninitialized_default, __uninitialized_default_n, // __uninitialized_default_a, __uninitialized_default_n_a. template<bool _TrivialValueType> struct __uninitialized_default_1 { template<typename _ForwardIterator> static void __uninit_default(_ForwardIterator __first, _ForwardIterator __last) { _ForwardIterator __cur = __first; __try { for (; __cur != __last; ++__cur) std::_Construct(std::__addressof(*__cur)); } __catch(...) { std::_Destroy(__first, __cur); __throw_exception_again; } } }; template<> struct __uninitialized_default_1<true> { template<typename _ForwardIterator> static void __uninit_default(_ForwardIterator __first, _ForwardIterator __last) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; std::fill(__first, __last, _ValueType()); } }; template<bool _TrivialValueType> struct __uninitialized_default_n_1 { template<typename _ForwardIterator, typename _Size> static _ForwardIterator __uninit_default_n(_ForwardIterator __first, _Size __n) { _ForwardIterator __cur = __first; __try { for (; __n > 0; --__n, (void) ++__cur) std::_Construct(std::__addressof(*__cur)); return __cur; } __catch(...) { std::_Destroy(__first, __cur); __throw_exception_again; } } }; template<> struct __uninitialized_default_n_1<true> { template<typename _ForwardIterator, typename _Size> static _ForwardIterator __uninit_default_n(_ForwardIterator __first, _Size __n) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; return std::fill_n(__first, __n, _ValueType()); } }; // __uninitialized_default // Fills [first, last) with std::distance(first, last) default // constructed value_types(s). template<typename _ForwardIterator> inline void __uninitialized_default(_ForwardIterator __first, _ForwardIterator __last) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; // trivial types can have deleted assignment const bool __assignable = is_copy_assignable<_ValueType>::value; std::__uninitialized_default_1<__is_trivial(_ValueType) && __assignable>:: __uninit_default(__first, __last); } // __uninitialized_default_n // Fills [first, first + n) with n default constructed value_type(s). template<typename _ForwardIterator, typename _Size> inline _ForwardIterator __uninitialized_default_n(_ForwardIterator __first, _Size __n) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; // trivial types can have deleted assignment const bool __assignable = is_copy_assignable<_ValueType>::value; return __uninitialized_default_n_1<__is_trivial(_ValueType) && __assignable>:: __uninit_default_n(__first, __n); } // __uninitialized_default_a // Fills [first, last) with std::distance(first, last) default // constructed value_types(s), constructed with the allocator alloc. template<typename _ForwardIterator, typename _Allocator> void __uninitialized_default_a(_ForwardIterator __first, _ForwardIterator __last, _Allocator& __alloc) { _ForwardIterator __cur = __first; __try { typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; for (; __cur != __last; ++__cur) __traits::construct(__alloc, std::__addressof(*__cur)); } __catch(...) { std::_Destroy(__first, __cur, __alloc); __throw_exception_again; } } template<typename _ForwardIterator, typename _Tp> inline void __uninitialized_default_a(_ForwardIterator __first, _ForwardIterator __last, allocator<_Tp>&) { std::__uninitialized_default(__first, __last); } // __uninitialized_default_n_a // Fills [first, first + n) with n default constructed value_types(s), // constructed with the allocator alloc. template<typename _ForwardIterator, typename _Size, typename _Allocator> _ForwardIterator __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, _Allocator& __alloc) { _ForwardIterator __cur = __first; __try { typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; for (; __n > 0; --__n, (void) ++__cur) __traits::construct(__alloc, std::__addressof(*__cur)); return __cur; } __catch(...) { std::_Destroy(__first, __cur, __alloc); __throw_exception_again; } } template<typename _ForwardIterator, typename _Size, typename _Tp> inline _ForwardIterator __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, allocator<_Tp>&) { return std::__uninitialized_default_n(__first, __n); } template<bool _TrivialValueType> struct __uninitialized_default_novalue_1 { template<typename _ForwardIterator> static void __uninit_default_novalue(_ForwardIterator __first, _ForwardIterator __last) { _ForwardIterator __cur = __first; __try { for (; __cur != __last; ++__cur) std::_Construct_novalue(std::__addressof(*__cur)); } __catch(...) { std::_Destroy(__first, __cur); __throw_exception_again; } } }; template<> struct __uninitialized_default_novalue_1<true> { template<typename _ForwardIterator> static void __uninit_default_novalue(_ForwardIterator __first, _ForwardIterator __last) { } }; template<bool _TrivialValueType> struct __uninitialized_default_novalue_n_1 { template<typename _ForwardIterator, typename _Size> static _ForwardIterator __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) { _ForwardIterator __cur = __first; __try { for (; __n > 0; --__n, (void) ++__cur) std::_Construct_novalue(std::__addressof(*__cur)); return __cur; } __catch(...) { std::_Destroy(__first, __cur); __throw_exception_again; } } }; template<> struct __uninitialized_default_novalue_n_1<true> { template<typename _ForwardIterator, typename _Size> static _ForwardIterator __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) { return std::next(__first, __n); } }; // __uninitialized_default_novalue // Fills [first, last) with std::distance(first, last) default-initialized // value_types(s). template<typename _ForwardIterator> inline void __uninitialized_default_novalue(_ForwardIterator __first, _ForwardIterator __last) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; std::__uninitialized_default_novalue_1< is_trivially_default_constructible<_ValueType>::value>:: __uninit_default_novalue(__first, __last); } // __uninitialized_default_n // Fills [first, first + n) with n default-initialized value_type(s). template<typename _ForwardIterator, typename _Size> inline _ForwardIterator __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; return __uninitialized_default_novalue_n_1< is_trivially_default_constructible<_ValueType>::value>:: __uninit_default_novalue_n(__first, __n); } template<typename _InputIterator, typename _Size, typename _ForwardIterator> _ForwardIterator __uninitialized_copy_n(_InputIterator __first, _Size __n, _ForwardIterator __result, input_iterator_tag) { _ForwardIterator __cur = __result; __try { for (; __n > 0; --__n, (void) ++__first, ++__cur) std::_Construct(std::__addressof(*__cur), *__first); return __cur; } __catch(...) { std::_Destroy(__result, __cur); __throw_exception_again; } } template<typename _RandomAccessIterator, typename _Size, typename _ForwardIterator> inline _ForwardIterator __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, _ForwardIterator __result, random_access_iterator_tag) { return std::uninitialized_copy(__first, __first + __n, __result); } template<typename _InputIterator, typename _Size, typename _ForwardIterator> pair<_InputIterator, _ForwardIterator> __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, _ForwardIterator __result, input_iterator_tag) { _ForwardIterator __cur = __result; __try { for (; __n > 0; --__n, (void) ++__first, ++__cur) std::_Construct(std::__addressof(*__cur), *__first); return {__first, __cur}; } __catch(...) { std::_Destroy(__result, __cur); __throw_exception_again; } } template<typename _RandomAccessIterator, typename _Size, typename _ForwardIterator> inline pair<_RandomAccessIterator, _ForwardIterator> __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n, _ForwardIterator __result, random_access_iterator_tag) { auto __second_res = uninitialized_copy(__first, __first + __n, __result); auto __first_res = std::next(__first, __n); return {__first_res, __second_res}; } /** * @brief Copies the range [first,first+n) into result. * @param __first An input iterator. * @param __n The number of elements to copy. * @param __result An output iterator. * @return __result + __n * * Like copy_n(), but does not require an initialized output range. */ template<typename _InputIterator, typename _Size, typename _ForwardIterator> inline _ForwardIterator uninitialized_copy_n(_InputIterator __first, _Size __n, _ForwardIterator __result) { return std::__uninitialized_copy_n(__first, __n, __result, std::__iterator_category(__first)); } template<typename _InputIterator, typename _Size, typename _ForwardIterator> inline pair<_InputIterator, _ForwardIterator> __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, _ForwardIterator __result) { return std::__uninitialized_copy_n_pair(__first, __n, __result, std::__iterator_category(__first)); } #endif #if __cplusplus >= 201703L # define __cpp_lib_raw_memory_algorithms 201606L template <typename _ForwardIterator> inline void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) { __uninitialized_default_novalue(__first, __last); } template <typename _ForwardIterator, typename _Size> inline _ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __count) { return __uninitialized_default_novalue_n(__first, __count); } template <typename _ForwardIterator> inline void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) { return __uninitialized_default(__first, __last); } template <typename _ForwardIterator, typename _Size> inline _ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __count) { return __uninitialized_default_n(__first, __count); } template <typename _InputIterator, typename _ForwardIterator> inline _ForwardIterator uninitialized_move(_InputIterator __first, _InputIterator __last, _ForwardIterator __result) { return std::uninitialized_copy (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result); } template <typename _InputIterator, typename _Size, typename _ForwardIterator> inline pair<_InputIterator, _ForwardIterator> uninitialized_move_n(_InputIterator __first, _Size __count, _ForwardIterator __result) { auto __res = std::__uninitialized_copy_n_pair (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), __count, __result); return {__res.first.base(), __res.second}; } #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _STL_UNINITIALIZED_H */ c++/8/bits/hashtable_policy.h 0000644 00000204603 15146341150 0011714 0 ustar 00 // Internal policy header for unordered_set and unordered_map -*- C++ -*- // Copyright (C) 2010-2018 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/hashtable_policy.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. * @headername{unordered_map,unordered_set} */ #ifndef _HASHTABLE_POLICY_H #define _HASHTABLE_POLICY_H 1 #include <tuple> // for std::tuple, std::forward_as_tuple #include <cstdint> // for std::uint_fast64_t #include <bits/stl_algobase.h> // for std::min. namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> class _Hashtable; namespace __detail { /** * @defgroup hashtable-detail Base and Implementation Classes * @ingroup unordered_associative_containers * @{ */ template<typename _Key, typename _Value, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _Traits> struct _Hashtable_base; // Helper function: return distance(first, last) for forward // iterators, or 0/1 for input iterators. template<class _Iterator> inline typename std::iterator_traits<_Iterator>::difference_type __distance_fw(_Iterator __first, _Iterator __last, std::input_iterator_tag) { return __first != __last ? 1 : 0; } template<class _Iterator> inline typename std::iterator_traits<_Iterator>::difference_type __distance_fw(_Iterator __first, _Iterator __last, std::forward_iterator_tag) { return std::distance(__first, __last); } template<class _Iterator> inline typename std::iterator_traits<_Iterator>::difference_type __distance_fw(_Iterator __first, _Iterator __last) { return __distance_fw(__first, __last, std::__iterator_category(__first)); } struct _Identity { template<typename _Tp> _Tp&& operator()(_Tp&& __x) const { return std::forward<_Tp>(__x); } }; struct _Select1st { template<typename _Tp> auto operator()(_Tp&& __x) const -> decltype(std::get<0>(std::forward<_Tp>(__x))) { return std::get<0>(std::forward<_Tp>(__x)); } }; template<typename _NodeAlloc> struct _Hashtable_alloc; // Functor recycling a pool of nodes and using allocation once the pool is // empty. template<typename _NodeAlloc> struct _ReuseOrAllocNode { private: using __node_alloc_type = _NodeAlloc; using __hashtable_alloc = _Hashtable_alloc<__node_alloc_type>; using __node_alloc_traits = typename __hashtable_alloc::__node_alloc_traits; using __node_type = typename __hashtable_alloc::__node_type; public: _ReuseOrAllocNode(__node_type* __nodes, __hashtable_alloc& __h) : _M_nodes(__nodes), _M_h(__h) { } _ReuseOrAllocNode(const _ReuseOrAllocNode&) = delete; ~_ReuseOrAllocNode() { _M_h._M_deallocate_nodes(_M_nodes); } template<typename _Arg> __node_type* operator()(_Arg&& __arg) const { if (_M_nodes) { __node_type* __node = _M_nodes; _M_nodes = _M_nodes->_M_next(); __node->_M_nxt = nullptr; auto& __a = _M_h._M_node_allocator(); __node_alloc_traits::destroy(__a, __node->_M_valptr()); __try { __node_alloc_traits::construct(__a, __node->_M_valptr(), std::forward<_Arg>(__arg)); } __catch(...) { __node->~__node_type(); __node_alloc_traits::deallocate(__a, __node, 1); __throw_exception_again; } return __node; } return _M_h._M_allocate_node(std::forward<_Arg>(__arg)); } private: mutable __node_type* _M_nodes; __hashtable_alloc& _M_h; }; // Functor similar to the previous one but without any pool of nodes to // recycle. template<typename _NodeAlloc> struct _AllocNode { private: using __hashtable_alloc = _Hashtable_alloc<_NodeAlloc>; using __node_type = typename __hashtable_alloc::__node_type; public: _AllocNode(__hashtable_alloc& __h) : _M_h(__h) { } template<typename _Arg> __node_type* operator()(_Arg&& __arg) const { return _M_h._M_allocate_node(std::forward<_Arg>(__arg)); } private: __hashtable_alloc& _M_h; }; // Auxiliary types used for all instantiations of _Hashtable nodes // and iterators. /** * struct _Hashtable_traits * * Important traits for hash tables. * * @tparam _Cache_hash_code Boolean value. True if the value of * the hash function is stored along with the value. This is a * time-space tradeoff. Storing it may improve lookup speed by * reducing the number of times we need to call the _Equal * function. * * @tparam _Constant_iterators Boolean value. True if iterator and * const_iterator are both constant iterator types. This is true * for unordered_set and unordered_multiset, false for * unordered_map and unordered_multimap. * * @tparam _Unique_keys Boolean value. True if the return value * of _Hashtable::count(k) is always at most one, false if it may * be an arbitrary number. This is true for unordered_set and * unordered_map, false for unordered_multiset and * unordered_multimap. */ template<bool _Cache_hash_code, bool _Constant_iterators, bool _Unique_keys> struct _Hashtable_traits { using __hash_cached = __bool_constant<_Cache_hash_code>; using __constant_iterators = __bool_constant<_Constant_iterators>; using __unique_keys = __bool_constant<_Unique_keys>; }; /** * struct _Hash_node_base * * Nodes, used to wrap elements stored in the hash table. A policy * template parameter of class template _Hashtable controls whether * nodes also store a hash code. In some cases (e.g. strings) this * may be a performance win. */ struct _Hash_node_base { _Hash_node_base* _M_nxt; _Hash_node_base() noexcept : _M_nxt() { } _Hash_node_base(_Hash_node_base* __next) noexcept : _M_nxt(__next) { } }; /** * struct _Hash_node_value_base * * Node type with the value to store. */ template<typename _Value> struct _Hash_node_value_base : _Hash_node_base { typedef _Value value_type; __gnu_cxx::__aligned_buffer<_Value> _M_storage; _Value* _M_valptr() noexcept { return _M_storage._M_ptr(); } const _Value* _M_valptr() const noexcept { return _M_storage._M_ptr(); } _Value& _M_v() noexcept { return *_M_valptr(); } const _Value& _M_v() const noexcept { return *_M_valptr(); } }; /** * Primary template struct _Hash_node. */ template<typename _Value, bool _Cache_hash_code> struct _Hash_node; /** * Specialization for nodes with caches, struct _Hash_node. * * Base class is __detail::_Hash_node_value_base. */ template<typename _Value> struct _Hash_node<_Value, true> : _Hash_node_value_base<_Value> { std::size_t _M_hash_code; _Hash_node* _M_next() const noexcept { return static_cast<_Hash_node*>(this->_M_nxt); } }; /** * Specialization for nodes without caches, struct _Hash_node. * * Base class is __detail::_Hash_node_value_base. */ template<typename _Value> struct _Hash_node<_Value, false> : _Hash_node_value_base<_Value> { _Hash_node* _M_next() const noexcept { return static_cast<_Hash_node*>(this->_M_nxt); } }; /// Base class for node iterators. template<typename _Value, bool _Cache_hash_code> struct _Node_iterator_base { using __node_type = _Hash_node<_Value, _Cache_hash_code>; __node_type* _M_cur; _Node_iterator_base(__node_type* __p) noexcept : _M_cur(__p) { } void _M_incr() noexcept { _M_cur = _M_cur->_M_next(); } }; template<typename _Value, bool _Cache_hash_code> inline bool operator==(const _Node_iterator_base<_Value, _Cache_hash_code>& __x, const _Node_iterator_base<_Value, _Cache_hash_code >& __y) noexcept { return __x._M_cur == __y._M_cur; } template<typename _Value, bool _Cache_hash_code> inline bool operator!=(const _Node_iterator_base<_Value, _Cache_hash_code>& __x, const _Node_iterator_base<_Value, _Cache_hash_code>& __y) noexcept { return __x._M_cur != __y._M_cur; } /// Node iterators, used to iterate through all the hashtable. template<typename _Value, bool __constant_iterators, bool __cache> struct _Node_iterator : public _Node_iterator_base<_Value, __cache> { private: using __base_type = _Node_iterator_base<_Value, __cache>; using __node_type = typename __base_type::__node_type; public: typedef _Value value_type; typedef std::ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; using pointer = typename std::conditional<__constant_iterators, const _Value*, _Value*>::type; using reference = typename std::conditional<__constant_iterators, const _Value&, _Value&>::type; _Node_iterator() noexcept : __base_type(0) { } explicit _Node_iterator(__node_type* __p) noexcept : __base_type(__p) { } reference operator*() const noexcept { return this->_M_cur->_M_v(); } pointer operator->() const noexcept { return this->_M_cur->_M_valptr(); } _Node_iterator& operator++() noexcept { this->_M_incr(); return *this; } _Node_iterator operator++(int) noexcept { _Node_iterator __tmp(*this); this->_M_incr(); return __tmp; } }; /// Node const_iterators, used to iterate through all the hashtable. template<typename _Value, bool __constant_iterators, bool __cache> struct _Node_const_iterator : public _Node_iterator_base<_Value, __cache> { private: using __base_type = _Node_iterator_base<_Value, __cache>; using __node_type = typename __base_type::__node_type; public: typedef _Value value_type; typedef std::ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; typedef const _Value* pointer; typedef const _Value& reference; _Node_const_iterator() noexcept : __base_type(0) { } explicit _Node_const_iterator(__node_type* __p) noexcept : __base_type(__p) { } _Node_const_iterator(const _Node_iterator<_Value, __constant_iterators, __cache>& __x) noexcept : __base_type(__x._M_cur) { } reference operator*() const noexcept { return this->_M_cur->_M_v(); } pointer operator->() const noexcept { return this->_M_cur->_M_valptr(); } _Node_const_iterator& operator++() noexcept { this->_M_incr(); return *this; } _Node_const_iterator operator++(int) noexcept { _Node_const_iterator __tmp(*this); this->_M_incr(); return __tmp; } }; // Many of class template _Hashtable's template parameters are policy // classes. These are defaults for the policies. /// Default range hashing function: use division to fold a large number /// into the range [0, N). struct _Mod_range_hashing { typedef std::size_t first_argument_type; typedef std::size_t second_argument_type; typedef std::size_t result_type; result_type operator()(first_argument_type __num, second_argument_type __den) const noexcept { return __num % __den; } }; /// Default ranged hash function H. In principle it should be a /// function object composed from objects of type H1 and H2 such that /// h(k, N) = h2(h1(k), N), but that would mean making extra copies of /// h1 and h2. So instead we'll just use a tag to tell class template /// hashtable to do that composition. struct _Default_ranged_hash { }; /// Default value for rehash policy. Bucket size is (usually) the /// smallest prime that keeps the load factor small enough. struct _Prime_rehash_policy { using __has_load_factor = std::true_type; _Prime_rehash_policy(float __z = 1.0) noexcept : _M_max_load_factor(__z), _M_next_resize(0) { } float max_load_factor() const noexcept { return _M_max_load_factor; } // Return a bucket size no smaller than n. std::size_t _M_next_bkt(std::size_t __n) const; // Return a bucket count appropriate for n elements std::size_t _M_bkt_for_elements(std::size_t __n) const { return __builtin_ceil(__n / (long double)_M_max_load_factor); } // __n_bkt is current bucket count, __n_elt is current element count, // and __n_ins is number of elements to be inserted. Do we need to // increase bucket count? If so, return make_pair(true, n), where n // is the new bucket count. If not, return make_pair(false, 0). std::pair<bool, std::size_t> _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, std::size_t __n_ins) const; typedef std::size_t _State; _State _M_state() const { return _M_next_resize; } void _M_reset() noexcept { _M_next_resize = 0; } void _M_reset(_State __state) { _M_next_resize = __state; } static const std::size_t _S_growth_factor = 2; float _M_max_load_factor; mutable std::size_t _M_next_resize; }; /// Range hashing function assuming that second arg is a power of 2. struct _Mask_range_hashing { typedef std::size_t first_argument_type; typedef std::size_t second_argument_type; typedef std::size_t result_type; result_type operator()(first_argument_type __num, second_argument_type __den) const noexcept { return __num & (__den - 1); } }; /// Compute closest power of 2. _GLIBCXX14_CONSTEXPR inline std::size_t __clp2(std::size_t __n) noexcept { #if __SIZEOF_SIZE_T__ >= 8 std::uint_fast64_t __x = __n; #else std::uint_fast32_t __x = __n; #endif // Algorithm from Hacker's Delight, Figure 3-3. __x = __x - 1; __x = __x | (__x >> 1); __x = __x | (__x >> 2); __x = __x | (__x >> 4); __x = __x | (__x >> 8); __x = __x | (__x >>16); #if __SIZEOF_SIZE_T__ >= 8 __x = __x | (__x >>32); #endif return __x + 1; } /// Rehash policy providing power of 2 bucket numbers. Avoids modulo /// operations. struct _Power2_rehash_policy { using __has_load_factor = std::true_type; _Power2_rehash_policy(float __z = 1.0) noexcept : _M_max_load_factor(__z), _M_next_resize(0) { } float max_load_factor() const noexcept { return _M_max_load_factor; } // Return a bucket size no smaller than n (as long as n is not above the // highest power of 2). std::size_t _M_next_bkt(std::size_t __n) noexcept { const auto __max_width = std::min<size_t>(sizeof(size_t), 8); const auto __max_bkt = size_t(1) << (__max_width * __CHAR_BIT__ - 1); std::size_t __res = __clp2(__n); if (__res == __n) __res <<= 1; if (__res == 0) __res = __max_bkt; if (__res == __max_bkt) // Set next resize to the max value so that we never try to rehash again // as we already reach the biggest possible bucket number. // Note that it might result in max_load_factor not being respected. _M_next_resize = std::size_t(-1); else _M_next_resize = __builtin_ceil(__res * (long double)_M_max_load_factor); return __res; } // Return a bucket count appropriate for n elements std::size_t _M_bkt_for_elements(std::size_t __n) const noexcept { return __builtin_ceil(__n / (long double)_M_max_load_factor); } // __n_bkt is current bucket count, __n_elt is current element count, // and __n_ins is number of elements to be inserted. Do we need to // increase bucket count? If so, return make_pair(true, n), where n // is the new bucket count. If not, return make_pair(false, 0). std::pair<bool, std::size_t> _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, std::size_t __n_ins) noexcept { if (__n_elt + __n_ins >= _M_next_resize) { long double __min_bkts = (__n_elt + __n_ins) / (long double)_M_max_load_factor; if (__min_bkts >= __n_bkt) return std::make_pair(true, _M_next_bkt(std::max<std::size_t>(__builtin_floor(__min_bkts) + 1, __n_bkt * _S_growth_factor))); _M_next_resize = __builtin_floor(__n_bkt * (long double)_M_max_load_factor); return std::make_pair(false, 0); } else return std::make_pair(false, 0); } typedef std::size_t _State; _State _M_state() const noexcept { return _M_next_resize; } void _M_reset() noexcept { _M_next_resize = 0; } void _M_reset(_State __state) noexcept { _M_next_resize = __state; } static const std::size_t _S_growth_factor = 2; float _M_max_load_factor; std::size_t _M_next_resize; }; // Base classes for std::_Hashtable. We define these base classes // because in some cases we want to do different things depending on // the value of a policy class. In some cases the policy class // affects which member functions and nested typedefs are defined; // we handle that by specializing base class templates. Several of // the base class templates need to access other members of class // template _Hashtable, so we use a variant of the "Curiously // Recurring Template Pattern" (CRTP) technique. /** * Primary class template _Map_base. * * If the hashtable has a value type of the form pair<T1, T2> and a * key extraction policy (_ExtractKey) that returns the first part * of the pair, the hashtable gets a mapped_type typedef. If it * satisfies those criteria and also has unique keys, then it also * gets an operator[]. */ template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits, bool _Unique_keys = _Traits::__unique_keys::value> struct _Map_base { }; /// Partial specialization, __unique_keys set to false. template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, false> { using mapped_type = typename std::tuple_element<1, _Pair>::type; }; /// Partial specialization, __unique_keys set to true. template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> struct _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true> { private: using __hashtable_base = __detail::_Hashtable_base<_Key, _Pair, _Select1st, _Equal, _H1, _H2, _Hash, _Traits>; using __hashtable = _Hashtable<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; using __hash_code = typename __hashtable_base::__hash_code; using __node_type = typename __hashtable_base::__node_type; public: using key_type = typename __hashtable_base::key_type; using iterator = typename __hashtable_base::iterator; using mapped_type = typename std::tuple_element<1, _Pair>::type; mapped_type& operator[](const key_type& __k); mapped_type& operator[](key_type&& __k); // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 761. unordered_map needs an at() member function. mapped_type& at(const key_type& __k); const mapped_type& at(const key_type& __k) const; }; template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: operator[](const key_type& __k) -> mapped_type& { __hashtable* __h = static_cast<__hashtable*>(this); __hash_code __code = __h->_M_hash_code(__k); std::size_t __n = __h->_M_bucket_index(__k, __code); __node_type* __p = __h->_M_find_node(__n, __k, __code); if (!__p) { __p = __h->_M_allocate_node(std::piecewise_construct, std::tuple<const key_type&>(__k), std::tuple<>()); return __h->_M_insert_unique_node(__n, __code, __p)->second; } return __p->_M_v().second; } template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: operator[](key_type&& __k) -> mapped_type& { __hashtable* __h = static_cast<__hashtable*>(this); __hash_code __code = __h->_M_hash_code(__k); std::size_t __n = __h->_M_bucket_index(__k, __code); __node_type* __p = __h->_M_find_node(__n, __k, __code); if (!__p) { __p = __h->_M_allocate_node(std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::tuple<>()); return __h->_M_insert_unique_node(__n, __code, __p)->second; } return __p->_M_v().second; } template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: at(const key_type& __k) -> mapped_type& { __hashtable* __h = static_cast<__hashtable*>(this); __hash_code __code = __h->_M_hash_code(__k); std::size_t __n = __h->_M_bucket_index(__k, __code); __node_type* __p = __h->_M_find_node(__n, __k, __code); if (!__p) __throw_out_of_range(__N("_Map_base::at")); return __p->_M_v().second; } template<typename _Key, typename _Pair, typename _Alloc, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> auto _Map_base<_Key, _Pair, _Alloc, _Select1st, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: at(const key_type& __k) const -> const mapped_type& { const __hashtable* __h = static_cast<const __hashtable*>(this); __hash_code __code = __h->_M_hash_code(__k); std::size_t __n = __h->_M_bucket_index(__k, __code); __node_type* __p = __h->_M_find_node(__n, __k, __code); if (!__p) __throw_out_of_range(__N("_Map_base::at")); return __p->_M_v().second; } /** * Primary class template _Insert_base. * * Defines @c insert member functions appropriate to all _Hashtables. */ template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> struct _Insert_base { protected: using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; using __hashtable_base = _Hashtable_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, _Hash, _Traits>; using value_type = typename __hashtable_base::value_type; using iterator = typename __hashtable_base::iterator; using const_iterator = typename __hashtable_base::const_iterator; using size_type = typename __hashtable_base::size_type; using __unique_keys = typename __hashtable_base::__unique_keys; using __ireturn_type = typename __hashtable_base::__ireturn_type; using __node_type = _Hash_node<_Value, _Traits::__hash_cached::value>; using __node_alloc_type = __alloc_rebind<_Alloc, __node_type>; using __node_gen_type = _AllocNode<__node_alloc_type>; __hashtable& _M_conjure_hashtable() { return *(static_cast<__hashtable*>(this)); } template<typename _InputIterator, typename _NodeGetter> void _M_insert_range(_InputIterator __first, _InputIterator __last, const _NodeGetter&, true_type); template<typename _InputIterator, typename _NodeGetter> void _M_insert_range(_InputIterator __first, _InputIterator __last, const _NodeGetter&, false_type); public: __ireturn_type insert(const value_type& __v) { __hashtable& __h = _M_conjure_hashtable(); __node_gen_type __node_gen(__h); return __h._M_insert(__v, __node_gen, __unique_keys()); } iterator insert(const_iterator __hint, const value_type& __v) { __hashtable& __h = _M_conjure_hashtable(); __node_gen_type __node_gen(__h); return __h._M_insert(__hint, __v, __node_gen, __unique_keys()); } void insert(initializer_list<value_type> __l) { this->insert(__l.begin(), __l.end()); } template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { __hashtable& __h = _M_conjure_hashtable(); __node_gen_type __node_gen(__h); return _M_insert_range(__first, __last, __node_gen, __unique_keys()); } }; template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> template<typename _InputIterator, typename _NodeGetter> void _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_insert_range(_InputIterator __first, _InputIterator __last, const _NodeGetter& __node_gen, true_type) { size_type __n_elt = __detail::__distance_fw(__first, __last); if (__n_elt == 0) return; __hashtable& __h = _M_conjure_hashtable(); for (; __first != __last; ++__first) { if (__h._M_insert(*__first, __node_gen, __unique_keys(), __n_elt).second) __n_elt = 1; else if (__n_elt != 1) --__n_elt; } } template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> template<typename _InputIterator, typename _NodeGetter> void _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_insert_range(_InputIterator __first, _InputIterator __last, const _NodeGetter& __node_gen, false_type) { using __rehash_type = typename __hashtable::__rehash_type; using __rehash_state = typename __hashtable::__rehash_state; using pair_type = std::pair<bool, std::size_t>; size_type __n_elt = __detail::__distance_fw(__first, __last); if (__n_elt == 0) return; __hashtable& __h = _M_conjure_hashtable(); __rehash_type& __rehash = __h._M_rehash_policy; const __rehash_state& __saved_state = __rehash._M_state(); pair_type __do_rehash = __rehash._M_need_rehash(__h._M_bucket_count, __h._M_element_count, __n_elt); if (__do_rehash.first) __h._M_rehash(__do_rehash.second, __saved_state); for (; __first != __last; ++__first) __h._M_insert(*__first, __node_gen, __unique_keys()); } /** * Primary class template _Insert. * * Defines @c insert member functions that depend on _Hashtable policies, * via partial specializations. */ template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits, bool _Constant_iterators = _Traits::__constant_iterators::value> struct _Insert; /// Specialization. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true> : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits> { using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; using __hashtable_base = _Hashtable_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, _Hash, _Traits>; using value_type = typename __base_type::value_type; using iterator = typename __base_type::iterator; using const_iterator = typename __base_type::const_iterator; using __unique_keys = typename __base_type::__unique_keys; using __ireturn_type = typename __hashtable_base::__ireturn_type; using __hashtable = typename __base_type::__hashtable; using __node_gen_type = typename __base_type::__node_gen_type; using __base_type::insert; __ireturn_type insert(value_type&& __v) { __hashtable& __h = this->_M_conjure_hashtable(); __node_gen_type __node_gen(__h); return __h._M_insert(std::move(__v), __node_gen, __unique_keys()); } iterator insert(const_iterator __hint, value_type&& __v) { __hashtable& __h = this->_M_conjure_hashtable(); __node_gen_type __node_gen(__h); return __h._M_insert(__hint, std::move(__v), __node_gen, __unique_keys()); } }; /// Specialization. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> struct _Insert<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, false> : public _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits> { using __base_type = _Insert_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; using value_type = typename __base_type::value_type; using iterator = typename __base_type::iterator; using const_iterator = typename __base_type::const_iterator; using __unique_keys = typename __base_type::__unique_keys; using __hashtable = typename __base_type::__hashtable; using __ireturn_type = typename __base_type::__ireturn_type; using __base_type::insert; template<typename _Pair> using __is_cons = std::is_constructible<value_type, _Pair&&>; template<typename _Pair> using _IFcons = std::enable_if<__is_cons<_Pair>::value>; template<typename _Pair> using _IFconsp = typename _IFcons<_Pair>::type; template<typename _Pair, typename = _IFconsp<_Pair>> __ireturn_type insert(_Pair&& __v) { __hashtable& __h = this->_M_conjure_hashtable(); return __h._M_emplace(__unique_keys(), std::forward<_Pair>(__v)); } template<typename _Pair, typename = _IFconsp<_Pair>> iterator insert(const_iterator __hint, _Pair&& __v) { __hashtable& __h = this->_M_conjure_hashtable(); return __h._M_emplace(__hint, __unique_keys(), std::forward<_Pair>(__v)); } }; template<typename _Policy> using __has_load_factor = typename _Policy::__has_load_factor; /** * Primary class template _Rehash_base. * * Give hashtable the max_load_factor functions and reserve iff the * rehash policy supports it. */ template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits, typename = __detected_or_t<std::false_type, __has_load_factor, _RehashPolicy>> struct _Rehash_base; /// Specialization when rehash policy doesn't provide load factor management. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, std::false_type> { }; /// Specialization when rehash policy provide load factor management. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> struct _Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, std::true_type> { using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; float max_load_factor() const noexcept { const __hashtable* __this = static_cast<const __hashtable*>(this); return __this->__rehash_policy().max_load_factor(); } void max_load_factor(float __z) { __hashtable* __this = static_cast<__hashtable*>(this); __this->__rehash_policy(_RehashPolicy(__z)); } void reserve(std::size_t __n) { __hashtable* __this = static_cast<__hashtable*>(this); __this->rehash(__builtin_ceil(__n / max_load_factor())); } }; /** * Primary class template _Hashtable_ebo_helper. * * Helper class using EBO when it is not forbidden (the type is not * final) and when it is worth it (the type is empty.) */ template<int _Nm, typename _Tp, bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)> struct _Hashtable_ebo_helper; /// Specialization using EBO. template<int _Nm, typename _Tp> struct _Hashtable_ebo_helper<_Nm, _Tp, true> : private _Tp { _Hashtable_ebo_helper() = default; template<typename _OtherTp> _Hashtable_ebo_helper(_OtherTp&& __tp) : _Tp(std::forward<_OtherTp>(__tp)) { } static const _Tp& _S_cget(const _Hashtable_ebo_helper& __eboh) { return static_cast<const _Tp&>(__eboh); } static _Tp& _S_get(_Hashtable_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); } }; /// Specialization not using EBO. template<int _Nm, typename _Tp> struct _Hashtable_ebo_helper<_Nm, _Tp, false> { _Hashtable_ebo_helper() = default; template<typename _OtherTp> _Hashtable_ebo_helper(_OtherTp&& __tp) : _M_tp(std::forward<_OtherTp>(__tp)) { } static const _Tp& _S_cget(const _Hashtable_ebo_helper& __eboh) { return __eboh._M_tp; } static _Tp& _S_get(_Hashtable_ebo_helper& __eboh) { return __eboh._M_tp; } private: _Tp _M_tp; }; /** * Primary class template _Local_iterator_base. * * Base class for local iterators, used to iterate within a bucket * but not between buckets. */ template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash, bool __cache_hash_code> struct _Local_iterator_base; /** * Primary class template _Hash_code_base. * * Encapsulates two policy issues that aren't quite orthogonal. * (1) the difference between using a ranged hash function and using * the combination of a hash function and a range-hashing function. * In the former case we don't have such things as hash codes, so * we have a dummy type as placeholder. * (2) Whether or not we cache hash codes. Caching hash codes is * meaningless if we have a ranged hash function. * * We also put the key extraction objects here, for convenience. * Each specialization derives from one or more of the template * parameters to benefit from Ebo. This is important as this type * is inherited in some cases by the _Local_iterator_base type used * to implement local_iterator and const_local_iterator. As with * any iterator type we prefer to make it as small as possible. * * Primary template is unused except as a hook for specializations. */ template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash, bool __cache_hash_code> struct _Hash_code_base; /// Specialization: ranged hash function, no caching hash codes. H1 /// and H2 are provided but ignored. We define a dummy hash code type. template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash> struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, false> : private _Hashtable_ebo_helper<0, _ExtractKey>, private _Hashtable_ebo_helper<1, _Hash> { private: using __ebo_extract_key = _Hashtable_ebo_helper<0, _ExtractKey>; using __ebo_hash = _Hashtable_ebo_helper<1, _Hash>; protected: typedef void* __hash_code; typedef _Hash_node<_Value, false> __node_type; // We need the default constructor for the local iterators and _Hashtable // default constructor. _Hash_code_base() = default; _Hash_code_base(const _ExtractKey& __ex, const _H1&, const _H2&, const _Hash& __h) : __ebo_extract_key(__ex), __ebo_hash(__h) { } __hash_code _M_hash_code(const _Key& __key) const { return 0; } std::size_t _M_bucket_index(const _Key& __k, __hash_code, std::size_t __n) const { return _M_ranged_hash()(__k, __n); } std::size_t _M_bucket_index(const __node_type* __p, std::size_t __n) const noexcept( noexcept(declval<const _Hash&>()(declval<const _Key&>(), (std::size_t)0)) ) { return _M_ranged_hash()(_M_extract()(__p->_M_v()), __n); } void _M_store_code(__node_type*, __hash_code) const { } void _M_copy_code(__node_type*, const __node_type*) const { } void _M_swap(_Hash_code_base& __x) { std::swap(_M_extract(), __x._M_extract()); std::swap(_M_ranged_hash(), __x._M_ranged_hash()); } const _ExtractKey& _M_extract() const { return __ebo_extract_key::_S_cget(*this); } _ExtractKey& _M_extract() { return __ebo_extract_key::_S_get(*this); } const _Hash& _M_ranged_hash() const { return __ebo_hash::_S_cget(*this); } _Hash& _M_ranged_hash() { return __ebo_hash::_S_get(*this); } }; // No specialization for ranged hash function while caching hash codes. // That combination is meaningless, and trying to do it is an error. /// Specialization: ranged hash function, cache hash codes. This /// combination is meaningless, so we provide only a declaration /// and no definition. template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash> struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, true>; /// Specialization: hash function and range-hashing function, no /// caching of hash codes. /// Provides typedef and accessor required by C++ 11. template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2> struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Default_ranged_hash, false> : private _Hashtable_ebo_helper<0, _ExtractKey>, private _Hashtable_ebo_helper<1, _H1>, private _Hashtable_ebo_helper<2, _H2> { private: using __ebo_extract_key = _Hashtable_ebo_helper<0, _ExtractKey>; using __ebo_h1 = _Hashtable_ebo_helper<1, _H1>; using __ebo_h2 = _Hashtable_ebo_helper<2, _H2>; // Gives the local iterator implementation access to _M_bucket_index(). friend struct _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Default_ranged_hash, false>; public: typedef _H1 hasher; hasher hash_function() const { return _M_h1(); } protected: typedef std::size_t __hash_code; typedef _Hash_node<_Value, false> __node_type; // We need the default constructor for the local iterators and _Hashtable // default constructor. _Hash_code_base() = default; _Hash_code_base(const _ExtractKey& __ex, const _H1& __h1, const _H2& __h2, const _Default_ranged_hash&) : __ebo_extract_key(__ex), __ebo_h1(__h1), __ebo_h2(__h2) { } __hash_code _M_hash_code(const _Key& __k) const { static_assert(__is_invocable<const _H1&, const _Key&>{}, "hash function must be invocable with an argument of key type"); return _M_h1()(__k); } std::size_t _M_bucket_index(const _Key&, __hash_code __c, std::size_t __n) const { return _M_h2()(__c, __n); } std::size_t _M_bucket_index(const __node_type* __p, std::size_t __n) const noexcept( noexcept(declval<const _H1&>()(declval<const _Key&>())) && noexcept(declval<const _H2&>()((__hash_code)0, (std::size_t)0)) ) { return _M_h2()(_M_h1()(_M_extract()(__p->_M_v())), __n); } void _M_store_code(__node_type*, __hash_code) const { } void _M_copy_code(__node_type*, const __node_type*) const { } void _M_swap(_Hash_code_base& __x) { std::swap(_M_extract(), __x._M_extract()); std::swap(_M_h1(), __x._M_h1()); std::swap(_M_h2(), __x._M_h2()); } const _ExtractKey& _M_extract() const { return __ebo_extract_key::_S_cget(*this); } _ExtractKey& _M_extract() { return __ebo_extract_key::_S_get(*this); } const _H1& _M_h1() const { return __ebo_h1::_S_cget(*this); } _H1& _M_h1() { return __ebo_h1::_S_get(*this); } const _H2& _M_h2() const { return __ebo_h2::_S_cget(*this); } _H2& _M_h2() { return __ebo_h2::_S_get(*this); } }; /// Specialization: hash function and range-hashing function, /// caching hash codes. H is provided but ignored. Provides /// typedef and accessor required by C++ 11. template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2> struct _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Default_ranged_hash, true> : private _Hashtable_ebo_helper<0, _ExtractKey>, private _Hashtable_ebo_helper<1, _H1>, private _Hashtable_ebo_helper<2, _H2> { private: // Gives the local iterator implementation access to _M_h2(). friend struct _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Default_ranged_hash, true>; using __ebo_extract_key = _Hashtable_ebo_helper<0, _ExtractKey>; using __ebo_h1 = _Hashtable_ebo_helper<1, _H1>; using __ebo_h2 = _Hashtable_ebo_helper<2, _H2>; public: typedef _H1 hasher; hasher hash_function() const { return _M_h1(); } protected: typedef std::size_t __hash_code; typedef _Hash_node<_Value, true> __node_type; // We need the default constructor for _Hashtable default constructor. _Hash_code_base() = default; _Hash_code_base(const _ExtractKey& __ex, const _H1& __h1, const _H2& __h2, const _Default_ranged_hash&) : __ebo_extract_key(__ex), __ebo_h1(__h1), __ebo_h2(__h2) { } __hash_code _M_hash_code(const _Key& __k) const { static_assert(__is_invocable<const _H1&, const _Key&>{}, "hash function must be invocable with an argument of key type"); return _M_h1()(__k); } std::size_t _M_bucket_index(const _Key&, __hash_code __c, std::size_t __n) const { return _M_h2()(__c, __n); } std::size_t _M_bucket_index(const __node_type* __p, std::size_t __n) const noexcept( noexcept(declval<const _H2&>()((__hash_code)0, (std::size_t)0)) ) { return _M_h2()(__p->_M_hash_code, __n); } void _M_store_code(__node_type* __n, __hash_code __c) const { __n->_M_hash_code = __c; } void _M_copy_code(__node_type* __to, const __node_type* __from) const { __to->_M_hash_code = __from->_M_hash_code; } void _M_swap(_Hash_code_base& __x) { std::swap(_M_extract(), __x._M_extract()); std::swap(_M_h1(), __x._M_h1()); std::swap(_M_h2(), __x._M_h2()); } const _ExtractKey& _M_extract() const { return __ebo_extract_key::_S_cget(*this); } _ExtractKey& _M_extract() { return __ebo_extract_key::_S_get(*this); } const _H1& _M_h1() const { return __ebo_h1::_S_cget(*this); } _H1& _M_h1() { return __ebo_h1::_S_get(*this); } const _H2& _M_h2() const { return __ebo_h2::_S_cget(*this); } _H2& _M_h2() { return __ebo_h2::_S_get(*this); } }; /** * Primary class template _Equal_helper. * */ template <typename _Key, typename _Value, typename _ExtractKey, typename _Equal, typename _HashCodeType, bool __cache_hash_code> struct _Equal_helper; /// Specialization. template<typename _Key, typename _Value, typename _ExtractKey, typename _Equal, typename _HashCodeType> struct _Equal_helper<_Key, _Value, _ExtractKey, _Equal, _HashCodeType, true> { static bool _S_equals(const _Equal& __eq, const _ExtractKey& __extract, const _Key& __k, _HashCodeType __c, _Hash_node<_Value, true>* __n) { return __c == __n->_M_hash_code && __eq(__k, __extract(__n->_M_v())); } }; /// Specialization. template<typename _Key, typename _Value, typename _ExtractKey, typename _Equal, typename _HashCodeType> struct _Equal_helper<_Key, _Value, _ExtractKey, _Equal, _HashCodeType, false> { static bool _S_equals(const _Equal& __eq, const _ExtractKey& __extract, const _Key& __k, _HashCodeType, _Hash_node<_Value, false>* __n) { return __eq(__k, __extract(__n->_M_v())); } }; /// Partial specialization used when nodes contain a cached hash code. template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash> struct _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, true> : private _Hashtable_ebo_helper<0, _H2> { protected: using __base_type = _Hashtable_ebo_helper<0, _H2>; using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, true>; _Local_iterator_base() = default; _Local_iterator_base(const __hash_code_base& __base, _Hash_node<_Value, true>* __p, std::size_t __bkt, std::size_t __bkt_count) : __base_type(__base._M_h2()), _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { } void _M_incr() { _M_cur = _M_cur->_M_next(); if (_M_cur) { std::size_t __bkt = __base_type::_S_get(*this)(_M_cur->_M_hash_code, _M_bucket_count); if (__bkt != _M_bucket) _M_cur = nullptr; } } _Hash_node<_Value, true>* _M_cur; std::size_t _M_bucket; std::size_t _M_bucket_count; public: const void* _M_curr() const { return _M_cur; } // for equality ops std::size_t _M_get_bucket() const { return _M_bucket; } // for debug mode }; // Uninitialized storage for a _Hash_code_base. // This type is DefaultConstructible and Assignable even if the // _Hash_code_base type isn't, so that _Local_iterator_base<..., false> // can be DefaultConstructible and Assignable. template<typename _Tp, bool _IsEmpty = std::is_empty<_Tp>::value> struct _Hash_code_storage { __gnu_cxx::__aligned_buffer<_Tp> _M_storage; _Tp* _M_h() { return _M_storage._M_ptr(); } const _Tp* _M_h() const { return _M_storage._M_ptr(); } }; // Empty partial specialization for empty _Hash_code_base types. template<typename _Tp> struct _Hash_code_storage<_Tp, true> { static_assert( std::is_empty<_Tp>::value, "Type must be empty" ); // As _Tp is an empty type there will be no bytes written/read through // the cast pointer, so no strict-aliasing violation. _Tp* _M_h() { return reinterpret_cast<_Tp*>(this); } const _Tp* _M_h() const { return reinterpret_cast<const _Tp*>(this); } }; template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash> using __hash_code_for_local_iter = _Hash_code_storage<_Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, false>>; // Partial specialization used when hash codes are not cached template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash> struct _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, false> : __hash_code_for_local_iter<_Key, _Value, _ExtractKey, _H1, _H2, _Hash> { protected: using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, false>; _Local_iterator_base() : _M_bucket_count(-1) { } _Local_iterator_base(const __hash_code_base& __base, _Hash_node<_Value, false>* __p, std::size_t __bkt, std::size_t __bkt_count) : _M_cur(__p), _M_bucket(__bkt), _M_bucket_count(__bkt_count) { _M_init(__base); } ~_Local_iterator_base() { if (_M_bucket_count != -1) _M_destroy(); } _Local_iterator_base(const _Local_iterator_base& __iter) : _M_cur(__iter._M_cur), _M_bucket(__iter._M_bucket), _M_bucket_count(__iter._M_bucket_count) { if (_M_bucket_count != -1) _M_init(*__iter._M_h()); } _Local_iterator_base& operator=(const _Local_iterator_base& __iter) { if (_M_bucket_count != -1) _M_destroy(); _M_cur = __iter._M_cur; _M_bucket = __iter._M_bucket; _M_bucket_count = __iter._M_bucket_count; if (_M_bucket_count != -1) _M_init(*__iter._M_h()); return *this; } void _M_incr() { _M_cur = _M_cur->_M_next(); if (_M_cur) { std::size_t __bkt = this->_M_h()->_M_bucket_index(_M_cur, _M_bucket_count); if (__bkt != _M_bucket) _M_cur = nullptr; } } _Hash_node<_Value, false>* _M_cur; std::size_t _M_bucket; std::size_t _M_bucket_count; void _M_init(const __hash_code_base& __base) { ::new(this->_M_h()) __hash_code_base(__base); } void _M_destroy() { this->_M_h()->~__hash_code_base(); } public: const void* _M_curr() const { return _M_cur; } // for equality ops and debug mode std::size_t _M_get_bucket() const { return _M_bucket; } // for debug mode }; template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash, bool __cache> inline bool operator==(const _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, __cache>& __x, const _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, __cache>& __y) { return __x._M_curr() == __y._M_curr(); } template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash, bool __cache> inline bool operator!=(const _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, __cache>& __x, const _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, __cache>& __y) { return __x._M_curr() != __y._M_curr(); } /// local iterators template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash, bool __constant_iterators, bool __cache> struct _Local_iterator : public _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, __cache> { private: using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, __cache>; using __hash_code_base = typename __base_type::__hash_code_base; public: typedef _Value value_type; typedef typename std::conditional<__constant_iterators, const _Value*, _Value*>::type pointer; typedef typename std::conditional<__constant_iterators, const _Value&, _Value&>::type reference; typedef std::ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; _Local_iterator() = default; _Local_iterator(const __hash_code_base& __base, _Hash_node<_Value, __cache>* __p, std::size_t __bkt, std::size_t __bkt_count) : __base_type(__base, __p, __bkt, __bkt_count) { } reference operator*() const { return this->_M_cur->_M_v(); } pointer operator->() const { return this->_M_cur->_M_valptr(); } _Local_iterator& operator++() { this->_M_incr(); return *this; } _Local_iterator operator++(int) { _Local_iterator __tmp(*this); this->_M_incr(); return __tmp; } }; /// local const_iterators template<typename _Key, typename _Value, typename _ExtractKey, typename _H1, typename _H2, typename _Hash, bool __constant_iterators, bool __cache> struct _Local_const_iterator : public _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, __cache> { private: using __base_type = _Local_iterator_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, __cache>; using __hash_code_base = typename __base_type::__hash_code_base; public: typedef _Value value_type; typedef const _Value* pointer; typedef const _Value& reference; typedef std::ptrdiff_t difference_type; typedef std::forward_iterator_tag iterator_category; _Local_const_iterator() = default; _Local_const_iterator(const __hash_code_base& __base, _Hash_node<_Value, __cache>* __p, std::size_t __bkt, std::size_t __bkt_count) : __base_type(__base, __p, __bkt, __bkt_count) { } _Local_const_iterator(const _Local_iterator<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, __constant_iterators, __cache>& __x) : __base_type(__x) { } reference operator*() const { return this->_M_cur->_M_v(); } pointer operator->() const { return this->_M_cur->_M_valptr(); } _Local_const_iterator& operator++() { this->_M_incr(); return *this; } _Local_const_iterator operator++(int) { _Local_const_iterator __tmp(*this); this->_M_incr(); return __tmp; } }; /** * Primary class template _Hashtable_base. * * Helper class adding management of _Equal functor to * _Hash_code_base type. * * Base class templates are: * - __detail::_Hash_code_base * - __detail::_Hashtable_ebo_helper */ template<typename _Key, typename _Value, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _Traits> struct _Hashtable_base : public _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, _Traits::__hash_cached::value>, private _Hashtable_ebo_helper<0, _Equal> { public: typedef _Key key_type; typedef _Value value_type; typedef _Equal key_equal; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; using __traits_type = _Traits; using __hash_cached = typename __traits_type::__hash_cached; using __constant_iterators = typename __traits_type::__constant_iterators; using __unique_keys = typename __traits_type::__unique_keys; using __hash_code_base = _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, __hash_cached::value>; using __hash_code = typename __hash_code_base::__hash_code; using __node_type = typename __hash_code_base::__node_type; using iterator = __detail::_Node_iterator<value_type, __constant_iterators::value, __hash_cached::value>; using const_iterator = __detail::_Node_const_iterator<value_type, __constant_iterators::value, __hash_cached::value>; using local_iterator = __detail::_Local_iterator<key_type, value_type, _ExtractKey, _H1, _H2, _Hash, __constant_iterators::value, __hash_cached::value>; using const_local_iterator = __detail::_Local_const_iterator<key_type, value_type, _ExtractKey, _H1, _H2, _Hash, __constant_iterators::value, __hash_cached::value>; using __ireturn_type = typename std::conditional<__unique_keys::value, std::pair<iterator, bool>, iterator>::type; private: using _EqualEBO = _Hashtable_ebo_helper<0, _Equal>; using _EqualHelper = _Equal_helper<_Key, _Value, _ExtractKey, _Equal, __hash_code, __hash_cached::value>; protected: _Hashtable_base() = default; _Hashtable_base(const _ExtractKey& __ex, const _H1& __h1, const _H2& __h2, const _Hash& __hash, const _Equal& __eq) : __hash_code_base(__ex, __h1, __h2, __hash), _EqualEBO(__eq) { } bool _M_equals(const _Key& __k, __hash_code __c, __node_type* __n) const { static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{}, "key equality predicate must be invocable with two arguments of " "key type"); return _EqualHelper::_S_equals(_M_eq(), this->_M_extract(), __k, __c, __n); } void _M_swap(_Hashtable_base& __x) { __hash_code_base::_M_swap(__x); std::swap(_M_eq(), __x._M_eq()); } const _Equal& _M_eq() const { return _EqualEBO::_S_cget(*this); } _Equal& _M_eq() { return _EqualEBO::_S_get(*this); } }; /** * struct _Equality_base. * * Common types and functions for class _Equality. */ struct _Equality_base { protected: template<typename _Uiterator> static bool _S_is_permutation(_Uiterator, _Uiterator, _Uiterator); }; // See std::is_permutation in N3068. template<typename _Uiterator> bool _Equality_base:: _S_is_permutation(_Uiterator __first1, _Uiterator __last1, _Uiterator __first2) { for (; __first1 != __last1; ++__first1, ++__first2) if (!(*__first1 == *__first2)) break; if (__first1 == __last1) return true; _Uiterator __last2 = __first2; std::advance(__last2, std::distance(__first1, __last1)); for (_Uiterator __it1 = __first1; __it1 != __last1; ++__it1) { _Uiterator __tmp = __first1; while (__tmp != __it1 && !bool(*__tmp == *__it1)) ++__tmp; // We've seen this one before. if (__tmp != __it1) continue; std::ptrdiff_t __n2 = 0; for (__tmp = __first2; __tmp != __last2; ++__tmp) if (*__tmp == *__it1) ++__n2; if (!__n2) return false; std::ptrdiff_t __n1 = 0; for (__tmp = __it1; __tmp != __last1; ++__tmp) if (*__tmp == *__it1) ++__n1; if (__n1 != __n2) return false; } return true; } /** * Primary class template _Equality. * * This is for implementing equality comparison for unordered * containers, per N3068, by John Lakos and Pablo Halpern. * Algorithmically, we follow closely the reference implementations * therein. */ template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits, bool _Unique_keys = _Traits::__unique_keys::value> struct _Equality; /// Specialization. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true> { using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; bool _M_equal(const __hashtable&) const; }; template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> bool _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>:: _M_equal(const __hashtable& __other) const { const __hashtable* __this = static_cast<const __hashtable*>(this); if (__this->size() != __other.size()) return false; for (auto __itx = __this->begin(); __itx != __this->end(); ++__itx) { const auto __ity = __other.find(_ExtractKey()(*__itx)); if (__ity == __other.end() || !bool(*__ity == *__itx)) return false; } return true; } /// Specialization. template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> struct _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, false> : public _Equality_base { using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>; bool _M_equal(const __hashtable&) const; }; template<typename _Key, typename _Value, typename _Alloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> bool _Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, false>:: _M_equal(const __hashtable& __other) const { const __hashtable* __this = static_cast<const __hashtable*>(this); if (__this->size() != __other.size()) return false; for (auto __itx = __this->begin(); __itx != __this->end();) { const auto __xrange = __this->equal_range(_ExtractKey()(*__itx)); const auto __yrange = __other.equal_range(_ExtractKey()(*__itx)); if (std::distance(__xrange.first, __xrange.second) != std::distance(__yrange.first, __yrange.second)) return false; if (!_S_is_permutation(__xrange.first, __xrange.second, __yrange.first)) return false; __itx = __xrange.second; } return true; } /** * This type deals with all allocation and keeps an allocator instance through * inheritance to benefit from EBO when possible. */ template<typename _NodeAlloc> struct _Hashtable_alloc : private _Hashtable_ebo_helper<0, _NodeAlloc> { private: using __ebo_node_alloc = _Hashtable_ebo_helper<0, _NodeAlloc>; public: using __node_type = typename _NodeAlloc::value_type; using __node_alloc_type = _NodeAlloc; // Use __gnu_cxx to benefit from _S_always_equal and al. using __node_alloc_traits = __gnu_cxx::__alloc_traits<__node_alloc_type>; using __value_alloc_traits = typename __node_alloc_traits::template rebind_traits<typename __node_type::value_type>; using __node_base = __detail::_Hash_node_base; using __bucket_type = __node_base*; using __bucket_alloc_type = __alloc_rebind<__node_alloc_type, __bucket_type>; using __bucket_alloc_traits = std::allocator_traits<__bucket_alloc_type>; _Hashtable_alloc() = default; _Hashtable_alloc(const _Hashtable_alloc&) = default; _Hashtable_alloc(_Hashtable_alloc&&) = default; template<typename _Alloc> _Hashtable_alloc(_Alloc&& __a) : __ebo_node_alloc(std::forward<_Alloc>(__a)) { } __node_alloc_type& _M_node_allocator() { return __ebo_node_alloc::_S_get(*this); } const __node_alloc_type& _M_node_allocator() const { return __ebo_node_alloc::_S_cget(*this); } template<typename... _Args> __node_type* _M_allocate_node(_Args&&... __args); void _M_deallocate_node(__node_type* __n); // Deallocate the linked list of nodes pointed to by __n void _M_deallocate_nodes(__node_type* __n); __bucket_type* _M_allocate_buckets(std::size_t __n); void _M_deallocate_buckets(__bucket_type*, std::size_t __n); }; // Definitions of class template _Hashtable_alloc's out-of-line member // functions. template<typename _NodeAlloc> template<typename... _Args> typename _Hashtable_alloc<_NodeAlloc>::__node_type* _Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&&... __args) { auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1); __node_type* __n = std::__to_address(__nptr); __try { ::new ((void*)__n) __node_type; __node_alloc_traits::construct(_M_node_allocator(), __n->_M_valptr(), std::forward<_Args>(__args)...); return __n; } __catch(...) { __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1); __throw_exception_again; } } template<typename _NodeAlloc> void _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(__node_type* __n) { typedef typename __node_alloc_traits::pointer _Ptr; auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__n); __node_alloc_traits::destroy(_M_node_allocator(), __n->_M_valptr()); __n->~__node_type(); __node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1); } template<typename _NodeAlloc> void _Hashtable_alloc<_NodeAlloc>::_M_deallocate_nodes(__node_type* __n) { while (__n) { __node_type* __tmp = __n; __n = __n->_M_next(); _M_deallocate_node(__tmp); } } template<typename _NodeAlloc> typename _Hashtable_alloc<_NodeAlloc>::__bucket_type* _Hashtable_alloc<_NodeAlloc>::_M_allocate_buckets(std::size_t __n) { __bucket_alloc_type __alloc(_M_node_allocator()); auto __ptr = __bucket_alloc_traits::allocate(__alloc, __n); __bucket_type* __p = std::__to_address(__ptr); __builtin_memset(__p, 0, __n * sizeof(__bucket_type)); return __p; } template<typename _NodeAlloc> void _Hashtable_alloc<_NodeAlloc>::_M_deallocate_buckets(__bucket_type* __bkts, std::size_t __n) { typedef typename __bucket_alloc_traits::pointer _Ptr; auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__bkts); __bucket_alloc_type __alloc(_M_node_allocator()); __bucket_alloc_traits::deallocate(__alloc, __ptr, __n); } //@} hashtable-detail } // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _HASHTABLE_POLICY_H c++/8/bits/invoke.h 0000644 00000007111 15146341150 0007670 0 ustar 00 // Implementation of INVOKE -*- C++ -*- // Copyright (C) 2016-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file include/bits/invoke.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{functional} */ #ifndef _GLIBCXX_INVOKE_H #define _GLIBCXX_INVOKE_H 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <type_traits> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup utilities * @{ */ // Used by __invoke_impl instead of std::forward<_Tp> so that a // reference_wrapper is converted to an lvalue-reference. template<typename _Tp, typename _Up = typename __inv_unwrap<_Tp>::type> constexpr _Up&& __invfwd(typename remove_reference<_Tp>::type& __t) noexcept { return static_cast<_Up&&>(__t); } template<typename _Res, typename _Fn, typename... _Args> constexpr _Res __invoke_impl(__invoke_other, _Fn&& __f, _Args&&... __args) { return std::forward<_Fn>(__f)(std::forward<_Args>(__args)...); } template<typename _Res, typename _MemFun, typename _Tp, typename... _Args> constexpr _Res __invoke_impl(__invoke_memfun_ref, _MemFun&& __f, _Tp&& __t, _Args&&... __args) { return (__invfwd<_Tp>(__t).*__f)(std::forward<_Args>(__args)...); } template<typename _Res, typename _MemFun, typename _Tp, typename... _Args> constexpr _Res __invoke_impl(__invoke_memfun_deref, _MemFun&& __f, _Tp&& __t, _Args&&... __args) { return ((*std::forward<_Tp>(__t)).*__f)(std::forward<_Args>(__args)...); } template<typename _Res, typename _MemPtr, typename _Tp> constexpr _Res __invoke_impl(__invoke_memobj_ref, _MemPtr&& __f, _Tp&& __t) { return __invfwd<_Tp>(__t).*__f; } template<typename _Res, typename _MemPtr, typename _Tp> constexpr _Res __invoke_impl(__invoke_memobj_deref, _MemPtr&& __f, _Tp&& __t) { return (*std::forward<_Tp>(__t)).*__f; } /// Invoke a callable object. template<typename _Callable, typename... _Args> constexpr typename __invoke_result<_Callable, _Args...>::type __invoke(_Callable&& __fn, _Args&&... __args) noexcept(__is_nothrow_invocable<_Callable, _Args...>::value) { using __result = __invoke_result<_Callable, _Args...>; using __type = typename __result::type; using __tag = typename __result::__invoke_type; return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn), std::forward<_Args>(__args)...); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_INVOKE_H c++/8/bits/node_handle.h 0000644 00000020030 15146341150 0010630 0 ustar 00 // Node handles for containers -*- C++ -*- // Copyright (C) 2016-2018 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/node_handle.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. * @headername{map,set,unordered_map,unordered_set} */ #ifndef _NODE_HANDLE #define _NODE_HANDLE 1 #pragma GCC system_header #if __cplusplus > 201402L # define __cpp_lib_node_extract 201606 #include <optional> #include <bits/alloc_traits.h> #include <bits/ptr_traits.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Base class for node handle types of maps and sets. template<typename _Val, typename _NodeAlloc> class _Node_handle_common { using _AllocTraits = allocator_traits<_NodeAlloc>; public: using allocator_type = __alloc_rebind<_NodeAlloc, _Val>; allocator_type get_allocator() const noexcept { __glibcxx_assert(!this->empty()); return allocator_type(*_M_alloc); } explicit operator bool() const noexcept { return _M_ptr != nullptr; } [[nodiscard]] bool empty() const noexcept { return _M_ptr == nullptr; } protected: constexpr _Node_handle_common() noexcept : _M_ptr(), _M_alloc() {} ~_Node_handle_common() { _M_destroy(); } _Node_handle_common(_Node_handle_common&& __nh) noexcept : _M_ptr(__nh._M_ptr), _M_alloc(std::move(__nh._M_alloc)) { __nh._M_ptr = nullptr; __nh._M_alloc = nullopt; } _Node_handle_common& operator=(_Node_handle_common&& __nh) noexcept { _M_destroy(); _M_ptr = __nh._M_ptr; if constexpr (is_move_assignable_v<_NodeAlloc>) { if (_AllocTraits::propagate_on_container_move_assignment::value || !this->_M_alloc) this->_M_alloc = std::move(__nh._M_alloc); else { __glibcxx_assert(this->_M_alloc == __nh._M_alloc); } } else { __glibcxx_assert(_M_alloc); } __nh._M_ptr = nullptr; __nh._M_alloc = nullopt; return *this; } _Node_handle_common(typename _AllocTraits::pointer __ptr, const _NodeAlloc& __alloc) : _M_ptr(__ptr), _M_alloc(__alloc) { } void _M_swap(_Node_handle_common& __nh) noexcept { using std::swap; swap(_M_ptr, __nh._M_ptr); if (_AllocTraits::propagate_on_container_swap::value || !_M_alloc || !__nh._M_alloc) _M_alloc.swap(__nh._M_alloc); else { __glibcxx_assert(_M_alloc == __nh._M_alloc); } } private: void _M_destroy() noexcept { if (_M_ptr != nullptr) { allocator_type __alloc(*_M_alloc); allocator_traits<allocator_type>::destroy(__alloc, _M_ptr->_M_valptr()); _AllocTraits::deallocate(*_M_alloc, _M_ptr, 1); } } protected: typename _AllocTraits::pointer _M_ptr; private: optional<_NodeAlloc> _M_alloc; template<typename _Key2, typename _Value2, typename _KeyOfValue, typename _Compare, typename _ValueAlloc> friend class _Rb_tree; }; /// Node handle type for maps. template<typename _Key, typename _Value, typename _NodeAlloc> class _Node_handle : public _Node_handle_common<_Value, _NodeAlloc> { public: constexpr _Node_handle() noexcept = default; ~_Node_handle() = default; _Node_handle(_Node_handle&&) noexcept = default; _Node_handle& operator=(_Node_handle&&) noexcept = default; using key_type = _Key; using mapped_type = typename _Value::second_type; key_type& key() const noexcept { __glibcxx_assert(!this->empty()); return *_M_pkey; } mapped_type& mapped() const noexcept { __glibcxx_assert(!this->empty()); return *_M_pmapped; } void swap(_Node_handle& __nh) noexcept { this->_M_swap(__nh); using std::swap; swap(_M_pkey, __nh._M_pkey); swap(_M_pmapped, __nh._M_pmapped); } friend void swap(_Node_handle& __x, _Node_handle& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } private: using _AllocTraits = allocator_traits<_NodeAlloc>; _Node_handle(typename _AllocTraits::pointer __ptr, const _NodeAlloc& __alloc) : _Node_handle_common<_Value, _NodeAlloc>(__ptr, __alloc) { if (__ptr) { auto& __key = const_cast<_Key&>(__ptr->_M_valptr()->first); _M_pkey = _S_pointer_to(__key); _M_pmapped = _S_pointer_to(__ptr->_M_valptr()->second); } else { _M_pkey = nullptr; _M_pmapped = nullptr; } } template<typename _Tp> using __pointer = __ptr_rebind<typename _AllocTraits::pointer, remove_reference_t<_Tp>>; __pointer<_Key> _M_pkey = nullptr; __pointer<typename _Value::second_type> _M_pmapped = nullptr; template<typename _Tp> __pointer<_Tp> _S_pointer_to(_Tp& __obj) { return pointer_traits<__pointer<_Tp>>::pointer_to(__obj); } const key_type& _M_key() const noexcept { return key(); } template<typename _Key2, typename _Value2, typename _KeyOfValue, typename _Compare, typename _ValueAlloc> friend class _Rb_tree; template<typename _Key2, typename _Value2, typename _ValueAlloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> friend class _Hashtable; }; /// Node handle type for sets. template<typename _Value, typename _NodeAlloc> class _Node_handle<_Value, _Value, _NodeAlloc> : public _Node_handle_common<_Value, _NodeAlloc> { public: constexpr _Node_handle() noexcept = default; ~_Node_handle() = default; _Node_handle(_Node_handle&&) noexcept = default; _Node_handle& operator=(_Node_handle&&) noexcept = default; using value_type = _Value; value_type& value() const noexcept { __glibcxx_assert(!this->empty()); return *this->_M_ptr->_M_valptr(); } void swap(_Node_handle& __nh) noexcept { this->_M_swap(__nh); } friend void swap(_Node_handle& __x, _Node_handle& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } private: using _AllocTraits = allocator_traits<_NodeAlloc>; _Node_handle(typename _AllocTraits::pointer __ptr, const _NodeAlloc& __alloc) : _Node_handle_common<_Value, _NodeAlloc>(__ptr, __alloc) { } const value_type& _M_key() const noexcept { return value(); } template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc> friend class _Rb_tree; template<typename _Key2, typename _Value2, typename _ValueAlloc, typename _ExtractKey, typename _Equal, typename _H1, typename _H2, typename _Hash, typename _RehashPolicy, typename _Traits> friend class _Hashtable; }; /// Return type of insert(node_handle&&) on unique maps/sets. template<typename _Iterator, typename _NodeHandle> struct _Node_insert_return { _Iterator position = _Iterator(); bool inserted = false; _NodeHandle node; }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++17 #endif c++/8/bits/stl_map.h 0000644 00000147067 15146341150 0010053 0 ustar 00 // Map implementation -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_map.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{map} */ #ifndef _STL_MAP_H #define _STL_MAP_H 1 #include <bits/functexcept.h> #include <bits/concept_check.h> #if __cplusplus >= 201103L #include <initializer_list> #include <tuple> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template <typename _Key, typename _Tp, typename _Compare, typename _Alloc> class multimap; /** * @brief A standard container made up of (key,value) pairs, which can be * retrieved based on a key, in logarithmic time. * * @ingroup associative_containers * * @tparam _Key Type of key objects. * @tparam _Tp Type of mapped objects. * @tparam _Compare Comparison function object type, defaults to less<_Key>. * @tparam _Alloc Allocator type, defaults to * allocator<pair<const _Key, _Tp>. * * Meets the requirements of a <a href="tables.html#65">container</a>, a * <a href="tables.html#66">reversible container</a>, and an * <a href="tables.html#69">associative container</a> (using unique keys). * For a @c map<Key,T> the key_type is Key, the mapped_type is T, and the * value_type is std::pair<const Key,T>. * * Maps support bidirectional iterators. * * The private tree data is declared exactly the same way for map and * multimap; the distinction is made entirely in how the tree functions are * called (*_unique versus *_equal, same as the standard). */ template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > > class map { public: typedef _Key key_type; typedef _Tp mapped_type; typedef std::pair<const _Key, _Tp> value_type; typedef _Compare key_compare; typedef _Alloc allocator_type; private: #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename _Alloc::value_type _Alloc_value_type; # if __cplusplus < 201103L __glibcxx_class_requires(_Tp, _SGIAssignableConcept) # endif __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept) #endif #if __cplusplus >= 201103L && defined(__STRICT_ANSI__) static_assert(is_same<typename _Alloc::value_type, value_type>::value, "std::map must have the same value_type as its allocator"); #endif public: class value_compare : public std::binary_function<value_type, value_type, bool> { friend class map<_Key, _Tp, _Compare, _Alloc>; protected: _Compare comp; value_compare(_Compare __c) : comp(__c) { } public: bool operator()(const value_type& __x, const value_type& __y) const { return comp(__x.first, __y.first); } }; private: /// This turns a red-black tree into a [multi]map. typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<value_type>::other _Pair_alloc_type; typedef _Rb_tree<key_type, value_type, _Select1st<value_type>, key_compare, _Pair_alloc_type> _Rep_type; /// The actual tree structure. _Rep_type _M_t; typedef __gnu_cxx::__alloc_traits<_Pair_alloc_type> _Alloc_traits; public: // many of these are specified differently in ISO, but the following are // "functionally equivalent" 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 _Rep_type::iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; typedef typename _Rep_type::size_type size_type; typedef typename _Rep_type::difference_type difference_type; typedef typename _Rep_type::reverse_iterator reverse_iterator; typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; #if __cplusplus > 201402L using node_type = typename _Rep_type::node_type; using insert_return_type = typename _Rep_type::insert_return_type; #endif // [23.3.1.1] construct/copy/destroy // (get_allocator() is also listed in this section) /** * @brief Default constructor creates no elements. */ #if __cplusplus < 201103L map() : _M_t() { } #else map() = default; #endif /** * @brief Creates a %map with no elements. * @param __comp A comparison object. * @param __a An allocator object. */ explicit map(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Pair_alloc_type(__a)) { } /** * @brief %Map copy constructor. * * Whether the allocator is copied depends on the allocator traits. */ #if __cplusplus < 201103L map(const map& __x) : _M_t(__x._M_t) { } #else map(const map&) = default; /** * @brief %Map move constructor. * * The newly-created %map contains the exact contents of the moved * instance. The moved instance is a valid, but unspecified, %map. */ map(map&&) = default; /** * @brief Builds a %map from an initializer_list. * @param __l An initializer_list. * @param __comp A comparison object. * @param __a An allocator object. * * Create a %map consisting of copies of the elements in the * initializer_list @a __l. * This is linear in N if the range is already sorted, and NlogN * otherwise (where N is @a __l.size()). */ map(initializer_list<value_type> __l, const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _M_t(__comp, _Pair_alloc_type(__a)) { _M_t._M_insert_unique(__l.begin(), __l.end()); } /// Allocator-extended default constructor. explicit map(const allocator_type& __a) : _M_t(_Compare(), _Pair_alloc_type(__a)) { } /// Allocator-extended copy constructor. map(const map& __m, const allocator_type& __a) : _M_t(__m._M_t, _Pair_alloc_type(__a)) { } /// Allocator-extended move constructor. map(map&& __m, const allocator_type& __a) noexcept(is_nothrow_copy_constructible<_Compare>::value && _Alloc_traits::_S_always_equal()) : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { } /// Allocator-extended initialier-list constructor. map(initializer_list<value_type> __l, const allocator_type& __a) : _M_t(_Compare(), _Pair_alloc_type(__a)) { _M_t._M_insert_unique(__l.begin(), __l.end()); } /// Allocator-extended range constructor. template<typename _InputIterator> map(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : _M_t(_Compare(), _Pair_alloc_type(__a)) { _M_t._M_insert_unique(__first, __last); } #endif /** * @brief Builds a %map from a range. * @param __first An input iterator. * @param __last An input iterator. * * Create a %map consisting of copies of the elements from * [__first,__last). This is linear in N if the range is * already sorted, and NlogN otherwise (where N is * distance(__first,__last)). */ template<typename _InputIterator> map(_InputIterator __first, _InputIterator __last) : _M_t() { _M_t._M_insert_unique(__first, __last); } /** * @brief Builds a %map from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __comp A comparison functor. * @param __a An allocator object. * * Create a %map consisting of copies of the elements from * [__first,__last). This is linear in N if the range is * already sorted, and NlogN otherwise (where N is * distance(__first,__last)). */ template<typename _InputIterator> map(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Pair_alloc_type(__a)) { _M_t._M_insert_unique(__first, __last); } #if __cplusplus >= 201103L /** * The dtor only erases the elements, and note that if the elements * themselves are pointers, the pointed-to memory is not touched in any * way. Managing the pointer is the user's responsibility. */ ~map() = default; #endif /** * @brief %Map assignment operator. * * Whether the allocator is copied depends on the allocator traits. */ #if __cplusplus < 201103L map& operator=(const map& __x) { _M_t = __x._M_t; return *this; } #else map& operator=(const map&) = default; /// Move assignment operator. map& operator=(map&&) = default; /** * @brief %Map list assignment operator. * @param __l An initializer_list. * * This function fills a %map with copies of the elements in the * initializer list @a __l. * * Note that the assignment completely changes the %map and * that the resulting %map's size is the same as the number * of elements assigned. */ map& operator=(initializer_list<value_type> __l) { _M_t._M_assign_unique(__l.begin(), __l.end()); return *this; } #endif /// Get a copy of the memory allocation object. allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_t.get_allocator()); } // iterators /** * Returns a read/write iterator that points to the first pair in the * %map. * Iteration is done in ascending order according to the keys. */ iterator begin() _GLIBCXX_NOEXCEPT { return _M_t.begin(); } /** * Returns a read-only (constant) iterator that points to the first pair * in the %map. Iteration is done in ascending order according to the * keys. */ const_iterator begin() const _GLIBCXX_NOEXCEPT { return _M_t.begin(); } /** * Returns a read/write iterator that points one past the last * pair in the %map. Iteration is done in ascending order * according to the keys. */ iterator end() _GLIBCXX_NOEXCEPT { return _M_t.end(); } /** * Returns a read-only (constant) iterator that points one past the last * pair in the %map. Iteration is done in ascending order according to * the keys. */ const_iterator end() const _GLIBCXX_NOEXCEPT { return _M_t.end(); } /** * Returns a read/write reverse iterator that points to the last pair in * the %map. Iteration is done in descending order according to the * keys. */ reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return _M_t.rbegin(); } /** * Returns a read-only (constant) reverse iterator that points to the * last pair in the %map. Iteration is done in descending order * according to the keys. */ const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return _M_t.rbegin(); } /** * Returns a read/write reverse iterator that points to one before the * first pair in the %map. Iteration is done in descending order * according to the keys. */ reverse_iterator rend() _GLIBCXX_NOEXCEPT { return _M_t.rend(); } /** * Returns a read-only (constant) reverse iterator that points to one * before the first pair in the %map. Iteration is done in descending * order according to the keys. */ const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return _M_t.rend(); } #if __cplusplus >= 201103L /** * Returns a read-only (constant) iterator that points to the first pair * in the %map. Iteration is done in ascending order according to the * keys. */ const_iterator cbegin() const noexcept { return _M_t.begin(); } /** * Returns a read-only (constant) iterator that points one past the last * pair in the %map. Iteration is done in ascending order according to * the keys. */ const_iterator cend() const noexcept { return _M_t.end(); } /** * Returns a read-only (constant) reverse iterator that points to the * last pair in the %map. Iteration is done in descending order * according to the keys. */ const_reverse_iterator crbegin() const noexcept { return _M_t.rbegin(); } /** * Returns a read-only (constant) reverse iterator that points to one * before the first pair in the %map. Iteration is done in descending * order according to the keys. */ const_reverse_iterator crend() const noexcept { return _M_t.rend(); } #endif // capacity /** Returns true if the %map is empty. (Thus begin() would equal * end().) */ bool empty() const _GLIBCXX_NOEXCEPT { return _M_t.empty(); } /** Returns the size of the %map. */ size_type size() const _GLIBCXX_NOEXCEPT { return _M_t.size(); } /** Returns the maximum size of the %map. */ size_type max_size() const _GLIBCXX_NOEXCEPT { return _M_t.max_size(); } // [23.3.1.2] element access /** * @brief Subscript ( @c [] ) access to %map data. * @param __k The key for which data should be retrieved. * @return A reference to the data of the (key,data) %pair. * * Allows for easy lookup with the subscript ( @c [] ) * operator. Returns data associated with the key specified in * subscript. If the key does not exist, a pair with that key * is created using default values, which is then returned. * * Lookup requires logarithmic time. */ mapped_type& operator[](const key_type& __k) { // concept requirements __glibcxx_function_requires(_DefaultConstructibleConcept<mapped_type>) iterator __i = lower_bound(__k); // __i->first is greater than or equivalent to __k. if (__i == end() || key_comp()(__k, (*__i).first)) #if __cplusplus >= 201103L __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, std::tuple<const key_type&>(__k), std::tuple<>()); #else __i = insert(__i, value_type(__k, mapped_type())); #endif return (*__i).second; } #if __cplusplus >= 201103L mapped_type& operator[](key_type&& __k) { // concept requirements __glibcxx_function_requires(_DefaultConstructibleConcept<mapped_type>) iterator __i = lower_bound(__k); // __i->first is greater than or equivalent to __k. if (__i == end() || key_comp()(__k, (*__i).first)) __i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::tuple<>()); return (*__i).second; } #endif // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 464. Suggestion for new member functions in standard containers. /** * @brief Access to %map data. * @param __k The key for which data should be retrieved. * @return A reference to the data whose key is equivalent to @a __k, if * such a data is present in the %map. * @throw std::out_of_range If no such data is present. */ mapped_type& at(const key_type& __k) { iterator __i = lower_bound(__k); if (__i == end() || key_comp()(__k, (*__i).first)) __throw_out_of_range(__N("map::at")); return (*__i).second; } const mapped_type& at(const key_type& __k) const { const_iterator __i = lower_bound(__k); if (__i == end() || key_comp()(__k, (*__i).first)) __throw_out_of_range(__N("map::at")); return (*__i).second; } // modifiers #if __cplusplus >= 201103L /** * @brief Attempts to build and insert a std::pair into the %map. * * @param __args Arguments used to generate a new pair instance (see * std::piecewise_contruct for passing arguments to each * part of the pair constructor). * * @return A pair, of which the first element is an iterator that points * to the possibly inserted pair, and the second is a bool that * is true if the pair was actually inserted. * * This function attempts to build and insert a (key, value) %pair into * the %map. * A %map relies on unique keys and thus a %pair is only inserted if its * first element (the key) is not already present in the %map. * * Insertion requires logarithmic time. */ template<typename... _Args> std::pair<iterator, bool> emplace(_Args&&... __args) { return _M_t._M_emplace_unique(std::forward<_Args>(__args)...); } /** * @brief Attempts to build and insert a std::pair into the %map. * * @param __pos An iterator that serves as a hint as to where the pair * should be inserted. * @param __args Arguments used to generate a new pair instance (see * std::piecewise_contruct for passing arguments to each * part of the pair constructor). * @return An iterator that points to the element with key of the * std::pair built from @a __args (may or may not be that * std::pair). * * This function is not concerned about whether the insertion took place, * and thus does not return a boolean like the single-argument emplace() * does. * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires logarithmic time (if the hint is not taken). */ template<typename... _Args> iterator emplace_hint(const_iterator __pos, _Args&&... __args) { return _M_t._M_emplace_hint_unique(__pos, std::forward<_Args>(__args)...); } #endif #if __cplusplus > 201402L /// Extract a node. node_type extract(const_iterator __pos) { __glibcxx_assert(__pos != end()); return _M_t.extract(__pos); } /// Extract a node. node_type extract(const key_type& __x) { return _M_t.extract(__x); } /// Re-insert an extracted node. insert_return_type insert(node_type&& __nh) { return _M_t._M_reinsert_node_unique(std::move(__nh)); } /// Re-insert an extracted node. iterator insert(const_iterator __hint, node_type&& __nh) { return _M_t._M_reinsert_node_hint_unique(__hint, std::move(__nh)); } template<typename, typename> friend class std::_Rb_tree_merge_helper; template<typename _C2> void merge(map<_Key, _Tp, _C2, _Alloc>& __source) { using _Merge_helper = _Rb_tree_merge_helper<map, _C2>; _M_t._M_merge_unique(_Merge_helper::_S_get_tree(__source)); } template<typename _C2> void merge(map<_Key, _Tp, _C2, _Alloc>&& __source) { merge(__source); } template<typename _C2> void merge(multimap<_Key, _Tp, _C2, _Alloc>& __source) { using _Merge_helper = _Rb_tree_merge_helper<map, _C2>; _M_t._M_merge_unique(_Merge_helper::_S_get_tree(__source)); } template<typename _C2> void merge(multimap<_Key, _Tp, _C2, _Alloc>&& __source) { merge(__source); } #endif // C++17 #if __cplusplus > 201402L #define __cpp_lib_map_try_emplace 201411 /** * @brief Attempts to build and insert a std::pair into the %map. * * @param __k Key to use for finding a possibly existing pair in * the map. * @param __args Arguments used to generate the .second for a new pair * instance. * * @return A pair, of which the first element is an iterator that points * to the possibly inserted pair, and the second is a bool that * is true if the pair was actually inserted. * * This function attempts to build and insert a (key, value) %pair into * the %map. * A %map relies on unique keys and thus a %pair is only inserted if its * first element (the key) is not already present in the %map. * If a %pair is not inserted, this function has no effect. * * Insertion requires logarithmic time. */ template <typename... _Args> pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) { iterator __i = lower_bound(__k); if (__i == end() || key_comp()(__k, (*__i).first)) { __i = emplace_hint(__i, std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple( std::forward<_Args>(__args)...)); return {__i, true}; } return {__i, false}; } // move-capable overload template <typename... _Args> pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) { iterator __i = lower_bound(__k); if (__i == end() || key_comp()(__k, (*__i).first)) { __i = emplace_hint(__i, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple( std::forward<_Args>(__args)...)); return {__i, true}; } return {__i, false}; } /** * @brief Attempts to build and insert a std::pair into the %map. * * @param __hint An iterator that serves as a hint as to where the * pair should be inserted. * @param __k Key to use for finding a possibly existing pair in * the map. * @param __args Arguments used to generate the .second for a new pair * instance. * @return An iterator that points to the element with key of the * std::pair built from @a __args (may or may not be that * std::pair). * * This function is not concerned about whether the insertion took place, * and thus does not return a boolean like the single-argument * try_emplace() does. However, if insertion did not take place, * this function has no effect. * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires logarithmic time (if the hint is not taken). */ template <typename... _Args> iterator try_emplace(const_iterator __hint, const key_type& __k, _Args&&... __args) { iterator __i; auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k); if (__true_hint.second) __i = emplace_hint(iterator(__true_hint.second), std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple( std::forward<_Args>(__args)...)); else __i = iterator(__true_hint.first); return __i; } // move-capable overload template <typename... _Args> iterator try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args) { iterator __i; auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k); if (__true_hint.second) __i = emplace_hint(iterator(__true_hint.second), std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple( std::forward<_Args>(__args)...)); else __i = iterator(__true_hint.first); return __i; } #endif /** * @brief Attempts to insert a std::pair into the %map. * @param __x Pair to be inserted (see std::make_pair for easy * creation of pairs). * * @return A pair, of which the first element is an iterator that * points to the possibly inserted pair, and the second is * a bool that is true if the pair was actually inserted. * * This function attempts to insert a (key, value) %pair into the %map. * A %map relies on unique keys and thus a %pair is only inserted if its * first element (the key) is not already present in the %map. * * Insertion requires logarithmic time. * @{ */ std::pair<iterator, bool> insert(const value_type& __x) { return _M_t._M_insert_unique(__x); } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2354. Unnecessary copying when inserting into maps with braced-init std::pair<iterator, bool> insert(value_type&& __x) { return _M_t._M_insert_unique(std::move(__x)); } template<typename _Pair> __enable_if_t<is_constructible<value_type, _Pair>::value, pair<iterator, bool>> insert(_Pair&& __x) { return _M_t._M_emplace_unique(std::forward<_Pair>(__x)); } #endif // @} #if __cplusplus >= 201103L /** * @brief Attempts to insert a list of std::pairs into the %map. * @param __list A std::initializer_list<value_type> of pairs to be * inserted. * * Complexity similar to that of the range constructor. */ void insert(std::initializer_list<value_type> __list) { insert(__list.begin(), __list.end()); } #endif /** * @brief Attempts to insert a std::pair into the %map. * @param __position An iterator that serves as a hint as to where the * pair should be inserted. * @param __x Pair to be inserted (see std::make_pair for easy creation * of pairs). * @return An iterator that points to the element with key of * @a __x (may or may not be the %pair passed in). * * This function is not concerned about whether the insertion * took place, and thus does not return a boolean like the * single-argument insert() does. Note that the first * parameter is only a hint and can potentially improve the * performance of the insertion process. A bad hint would * cause no gains in efficiency. * * See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires logarithmic time (if the hint is not taken). * @{ */ iterator #if __cplusplus >= 201103L insert(const_iterator __position, const value_type& __x) #else insert(iterator __position, const value_type& __x) #endif { return _M_t._M_insert_unique_(__position, __x); } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2354. Unnecessary copying when inserting into maps with braced-init iterator insert(const_iterator __position, value_type&& __x) { return _M_t._M_insert_unique_(__position, std::move(__x)); } template<typename _Pair> __enable_if_t<is_constructible<value_type, _Pair>::value, iterator> insert(const_iterator __position, _Pair&& __x) { return _M_t._M_emplace_hint_unique(__position, std::forward<_Pair>(__x)); } #endif // @} /** * @brief Template function that attempts to insert a range of elements. * @param __first Iterator pointing to the start of the range to be * inserted. * @param __last Iterator pointing to the end of the range. * * Complexity similar to that of the range constructor. */ template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_t._M_insert_unique(__first, __last); } #if __cplusplus > 201402L #define __cpp_lib_map_insertion 201411 /** * @brief Attempts to insert or assign a std::pair into the %map. * @param __k Key to use for finding a possibly existing pair in * the map. * @param __obj Argument used to generate the .second for a pair * instance. * * @return A pair, of which the first element is an iterator that * points to the possibly inserted pair, and the second is * a bool that is true if the pair was actually inserted. * * This function attempts to insert a (key, value) %pair into the %map. * A %map relies on unique keys and thus a %pair is only inserted if its * first element (the key) is not already present in the %map. * If the %pair was already in the %map, the .second of the %pair * is assigned from __obj. * * Insertion requires logarithmic time. */ template <typename _Obj> pair<iterator, bool> insert_or_assign(const key_type& __k, _Obj&& __obj) { iterator __i = lower_bound(__k); if (__i == end() || key_comp()(__k, (*__i).first)) { __i = emplace_hint(__i, std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple( std::forward<_Obj>(__obj))); return {__i, true}; } (*__i).second = std::forward<_Obj>(__obj); return {__i, false}; } // move-capable overload template <typename _Obj> pair<iterator, bool> insert_or_assign(key_type&& __k, _Obj&& __obj) { iterator __i = lower_bound(__k); if (__i == end() || key_comp()(__k, (*__i).first)) { __i = emplace_hint(__i, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple( std::forward<_Obj>(__obj))); return {__i, true}; } (*__i).second = std::forward<_Obj>(__obj); return {__i, false}; } /** * @brief Attempts to insert or assign a std::pair into the %map. * @param __hint An iterator that serves as a hint as to where the * pair should be inserted. * @param __k Key to use for finding a possibly existing pair in * the map. * @param __obj Argument used to generate the .second for a pair * instance. * * @return An iterator that points to the element with key of * @a __x (may or may not be the %pair passed in). * * This function attempts to insert a (key, value) %pair into the %map. * A %map relies on unique keys and thus a %pair is only inserted if its * first element (the key) is not already present in the %map. * If the %pair was already in the %map, the .second of the %pair * is assigned from __obj. * * Insertion requires logarithmic time. */ template <typename _Obj> iterator insert_or_assign(const_iterator __hint, const key_type& __k, _Obj&& __obj) { iterator __i; auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k); if (__true_hint.second) { return emplace_hint(iterator(__true_hint.second), std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple( std::forward<_Obj>(__obj))); } __i = iterator(__true_hint.first); (*__i).second = std::forward<_Obj>(__obj); return __i; } // move-capable overload template <typename _Obj> iterator insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj) { iterator __i; auto __true_hint = _M_t._M_get_insert_hint_unique_pos(__hint, __k); if (__true_hint.second) { return emplace_hint(iterator(__true_hint.second), std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple( std::forward<_Obj>(__obj))); } __i = iterator(__true_hint.first); (*__i).second = std::forward<_Obj>(__obj); return __i; } #endif #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. /** * @brief Erases an element from a %map. * @param __position An iterator pointing to the element to be erased. * @return An iterator pointing to the element immediately following * @a position prior to the element being erased. If no such * element exists, end() is returned. * * This function erases an element, pointed to by the given * iterator, from a %map. Note that this function only erases * the element, and that if the element is itself a pointer, * the pointed-to memory is not touched in any way. Managing * the pointer is the user's responsibility. * * @{ */ iterator erase(const_iterator __position) { return _M_t.erase(__position); } // LWG 2059 _GLIBCXX_ABI_TAG_CXX11 iterator erase(iterator __position) { return _M_t.erase(__position); } // @} #else /** * @brief Erases an element from a %map. * @param __position An iterator pointing to the element to be erased. * * This function erases an element, pointed to by the given * iterator, from a %map. Note that this function only erases * the element, and that if the element is itself a pointer, * the pointed-to memory is not touched in any way. Managing * the pointer is the user's responsibility. */ void erase(iterator __position) { _M_t.erase(__position); } #endif /** * @brief Erases elements according to the provided key. * @param __x Key of element to be erased. * @return The number of elements erased. * * This function erases all the elements located by the given key from * a %map. * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ size_type erase(const key_type& __x) { return _M_t.erase(__x); } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. /** * @brief Erases a [first,last) range of elements from a %map. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to * be erased. * @return The iterator @a __last. * * This function erases a sequence of elements from a %map. * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ iterator erase(const_iterator __first, const_iterator __last) { return _M_t.erase(__first, __last); } #else /** * @brief Erases a [__first,__last) range of elements from a %map. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to * be erased. * * This function erases a sequence of elements from a %map. * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ void erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } #endif /** * @brief Swaps data with another %map. * @param __x A %map of the same element and allocator types. * * This exchanges the elements between two maps in constant * time. (It is only swapping a pointer, an integer, and an * instance of the @c Compare type (which itself is often * stateless and empty), so it should be quite fast.) Note * that the global std::swap() function is specialized such * that std::swap(m1,m2) will feed to this function. * * Whether the allocators are swapped depends on the allocator traits. */ void swap(map& __x) _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value) { _M_t.swap(__x._M_t); } /** * Erases all elements in a %map. Note that this function only * erases the elements, and that if the elements themselves are * pointers, the pointed-to memory is not touched in any way. * Managing the pointer is the user's responsibility. */ void clear() _GLIBCXX_NOEXCEPT { _M_t.clear(); } // observers /** * Returns the key comparison object out of which the %map was * constructed. */ key_compare key_comp() const { return _M_t.key_comp(); } /** * Returns a value comparison object, built from the key comparison * object out of which the %map was constructed. */ value_compare value_comp() const { return value_compare(_M_t.key_comp()); } // [23.3.1.3] map operations //@{ /** * @brief Tries to locate an element in a %map. * @param __x Key of (key, value) %pair to be located. * @return Iterator pointing to sought-after element, or end() if not * found. * * This function takes a key and tries to locate the element with which * the key matches. If successful the function returns an iterator * pointing to the sought after %pair. If unsuccessful it returns the * past-the-end ( @c end() ) iterator. */ iterator find(const key_type& __x) { return _M_t.find(__x); } #if __cplusplus > 201103L template<typename _Kt> auto find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x)) { return _M_t._M_find_tr(__x); } #endif //@} //@{ /** * @brief Tries to locate an element in a %map. * @param __x Key of (key, value) %pair to be located. * @return Read-only (constant) iterator pointing to sought-after * element, or end() if not found. * * This function takes a key and tries to locate the element with which * the key matches. If successful the function returns a constant * iterator pointing to the sought after %pair. If unsuccessful it * returns the past-the-end ( @c end() ) iterator. */ const_iterator find(const key_type& __x) const { return _M_t.find(__x); } #if __cplusplus > 201103L template<typename _Kt> auto find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x)) { return _M_t._M_find_tr(__x); } #endif //@} //@{ /** * @brief Finds the number of elements with given key. * @param __x Key of (key, value) pairs to be located. * @return Number of elements with specified key. * * This function only makes sense for multimaps; for map the result will * either be 0 (not present) or 1 (present). */ size_type count(const key_type& __x) const { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } #if __cplusplus > 201103L template<typename _Kt> auto count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x)) { return _M_t._M_count_tr(__x); } #endif //@} //@{ /** * @brief Finds the beginning of a subsequence matching given key. * @param __x Key of (key, value) pair to be located. * @return Iterator pointing to first element equal to or greater * than key, or end(). * * This function returns the first element of a subsequence of elements * that matches the given key. If unsuccessful it returns an iterator * pointing to the first element that has a greater value than given key * or end() if no such element exists. */ iterator lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto lower_bound(const _Kt& __x) -> decltype(iterator(_M_t._M_lower_bound_tr(__x))) { return iterator(_M_t._M_lower_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds the beginning of a subsequence matching given key. * @param __x Key of (key, value) pair to be located. * @return Read-only (constant) iterator pointing to first element * equal to or greater than key, or end(). * * This function returns the first element of a subsequence of elements * that matches the given key. If unsuccessful it returns an iterator * pointing to the first element that has a greater value than given key * or end() if no such element exists. */ const_iterator lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto lower_bound(const _Kt& __x) const -> decltype(const_iterator(_M_t._M_lower_bound_tr(__x))) { return const_iterator(_M_t._M_lower_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds the end of a subsequence matching given key. * @param __x Key of (key, value) pair to be located. * @return Iterator pointing to the first element * greater than key, or end(). */ iterator upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto upper_bound(const _Kt& __x) -> decltype(iterator(_M_t._M_upper_bound_tr(__x))) { return iterator(_M_t._M_upper_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds the end of a subsequence matching given key. * @param __x Key of (key, value) pair to be located. * @return Read-only (constant) iterator pointing to first iterator * greater than key, or end(). */ const_iterator upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto upper_bound(const _Kt& __x) const -> decltype(const_iterator(_M_t._M_upper_bound_tr(__x))) { return const_iterator(_M_t._M_upper_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds a subsequence matching given key. * @param __x Key of (key, value) pairs to be located. * @return Pair of iterators that possibly points to the subsequence * matching given key. * * This function is equivalent to * @code * std::make_pair(c.lower_bound(val), * c.upper_bound(val)) * @endcode * (but is faster than making the calls separately). * * This function probably only makes sense for multimaps. */ std::pair<iterator, iterator> equal_range(const key_type& __x) { return _M_t.equal_range(__x); } #if __cplusplus > 201103L template<typename _Kt> auto equal_range(const _Kt& __x) -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x))) { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); } #endif //@} //@{ /** * @brief Finds a subsequence matching given key. * @param __x Key of (key, value) pairs to be located. * @return Pair of read-only (constant) iterators that possibly points * to the subsequence matching given key. * * This function is equivalent to * @code * std::make_pair(c.lower_bound(val), * c.upper_bound(val)) * @endcode * (but is faster than making the calls separately). * * This function probably only makes sense for multimaps. */ std::pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } #if __cplusplus > 201103L template<typename _Kt> auto equal_range(const _Kt& __x) const -> decltype(pair<const_iterator, const_iterator>( _M_t._M_equal_range_tr(__x))) { return pair<const_iterator, const_iterator>( _M_t._M_equal_range_tr(__x)); } #endif //@} template<typename _K1, typename _T1, typename _C1, typename _A1> friend bool operator==(const map<_K1, _T1, _C1, _A1>&, const map<_K1, _T1, _C1, _A1>&); template<typename _K1, typename _T1, typename _C1, typename _A1> friend bool operator<(const map<_K1, _T1, _C1, _A1>&, const map<_K1, _T1, _C1, _A1>&); }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _Compare = less<__iter_key_t<_InputIterator>>, typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) -> map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Compare, _Allocator>; template<typename _Key, typename _Tp, typename _Compare = less<_Key>, typename _Allocator = allocator<pair<const _Key, _Tp>>, typename = _RequireAllocator<_Allocator>> map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator()) -> map<_Key, _Tp, _Compare, _Allocator>; template <typename _InputIterator, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> map(_InputIterator, _InputIterator, _Allocator) -> map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, less<__iter_key_t<_InputIterator>>, _Allocator>; template<typename _Key, typename _Tp, typename _Allocator, typename = _RequireAllocator<_Allocator>> map(initializer_list<pair<_Key, _Tp>>, _Allocator) -> map<_Key, _Tp, less<_Key>, _Allocator>; #endif /** * @brief Map equality comparison. * @param __x A %map. * @param __y A %map of the same type as @a x. * @return True iff the size and elements of the maps are equal. * * This is an equivalence relation. It is linear in the size of the * maps. Maps are considered equivalent if their sizes are equal, * and if corresponding elements compare equal. */ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator==(const map<_Key, _Tp, _Compare, _Alloc>& __x, const map<_Key, _Tp, _Compare, _Alloc>& __y) { return __x._M_t == __y._M_t; } /** * @brief Map ordering relation. * @param __x A %map. * @param __y A %map of the same type as @a x. * @return True iff @a x is lexicographically less than @a y. * * This is a total ordering relation. It is linear in the size of the * maps. The elements must be comparable with @c <. * * See std::lexicographical_compare() for how the determination is made. */ template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x, const map<_Key, _Tp, _Compare, _Alloc>& __y) { return __x._M_t < __y._M_t; } /// Based on operator== template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator!=(const map<_Key, _Tp, _Compare, _Alloc>& __x, const map<_Key, _Tp, _Compare, _Alloc>& __y) { return !(__x == __y); } /// Based on operator< template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator>(const map<_Key, _Tp, _Compare, _Alloc>& __x, const map<_Key, _Tp, _Compare, _Alloc>& __y) { return __y < __x; } /// Based on operator< template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator<=(const map<_Key, _Tp, _Compare, _Alloc>& __x, const map<_Key, _Tp, _Compare, _Alloc>& __y) { return !(__y < __x); } /// Based on operator< template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline bool operator>=(const map<_Key, _Tp, _Compare, _Alloc>& __x, const map<_Key, _Tp, _Compare, _Alloc>& __y) { return !(__x < __y); } /// See std::map::swap(). template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> inline void swap(map<_Key, _Tp, _Compare, _Alloc>& __x, map<_Key, _Tp, _Compare, _Alloc>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER #if __cplusplus > 201402L // Allow std::map access to internals of compatible maps. template<typename _Key, typename _Val, typename _Cmp1, typename _Alloc, typename _Cmp2> struct _Rb_tree_merge_helper<_GLIBCXX_STD_C::map<_Key, _Val, _Cmp1, _Alloc>, _Cmp2> { private: friend class _GLIBCXX_STD_C::map<_Key, _Val, _Cmp1, _Alloc>; static auto& _S_get_tree(_GLIBCXX_STD_C::map<_Key, _Val, _Cmp2, _Alloc>& __map) { return __map._M_t; } static auto& _S_get_tree(_GLIBCXX_STD_C::multimap<_Key, _Val, _Cmp2, _Alloc>& __map) { return __map._M_t; } }; #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _STL_MAP_H */ c++/8/bits/stream_iterator.h 0000644 00000014776 15146341150 0011620 0 ustar 00 // Stream iterators // Copyright (C) 2001-2018 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/stream_iterator.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iterator} */ #ifndef _STREAM_ITERATOR_H #define _STREAM_ITERATOR_H 1 #pragma GCC system_header #include <debug/debug.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup iterators * @{ */ /// Provides input iterator semantics for streams. template<typename _Tp, typename _CharT = char, typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t> class istream_iterator : public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&> { public: typedef _CharT char_type; typedef _Traits traits_type; typedef basic_istream<_CharT, _Traits> istream_type; private: istream_type* _M_stream; _Tp _M_value; bool _M_ok; public: /// Construct end of input stream iterator. _GLIBCXX_CONSTEXPR istream_iterator() : _M_stream(0), _M_value(), _M_ok(false) {} /// Construct start of input stream iterator. istream_iterator(istream_type& __s) : _M_stream(std::__addressof(__s)) { _M_read(); } istream_iterator(const istream_iterator& __obj) : _M_stream(__obj._M_stream), _M_value(__obj._M_value), _M_ok(__obj._M_ok) { } const _Tp& operator*() const { __glibcxx_requires_cond(_M_ok, _M_message(__gnu_debug::__msg_deref_istream) ._M_iterator(*this)); return _M_value; } const _Tp* operator->() const { return std::__addressof((operator*())); } istream_iterator& operator++() { __glibcxx_requires_cond(_M_ok, _M_message(__gnu_debug::__msg_inc_istream) ._M_iterator(*this)); _M_read(); return *this; } istream_iterator operator++(int) { __glibcxx_requires_cond(_M_ok, _M_message(__gnu_debug::__msg_inc_istream) ._M_iterator(*this)); istream_iterator __tmp = *this; _M_read(); return __tmp; } bool _M_equal(const istream_iterator& __x) const { return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); } private: void _M_read() { _M_ok = (_M_stream && *_M_stream) ? true : false; if (_M_ok) { *_M_stream >> _M_value; _M_ok = *_M_stream ? true : false; } } }; /// Return true if x and y are both end or not end, or x and y are the same. template<typename _Tp, typename _CharT, typename _Traits, typename _Dist> inline bool operator==(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) { return __x._M_equal(__y); } /// Return false if x and y are both end or not end, or x and y are the same. template <class _Tp, class _CharT, class _Traits, class _Dist> inline bool operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __x, const istream_iterator<_Tp, _CharT, _Traits, _Dist>& __y) { return !__x._M_equal(__y); } /** * @brief Provides output iterator semantics for streams. * * This class provides an iterator to write to an ostream. The type Tp is * the only type written by this iterator and there must be an * operator<<(Tp) defined. * * @tparam _Tp The type to write to the ostream. * @tparam _CharT The ostream char_type. * @tparam _Traits The ostream char_traits. */ template<typename _Tp, typename _CharT = char, typename _Traits = char_traits<_CharT> > class ostream_iterator : public iterator<output_iterator_tag, void, void, void, void> { public: //@{ /// Public typedef typedef _CharT char_type; typedef _Traits traits_type; typedef basic_ostream<_CharT, _Traits> ostream_type; //@} private: ostream_type* _M_stream; const _CharT* _M_string; public: /// Construct from an ostream. ostream_iterator(ostream_type& __s) : _M_stream(std::__addressof(__s)), _M_string(0) {} /** * Construct from an ostream. * * The delimiter string @a c is written to the stream after every Tp * written to the stream. The delimiter is not copied, and thus must * not be destroyed while this iterator is in use. * * @param __s Underlying ostream to write to. * @param __c CharT delimiter string to insert. */ ostream_iterator(ostream_type& __s, const _CharT* __c) : _M_stream(&__s), _M_string(__c) { } /// Copy constructor. ostream_iterator(const ostream_iterator& __obj) : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { } /// Writes @a value to underlying ostream using operator<<. If /// constructed with delimiter string, writes delimiter to ostream. ostream_iterator& operator=(const _Tp& __value) { __glibcxx_requires_cond(_M_stream != 0, _M_message(__gnu_debug::__msg_output_ostream) ._M_iterator(*this)); *_M_stream << __value; if (_M_string) *_M_stream << _M_string; return *this; } ostream_iterator& operator*() { return *this; } ostream_iterator& operator++() { return *this; } ostream_iterator& operator++(int) { return *this; } }; // @} group iterators _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/bits/stl_stack.h 0000644 00000027242 15146341150 0010373 0 ustar 00 // Stack implementation -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_stack.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{stack} */ #ifndef _STL_STACK_H #define _STL_STACK_H 1 #include <bits/concept_check.h> #include <debug/debug.h> #if __cplusplus >= 201103L # include <bits/uses_allocator.h> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief A standard container giving FILO behavior. * * @ingroup sequences * * @tparam _Tp Type of element. * @tparam _Sequence Type of underlying sequence, defaults to deque<_Tp>. * * Meets many of the requirements of a * <a href="tables.html#65">container</a>, * but does not define anything to do with iterators. Very few of the * other standard container interfaces are defined. * * This is not a true container, but an @e adaptor. It holds * another container, and provides a wrapper interface to that * container. The wrapper is what enforces strict * first-in-last-out %stack behavior. * * The second template parameter defines the type of the underlying * sequence/container. It defaults to std::deque, but it can be * any type that supports @c back, @c push_back, and @c pop_back, * such as std::list, std::vector, or an appropriate user-defined * type. * * Members not found in @a normal containers are @c container_type, * which is a typedef for the second Sequence parameter, and @c * push, @c pop, and @c top, which are standard %stack/FILO * operations. */ template<typename _Tp, typename _Sequence = deque<_Tp> > class stack { #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename _Sequence::value_type _Sequence_value_type; # if __cplusplus < 201103L __glibcxx_class_requires(_Tp, _SGIAssignableConcept) __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept) # endif __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept) #endif template<typename _Tp1, typename _Seq1> friend bool operator==(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); template<typename _Tp1, typename _Seq1> friend bool operator<(const stack<_Tp1, _Seq1>&, const stack<_Tp1, _Seq1>&); #if __cplusplus >= 201103L template<typename _Alloc> using _Uses = typename enable_if<uses_allocator<_Sequence, _Alloc>::value>::type; #endif public: typedef typename _Sequence::value_type value_type; typedef typename _Sequence::reference reference; typedef typename _Sequence::const_reference const_reference; typedef typename _Sequence::size_type size_type; typedef _Sequence container_type; protected: // See queue::c for notes on this name. _Sequence c; public: // XXX removed old def ctor, added def arg to this one to match 14882 /** * @brief Default constructor creates no elements. */ #if __cplusplus < 201103L explicit stack(const _Sequence& __c = _Sequence()) : c(__c) { } #else template<typename _Seq = _Sequence, typename _Requires = typename enable_if<is_default_constructible<_Seq>::value>::type> stack() : c() { } explicit stack(const _Sequence& __c) : c(__c) { } explicit stack(_Sequence&& __c) : c(std::move(__c)) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> explicit stack(const _Alloc& __a) : c(__a) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> stack(const _Sequence& __c, const _Alloc& __a) : c(__c, __a) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> stack(_Sequence&& __c, const _Alloc& __a) : c(std::move(__c), __a) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> stack(const stack& __q, const _Alloc& __a) : c(__q.c, __a) { } template<typename _Alloc, typename _Requires = _Uses<_Alloc>> stack(stack&& __q, const _Alloc& __a) : c(std::move(__q.c), __a) { } #endif /** * Returns true if the %stack is empty. */ bool empty() const { return c.empty(); } /** Returns the number of elements in the %stack. */ size_type size() const { return c.size(); } /** * Returns a read/write reference to the data at the first * element of the %stack. */ reference top() { __glibcxx_requires_nonempty(); return c.back(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %stack. */ const_reference top() const { __glibcxx_requires_nonempty(); return c.back(); } /** * @brief Add data to the top of the %stack. * @param __x Data to be added. * * This is a typical %stack operation. The function creates an * element at the top of the %stack and assigns the given data * to it. The time complexity of the operation depends on the * underlying sequence. */ void push(const value_type& __x) { c.push_back(__x); } #if __cplusplus >= 201103L void push(value_type&& __x) { c.push_back(std::move(__x)); } #if __cplusplus > 201402L template<typename... _Args> decltype(auto) emplace(_Args&&... __args) { return c.emplace_back(std::forward<_Args>(__args)...); } #else template<typename... _Args> void emplace(_Args&&... __args) { c.emplace_back(std::forward<_Args>(__args)...); } #endif #endif /** * @brief Removes first element. * * This is a typical %stack operation. It shrinks the %stack * by one. The time complexity of the operation depends on the * underlying sequence. * * Note that no data is returned, and if the first element's * data is needed, it should be retrieved before pop() is * called. */ void pop() { __glibcxx_requires_nonempty(); c.pop_back(); } #if __cplusplus >= 201103L void swap(stack& __s) #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 noexcept(__is_nothrow_swappable<_Sequence>::value) #else noexcept(__is_nothrow_swappable<_Tp>::value) #endif { using std::swap; swap(c, __s.c); } #endif // __cplusplus >= 201103L }; #if __cpp_deduction_guides >= 201606 template<typename _Container, typename = enable_if_t<!__is_allocator<_Container>::value>> stack(_Container) -> stack<typename _Container::value_type, _Container>; template<typename _Container, typename _Allocator, typename = enable_if_t<!__is_allocator<_Container>::value>, typename = enable_if_t<__is_allocator<_Allocator>::value>> stack(_Container, _Allocator) -> stack<typename _Container::value_type, _Container>; #endif /** * @brief Stack equality comparison. * @param __x A %stack. * @param __y A %stack of the same type as @a __x. * @return True iff the size and elements of the stacks are equal. * * This is an equivalence relation. Complexity and semantics * depend on the underlying sequence type, but the expected rules * are: this relation is linear in the size of the sequences, and * stacks are considered equivalent if their sequences compare * equal. */ template<typename _Tp, typename _Seq> inline bool operator==(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return __x.c == __y.c; } /** * @brief Stack ordering relation. * @param __x A %stack. * @param __y A %stack of the same type as @a x. * @return True iff @a x is lexicographically less than @a __y. * * This is an total ordering relation. Complexity and semantics * depend on the underlying sequence type, but the expected rules * are: this relation is linear in the size of the sequences, the * elements must be comparable with @c <, and * std::lexicographical_compare() is usually used to make the * determination. */ template<typename _Tp, typename _Seq> inline bool operator<(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return __x.c < __y.c; } /// Based on operator== template<typename _Tp, typename _Seq> inline bool operator!=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return !(__x == __y); } /// Based on operator< template<typename _Tp, typename _Seq> inline bool operator>(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return __y < __x; } /// Based on operator< template<typename _Tp, typename _Seq> inline bool operator<=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return !(__y < __x); } /// Based on operator< template<typename _Tp, typename _Seq> inline bool operator>=(const stack<_Tp, _Seq>& __x, const stack<_Tp, _Seq>& __y) { return !(__x < __y); } #if __cplusplus >= 201103L template<typename _Tp, typename _Seq> inline #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 // Constrained free swap overload, see p0185r1 typename enable_if<__is_swappable<_Seq>::value>::type #else void #endif swap(stack<_Tp, _Seq>& __x, stack<_Tp, _Seq>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<typename _Tp, typename _Seq, typename _Alloc> struct uses_allocator<stack<_Tp, _Seq>, _Alloc> : public uses_allocator<_Seq, _Alloc>::type { }; #endif // __cplusplus >= 201103L _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _STL_STACK_H */ c++/8/bits/unordered_map.h 0000644 00000223115 15146341150 0011225 0 ustar 00 // unordered_map implementation -*- C++ -*- // Copyright (C) 2010-2018 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/unordered_map.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{unordered_map} */ #ifndef _UNORDERED_MAP_H #define _UNORDERED_MAP_H namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /// Base types for unordered_map. template<bool _Cache> using __umap_traits = __detail::_Hashtable_traits<_Cache, false, true>; template<typename _Key, typename _Tp, typename _Hash = hash<_Key>, typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator<std::pair<const _Key, _Tp> >, typename _Tr = __umap_traits<__cache_default<_Key, _Hash>::value>> using __umap_hashtable = _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, __detail::_Select1st, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, __detail::_Prime_rehash_policy, _Tr>; /// Base types for unordered_multimap. template<bool _Cache> using __ummap_traits = __detail::_Hashtable_traits<_Cache, false, false>; template<typename _Key, typename _Tp, typename _Hash = hash<_Key>, typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator<std::pair<const _Key, _Tp> >, typename _Tr = __ummap_traits<__cache_default<_Key, _Hash>::value>> using __ummap_hashtable = _Hashtable<_Key, std::pair<const _Key, _Tp>, _Alloc, __detail::_Select1st, _Pred, _Hash, __detail::_Mod_range_hashing, __detail::_Default_ranged_hash, __detail::_Prime_rehash_policy, _Tr>; template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> class unordered_multimap; /** * @brief A standard container composed of unique keys (containing * at most one of each key value) that associates values of another type * with the keys. * * @ingroup unordered_associative_containers * * @tparam _Key Type of key objects. * @tparam _Tp Type of mapped objects. * @tparam _Hash Hashing function object type, defaults to hash<_Value>. * @tparam _Pred Predicate function object type, defaults * to equal_to<_Value>. * @tparam _Alloc Allocator type, defaults to * std::allocator<std::pair<const _Key, _Tp>>. * * Meets the requirements of a <a href="tables.html#65">container</a>, and * <a href="tables.html#xx">unordered associative container</a> * * The resulting value type of the container is std::pair<const _Key, _Tp>. * * Base is _Hashtable, dispatched at compile time via template * alias __umap_hashtable. */ template<typename _Key, typename _Tp, typename _Hash = hash<_Key>, typename _Pred = equal_to<_Key>, typename _Alloc = allocator<std::pair<const _Key, _Tp>>> class unordered_map { typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable; _Hashtable _M_h; public: // typedefs: //@{ /// Public typedefs. typedef typename _Hashtable::key_type key_type; typedef typename _Hashtable::value_type value_type; typedef typename _Hashtable::mapped_type mapped_type; typedef typename _Hashtable::hasher hasher; typedef typename _Hashtable::key_equal key_equal; typedef typename _Hashtable::allocator_type allocator_type; //@} //@{ /// Iterator-related typedefs. typedef typename _Hashtable::pointer pointer; typedef typename _Hashtable::const_pointer const_pointer; typedef typename _Hashtable::reference reference; typedef typename _Hashtable::const_reference const_reference; typedef typename _Hashtable::iterator iterator; typedef typename _Hashtable::const_iterator const_iterator; typedef typename _Hashtable::local_iterator local_iterator; typedef typename _Hashtable::const_local_iterator const_local_iterator; typedef typename _Hashtable::size_type size_type; typedef typename _Hashtable::difference_type difference_type; //@} #if __cplusplus > 201402L using node_type = typename _Hashtable::node_type; using insert_return_type = typename _Hashtable::insert_return_type; #endif //construct/destroy/copy /// Default constructor. unordered_map() = default; /** * @brief Default constructor creates no elements. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. */ explicit unordered_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__n, __hf, __eql, __a) { } /** * @brief Builds an %unordered_map from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. * * Create an %unordered_map consisting of copies of the elements from * [__first,__last). This is linear in N (where N is * distance(__first,__last)). */ template<typename _InputIterator> unordered_map(_InputIterator __first, _InputIterator __last, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__first, __last, __n, __hf, __eql, __a) { } /// Copy constructor. unordered_map(const unordered_map&) = default; /// Move constructor. unordered_map(unordered_map&&) = default; /** * @brief Creates an %unordered_map with no elements. * @param __a An allocator object. */ explicit unordered_map(const allocator_type& __a) : _M_h(__a) { } /* * @brief Copy constructor with allocator argument. * @param __uset Input %unordered_map to copy. * @param __a An allocator object. */ unordered_map(const unordered_map& __umap, const allocator_type& __a) : _M_h(__umap._M_h, __a) { } /* * @brief Move constructor with allocator argument. * @param __uset Input %unordered_map to move. * @param __a An allocator object. */ unordered_map(unordered_map&& __umap, const allocator_type& __a) : _M_h(std::move(__umap._M_h), __a) { } /** * @brief Builds an %unordered_map from an initializer_list. * @param __l An initializer_list. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. * * Create an %unordered_map consisting of copies of the elements in the * list. This is linear in N (where N is @a __l.size()). */ unordered_map(initializer_list<value_type> __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__l, __n, __hf, __eql, __a) { } unordered_map(size_type __n, const allocator_type& __a) : unordered_map(__n, hasher(), key_equal(), __a) { } unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__n, __hf, key_equal(), __a) { } template<typename _InputIterator> unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) { } template<typename _InputIterator> unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__first, __last, __n, __hf, key_equal(), __a) { } unordered_map(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) : unordered_map(__l, __n, hasher(), key_equal(), __a) { } unordered_map(initializer_list<value_type> __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__l, __n, __hf, key_equal(), __a) { } /// Copy assignment operator. unordered_map& operator=(const unordered_map&) = default; /// Move assignment operator. unordered_map& operator=(unordered_map&&) = default; /** * @brief %Unordered_map list assignment operator. * @param __l An initializer_list. * * This function fills an %unordered_map with copies of the elements in * the initializer list @a __l. * * Note that the assignment completely changes the %unordered_map and * that the resulting %unordered_map's size is the same as the number * of elements assigned. */ unordered_map& operator=(initializer_list<value_type> __l) { _M_h = __l; return *this; } /// Returns the allocator object used by the %unordered_map. allocator_type get_allocator() const noexcept { return _M_h.get_allocator(); } // size and capacity: /// Returns true if the %unordered_map is empty. bool empty() const noexcept { return _M_h.empty(); } /// Returns the size of the %unordered_map. size_type size() const noexcept { return _M_h.size(); } /// Returns the maximum size of the %unordered_map. size_type max_size() const noexcept { return _M_h.max_size(); } // iterators. /** * Returns a read/write iterator that points to the first element in the * %unordered_map. */ iterator begin() noexcept { return _M_h.begin(); } //@{ /** * Returns a read-only (constant) iterator that points to the first * element in the %unordered_map. */ const_iterator begin() const noexcept { return _M_h.begin(); } const_iterator cbegin() const noexcept { return _M_h.begin(); } //@} /** * Returns a read/write iterator that points one past the last element in * the %unordered_map. */ iterator end() noexcept { return _M_h.end(); } //@{ /** * Returns a read-only (constant) iterator that points one past the last * element in the %unordered_map. */ const_iterator end() const noexcept { return _M_h.end(); } const_iterator cend() const noexcept { return _M_h.end(); } //@} // modifiers. /** * @brief Attempts to build and insert a std::pair into the * %unordered_map. * * @param __args Arguments used to generate a new pair instance (see * std::piecewise_contruct for passing arguments to each * part of the pair constructor). * * @return A pair, of which the first element is an iterator that points * to the possibly inserted pair, and the second is a bool that * is true if the pair was actually inserted. * * This function attempts to build and insert a (key, value) %pair into * the %unordered_map. * An %unordered_map relies on unique keys and thus a %pair is only * inserted if its first element (the key) is not already present in the * %unordered_map. * * Insertion requires amortized constant time. */ template<typename... _Args> std::pair<iterator, bool> emplace(_Args&&... __args) { return _M_h.emplace(std::forward<_Args>(__args)...); } /** * @brief Attempts to build and insert a std::pair into the * %unordered_map. * * @param __pos An iterator that serves as a hint as to where the pair * should be inserted. * @param __args Arguments used to generate a new pair instance (see * std::piecewise_contruct for passing arguments to each * part of the pair constructor). * @return An iterator that points to the element with key of the * std::pair built from @a __args (may or may not be that * std::pair). * * This function is not concerned about whether the insertion took place, * and thus does not return a boolean like the single-argument emplace() * does. * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires amortized constant time. */ template<typename... _Args> iterator emplace_hint(const_iterator __pos, _Args&&... __args) { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); } #if __cplusplus > 201402L /// Extract a node. node_type extract(const_iterator __pos) { __glibcxx_assert(__pos != end()); return _M_h.extract(__pos); } /// Extract a node. node_type extract(const key_type& __key) { return _M_h.extract(__key); } /// Re-insert an extracted node. insert_return_type insert(node_type&& __nh) { return _M_h._M_reinsert_node(std::move(__nh)); } /// Re-insert an extracted node. iterator insert(const_iterator, node_type&& __nh) { return _M_h._M_reinsert_node(std::move(__nh)).position; } #define __cpp_lib_unordered_map_try_emplace 201411 /** * @brief Attempts to build and insert a std::pair into the * %unordered_map. * * @param __k Key to use for finding a possibly existing pair in * the unordered_map. * @param __args Arguments used to generate the .second for a * new pair instance. * * @return A pair, of which the first element is an iterator that points * to the possibly inserted pair, and the second is a bool that * is true if the pair was actually inserted. * * This function attempts to build and insert a (key, value) %pair into * the %unordered_map. * An %unordered_map relies on unique keys and thus a %pair is only * inserted if its first element (the key) is not already present in the * %unordered_map. * If a %pair is not inserted, this function has no effect. * * Insertion requires amortized constant time. */ template <typename... _Args> pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) { iterator __i = find(__k); if (__i == end()) { __i = emplace(std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple( std::forward<_Args>(__args)...)) .first; return {__i, true}; } return {__i, false}; } // move-capable overload template <typename... _Args> pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) { iterator __i = find(__k); if (__i == end()) { __i = emplace(std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple( std::forward<_Args>(__args)...)) .first; return {__i, true}; } return {__i, false}; } /** * @brief Attempts to build and insert a std::pair into the * %unordered_map. * * @param __hint An iterator that serves as a hint as to where the pair * should be inserted. * @param __k Key to use for finding a possibly existing pair in * the unordered_map. * @param __args Arguments used to generate the .second for a * new pair instance. * @return An iterator that points to the element with key of the * std::pair built from @a __args (may or may not be that * std::pair). * * This function is not concerned about whether the insertion took place, * and thus does not return a boolean like the single-argument emplace() * does. However, if insertion did not take place, * this function has no effect. * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires amortized constant time. */ template <typename... _Args> iterator try_emplace(const_iterator __hint, const key_type& __k, _Args&&... __args) { iterator __i = find(__k); if (__i == end()) __i = emplace_hint(__hint, std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple( std::forward<_Args>(__args)...)); return __i; } // move-capable overload template <typename... _Args> iterator try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args) { iterator __i = find(__k); if (__i == end()) __i = emplace_hint(__hint, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple( std::forward<_Args>(__args)...)); return __i; } #endif // C++17 //@{ /** * @brief Attempts to insert a std::pair into the %unordered_map. * @param __x Pair to be inserted (see std::make_pair for easy * creation of pairs). * * @return A pair, of which the first element is an iterator that * points to the possibly inserted pair, and the second is * a bool that is true if the pair was actually inserted. * * This function attempts to insert a (key, value) %pair into the * %unordered_map. An %unordered_map relies on unique keys and thus a * %pair is only inserted if its first element (the key) is not already * present in the %unordered_map. * * Insertion requires amortized constant time. */ std::pair<iterator, bool> insert(const value_type& __x) { return _M_h.insert(__x); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2354. Unnecessary copying when inserting into maps with braced-init std::pair<iterator, bool> insert(value_type&& __x) { return _M_h.insert(std::move(__x)); } template<typename _Pair> __enable_if_t<is_constructible<value_type, _Pair&&>::value, pair<iterator, bool>> insert(_Pair&& __x) { return _M_h.emplace(std::forward<_Pair>(__x)); } //@} //@{ /** * @brief Attempts to insert a std::pair into the %unordered_map. * @param __hint An iterator that serves as a hint as to where the * pair should be inserted. * @param __x Pair to be inserted (see std::make_pair for easy creation * of pairs). * @return An iterator that points to the element with key of * @a __x (may or may not be the %pair passed in). * * This function is not concerned about whether the insertion took place, * and thus does not return a boolean like the single-argument insert() * does. Note that the first parameter is only a hint and can * potentially improve the performance of the insertion process. A bad * hint would cause no gains in efficiency. * * See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires amortized constant time. */ iterator insert(const_iterator __hint, const value_type& __x) { return _M_h.insert(__hint, __x); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2354. Unnecessary copying when inserting into maps with braced-init iterator insert(const_iterator __hint, value_type&& __x) { return _M_h.insert(__hint, std::move(__x)); } template<typename _Pair> __enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator> insert(const_iterator __hint, _Pair&& __x) { return _M_h.emplace_hint(__hint, std::forward<_Pair>(__x)); } //@} /** * @brief A template function that attempts to insert a range of * elements. * @param __first Iterator pointing to the start of the range to be * inserted. * @param __last Iterator pointing to the end of the range. * * Complexity similar to that of the range constructor. */ template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_h.insert(__first, __last); } /** * @brief Attempts to insert a list of elements into the %unordered_map. * @param __l A std::initializer_list<value_type> of elements * to be inserted. * * Complexity similar to that of the range constructor. */ void insert(initializer_list<value_type> __l) { _M_h.insert(__l); } #if __cplusplus > 201402L #define __cpp_lib_unordered_map_insertion 201411 /** * @brief Attempts to insert a std::pair into the %unordered_map. * @param __k Key to use for finding a possibly existing pair in * the map. * @param __obj Argument used to generate the .second for a pair * instance. * * @return A pair, of which the first element is an iterator that * points to the possibly inserted pair, and the second is * a bool that is true if the pair was actually inserted. * * This function attempts to insert a (key, value) %pair into the * %unordered_map. An %unordered_map relies on unique keys and thus a * %pair is only inserted if its first element (the key) is not already * present in the %unordered_map. * If the %pair was already in the %unordered_map, the .second of * the %pair is assigned from __obj. * * Insertion requires amortized constant time. */ template <typename _Obj> pair<iterator, bool> insert_or_assign(const key_type& __k, _Obj&& __obj) { iterator __i = find(__k); if (__i == end()) { __i = emplace(std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple(std::forward<_Obj>(__obj))) .first; return {__i, true}; } (*__i).second = std::forward<_Obj>(__obj); return {__i, false}; } // move-capable overload template <typename _Obj> pair<iterator, bool> insert_or_assign(key_type&& __k, _Obj&& __obj) { iterator __i = find(__k); if (__i == end()) { __i = emplace(std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple(std::forward<_Obj>(__obj))) .first; return {__i, true}; } (*__i).second = std::forward<_Obj>(__obj); return {__i, false}; } /** * @brief Attempts to insert a std::pair into the %unordered_map. * @param __hint An iterator that serves as a hint as to where the * pair should be inserted. * @param __k Key to use for finding a possibly existing pair in * the unordered_map. * @param __obj Argument used to generate the .second for a pair * instance. * @return An iterator that points to the element with key of * @a __x (may or may not be the %pair passed in). * * This function is not concerned about whether the insertion took place, * and thus does not return a boolean like the single-argument insert() * does. * If the %pair was already in the %unordered map, the .second of * the %pair is assigned from __obj. * Note that the first parameter is only a hint and can * potentially improve the performance of the insertion process. A bad * hint would cause no gains in efficiency. * * See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires amortized constant time. */ template <typename _Obj> iterator insert_or_assign(const_iterator __hint, const key_type& __k, _Obj&& __obj) { iterator __i = find(__k); if (__i == end()) { return emplace_hint(__hint, std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple( std::forward<_Obj>(__obj))); } (*__i).second = std::forward<_Obj>(__obj); return __i; } // move-capable overload template <typename _Obj> iterator insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj) { iterator __i = find(__k); if (__i == end()) { return emplace_hint(__hint, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple( std::forward<_Obj>(__obj))); } (*__i).second = std::forward<_Obj>(__obj); return __i; } #endif //@{ /** * @brief Erases an element from an %unordered_map. * @param __position An iterator pointing to the element to be erased. * @return An iterator pointing to the element immediately following * @a __position prior to the element being erased. If no such * element exists, end() is returned. * * This function erases an element, pointed to by the given iterator, * from an %unordered_map. * Note that this function only erases the element, and that if the * element is itself a pointer, the pointed-to memory is not touched in * any way. Managing the pointer is the user's responsibility. */ iterator erase(const_iterator __position) { return _M_h.erase(__position); } // LWG 2059. iterator erase(iterator __position) { return _M_h.erase(__position); } //@} /** * @brief Erases elements according to the provided key. * @param __x Key of element to be erased. * @return The number of elements erased. * * This function erases all the elements located by the given key from * an %unordered_map. For an %unordered_map the result of this function * can only be 0 (not present) or 1 (present). * Note that this function only erases the element, and that if the * element is itself a pointer, the pointed-to memory is not touched in * any way. Managing the pointer is the user's responsibility. */ size_type erase(const key_type& __x) { return _M_h.erase(__x); } /** * @brief Erases a [__first,__last) range of elements from an * %unordered_map. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to * be erased. * @return The iterator @a __last. * * This function erases a sequence of elements from an %unordered_map. * Note that this function only erases the elements, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ iterator erase(const_iterator __first, const_iterator __last) { return _M_h.erase(__first, __last); } /** * Erases all elements in an %unordered_map. * Note that this function only erases the elements, and that if the * elements themselves are pointers, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ void clear() noexcept { _M_h.clear(); } /** * @brief Swaps data with another %unordered_map. * @param __x An %unordered_map of the same element and allocator * types. * * This exchanges the elements between two %unordered_map in constant * time. * Note that the global std::swap() function is specialized such that * std::swap(m1,m2) will feed to this function. */ void swap(unordered_map& __x) noexcept( noexcept(_M_h.swap(__x._M_h)) ) { _M_h.swap(__x._M_h); } #if __cplusplus > 201402L template<typename, typename, typename> friend class std::_Hash_merge_helper; template<typename _H2, typename _P2> void merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source) { using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>; _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source)); } template<typename _H2, typename _P2> void merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source) { merge(__source); } template<typename _H2, typename _P2> void merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source) { using _Merge_helper = _Hash_merge_helper<unordered_map, _H2, _P2>; _M_h._M_merge_unique(_Merge_helper::_S_get_table(__source)); } template<typename _H2, typename _P2> void merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source) { merge(__source); } #endif // C++17 // observers. /// Returns the hash functor object with which the %unordered_map was /// constructed. hasher hash_function() const { return _M_h.hash_function(); } /// Returns the key comparison object with which the %unordered_map was /// constructed. key_equal key_eq() const { return _M_h.key_eq(); } // lookup. //@{ /** * @brief Tries to locate an element in an %unordered_map. * @param __x Key to be located. * @return Iterator pointing to sought-after element, or end() if not * found. * * This function takes a key and tries to locate the element with which * the key matches. If successful the function returns an iterator * pointing to the sought after element. If unsuccessful it returns the * past-the-end ( @c end() ) iterator. */ iterator find(const key_type& __x) { return _M_h.find(__x); } const_iterator find(const key_type& __x) const { return _M_h.find(__x); } //@} /** * @brief Finds the number of elements. * @param __x Key to count. * @return Number of elements with specified key. * * This function only makes sense for %unordered_multimap; for * %unordered_map the result will either be 0 (not present) or 1 * (present). */ size_type count(const key_type& __x) const { return _M_h.count(__x); } //@{ /** * @brief Finds a subsequence matching given key. * @param __x Key to be located. * @return Pair of iterators that possibly points to the subsequence * matching given key. * * This function probably only makes sense for %unordered_multimap. */ std::pair<iterator, iterator> equal_range(const key_type& __x) { return _M_h.equal_range(__x); } std::pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { return _M_h.equal_range(__x); } //@} //@{ /** * @brief Subscript ( @c [] ) access to %unordered_map data. * @param __k The key for which data should be retrieved. * @return A reference to the data of the (key,data) %pair. * * Allows for easy lookup with the subscript ( @c [] )operator. Returns * data associated with the key specified in subscript. If the key does * not exist, a pair with that key is created using default values, which * is then returned. * * Lookup requires constant time. */ mapped_type& operator[](const key_type& __k) { return _M_h[__k]; } mapped_type& operator[](key_type&& __k) { return _M_h[std::move(__k)]; } //@} //@{ /** * @brief Access to %unordered_map data. * @param __k The key for which data should be retrieved. * @return A reference to the data whose key is equal to @a __k, if * such a data is present in the %unordered_map. * @throw std::out_of_range If no such data is present. */ mapped_type& at(const key_type& __k) { return _M_h.at(__k); } const mapped_type& at(const key_type& __k) const { return _M_h.at(__k); } //@} // bucket interface. /// Returns the number of buckets of the %unordered_map. size_type bucket_count() const noexcept { return _M_h.bucket_count(); } /// Returns the maximum number of buckets of the %unordered_map. size_type max_bucket_count() const noexcept { return _M_h.max_bucket_count(); } /* * @brief Returns the number of elements in a given bucket. * @param __n A bucket index. * @return The number of elements in the bucket. */ size_type bucket_size(size_type __n) const { return _M_h.bucket_size(__n); } /* * @brief Returns the bucket index of a given element. * @param __key A key instance. * @return The key bucket index. */ size_type bucket(const key_type& __key) const { return _M_h.bucket(__key); } /** * @brief Returns a read/write iterator pointing to the first bucket * element. * @param __n The bucket index. * @return A read/write local iterator. */ local_iterator begin(size_type __n) { return _M_h.begin(__n); } //@{ /** * @brief Returns a read-only (constant) iterator pointing to the first * bucket element. * @param __n The bucket index. * @return A read-only local iterator. */ const_local_iterator begin(size_type __n) const { return _M_h.begin(__n); } const_local_iterator cbegin(size_type __n) const { return _M_h.cbegin(__n); } //@} /** * @brief Returns a read/write iterator pointing to one past the last * bucket elements. * @param __n The bucket index. * @return A read/write local iterator. */ local_iterator end(size_type __n) { return _M_h.end(__n); } //@{ /** * @brief Returns a read-only (constant) iterator pointing to one past * the last bucket elements. * @param __n The bucket index. * @return A read-only local iterator. */ const_local_iterator end(size_type __n) const { return _M_h.end(__n); } const_local_iterator cend(size_type __n) const { return _M_h.cend(__n); } //@} // hash policy. /// Returns the average number of elements per bucket. float load_factor() const noexcept { return _M_h.load_factor(); } /// Returns a positive number that the %unordered_map tries to keep the /// load factor less than or equal to. float max_load_factor() const noexcept { return _M_h.max_load_factor(); } /** * @brief Change the %unordered_map maximum load factor. * @param __z The new maximum load factor. */ void max_load_factor(float __z) { _M_h.max_load_factor(__z); } /** * @brief May rehash the %unordered_map. * @param __n The new number of buckets. * * Rehash will occur only if the new number of buckets respect the * %unordered_map maximum load factor. */ void rehash(size_type __n) { _M_h.rehash(__n); } /** * @brief Prepare the %unordered_map for a specified number of * elements. * @param __n Number of elements required. * * Same as rehash(ceil(n / max_load_factor())). */ void reserve(size_type __n) { _M_h.reserve(__n); } template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1, typename _Alloc1> friend bool operator==(const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&, const unordered_map<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&); }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _Hash = hash<__iter_key_t<_InputIterator>>, typename _Pred = equal_to<__iter_key_t<_InputIterator>>, typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_map(_InputIterator, _InputIterator, typename unordered_map<int, int>::size_type = {}, _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) -> unordered_map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Hash, _Pred, _Allocator>; template<typename _Key, typename _Tp, typename _Hash = hash<_Key>, typename _Pred = equal_to<_Key>, typename _Allocator = allocator<pair<const _Key, _Tp>>, typename = _RequireAllocator<_Allocator>> unordered_map(initializer_list<pair<_Key, _Tp>>, typename unordered_map<int, int>::size_type = {}, _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) -> unordered_map<_Key, _Tp, _Hash, _Pred, _Allocator>; template<typename _InputIterator, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_map(_InputIterator, _InputIterator, typename unordered_map<int, int>::size_type, _Allocator) -> unordered_map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, hash<__iter_key_t<_InputIterator>>, equal_to<__iter_key_t<_InputIterator>>, _Allocator>; template<typename _InputIterator, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_map(_InputIterator, _InputIterator, _Allocator) -> unordered_map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, hash<__iter_key_t<_InputIterator>>, equal_to<__iter_key_t<_InputIterator>>, _Allocator>; template<typename _InputIterator, typename _Hash, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_map(_InputIterator, _InputIterator, typename unordered_map<int, int>::size_type, _Hash, _Allocator) -> unordered_map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Hash, equal_to<__iter_key_t<_InputIterator>>, _Allocator>; template<typename _Key, typename _Tp, typename _Allocator, typename = _RequireAllocator<_Allocator>> unordered_map(initializer_list<pair<_Key, _Tp>>, typename unordered_map<int, int>::size_type, _Allocator) -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>; template<typename _Key, typename _Tp, typename _Allocator, typename = _RequireAllocator<_Allocator>> unordered_map(initializer_list<pair<_Key, _Tp>>, _Allocator) -> unordered_map<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>; template<typename _Key, typename _Tp, typename _Hash, typename _Allocator, typename = _RequireAllocator<_Allocator>> unordered_map(initializer_list<pair<_Key, _Tp>>, typename unordered_map<int, int>::size_type, _Hash, _Allocator) -> unordered_map<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>; #endif /** * @brief A standard container composed of equivalent keys * (possibly containing multiple of each key value) that associates * values of another type with the keys. * * @ingroup unordered_associative_containers * * @tparam _Key Type of key objects. * @tparam _Tp Type of mapped objects. * @tparam _Hash Hashing function object type, defaults to hash<_Value>. * @tparam _Pred Predicate function object type, defaults * to equal_to<_Value>. * @tparam _Alloc Allocator type, defaults to * std::allocator<std::pair<const _Key, _Tp>>. * * Meets the requirements of a <a href="tables.html#65">container</a>, and * <a href="tables.html#xx">unordered associative container</a> * * The resulting value type of the container is std::pair<const _Key, _Tp>. * * Base is _Hashtable, dispatched at compile time via template * alias __ummap_hashtable. */ template<typename _Key, typename _Tp, typename _Hash = hash<_Key>, typename _Pred = equal_to<_Key>, typename _Alloc = allocator<std::pair<const _Key, _Tp>>> class unordered_multimap { typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable; _Hashtable _M_h; public: // typedefs: //@{ /// Public typedefs. typedef typename _Hashtable::key_type key_type; typedef typename _Hashtable::value_type value_type; typedef typename _Hashtable::mapped_type mapped_type; typedef typename _Hashtable::hasher hasher; typedef typename _Hashtable::key_equal key_equal; typedef typename _Hashtable::allocator_type allocator_type; //@} //@{ /// Iterator-related typedefs. typedef typename _Hashtable::pointer pointer; typedef typename _Hashtable::const_pointer const_pointer; typedef typename _Hashtable::reference reference; typedef typename _Hashtable::const_reference const_reference; typedef typename _Hashtable::iterator iterator; typedef typename _Hashtable::const_iterator const_iterator; typedef typename _Hashtable::local_iterator local_iterator; typedef typename _Hashtable::const_local_iterator const_local_iterator; typedef typename _Hashtable::size_type size_type; typedef typename _Hashtable::difference_type difference_type; //@} #if __cplusplus > 201402L using node_type = typename _Hashtable::node_type; #endif //construct/destroy/copy /// Default constructor. unordered_multimap() = default; /** * @brief Default constructor creates no elements. * @param __n Mnimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. */ explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__n, __hf, __eql, __a) { } /** * @brief Builds an %unordered_multimap from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. * * Create an %unordered_multimap consisting of copies of the elements * from [__first,__last). This is linear in N (where N is * distance(__first,__last)). */ template<typename _InputIterator> unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__first, __last, __n, __hf, __eql, __a) { } /// Copy constructor. unordered_multimap(const unordered_multimap&) = default; /// Move constructor. unordered_multimap(unordered_multimap&&) = default; /** * @brief Creates an %unordered_multimap with no elements. * @param __a An allocator object. */ explicit unordered_multimap(const allocator_type& __a) : _M_h(__a) { } /* * @brief Copy constructor with allocator argument. * @param __uset Input %unordered_multimap to copy. * @param __a An allocator object. */ unordered_multimap(const unordered_multimap& __ummap, const allocator_type& __a) : _M_h(__ummap._M_h, __a) { } /* * @brief Move constructor with allocator argument. * @param __uset Input %unordered_multimap to move. * @param __a An allocator object. */ unordered_multimap(unordered_multimap&& __ummap, const allocator_type& __a) : _M_h(std::move(__ummap._M_h), __a) { } /** * @brief Builds an %unordered_multimap from an initializer_list. * @param __l An initializer_list. * @param __n Minimal initial number of buckets. * @param __hf A hash functor. * @param __eql A key equality functor. * @param __a An allocator object. * * Create an %unordered_multimap consisting of copies of the elements in * the list. This is linear in N (where N is @a __l.size()). */ unordered_multimap(initializer_list<value_type> __l, size_type __n = 0, const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) : _M_h(__l, __n, __hf, __eql, __a) { } unordered_multimap(size_type __n, const allocator_type& __a) : unordered_multimap(__n, hasher(), key_equal(), __a) { } unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__n, __hf, key_equal(), __a) { } template<typename _InputIterator> unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) { } template<typename _InputIterator> unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) { } unordered_multimap(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) : unordered_multimap(__l, __n, hasher(), key_equal(), __a) { } unordered_multimap(initializer_list<value_type> __l, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__l, __n, __hf, key_equal(), __a) { } /// Copy assignment operator. unordered_multimap& operator=(const unordered_multimap&) = default; /// Move assignment operator. unordered_multimap& operator=(unordered_multimap&&) = default; /** * @brief %Unordered_multimap list assignment operator. * @param __l An initializer_list. * * This function fills an %unordered_multimap with copies of the * elements in the initializer list @a __l. * * Note that the assignment completely changes the %unordered_multimap * and that the resulting %unordered_multimap's size is the same as the * number of elements assigned. */ unordered_multimap& operator=(initializer_list<value_type> __l) { _M_h = __l; return *this; } /// Returns the allocator object used by the %unordered_multimap. allocator_type get_allocator() const noexcept { return _M_h.get_allocator(); } // size and capacity: /// Returns true if the %unordered_multimap is empty. bool empty() const noexcept { return _M_h.empty(); } /// Returns the size of the %unordered_multimap. size_type size() const noexcept { return _M_h.size(); } /// Returns the maximum size of the %unordered_multimap. size_type max_size() const noexcept { return _M_h.max_size(); } // iterators. /** * Returns a read/write iterator that points to the first element in the * %unordered_multimap. */ iterator begin() noexcept { return _M_h.begin(); } //@{ /** * Returns a read-only (constant) iterator that points to the first * element in the %unordered_multimap. */ const_iterator begin() const noexcept { return _M_h.begin(); } const_iterator cbegin() const noexcept { return _M_h.begin(); } //@} /** * Returns a read/write iterator that points one past the last element in * the %unordered_multimap. */ iterator end() noexcept { return _M_h.end(); } //@{ /** * Returns a read-only (constant) iterator that points one past the last * element in the %unordered_multimap. */ const_iterator end() const noexcept { return _M_h.end(); } const_iterator cend() const noexcept { return _M_h.end(); } //@} // modifiers. /** * @brief Attempts to build and insert a std::pair into the * %unordered_multimap. * * @param __args Arguments used to generate a new pair instance (see * std::piecewise_contruct for passing arguments to each * part of the pair constructor). * * @return An iterator that points to the inserted pair. * * This function attempts to build and insert a (key, value) %pair into * the %unordered_multimap. * * Insertion requires amortized constant time. */ template<typename... _Args> iterator emplace(_Args&&... __args) { return _M_h.emplace(std::forward<_Args>(__args)...); } /** * @brief Attempts to build and insert a std::pair into the * %unordered_multimap. * * @param __pos An iterator that serves as a hint as to where the pair * should be inserted. * @param __args Arguments used to generate a new pair instance (see * std::piecewise_contruct for passing arguments to each * part of the pair constructor). * @return An iterator that points to the element with key of the * std::pair built from @a __args. * * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires amortized constant time. */ template<typename... _Args> iterator emplace_hint(const_iterator __pos, _Args&&... __args) { return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); } //@{ /** * @brief Inserts a std::pair into the %unordered_multimap. * @param __x Pair to be inserted (see std::make_pair for easy * creation of pairs). * * @return An iterator that points to the inserted pair. * * Insertion requires amortized constant time. */ iterator insert(const value_type& __x) { return _M_h.insert(__x); } iterator insert(value_type&& __x) { return _M_h.insert(std::move(__x)); } template<typename _Pair> __enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator> insert(_Pair&& __x) { return _M_h.emplace(std::forward<_Pair>(__x)); } //@} //@{ /** * @brief Inserts a std::pair into the %unordered_multimap. * @param __hint An iterator that serves as a hint as to where the * pair should be inserted. * @param __x Pair to be inserted (see std::make_pair for easy creation * of pairs). * @return An iterator that points to the element with key of * @a __x (may or may not be the %pair passed in). * * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires amortized constant time. */ iterator insert(const_iterator __hint, const value_type& __x) { return _M_h.insert(__hint, __x); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2354. Unnecessary copying when inserting into maps with braced-init iterator insert(const_iterator __hint, value_type&& __x) { return _M_h.insert(__hint, std::move(__x)); } template<typename _Pair> __enable_if_t<is_constructible<value_type, _Pair&&>::value, iterator> insert(const_iterator __hint, _Pair&& __x) { return _M_h.emplace_hint(__hint, std::forward<_Pair>(__x)); } //@} /** * @brief A template function that attempts to insert a range of * elements. * @param __first Iterator pointing to the start of the range to be * inserted. * @param __last Iterator pointing to the end of the range. * * Complexity similar to that of the range constructor. */ template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_h.insert(__first, __last); } /** * @brief Attempts to insert a list of elements into the * %unordered_multimap. * @param __l A std::initializer_list<value_type> of elements * to be inserted. * * Complexity similar to that of the range constructor. */ void insert(initializer_list<value_type> __l) { _M_h.insert(__l); } #if __cplusplus > 201402L /// Extract a node. node_type extract(const_iterator __pos) { __glibcxx_assert(__pos != end()); return _M_h.extract(__pos); } /// Extract a node. node_type extract(const key_type& __key) { return _M_h.extract(__key); } /// Re-insert an extracted node. iterator insert(node_type&& __nh) { return _M_h._M_reinsert_node_multi(cend(), std::move(__nh)); } /// Re-insert an extracted node. iterator insert(const_iterator __hint, node_type&& __nh) { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); } #endif // C++17 //@{ /** * @brief Erases an element from an %unordered_multimap. * @param __position An iterator pointing to the element to be erased. * @return An iterator pointing to the element immediately following * @a __position prior to the element being erased. If no such * element exists, end() is returned. * * This function erases an element, pointed to by the given iterator, * from an %unordered_multimap. * Note that this function only erases the element, and that if the * element is itself a pointer, the pointed-to memory is not touched in * any way. Managing the pointer is the user's responsibility. */ iterator erase(const_iterator __position) { return _M_h.erase(__position); } // LWG 2059. iterator erase(iterator __position) { return _M_h.erase(__position); } //@} /** * @brief Erases elements according to the provided key. * @param __x Key of elements to be erased. * @return The number of elements erased. * * This function erases all the elements located by the given key from * an %unordered_multimap. * Note that this function only erases the element, and that if the * element is itself a pointer, the pointed-to memory is not touched in * any way. Managing the pointer is the user's responsibility. */ size_type erase(const key_type& __x) { return _M_h.erase(__x); } /** * @brief Erases a [__first,__last) range of elements from an * %unordered_multimap. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to * be erased. * @return The iterator @a __last. * * This function erases a sequence of elements from an * %unordered_multimap. * Note that this function only erases the elements, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ iterator erase(const_iterator __first, const_iterator __last) { return _M_h.erase(__first, __last); } /** * Erases all elements in an %unordered_multimap. * Note that this function only erases the elements, and that if the * elements themselves are pointers, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ void clear() noexcept { _M_h.clear(); } /** * @brief Swaps data with another %unordered_multimap. * @param __x An %unordered_multimap of the same element and allocator * types. * * This exchanges the elements between two %unordered_multimap in * constant time. * Note that the global std::swap() function is specialized such that * std::swap(m1,m2) will feed to this function. */ void swap(unordered_multimap& __x) noexcept( noexcept(_M_h.swap(__x._M_h)) ) { _M_h.swap(__x._M_h); } #if __cplusplus > 201402L template<typename, typename, typename> friend class std::_Hash_merge_helper; template<typename _H2, typename _P2> void merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>& __source) { using _Merge_helper = _Hash_merge_helper<unordered_multimap, _H2, _P2>; _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source)); } template<typename _H2, typename _P2> void merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source) { merge(__source); } template<typename _H2, typename _P2> void merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>& __source) { using _Merge_helper = _Hash_merge_helper<unordered_multimap, _H2, _P2>; _M_h._M_merge_multi(_Merge_helper::_S_get_table(__source)); } template<typename _H2, typename _P2> void merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source) { merge(__source); } #endif // C++17 // observers. /// Returns the hash functor object with which the %unordered_multimap /// was constructed. hasher hash_function() const { return _M_h.hash_function(); } /// Returns the key comparison object with which the %unordered_multimap /// was constructed. key_equal key_eq() const { return _M_h.key_eq(); } // lookup. //@{ /** * @brief Tries to locate an element in an %unordered_multimap. * @param __x Key to be located. * @return Iterator pointing to sought-after element, or end() if not * found. * * This function takes a key and tries to locate the element with which * the key matches. If successful the function returns an iterator * pointing to the sought after element. If unsuccessful it returns the * past-the-end ( @c end() ) iterator. */ iterator find(const key_type& __x) { return _M_h.find(__x); } const_iterator find(const key_type& __x) const { return _M_h.find(__x); } //@} /** * @brief Finds the number of elements. * @param __x Key to count. * @return Number of elements with specified key. */ size_type count(const key_type& __x) const { return _M_h.count(__x); } //@{ /** * @brief Finds a subsequence matching given key. * @param __x Key to be located. * @return Pair of iterators that possibly points to the subsequence * matching given key. */ std::pair<iterator, iterator> equal_range(const key_type& __x) { return _M_h.equal_range(__x); } std::pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { return _M_h.equal_range(__x); } //@} // bucket interface. /// Returns the number of buckets of the %unordered_multimap. size_type bucket_count() const noexcept { return _M_h.bucket_count(); } /// Returns the maximum number of buckets of the %unordered_multimap. size_type max_bucket_count() const noexcept { return _M_h.max_bucket_count(); } /* * @brief Returns the number of elements in a given bucket. * @param __n A bucket index. * @return The number of elements in the bucket. */ size_type bucket_size(size_type __n) const { return _M_h.bucket_size(__n); } /* * @brief Returns the bucket index of a given element. * @param __key A key instance. * @return The key bucket index. */ size_type bucket(const key_type& __key) const { return _M_h.bucket(__key); } /** * @brief Returns a read/write iterator pointing to the first bucket * element. * @param __n The bucket index. * @return A read/write local iterator. */ local_iterator begin(size_type __n) { return _M_h.begin(__n); } //@{ /** * @brief Returns a read-only (constant) iterator pointing to the first * bucket element. * @param __n The bucket index. * @return A read-only local iterator. */ const_local_iterator begin(size_type __n) const { return _M_h.begin(__n); } const_local_iterator cbegin(size_type __n) const { return _M_h.cbegin(__n); } //@} /** * @brief Returns a read/write iterator pointing to one past the last * bucket elements. * @param __n The bucket index. * @return A read/write local iterator. */ local_iterator end(size_type __n) { return _M_h.end(__n); } //@{ /** * @brief Returns a read-only (constant) iterator pointing to one past * the last bucket elements. * @param __n The bucket index. * @return A read-only local iterator. */ const_local_iterator end(size_type __n) const { return _M_h.end(__n); } const_local_iterator cend(size_type __n) const { return _M_h.cend(__n); } //@} // hash policy. /// Returns the average number of elements per bucket. float load_factor() const noexcept { return _M_h.load_factor(); } /// Returns a positive number that the %unordered_multimap tries to keep /// the load factor less than or equal to. float max_load_factor() const noexcept { return _M_h.max_load_factor(); } /** * @brief Change the %unordered_multimap maximum load factor. * @param __z The new maximum load factor. */ void max_load_factor(float __z) { _M_h.max_load_factor(__z); } /** * @brief May rehash the %unordered_multimap. * @param __n The new number of buckets. * * Rehash will occur only if the new number of buckets respect the * %unordered_multimap maximum load factor. */ void rehash(size_type __n) { _M_h.rehash(__n); } /** * @brief Prepare the %unordered_multimap for a specified number of * elements. * @param __n Number of elements required. * * Same as rehash(ceil(n / max_load_factor())). */ void reserve(size_type __n) { _M_h.reserve(__n); } template<typename _Key1, typename _Tp1, typename _Hash1, typename _Pred1, typename _Alloc1> friend bool operator==(const unordered_multimap<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&, const unordered_multimap<_Key1, _Tp1, _Hash1, _Pred1, _Alloc1>&); }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _Hash = hash<__iter_key_t<_InputIterator>>, typename _Pred = equal_to<__iter_key_t<_InputIterator>>, typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_multimap(_InputIterator, _InputIterator, unordered_multimap<int, int>::size_type = {}, _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) -> unordered_multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Hash, _Pred, _Allocator>; template<typename _Key, typename _Tp, typename _Hash = hash<_Key>, typename _Pred = equal_to<_Key>, typename _Allocator = allocator<pair<const _Key, _Tp>>, typename = _RequireAllocator<_Allocator>> unordered_multimap(initializer_list<pair<_Key, _Tp>>, unordered_multimap<int, int>::size_type = {}, _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) -> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Allocator>; template<typename _InputIterator, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_multimap(_InputIterator, _InputIterator, unordered_multimap<int, int>::size_type, _Allocator) -> unordered_multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, hash<__iter_key_t<_InputIterator>>, equal_to<__iter_key_t<_InputIterator>>, _Allocator>; template<typename _InputIterator, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_multimap(_InputIterator, _InputIterator, _Allocator) -> unordered_multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, hash<__iter_key_t<_InputIterator>>, equal_to<__iter_key_t<_InputIterator>>, _Allocator>; template<typename _InputIterator, typename _Hash, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> unordered_multimap(_InputIterator, _InputIterator, unordered_multimap<int, int>::size_type, _Hash, _Allocator) -> unordered_multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, _Hash, equal_to<__iter_key_t<_InputIterator>>, _Allocator>; template<typename _Key, typename _Tp, typename _Allocator, typename = _RequireAllocator<_Allocator>> unordered_multimap(initializer_list<pair<_Key, _Tp>>, unordered_multimap<int, int>::size_type, _Allocator) -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>; template<typename _Key, typename _Tp, typename _Allocator, typename = _RequireAllocator<_Allocator>> unordered_multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) -> unordered_multimap<_Key, _Tp, hash<_Key>, equal_to<_Key>, _Allocator>; template<typename _Key, typename _Tp, typename _Hash, typename _Allocator, typename = _RequireAllocator<_Allocator>> unordered_multimap(initializer_list<pair<_Key, _Tp>>, unordered_multimap<int, int>::size_type, _Hash, _Allocator) -> unordered_multimap<_Key, _Tp, _Hash, equal_to<_Key>, _Allocator>; #endif template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> inline void swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> inline void swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> inline bool operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return __x._M_h._M_equal(__y._M_h); } template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> inline bool operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> inline bool operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return __x._M_h._M_equal(__y._M_h); } template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> inline bool operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } _GLIBCXX_END_NAMESPACE_CONTAINER #if __cplusplus > 201402L // Allow std::unordered_map access to internals of compatible maps. template<typename _Key, typename _Val, typename _Hash1, typename _Eq1, typename _Alloc, typename _Hash2, typename _Eq2> struct _Hash_merge_helper< _GLIBCXX_STD_C::unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>, _Hash2, _Eq2> { private: template<typename... _Tp> using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>; template<typename... _Tp> using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>; friend unordered_map<_Key, _Val, _Hash1, _Eq1, _Alloc>; static auto& _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map) { return __map._M_h; } static auto& _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map) { return __map._M_h; } }; // Allow std::unordered_multimap access to internals of compatible maps. template<typename _Key, typename _Val, typename _Hash1, typename _Eq1, typename _Alloc, typename _Hash2, typename _Eq2> struct _Hash_merge_helper< _GLIBCXX_STD_C::unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>, _Hash2, _Eq2> { private: template<typename... _Tp> using unordered_map = _GLIBCXX_STD_C::unordered_map<_Tp...>; template<typename... _Tp> using unordered_multimap = _GLIBCXX_STD_C::unordered_multimap<_Tp...>; friend unordered_multimap<_Key, _Val, _Hash1, _Eq1, _Alloc>; static auto& _S_get_table(unordered_map<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map) { return __map._M_h; } static auto& _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>& __map) { return __map._M_h; } }; #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _UNORDERED_MAP_H */ c++/8/bits/quoted_string.h 0000644 00000011675 15146341150 0011276 0 ustar 00 // Helpers for quoted stream manipulators -*- C++ -*- // Copyright (C) 2013-2018 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/quoted_string.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iomanip} */ #ifndef _GLIBCXX_QUOTED_STRING_H #define _GLIBCXX_QUOTED_STRING_H 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <sstream> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { /** * @brief Struct for delimited strings. */ template<typename _String, typename _CharT> struct _Quoted_string { static_assert(is_reference<_String>::value || is_pointer<_String>::value, "String type must be pointer or reference"); _Quoted_string(_String __str, _CharT __del, _CharT __esc) : _M_string(__str), _M_delim{__del}, _M_escape{__esc} { } _Quoted_string& operator=(_Quoted_string&) = delete; _String _M_string; _CharT _M_delim; _CharT _M_escape; }; #if __cplusplus >= 201703L template<typename _CharT, typename _Traits> struct _Quoted_string<basic_string_view<_CharT, _Traits>, _CharT> { _Quoted_string(basic_string_view<_CharT, _Traits> __str, _CharT __del, _CharT __esc) : _M_string(__str), _M_delim{__del}, _M_escape{__esc} { } _Quoted_string& operator=(_Quoted_string&) = delete; basic_string_view<_CharT, _Traits> _M_string; _CharT _M_delim; _CharT _M_escape; }; #endif // C++17 /** * @brief Inserter for quoted strings. * * _GLIBCXX_RESOLVE_LIB_DEFECTS * DR 2344 quoted()'s interaction with padding is unclear */ template<typename _CharT, typename _Traits> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const _Quoted_string<const _CharT*, _CharT>& __str) { std::basic_ostringstream<_CharT, _Traits> __ostr; __ostr << __str._M_delim; for (const _CharT* __c = __str._M_string; *__c; ++__c) { if (*__c == __str._M_delim || *__c == __str._M_escape) __ostr << __str._M_escape; __ostr << *__c; } __ostr << __str._M_delim; return __os << __ostr.str(); } /** * @brief Inserter for quoted strings. * * _GLIBCXX_RESOLVE_LIB_DEFECTS * DR 2344 quoted()'s interaction with padding is unclear */ template<typename _CharT, typename _Traits, typename _String> std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const _Quoted_string<_String, _CharT>& __str) { std::basic_ostringstream<_CharT, _Traits> __ostr; __ostr << __str._M_delim; for (auto __c : __str._M_string) { if (__c == __str._M_delim || __c == __str._M_escape) __ostr << __str._M_escape; __ostr << __c; } __ostr << __str._M_delim; return __os << __ostr.str(); } /** * @brief Extractor for delimited strings. * The left and right delimiters can be different. */ template<typename _CharT, typename _Traits, typename _Alloc> std::basic_istream<_CharT, _Traits>& operator>>(std::basic_istream<_CharT, _Traits>& __is, const _Quoted_string<basic_string<_CharT, _Traits, _Alloc>&, _CharT>& __str) { _CharT __c; __is >> __c; if (!__is.good()) return __is; if (__c != __str._M_delim) { __is.unget(); __is >> __str._M_string; return __is; } __str._M_string.clear(); std::ios_base::fmtflags __flags = __is.flags(__is.flags() & ~std::ios_base::skipws); do { __is >> __c; if (!__is.good()) break; if (__c == __str._M_escape) { __is >> __c; if (!__is.good()) break; } else if (__c == __str._M_delim) break; __str._M_string += __c; } while (true); __is.setf(__flags); return __is; } } // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif /* _GLIBCXX_QUOTED_STRING_H */ c++/8/bits/basic_string.tcc 0000644 00000150773 15146341150 0011403 0 ustar 00 // Components for manipulating sequences of characters -*- C++ -*- // Copyright (C) 1997-2018 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_string.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{string} */ // // ISO C++ 14882: 21 Strings library // // Written by Jason Merrill based upon the specification by Takanori Adachi // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. // Non-reference-counted implementation written by Paolo Carlini and // updated by Jonathan Wakely for ISO-14882-2011. #ifndef _BASIC_STRING_TCC #define _BASIC_STRING_TCC 1 #pragma GCC system_header #include <bits/cxxabi_forced.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if _GLIBCXX_USE_CXX11_ABI template<typename _CharT, typename _Traits, typename _Alloc> const typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>::npos; template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: swap(basic_string& __s) _GLIBCXX_NOEXCEPT { if (this == &__s) return; _Alloc_traits::_S_on_swap(_M_get_allocator(), __s._M_get_allocator()); if (_M_is_local()) if (__s._M_is_local()) { if (length() && __s.length()) { _CharT __tmp_data[_S_local_capacity + 1]; traits_type::copy(__tmp_data, __s._M_local_buf, _S_local_capacity + 1); traits_type::copy(__s._M_local_buf, _M_local_buf, _S_local_capacity + 1); traits_type::copy(_M_local_buf, __tmp_data, _S_local_capacity + 1); } else if (__s.length()) { traits_type::copy(_M_local_buf, __s._M_local_buf, _S_local_capacity + 1); _M_length(__s.length()); __s._M_set_length(0); return; } else if (length()) { traits_type::copy(__s._M_local_buf, _M_local_buf, _S_local_capacity + 1); __s._M_length(length()); _M_set_length(0); return; } } else { const size_type __tmp_capacity = __s._M_allocated_capacity; traits_type::copy(__s._M_local_buf, _M_local_buf, _S_local_capacity + 1); _M_data(__s._M_data()); __s._M_data(__s._M_local_buf); _M_capacity(__tmp_capacity); } else { const size_type __tmp_capacity = _M_allocated_capacity; if (__s._M_is_local()) { traits_type::copy(_M_local_buf, __s._M_local_buf, _S_local_capacity + 1); __s._M_data(_M_data()); _M_data(_M_local_buf); } else { pointer __tmp_ptr = _M_data(); _M_data(__s._M_data()); __s._M_data(__tmp_ptr); _M_capacity(__s._M_allocated_capacity); } __s._M_capacity(__tmp_capacity); } const size_type __tmp_length = length(); _M_length(__s.length()); __s._M_length(__tmp_length); } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::pointer basic_string<_CharT, _Traits, _Alloc>:: _M_create(size_type& __capacity, size_type __old_capacity) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 83. String::npos vs. string::max_size() if (__capacity > max_size()) std::__throw_length_error(__N("basic_string::_M_create")); // The below implements an exponential growth policy, necessary to // meet amortized linear time requirements of the library: see // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) { __capacity = 2 * __old_capacity; // Never allocate a string bigger than max_size. if (__capacity > max_size()) __capacity = max_size(); } // NB: Need an array of char_type[__capacity], plus a terminating // null char_type() element. return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1); } // NB: This is the special case for Input Iterators, used in // istreambuf_iterators, etc. // Input Iterators have a cost structure very different from // pointers, calling for a different coding style. template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InIterator> void basic_string<_CharT, _Traits, _Alloc>:: _M_construct(_InIterator __beg, _InIterator __end, std::input_iterator_tag) { size_type __len = 0; size_type __capacity = size_type(_S_local_capacity); while (__beg != __end && __len < __capacity) { _M_data()[__len++] = *__beg; ++__beg; } __try { while (__beg != __end) { if (__len == __capacity) { // Allocate more space. __capacity = __len + 1; pointer __another = _M_create(__capacity, __len); this->_S_copy(__another, _M_data(), __len); _M_dispose(); _M_data(__another); _M_capacity(__capacity); } _M_data()[__len++] = *__beg; ++__beg; } } __catch(...) { _M_dispose(); __throw_exception_again; } _M_set_length(__len); } template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InIterator> void basic_string<_CharT, _Traits, _Alloc>:: _M_construct(_InIterator __beg, _InIterator __end, std::forward_iterator_tag) { // NB: Not required, but considered best practice. if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) std::__throw_logic_error(__N("basic_string::" "_M_construct null not valid")); size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); if (__dnew > size_type(_S_local_capacity)) { _M_data(_M_create(__dnew, size_type(0))); _M_capacity(__dnew); } // Check for out_of_range and length_error exceptions. __try { this->_S_copy_chars(_M_data(), __beg, __end); } __catch(...) { _M_dispose(); __throw_exception_again; } _M_set_length(__dnew); } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: _M_construct(size_type __n, _CharT __c) { if (__n > size_type(_S_local_capacity)) { _M_data(_M_create(__n, size_type(0))); _M_capacity(__n); } if (__n) this->_S_assign(_M_data(), __n, __c); _M_set_length(__n); } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: _M_assign(const basic_string& __str) { if (this != &__str) { const size_type __rsize = __str.length(); const size_type __capacity = capacity(); if (__rsize > __capacity) { size_type __new_capacity = __rsize; pointer __tmp = _M_create(__new_capacity, __capacity); _M_dispose(); _M_data(__tmp); _M_capacity(__new_capacity); } if (__rsize) this->_S_copy(_M_data(), __str._M_data(), __rsize); _M_set_length(__rsize); } } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: reserve(size_type __res) { // Make sure we don't shrink below the current size. if (__res < length()) __res = length(); const size_type __capacity = capacity(); if (__res != __capacity) { if (__res > __capacity || __res > size_type(_S_local_capacity)) { pointer __tmp = _M_create(__res, __capacity); this->_S_copy(__tmp, _M_data(), length() + 1); _M_dispose(); _M_data(__tmp); _M_capacity(__res); } else if (!_M_is_local()) { this->_S_copy(_M_local_data(), _M_data(), length() + 1); _M_destroy(__capacity); _M_data(_M_local_data()); } } } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, size_type __len2) { const size_type __how_much = length() - __pos - __len1; size_type __new_capacity = length() + __len2 - __len1; pointer __r = _M_create(__new_capacity, capacity()); if (__pos) this->_S_copy(__r, _M_data(), __pos); if (__s && __len2) this->_S_copy(__r + __pos, __s, __len2); if (__how_much) this->_S_copy(__r + __pos + __len2, _M_data() + __pos + __len1, __how_much); _M_dispose(); _M_data(__r); _M_capacity(__new_capacity); } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: _M_erase(size_type __pos, size_type __n) { const size_type __how_much = length() - __pos - __n; if (__how_much && __n) this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much); _M_set_length(length() - __n); } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: resize(size_type __n, _CharT __c) { const size_type __size = this->size(); if (__size < __n) this->append(__n - __size, __c); else if (__n < __size) this->_M_set_length(__n); } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: _M_append(const _CharT* __s, size_type __n) { const size_type __len = __n + this->size(); if (__len <= this->capacity()) { if (__n) this->_S_copy(this->_M_data() + this->size(), __s, __n); } else this->_M_mutate(this->size(), size_type(0), __s, __n); this->_M_set_length(__len); return *this; } template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InputIterator> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: _M_replace_dispatch(const_iterator __i1, const_iterator __i2, _InputIterator __k1, _InputIterator __k2, std::__false_type) { const basic_string __s(__k1, __k2); const size_type __n1 = __i2 - __i1; return _M_replace(__i1 - begin(), __n1, __s._M_data(), __s.size()); } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, _CharT __c) { _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); const size_type __old_size = this->size(); const size_type __new_size = __old_size + __n2 - __n1; if (__new_size <= this->capacity()) { pointer __p = this->_M_data() + __pos1; const size_type __how_much = __old_size - __pos1 - __n1; if (__how_much && __n1 != __n2) this->_S_move(__p + __n2, __p + __n1, __how_much); } else this->_M_mutate(__pos1, __n1, 0, __n2); if (__n2) this->_S_assign(this->_M_data() + __pos1, __n2, __c); this->_M_set_length(__new_size); return *this; } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: _M_replace(size_type __pos, size_type __len1, const _CharT* __s, const size_type __len2) { _M_check_length(__len1, __len2, "basic_string::_M_replace"); const size_type __old_size = this->size(); const size_type __new_size = __old_size + __len2 - __len1; if (__new_size <= this->capacity()) { pointer __p = this->_M_data() + __pos; const size_type __how_much = __old_size - __pos - __len1; if (_M_disjunct(__s)) { if (__how_much && __len1 != __len2) this->_S_move(__p + __len2, __p + __len1, __how_much); if (__len2) this->_S_copy(__p, __s, __len2); } else { // Work in-place. if (__len2 && __len2 <= __len1) this->_S_move(__p, __s, __len2); if (__how_much && __len1 != __len2) this->_S_move(__p + __len2, __p + __len1, __how_much); if (__len2 > __len1) { if (__s + __len2 <= __p + __len1) this->_S_move(__p, __s, __len2); else if (__s >= __p + __len1) this->_S_copy(__p, __s + __len2 - __len1, __len2); else { const size_type __nleft = (__p + __len1) - __s; this->_S_move(__p, __s, __nleft); this->_S_copy(__p + __nleft, __p + __len2, __len2 - __nleft); } } } } else this->_M_mutate(__pos, __len1, __s, __len2); this->_M_set_length(__new_size); return *this; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: copy(_CharT* __s, size_type __n, size_type __pos) const { _M_check(__pos, "basic_string::copy"); __n = _M_limit(__pos, __n); __glibcxx_requires_string_len(__s, __n); if (__n) _S_copy(__s, _M_data() + __pos, __n); // 21.3.5.7 par 3: do not append null. (good.) return __n; } #else // !_GLIBCXX_USE_CXX11_ABI template<typename _CharT, typename _Traits, typename _Alloc> const typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; template<typename _CharT, typename _Traits, typename _Alloc> const _CharT basic_string<_CharT, _Traits, _Alloc>:: _Rep::_S_terminal = _CharT(); template<typename _CharT, typename _Traits, typename _Alloc> const typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>::npos; // Linker sets _S_empty_rep_storage to all 0s (one reference, empty string) // at static init time (before static ctors are run). template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[ (sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) / sizeof(size_type)]; // NB: This is the special case for Input Iterators, used in // istreambuf_iterators, etc. // Input Iterators have a cost structure very different from // pointers, calling for a different coding style. template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InIterator> _CharT* basic_string<_CharT, _Traits, _Alloc>:: _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, input_iterator_tag) { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (__beg == __end && __a == _Alloc()) return _S_empty_rep()._M_refdata(); #endif // Avoid reallocation for common case. _CharT __buf[128]; size_type __len = 0; while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) { __buf[__len++] = *__beg; ++__beg; } _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); _M_copy(__r->_M_refdata(), __buf, __len); __try { while (__beg != __end) { if (__len == __r->_M_capacity) { // Allocate more space. _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len); __r->_M_destroy(__a); __r = __another; } __r->_M_refdata()[__len++] = *__beg; ++__beg; } } __catch(...) { __r->_M_destroy(__a); __throw_exception_again; } __r->_M_set_length_and_sharable(__len); return __r->_M_refdata(); } template<typename _CharT, typename _Traits, typename _Alloc> template <typename _InIterator> _CharT* basic_string<_CharT, _Traits, _Alloc>:: _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, forward_iterator_tag) { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (__beg == __end && __a == _Alloc()) return _S_empty_rep()._M_refdata(); #endif // NB: Not required, but considered best practice. if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) __throw_logic_error(__N("basic_string::_S_construct null not valid")); const size_type __dnew = static_cast<size_type>(std::distance(__beg, __end)); // Check for out_of_range and length_error exceptions. _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); __try { _S_copy_chars(__r->_M_refdata(), __beg, __end); } __catch(...) { __r->_M_destroy(__a); __throw_exception_again; } __r->_M_set_length_and_sharable(__dnew); return __r->_M_refdata(); } template<typename _CharT, typename _Traits, typename _Alloc> _CharT* basic_string<_CharT, _Traits, _Alloc>:: _S_construct(size_type __n, _CharT __c, const _Alloc& __a) { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (__n == 0 && __a == _Alloc()) return _S_empty_rep()._M_refdata(); #endif // Check for out_of_range and length_error exceptions. _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); if (__n) _M_assign(__r->_M_refdata(), __n, __c); __r->_M_set_length_and_sharable(__n); return __r->_M_refdata(); } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const basic_string& __str) : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), __str.get_allocator()), __str.get_allocator()) { } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const _Alloc& __a) : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) { } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a) : _M_dataplus(_S_construct(__str._M_data() + __str._M_check(__pos, "basic_string::basic_string"), __str._M_data() + __str._M_limit(__pos, npos) + __pos, __a), __a) { } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const basic_string& __str, size_type __pos, size_type __n) : _M_dataplus(_S_construct(__str._M_data() + __str._M_check(__pos, "basic_string::basic_string"), __str._M_data() + __str._M_limit(__pos, __n) + __pos, _Alloc()), _Alloc()) { } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Alloc& __a) : _M_dataplus(_S_construct(__str._M_data() + __str._M_check(__pos, "basic_string::basic_string"), __str._M_data() + __str._M_limit(__pos, __n) + __pos, __a), __a) { } // TBD: DPG annotate template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const _CharT* __s, size_type __n, const _Alloc& __a) : _M_dataplus(_S_construct(__s, __s + __n, __a), __a) { } // TBD: DPG annotate template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(const _CharT* __s, const _Alloc& __a) : _M_dataplus(_S_construct(__s, __s ? __s + traits_type::length(__s) : __s + npos, __a), __a) { } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(size_type __n, _CharT __c, const _Alloc& __a) : _M_dataplus(_S_construct(__n, __c, __a), __a) { } // TBD: DPG annotate template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InputIterator> basic_string<_CharT, _Traits, _Alloc>:: basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) : _M_dataplus(_S_construct(__beg, __end, __a), __a) { } #if __cplusplus >= 201103L template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>:: basic_string(initializer_list<_CharT> __l, const _Alloc& __a) : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a) { } #endif template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: assign(const basic_string& __str) { if (_M_rep() != __str._M_rep()) { // XXX MT const allocator_type __a = this->get_allocator(); _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); _M_rep()->_M_dispose(__a); _M_data(__tmp); } return *this; } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: assign(const _CharT* __s, size_type __n) { __glibcxx_requires_string_len(__s, __n); _M_check_length(this->size(), __n, "basic_string::assign"); if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) return _M_replace_safe(size_type(0), this->size(), __s, __n); else { // Work in-place. const size_type __pos = __s - _M_data(); if (__pos >= __n) _M_copy(_M_data(), __s, __n); else if (__pos) _M_move(_M_data(), __s, __n); _M_rep()->_M_set_length_and_sharable(__n); return *this; } } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: append(size_type __n, _CharT __c) { if (__n) { _M_check_length(size_type(0), __n, "basic_string::append"); const size_type __len = __n + this->size(); if (__len > this->capacity() || _M_rep()->_M_is_shared()) this->reserve(__len); _M_assign(_M_data() + this->size(), __n, __c); _M_rep()->_M_set_length_and_sharable(__len); } return *this; } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: append(const _CharT* __s, size_type __n) { __glibcxx_requires_string_len(__s, __n); if (__n) { _M_check_length(size_type(0), __n, "basic_string::append"); const size_type __len = __n + this->size(); if (__len > this->capacity() || _M_rep()->_M_is_shared()) { if (_M_disjunct(__s)) this->reserve(__len); else { const size_type __off = __s - _M_data(); this->reserve(__len); __s = _M_data() + __off; } } _M_copy(_M_data() + this->size(), __s, __n); _M_rep()->_M_set_length_and_sharable(__len); } return *this; } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: append(const basic_string& __str) { const size_type __size = __str.size(); if (__size) { const size_type __len = __size + this->size(); if (__len > this->capacity() || _M_rep()->_M_is_shared()) this->reserve(__len); _M_copy(_M_data() + this->size(), __str._M_data(), __size); _M_rep()->_M_set_length_and_sharable(__len); } return *this; } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: append(const basic_string& __str, size_type __pos, size_type __n) { __str._M_check(__pos, "basic_string::append"); __n = __str._M_limit(__pos, __n); if (__n) { const size_type __len = __n + this->size(); if (__len > this->capacity() || _M_rep()->_M_is_shared()) this->reserve(__len); _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n); _M_rep()->_M_set_length_and_sharable(__len); } return *this; } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: insert(size_type __pos, const _CharT* __s, size_type __n) { __glibcxx_requires_string_len(__s, __n); _M_check(__pos, "basic_string::insert"); _M_check_length(size_type(0), __n, "basic_string::insert"); if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) return _M_replace_safe(__pos, size_type(0), __s, __n); else { // Work in-place. const size_type __off = __s - _M_data(); _M_mutate(__pos, 0, __n); __s = _M_data() + __off; _CharT* __p = _M_data() + __pos; if (__s + __n <= __p) _M_copy(__p, __s, __n); else if (__s >= __p) _M_copy(__p, __s + __n, __n); else { const size_type __nleft = __p - __s; _M_copy(__p, __s, __nleft); _M_copy(__p + __nleft, __p + __n, __n - __nleft); } return *this; } } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::iterator basic_string<_CharT, _Traits, _Alloc>:: erase(iterator __first, iterator __last) { _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last && __last <= _M_iend()); // NB: This isn't just an optimization (bail out early when // there is nothing to do, really), it's also a correctness // issue vs MT, see libstdc++/40518. const size_type __size = __last - __first; if (__size) { const size_type __pos = __first - _M_ibegin(); _M_mutate(__pos, __size, size_type(0)); _M_rep()->_M_set_leaked(); return iterator(_M_data() + __pos); } else return __first; } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: replace(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) { __glibcxx_requires_string_len(__s, __n2); _M_check(__pos, "basic_string::replace"); __n1 = _M_limit(__pos, __n1); _M_check_length(__n1, __n2, "basic_string::replace"); bool __left; if (_M_disjunct(__s) || _M_rep()->_M_is_shared()) return _M_replace_safe(__pos, __n1, __s, __n2); else if ((__left = __s + __n2 <= _M_data() + __pos) || _M_data() + __pos + __n1 <= __s) { // Work in-place: non-overlapping case. size_type __off = __s - _M_data(); __left ? __off : (__off += __n2 - __n1); _M_mutate(__pos, __n1, __n2); _M_copy(_M_data() + __pos, _M_data() + __off, __n2); return *this; } else { // Todo: overlapping case. const basic_string __tmp(__s, __n2); return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2); } } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>::_Rep:: _M_destroy(const _Alloc& __a) throw () { const size_type __size = sizeof(_Rep_base) + (this->_M_capacity + 1) * sizeof(_CharT); _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size); } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: _M_leak_hard() { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (_M_rep() == &_S_empty_rep()) return; #endif if (_M_rep()->_M_is_shared()) _M_mutate(0, 0, 0); _M_rep()->_M_set_leaked(); } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: _M_mutate(size_type __pos, size_type __len1, size_type __len2) { const size_type __old_size = this->size(); const size_type __new_size = __old_size + __len2 - __len1; const size_type __how_much = __old_size - __pos - __len1; if (__new_size > this->capacity() || _M_rep()->_M_is_shared()) { // Must reallocate. const allocator_type __a = get_allocator(); _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a); if (__pos) _M_copy(__r->_M_refdata(), _M_data(), __pos); if (__how_much) _M_copy(__r->_M_refdata() + __pos + __len2, _M_data() + __pos + __len1, __how_much); _M_rep()->_M_dispose(__a); _M_data(__r->_M_refdata()); } else if (__how_much && __len1 != __len2) { // Work in-place. _M_move(_M_data() + __pos + __len2, _M_data() + __pos + __len1, __how_much); } _M_rep()->_M_set_length_and_sharable(__new_size); } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: reserve(size_type __res) { if (__res != this->capacity() || _M_rep()->_M_is_shared()) { // Make sure we don't shrink below the current size if (__res < this->size()) __res = this->size(); const allocator_type __a = get_allocator(); _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size()); _M_rep()->_M_dispose(__a); _M_data(__tmp); } } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: swap(basic_string& __s) { if (_M_rep()->_M_is_leaked()) _M_rep()->_M_set_sharable(); if (__s._M_rep()->_M_is_leaked()) __s._M_rep()->_M_set_sharable(); if (this->get_allocator() == __s.get_allocator()) { _CharT* __tmp = _M_data(); _M_data(__s._M_data()); __s._M_data(__tmp); } // The code below can usually be optimized away. else { const basic_string __tmp1(_M_ibegin(), _M_iend(), __s.get_allocator()); const basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), this->get_allocator()); *this = __tmp2; __s = __tmp1; } } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::_Rep* basic_string<_CharT, _Traits, _Alloc>::_Rep:: _S_create(size_type __capacity, size_type __old_capacity, const _Alloc& __alloc) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 83. String::npos vs. string::max_size() if (__capacity > _S_max_size) __throw_length_error(__N("basic_string::_S_create")); // The standard places no restriction on allocating more memory // than is strictly needed within this layer at the moment or as // requested by an explicit application call to reserve(). // Many malloc implementations perform quite poorly when an // application attempts to allocate memory in a stepwise fashion // growing each allocation size by only 1 char. Additionally, // it makes little sense to allocate less linear memory than the // natural blocking size of the malloc implementation. // Unfortunately, we would need a somewhat low-level calculation // with tuned parameters to get this perfect for any particular // malloc implementation. Fortunately, generalizations about // common features seen among implementations seems to suffice. // __pagesize need not match the actual VM page size for good // results in practice, thus we pick a common value on the low // side. __malloc_header_size is an estimate of the amount of // overhead per memory allocation (in practice seen N * sizeof // (void*) where N is 0, 2 or 4). According to folklore, // picking this value on the high side is better than // low-balling it (especially when this algorithm is used with // malloc implementations that allocate memory blocks rounded up // to a size which is a power of 2). const size_type __pagesize = 4096; const size_type __malloc_header_size = 4 * sizeof(void*); // The below implements an exponential growth policy, necessary to // meet amortized linear time requirements of the library: see // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. // It's active for allocations requiring an amount of memory above // system pagesize. This is consistent with the requirements of the // standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) __capacity = 2 * __old_capacity; // NB: Need an array of char_type[__capacity], plus a terminating // null char_type() element, plus enough for the _Rep data structure. // Whew. Seemingly so needy, yet so elemental. size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); const size_type __adj_size = __size + __malloc_header_size; if (__adj_size > __pagesize && __capacity > __old_capacity) { const size_type __extra = __pagesize - __adj_size % __pagesize; __capacity += __extra / sizeof(_CharT); // Never allocate a string bigger than _S_max_size. if (__capacity > _S_max_size) __capacity = _S_max_size; __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep); } // NB: Might throw, but no worries about a leak, mate: _Rep() // does not throw. void* __place = _Raw_bytes_alloc(__alloc).allocate(__size); _Rep *__p = new (__place) _Rep; __p->_M_capacity = __capacity; // ABI compatibility - 3.4.x set in _S_create both // _M_refcount and _M_length. All callers of _S_create // in basic_string.tcc then set just _M_length. // In 4.0.x and later both _M_refcount and _M_length // are initialized in the callers, unfortunately we can // have 3.4.x compiled code with _S_create callers inlined // calling 4.0.x+ _S_create. __p->_M_set_sharable(); return __p; } template<typename _CharT, typename _Traits, typename _Alloc> _CharT* basic_string<_CharT, _Traits, _Alloc>::_Rep:: _M_clone(const _Alloc& __alloc, size_type __res) { // Requested capacity of the clone. const size_type __requested_cap = this->_M_length + __res; _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, __alloc); if (this->_M_length) _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length); __r->_M_set_length_and_sharable(this->_M_length); return __r->_M_refdata(); } template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: resize(size_type __n, _CharT __c) { const size_type __size = this->size(); _M_check_length(__size, __n, "basic_string::resize"); if (__size < __n) this->append(__n - __size, __c); else if (__n < __size) this->erase(__n); // else nothing (in particular, avoid calling _M_mutate() unnecessarily.) } template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InputIterator> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1, _InputIterator __k2, __false_type) { const basic_string __s(__k1, __k2); const size_type __n1 = __i2 - __i1; _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch"); return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), __s.size()); } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, _CharT __c) { _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); _M_mutate(__pos1, __n1, __n2); if (__n2) _M_assign(_M_data() + __pos1, __n2, __c); return *this; } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) { _M_mutate(__pos1, __n1, __n2); if (__n2) _M_copy(_M_data() + __pos1, __s, __n2); return *this; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: copy(_CharT* __s, size_type __n, size_type __pos) const { _M_check(__pos, "basic_string::copy"); __n = _M_limit(__pos, __n); __glibcxx_requires_string_len(__s, __n); if (__n) _M_copy(__s, _M_data() + __pos, __n); // 21.3.5.7 par 3: do not append null. (good.) return __n; } #endif // !_GLIBCXX_USE_CXX11_ABI template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc> operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { __glibcxx_requires_string(__lhs); typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __string_type::size_type __size_type; const __size_type __len = _Traits::length(__lhs); __string_type __str; __str.reserve(__len + __rhs.size()); __str.append(__lhs, __len); __str.append(__rhs); return __str; } template<typename _CharT, typename _Traits, typename _Alloc> basic_string<_CharT, _Traits, _Alloc> operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs) { typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __string_type::size_type __size_type; __string_type __str; const __size_type __len = __rhs.size(); __str.reserve(__len + 1); __str.append(__size_type(1), __lhs); __str.append(__rhs); return __str; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string_len(__s, __n); const size_type __size = this->size(); if (__n == 0) return __pos <= __size ? __pos : npos; if (__pos >= __size) return npos; const _CharT __elem0 = __s[0]; const _CharT* const __data = data(); const _CharT* __first = __data + __pos; const _CharT* const __last = __data + __size; size_type __len = __size - __pos; while (__len >= __n) { // Find the first occurrence of __elem0: __first = traits_type::find(__first, __len - __n + 1, __elem0); if (!__first) return npos; // Compare the full strings from the first occurrence of __elem0. // We already know that __first[0] == __s[0] but compare them again // anyway because __s is probably aligned, which helps memcmp. if (traits_type::compare(__first, __s, __n) == 0) return __first - __data; __len = __last - ++__first; } return npos; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT { size_type __ret = npos; const size_type __size = this->size(); if (__pos < __size) { const _CharT* __data = _M_data(); const size_type __n = __size - __pos; const _CharT* __p = traits_type::find(__data + __pos, __n, __c); if (__p) __ret = __p - __data; } return __ret; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: rfind(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string_len(__s, __n); const size_type __size = this->size(); if (__n <= __size) { __pos = std::min(size_type(__size - __n), __pos); const _CharT* __data = _M_data(); do { if (traits_type::compare(__data + __pos, __s, __n) == 0) return __pos; } while (__pos-- > 0); } return npos; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: rfind(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT { size_type __size = this->size(); if (__size) { if (--__size > __pos) __size = __pos; for (++__size; __size-- > 0; ) if (traits_type::eq(_M_data()[__size], __c)) return __size; } return npos; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string_len(__s, __n); for (; __n && __pos < this->size(); ++__pos) { const _CharT* __p = traits_type::find(__s, __n, _M_data()[__pos]); if (__p) return __pos; } return npos; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string_len(__s, __n); size_type __size = this->size(); if (__size && __n) { if (--__size > __pos) __size = __pos; do { if (traits_type::find(__s, __n, _M_data()[__size])) return __size; } while (__size-- != 0); } return npos; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string_len(__s, __n); for (; __pos < this->size(); ++__pos) if (!traits_type::find(__s, __n, _M_data()[__pos])) return __pos; return npos; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find_first_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT { for (; __pos < this->size(); ++__pos) if (!traits_type::eq(_M_data()[__pos], __c)) return __pos; return npos; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string_len(__s, __n); size_type __size = this->size(); if (__size) { if (--__size > __pos) __size = __pos; do { if (!traits_type::find(__s, __n, _M_data()[__size])) return __size; } while (__size--); } return npos; } template<typename _CharT, typename _Traits, typename _Alloc> typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: find_last_not_of(_CharT __c, size_type __pos) const _GLIBCXX_NOEXCEPT { size_type __size = this->size(); if (__size) { if (--__size > __pos) __size = __pos; do { if (!traits_type::eq(_M_data()[__size], __c)) return __size; } while (__size--); } return npos; } template<typename _CharT, typename _Traits, typename _Alloc> int basic_string<_CharT, _Traits, _Alloc>:: compare(size_type __pos, size_type __n, const basic_string& __str) const { _M_check(__pos, "basic_string::compare"); __n = _M_limit(__pos, __n); const size_type __osize = __str.size(); const size_type __len = std::min(__n, __osize); int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); if (!__r) __r = _S_compare(__n, __osize); return __r; } template<typename _CharT, typename _Traits, typename _Alloc> int basic_string<_CharT, _Traits, _Alloc>:: compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2) const { _M_check(__pos1, "basic_string::compare"); __str._M_check(__pos2, "basic_string::compare"); __n1 = _M_limit(__pos1, __n1); __n2 = __str._M_limit(__pos2, __n2); const size_type __len = std::min(__n1, __n2); int __r = traits_type::compare(_M_data() + __pos1, __str.data() + __pos2, __len); if (!__r) __r = _S_compare(__n1, __n2); return __r; } template<typename _CharT, typename _Traits, typename _Alloc> int basic_string<_CharT, _Traits, _Alloc>:: compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_string(__s); const size_type __size = this->size(); const size_type __osize = traits_type::length(__s); const size_type __len = std::min(__size, __osize); int __r = traits_type::compare(_M_data(), __s, __len); if (!__r) __r = _S_compare(__size, __osize); return __r; } template<typename _CharT, typename _Traits, typename _Alloc> int basic_string <_CharT, _Traits, _Alloc>:: compare(size_type __pos, size_type __n1, const _CharT* __s) const { __glibcxx_requires_string(__s); _M_check(__pos, "basic_string::compare"); __n1 = _M_limit(__pos, __n1); const size_type __osize = traits_type::length(__s); const size_type __len = std::min(__n1, __osize); int __r = traits_type::compare(_M_data() + __pos, __s, __len); if (!__r) __r = _S_compare(__n1, __osize); return __r; } template<typename _CharT, typename _Traits, typename _Alloc> int basic_string <_CharT, _Traits, _Alloc>:: compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const { __glibcxx_requires_string_len(__s, __n2); _M_check(__pos, "basic_string::compare"); __n1 = _M_limit(__pos, __n1); const size_type __len = std::min(__n1, __n2); int __r = traits_type::compare(_M_data() + __pos, __s, __len); if (!__r) __r = _S_compare(__n1, __n2); return __r; } // 21.3.7.9 basic_string::getline and operators template<typename _CharT, typename _Traits, typename _Alloc> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __in, basic_string<_CharT, _Traits, _Alloc>& __str) { typedef basic_istream<_CharT, _Traits> __istream_type; typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __istream_type::ios_base __ios_base; typedef typename __istream_type::int_type __int_type; typedef typename __string_type::size_type __size_type; typedef ctype<_CharT> __ctype_type; typedef typename __ctype_type::ctype_base __ctype_base; __size_type __extracted = 0; typename __ios_base::iostate __err = __ios_base::goodbit; typename __istream_type::sentry __cerb(__in, false); if (__cerb) { __try { // Avoid reallocation for common case. __str.erase(); _CharT __buf[128]; __size_type __len = 0; const streamsize __w = __in.width(); const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) : __str.max_size(); const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); const __int_type __eof = _Traits::eof(); __int_type __c = __in.rdbuf()->sgetc(); while (__extracted < __n && !_Traits::eq_int_type(__c, __eof) && !__ct.is(__ctype_base::space, _Traits::to_char_type(__c))) { if (__len == sizeof(__buf) / sizeof(_CharT)) { __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); __len = 0; } __buf[__len++] = _Traits::to_char_type(__c); ++__extracted; __c = __in.rdbuf()->snextc(); } __str.append(__buf, __len); if (_Traits::eq_int_type(__c, __eof)) __err |= __ios_base::eofbit; __in.width(0); } __catch(__cxxabiv1::__forced_unwind&) { __in._M_setstate(__ios_base::badbit); __throw_exception_again; } __catch(...) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 91. Description of operator>> and getline() for string<> // might cause endless loop __in._M_setstate(__ios_base::badbit); } } // 211. operator>>(istream&, string&) doesn't set failbit if (!__extracted) __err |= __ios_base::failbit; if (__err) __in.setstate(__err); return __in; } template<typename _CharT, typename _Traits, typename _Alloc> basic_istream<_CharT, _Traits>& getline(basic_istream<_CharT, _Traits>& __in, basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) { typedef basic_istream<_CharT, _Traits> __istream_type; typedef basic_string<_CharT, _Traits, _Alloc> __string_type; typedef typename __istream_type::ios_base __ios_base; typedef typename __istream_type::int_type __int_type; typedef typename __string_type::size_type __size_type; __size_type __extracted = 0; const __size_type __n = __str.max_size(); typename __ios_base::iostate __err = __ios_base::goodbit; typename __istream_type::sentry __cerb(__in, true); if (__cerb) { __try { __str.erase(); const __int_type __idelim = _Traits::to_int_type(__delim); const __int_type __eof = _Traits::eof(); __int_type __c = __in.rdbuf()->sgetc(); while (__extracted < __n && !_Traits::eq_int_type(__c, __eof) && !_Traits::eq_int_type(__c, __idelim)) { __str += _Traits::to_char_type(__c); ++__extracted; __c = __in.rdbuf()->snextc(); } if (_Traits::eq_int_type(__c, __eof)) __err |= __ios_base::eofbit; else if (_Traits::eq_int_type(__c, __idelim)) { ++__extracted; __in.rdbuf()->sbumpc(); } else __err |= __ios_base::failbit; } __catch(__cxxabiv1::__forced_unwind&) { __in._M_setstate(__ios_base::badbit); __throw_exception_again; } __catch(...) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 91. Description of operator>> and getline() for string<> // might cause endless loop __in._M_setstate(__ios_base::badbit); } } if (!__extracted) __err |= __ios_base::failbit; if (__err) __in.setstate(__err); return __in; } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE // The explicit instantiations definitions in src/c++11/string-inst.cc // are compiled as C++14, so the new C++17 members aren't instantiated. // Until those definitions are compiled as C++17 suppress the declaration, // so C++17 code will implicitly instantiate std::string and std::wstring // as needed. # if __cplusplus <= 201402L && _GLIBCXX_EXTERN_TEMPLATE > 0 extern template class basic_string<char>; # elif ! _GLIBCXX_USE_CXX11_ABI // Still need to prevent implicit instantiation of the COW empty rep, // to ensure the definition in libstdc++.so is unique (PR 86138). extern template basic_string<char>::size_type basic_string<char>::_Rep::_S_empty_rep_storage[]; # endif extern template basic_istream<char>& operator>>(basic_istream<char>&, string&); extern template basic_ostream<char>& operator<<(basic_ostream<char>&, const string&); extern template basic_istream<char>& getline(basic_istream<char>&, string&, char); extern template basic_istream<char>& getline(basic_istream<char>&, string&); #ifdef _GLIBCXX_USE_WCHAR_T # if __cplusplus <= 201402L && _GLIBCXX_EXTERN_TEMPLATE > 0 extern template class basic_string<wchar_t>; # elif ! _GLIBCXX_USE_CXX11_ABI extern template basic_string<wchar_t>::size_type basic_string<wchar_t>::_Rep::_S_empty_rep_storage[]; # endif extern template basic_istream<wchar_t>& operator>>(basic_istream<wchar_t>&, wstring&); extern template basic_ostream<wchar_t>& operator<<(basic_ostream<wchar_t>&, const wstring&); extern template basic_istream<wchar_t>& getline(basic_istream<wchar_t>&, wstring&, wchar_t); extern template basic_istream<wchar_t>& getline(basic_istream<wchar_t>&, wstring&); #endif // _GLIBCXX_USE_WCHAR_T #endif // _GLIBCXX_EXTERN_TEMPLATE _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/locale_facets_nonio.tcc 0000644 00000130340 15146341150 0012706 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 2007-2018 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/locale_facets_nonio.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ #ifndef _LOCALE_FACETS_NONIO_TCC #define _LOCALE_FACETS_NONIO_TCC 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, bool _Intl> struct __use_cache<__moneypunct_cache<_CharT, _Intl> > { const __moneypunct_cache<_CharT, _Intl>* operator() (const locale& __loc) const { const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); const locale::facet** __caches = __loc._M_impl->_M_caches; if (!__caches[__i]) { __moneypunct_cache<_CharT, _Intl>* __tmp = 0; __try { __tmp = new __moneypunct_cache<_CharT, _Intl>; __tmp->_M_cache(__loc); } __catch(...) { delete __tmp; __throw_exception_again; } __loc._M_impl->_M_install_cache(__tmp, __i); } return static_cast< const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); } }; template<typename _CharT, bool _Intl> void __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) { const moneypunct<_CharT, _Intl>& __mp = use_facet<moneypunct<_CharT, _Intl> >(__loc); _M_decimal_point = __mp.decimal_point(); _M_thousands_sep = __mp.thousands_sep(); _M_frac_digits = __mp.frac_digits(); char* __grouping = 0; _CharT* __curr_symbol = 0; _CharT* __positive_sign = 0; _CharT* __negative_sign = 0; __try { const string& __g = __mp.grouping(); _M_grouping_size = __g.size(); __grouping = new char[_M_grouping_size]; __g.copy(__grouping, _M_grouping_size); _M_use_grouping = (_M_grouping_size && static_cast<signed char>(__grouping[0]) > 0 && (__grouping[0] != __gnu_cxx::__numeric_traits<char>::__max)); const basic_string<_CharT>& __cs = __mp.curr_symbol(); _M_curr_symbol_size = __cs.size(); __curr_symbol = new _CharT[_M_curr_symbol_size]; __cs.copy(__curr_symbol, _M_curr_symbol_size); const basic_string<_CharT>& __ps = __mp.positive_sign(); _M_positive_sign_size = __ps.size(); __positive_sign = new _CharT[_M_positive_sign_size]; __ps.copy(__positive_sign, _M_positive_sign_size); const basic_string<_CharT>& __ns = __mp.negative_sign(); _M_negative_sign_size = __ns.size(); __negative_sign = new _CharT[_M_negative_sign_size]; __ns.copy(__negative_sign, _M_negative_sign_size); _M_pos_format = __mp.pos_format(); _M_neg_format = __mp.neg_format(); const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); __ct.widen(money_base::_S_atoms, money_base::_S_atoms + money_base::_S_end, _M_atoms); _M_grouping = __grouping; _M_curr_symbol = __curr_symbol; _M_positive_sign = __positive_sign; _M_negative_sign = __negative_sign; _M_allocated = true; } __catch(...) { delete [] __grouping; delete [] __curr_symbol; delete [] __positive_sign; delete [] __negative_sign; __throw_exception_again; } } _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 template<typename _CharT, typename _InIter> template<bool _Intl> _InIter money_get<_CharT, _InIter>:: _M_extract(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, string& __units) const { typedef char_traits<_CharT> __traits_type; typedef typename string_type::size_type size_type; typedef money_base::part part; typedef __moneypunct_cache<_CharT, _Intl> __cache_type; const locale& __loc = __io._M_getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); __use_cache<__cache_type> __uc; const __cache_type* __lc = __uc(__loc); const char_type* __lit = __lc->_M_atoms; // Deduced sign. bool __negative = false; // Sign size. size_type __sign_size = 0; // True if sign is mandatory. const bool __mandatory_sign = (__lc->_M_positive_sign_size && __lc->_M_negative_sign_size); // String of grouping info from thousands_sep plucked from __units. string __grouping_tmp; if (__lc->_M_use_grouping) __grouping_tmp.reserve(32); // Last position before the decimal point. int __last_pos = 0; // Separator positions, then, possibly, fractional digits. int __n = 0; // If input iterator is in a valid state. bool __testvalid = true; // Flag marking when a decimal point is found. bool __testdecfound = false; // The tentative returned string is stored here. string __res; __res.reserve(32); const char_type* __lit_zero = __lit + money_base::_S_zero; const money_base::pattern __p = __lc->_M_neg_format; for (int __i = 0; __i < 4 && __testvalid; ++__i) { const part __which = static_cast<part>(__p.field[__i]); switch (__which) { case money_base::symbol: // According to 22.2.6.1.2, p2, symbol is required // if (__io.flags() & ios_base::showbase), otherwise // is optional and consumed only if other characters // are needed to complete the format. if (__io.flags() & ios_base::showbase || __sign_size > 1 || __i == 0 || (__i == 1 && (__mandatory_sign || (static_cast<part>(__p.field[0]) == money_base::sign) || (static_cast<part>(__p.field[2]) == money_base::space))) || (__i == 2 && ((static_cast<part>(__p.field[3]) == money_base::value) || (__mandatory_sign && (static_cast<part>(__p.field[3]) == money_base::sign))))) { const size_type __len = __lc->_M_curr_symbol_size; size_type __j = 0; for (; __beg != __end && __j < __len && *__beg == __lc->_M_curr_symbol[__j]; ++__beg, (void)++__j); if (__j != __len && (__j || __io.flags() & ios_base::showbase)) __testvalid = false; } break; case money_base::sign: // Sign might not exist, or be more than one character long. if (__lc->_M_positive_sign_size && __beg != __end && *__beg == __lc->_M_positive_sign[0]) { __sign_size = __lc->_M_positive_sign_size; ++__beg; } else if (__lc->_M_negative_sign_size && __beg != __end && *__beg == __lc->_M_negative_sign[0]) { __negative = true; __sign_size = __lc->_M_negative_sign_size; ++__beg; } else if (__lc->_M_positive_sign_size && !__lc->_M_negative_sign_size) // "... if no sign is detected, the result is given the sign // that corresponds to the source of the empty string" __negative = true; else if (__mandatory_sign) __testvalid = false; break; case money_base::value: // Extract digits, remove and stash away the // grouping of found thousands separators. for (; __beg != __end; ++__beg) { const char_type __c = *__beg; const char_type* __q = __traits_type::find(__lit_zero, 10, __c); if (__q != 0) { __res += money_base::_S_atoms[__q - __lit]; ++__n; } else if (__c == __lc->_M_decimal_point && !__testdecfound) { if (__lc->_M_frac_digits <= 0) break; __last_pos = __n; __n = 0; __testdecfound = true; } else if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep && !__testdecfound) { if (__n) { // Mark position for later analysis. __grouping_tmp += static_cast<char>(__n); __n = 0; } else { __testvalid = false; break; } } else break; } if (__res.empty()) __testvalid = false; break; case money_base::space: // At least one space is required. if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) ++__beg; else __testvalid = false; // fallthrough case money_base::none: // Only if not at the end of the pattern. if (__i != 3) for (; __beg != __end && __ctype.is(ctype_base::space, *__beg); ++__beg); break; } } // Need to get the rest of the sign characters, if they exist. if (__sign_size > 1 && __testvalid) { const char_type* __sign = __negative ? __lc->_M_negative_sign : __lc->_M_positive_sign; size_type __i = 1; for (; __beg != __end && __i < __sign_size && *__beg == __sign[__i]; ++__beg, (void)++__i); if (__i != __sign_size) __testvalid = false; } if (__testvalid) { // Strip leading zeros. if (__res.size() > 1) { const size_type __first = __res.find_first_not_of('0'); const bool __only_zeros = __first == string::npos; if (__first) __res.erase(0, __only_zeros ? __res.size() - 1 : __first); } // 22.2.6.1.2, p4 if (__negative && __res[0] != '0') __res.insert(__res.begin(), '-'); // Test for grouping fidelity. if (__grouping_tmp.size()) { // Add the ending grouping. __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos : __n); if (!std::__verify_grouping(__lc->_M_grouping, __lc->_M_grouping_size, __grouping_tmp)) __err |= ios_base::failbit; } // Iff not enough digits were supplied after the decimal-point. if (__testdecfound && __n != __lc->_M_frac_digits) __testvalid = false; } // Iff valid sequence is not recognized. if (!__testvalid) __err |= ios_base::failbit; else __units.swap(__res); // Iff no more characters are available. if (__beg == __end) __err |= ios_base::eofbit; return __beg; } #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ && _GLIBCXX_USE_CXX11_ABI == 0 template<typename _CharT, typename _InIter> _InIter money_get<_CharT, _InIter>:: __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, double& __units) const { string __str; __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) : _M_extract<false>(__beg, __end, __io, __err, __str); std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); return __beg; } #endif template<typename _CharT, typename _InIter> _InIter money_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, long double& __units) const { string __str; __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) : _M_extract<false>(__beg, __end, __io, __err, __str); std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); return __beg; } template<typename _CharT, typename _InIter> _InIter money_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, string_type& __digits) const { typedef typename string::size_type size_type; const locale& __loc = __io._M_getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); string __str; __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) : _M_extract<false>(__beg, __end, __io, __err, __str); const size_type __len = __str.size(); if (__len) { __digits.resize(__len); __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]); } return __beg; } template<typename _CharT, typename _OutIter> template<bool _Intl> _OutIter money_put<_CharT, _OutIter>:: _M_insert(iter_type __s, ios_base& __io, char_type __fill, const string_type& __digits) const { typedef typename string_type::size_type size_type; typedef money_base::part part; typedef __moneypunct_cache<_CharT, _Intl> __cache_type; const locale& __loc = __io._M_getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); __use_cache<__cache_type> __uc; const __cache_type* __lc = __uc(__loc); const char_type* __lit = __lc->_M_atoms; // Determine if negative or positive formats are to be used, and // discard leading negative_sign if it is present. const char_type* __beg = __digits.data(); money_base::pattern __p; const char_type* __sign; size_type __sign_size; if (!(*__beg == __lit[money_base::_S_minus])) { __p = __lc->_M_pos_format; __sign = __lc->_M_positive_sign; __sign_size = __lc->_M_positive_sign_size; } else { __p = __lc->_M_neg_format; __sign = __lc->_M_negative_sign; __sign_size = __lc->_M_negative_sign_size; if (__digits.size()) ++__beg; } // Look for valid numbers in the ctype facet within input digits. size_type __len = __ctype.scan_not(ctype_base::digit, __beg, __beg + __digits.size()) - __beg; if (__len) { // Assume valid input, and attempt to format. // Break down input numbers into base components, as follows: // final_value = grouped units + (decimal point) + (digits) string_type __value; __value.reserve(2 * __len); // Add thousands separators to non-decimal digits, per // grouping rules. long __paddec = __len - __lc->_M_frac_digits; if (__paddec > 0) { if (__lc->_M_frac_digits < 0) __paddec = __len; if (__lc->_M_grouping_size) { __value.assign(2 * __paddec, char_type()); _CharT* __vend = std::__add_grouping(&__value[0], __lc->_M_thousands_sep, __lc->_M_grouping, __lc->_M_grouping_size, __beg, __beg + __paddec); __value.erase(__vend - &__value[0]); } else __value.assign(__beg, __paddec); } // Deal with decimal point, decimal digits. if (__lc->_M_frac_digits > 0) { __value += __lc->_M_decimal_point; if (__paddec >= 0) __value.append(__beg + __paddec, __lc->_M_frac_digits); else { // Have to pad zeros in the decimal position. __value.append(-__paddec, __lit[money_base::_S_zero]); __value.append(__beg, __len); } } // Calculate length of resulting string. const ios_base::fmtflags __f = __io.flags() & ios_base::adjustfield; __len = __value.size() + __sign_size; __len += ((__io.flags() & ios_base::showbase) ? __lc->_M_curr_symbol_size : 0); string_type __res; __res.reserve(2 * __len); const size_type __width = static_cast<size_type>(__io.width()); const bool __testipad = (__f == ios_base::internal && __len < __width); // Fit formatted digits into the required pattern. for (int __i = 0; __i < 4; ++__i) { const part __which = static_cast<part>(__p.field[__i]); switch (__which) { case money_base::symbol: if (__io.flags() & ios_base::showbase) __res.append(__lc->_M_curr_symbol, __lc->_M_curr_symbol_size); break; case money_base::sign: // Sign might not exist, or be more than one // character long. In that case, add in the rest // below. if (__sign_size) __res += __sign[0]; break; case money_base::value: __res += __value; break; case money_base::space: // At least one space is required, but if internal // formatting is required, an arbitrary number of // fill spaces will be necessary. if (__testipad) __res.append(__width - __len, __fill); else __res += __fill; break; case money_base::none: if (__testipad) __res.append(__width - __len, __fill); break; } } // Special case of multi-part sign parts. if (__sign_size > 1) __res.append(__sign + 1, __sign_size - 1); // Pad, if still necessary. __len = __res.size(); if (__width > __len) { if (__f == ios_base::left) // After. __res.append(__width - __len, __fill); else // Before. __res.insert(0, __width - __len, __fill); __len = __width; } // Write resulting, fully-formatted string to output iterator. __s = std::__write(__s, __res.data(), __len); } __io.width(0); return __s; } #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ && _GLIBCXX_USE_CXX11_ABI == 0 template<typename _CharT, typename _OutIter> _OutIter money_put<_CharT, _OutIter>:: __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, double __units) const { return this->do_put(__s, __intl, __io, __fill, (long double) __units); } #endif template<typename _CharT, typename _OutIter> _OutIter money_put<_CharT, _OutIter>:: do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, long double __units) const { const locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); #if _GLIBCXX_USE_C99_STDIO // First try a buffer perhaps big enough. int __cs_size = 64; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 328. Bad sprintf format modifier in money_put<>::do_put() int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, "%.*Lf", 0, __units); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast<char*>(__builtin_alloca(__cs_size)); __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, "%.*Lf", 0, __units); } #else // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. const int __cs_size = __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 3; char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 0, __units); #endif string_type __digits(__len, char_type()); __ctype.widen(__cs, __cs + __len, &__digits[0]); return __intl ? _M_insert<true>(__s, __io, __fill, __digits) : _M_insert<false>(__s, __io, __fill, __digits); } template<typename _CharT, typename _OutIter> _OutIter money_put<_CharT, _OutIter>:: do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, const string_type& __digits) const { return __intl ? _M_insert<true>(__s, __io, __fill, __digits) : _M_insert<false>(__s, __io, __fill, __digits); } _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 // NB: Not especially useful. Without an ios_base object or some // kind of locale reference, we are left clawing at the air where // the side of the mountain used to be... template<typename _CharT, typename _InIter> time_base::dateorder time_get<_CharT, _InIter>::do_date_order() const { return time_base::no_order; } // Expand a strftime format string and parse it. E.g., do_get_date() may // pass %m/%d/%Y => extracted characters. template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm, const _CharT* __format) const { const locale& __loc = __io._M_getloc(); const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); const size_t __len = char_traits<_CharT>::length(__format); ios_base::iostate __tmperr = ios_base::goodbit; size_t __i = 0; for (; __beg != __end && __i < __len && !__tmperr; ++__i) { if (__ctype.narrow(__format[__i], 0) == '%') { // Verify valid formatting code, attempt to extract. char __c = __ctype.narrow(__format[++__i], 0); int __mem = 0; if (__c == 'E' || __c == 'O') __c = __ctype.narrow(__format[++__i], 0); switch (__c) { const char* __cs; _CharT __wcs[10]; case 'a': // Abbreviated weekday name [tm_wday] const char_type* __days1[7]; __tp._M_days_abbreviated(__days1); __beg = _M_extract_name(__beg, __end, __mem, __days1, 7, __io, __tmperr); if (!__tmperr) __tm->tm_wday = __mem; break; case 'A': // Weekday name [tm_wday]. const char_type* __days2[7]; __tp._M_days(__days2); __beg = _M_extract_name(__beg, __end, __mem, __days2, 7, __io, __tmperr); if (!__tmperr) __tm->tm_wday = __mem; break; case 'h': case 'b': // Abbreviated month name [tm_mon] const char_type* __months1[12]; __tp._M_months_abbreviated(__months1); __beg = _M_extract_name(__beg, __end, __mem, __months1, 12, __io, __tmperr); if (!__tmperr) __tm->tm_mon = __mem; break; case 'B': // Month name [tm_mon]. const char_type* __months2[12]; __tp._M_months(__months2); __beg = _M_extract_name(__beg, __end, __mem, __months2, 12, __io, __tmperr); if (!__tmperr) __tm->tm_mon = __mem; break; case 'c': // Default time and date representation. const char_type* __dt[2]; __tp._M_date_time_formats(__dt); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, __tm, __dt[0]); break; case 'd': // Day [01, 31]. [tm_mday] __beg = _M_extract_num(__beg, __end, __mem, 1, 31, 2, __io, __tmperr); if (!__tmperr) __tm->tm_mday = __mem; break; case 'e': // Day [1, 31], with single digits preceded by // space. [tm_mday] if (__ctype.is(ctype_base::space, *__beg)) __beg = _M_extract_num(++__beg, __end, __mem, 1, 9, 1, __io, __tmperr); else __beg = _M_extract_num(__beg, __end, __mem, 10, 31, 2, __io, __tmperr); if (!__tmperr) __tm->tm_mday = __mem; break; case 'D': // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] __cs = "%m/%d/%y"; __ctype.widen(__cs, __cs + 9, __wcs); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, __tm, __wcs); break; case 'H': // Hour [00, 23]. [tm_hour] __beg = _M_extract_num(__beg, __end, __mem, 0, 23, 2, __io, __tmperr); if (!__tmperr) __tm->tm_hour = __mem; break; case 'I': // Hour [01, 12]. [tm_hour] __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, __io, __tmperr); if (!__tmperr) __tm->tm_hour = __mem; break; case 'm': // Month [01, 12]. [tm_mon] __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, __io, __tmperr); if (!__tmperr) __tm->tm_mon = __mem - 1; break; case 'M': // Minute [00, 59]. [tm_min] __beg = _M_extract_num(__beg, __end, __mem, 0, 59, 2, __io, __tmperr); if (!__tmperr) __tm->tm_min = __mem; break; case 'n': if (__ctype.narrow(*__beg, 0) == '\n') ++__beg; else __tmperr |= ios_base::failbit; break; case 'R': // Equivalent to (%H:%M). __cs = "%H:%M"; __ctype.widen(__cs, __cs + 6, __wcs); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, __tm, __wcs); break; case 'S': // Seconds. [tm_sec] // [00, 60] in C99 (one leap-second), [00, 61] in C89. #if _GLIBCXX_USE_C99 __beg = _M_extract_num(__beg, __end, __mem, 0, 60, 2, #else __beg = _M_extract_num(__beg, __end, __mem, 0, 61, 2, #endif __io, __tmperr); if (!__tmperr) __tm->tm_sec = __mem; break; case 't': if (__ctype.narrow(*__beg, 0) == '\t') ++__beg; else __tmperr |= ios_base::failbit; break; case 'T': // Equivalent to (%H:%M:%S). __cs = "%H:%M:%S"; __ctype.widen(__cs, __cs + 9, __wcs); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, __tm, __wcs); break; case 'x': // Locale's date. const char_type* __dates[2]; __tp._M_date_formats(__dates); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, __tm, __dates[0]); break; case 'X': // Locale's time. const char_type* __times[2]; __tp._M_time_formats(__times); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, __tm, __times[0]); break; case 'y': case 'C': // C99 // Two digit year. case 'Y': // Year [1900). // NB: We parse either two digits, implicitly years since // 1900, or 4 digits, full year. In both cases we can // reconstruct [tm_year]. See also libstdc++/26701. __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, __io, __tmperr); if (!__tmperr) __tm->tm_year = __mem < 0 ? __mem + 100 : __mem - 1900; break; case 'Z': // Timezone info. if (__ctype.is(ctype_base::upper, *__beg)) { int __tmp; __beg = _M_extract_name(__beg, __end, __tmp, __timepunct_cache<_CharT>::_S_timezones, 14, __io, __tmperr); // GMT requires special effort. if (__beg != __end && !__tmperr && __tmp == 0 && (*__beg == __ctype.widen('-') || *__beg == __ctype.widen('+'))) { __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, __io, __tmperr); __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, __io, __tmperr); } } else __tmperr |= ios_base::failbit; break; default: // Not recognized. __tmperr |= ios_base::failbit; } } else { // Verify format and input match, extract and discard. if (__format[__i] == *__beg) ++__beg; else __tmperr |= ios_base::failbit; } } if (__tmperr || __i != __len) __err |= ios_base::failbit; return __beg; } template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: _M_extract_num(iter_type __beg, iter_type __end, int& __member, int __min, int __max, size_t __len, ios_base& __io, ios_base::iostate& __err) const { const locale& __loc = __io._M_getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); // As-is works for __len = 1, 2, 4, the values actually used. int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); ++__min; size_t __i = 0; int __value = 0; for (; __beg != __end && __i < __len; ++__beg, (void)++__i) { const char __c = __ctype.narrow(*__beg, '*'); if (__c >= '0' && __c <= '9') { __value = __value * 10 + (__c - '0'); const int __valuec = __value * __mult; if (__valuec > __max || __valuec + __mult < __min) break; __mult /= 10; } else break; } if (__i == __len) __member = __value; // Special encoding for do_get_year, 'y', and 'Y' above. else if (__len == 4 && __i == 2) __member = __value - 100; else __err |= ios_base::failbit; return __beg; } // Assumptions: // All elements in __names are unique. template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: _M_extract_name(iter_type __beg, iter_type __end, int& __member, const _CharT** __names, size_t __indexlen, ios_base& __io, ios_base::iostate& __err) const { typedef char_traits<_CharT> __traits_type; const locale& __loc = __io._M_getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) * __indexlen)); size_t __nmatches = 0; size_t __pos = 0; bool __testvalid = true; const char_type* __name; // Look for initial matches. // NB: Some of the locale data is in the form of all lowercase // names, and some is in the form of initially-capitalized // names. Look for both. if (__beg != __end) { const char_type __c = *__beg; for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) if (__c == __names[__i1][0] || __c == __ctype.toupper(__names[__i1][0])) __matches[__nmatches++] = __i1; } while (__nmatches > 1) { // Find smallest matching string. size_t __minlen = __traits_type::length(__names[__matches[0]]); for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) __minlen = std::min(__minlen, __traits_type::length(__names[__matches[__i2]])); ++__beg; ++__pos; if (__pos < __minlen && __beg != __end) for (size_t __i3 = 0; __i3 < __nmatches;) { __name = __names[__matches[__i3]]; if (!(__name[__pos] == *__beg)) __matches[__i3] = __matches[--__nmatches]; else ++__i3; } else break; } if (__nmatches == 1) { // Make sure found name is completely extracted. ++__beg; ++__pos; __name = __names[__matches[0]]; const size_t __len = __traits_type::length(__name); while (__pos < __len && __beg != __end && __name[__pos] == *__beg) ++__beg, (void)++__pos; if (__len == __pos) __member = __matches[0]; else __testvalid = false; } else __testvalid = false; if (!__testvalid) __err |= ios_base::failbit; return __beg; } template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: _M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member, const _CharT** __names, size_t __indexlen, ios_base& __io, ios_base::iostate& __err) const { typedef char_traits<_CharT> __traits_type; const locale& __loc = __io._M_getloc(); const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); int* __matches = static_cast<int*>(__builtin_alloca(2 * sizeof(int) * __indexlen)); size_t __nmatches = 0; size_t* __matches_lengths = 0; size_t __pos = 0; if (__beg != __end) { const char_type __c = *__beg; for (size_t __i = 0; __i < 2 * __indexlen; ++__i) if (__c == __names[__i][0] || __c == __ctype.toupper(__names[__i][0])) __matches[__nmatches++] = __i; } if (__nmatches) { ++__beg; ++__pos; __matches_lengths = static_cast<size_t*>(__builtin_alloca(sizeof(size_t) * __nmatches)); for (size_t __i = 0; __i < __nmatches; ++__i) __matches_lengths[__i] = __traits_type::length(__names[__matches[__i]]); } for (; __beg != __end; ++__beg, (void)++__pos) { size_t __nskipped = 0; const char_type __c = *__beg; for (size_t __i = 0; __i < __nmatches;) { const char_type* __name = __names[__matches[__i]]; if (__pos >= __matches_lengths[__i]) ++__nskipped, ++__i; else if (!(__name[__pos] == __c)) { --__nmatches; __matches[__i] = __matches[__nmatches]; __matches_lengths[__i] = __matches_lengths[__nmatches]; } else ++__i; } if (__nskipped == __nmatches) break; } if ((__nmatches == 1 && __matches_lengths[0] == __pos) || (__nmatches == 2 && (__matches_lengths[0] == __pos || __matches_lengths[1] == __pos))) __member = (__matches[0] >= __indexlen ? __matches[0] - __indexlen : __matches[0]); else __err |= ios_base::failbit; return __beg; } template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: do_get_time(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { const locale& __loc = __io._M_getloc(); const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); const char_type* __times[2]; __tp._M_time_formats(__times); __beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __times[0]); if (__beg == __end) __err |= ios_base::eofbit; return __beg; } template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: do_get_date(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { const locale& __loc = __io._M_getloc(); const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); const char_type* __dates[2]; __tp._M_date_formats(__dates); __beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __dates[0]); if (__beg == __end) __err |= ios_base::eofbit; return __beg; } template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { const locale& __loc = __io._M_getloc(); const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); const char_type* __days[14]; __tp._M_days_abbreviated(__days); __tp._M_days(__days + 7); int __tmpwday; ios_base::iostate __tmperr = ios_base::goodbit; __beg = _M_extract_wday_or_month(__beg, __end, __tmpwday, __days, 7, __io, __tmperr); if (!__tmperr) __tm->tm_wday = __tmpwday; else __err |= ios_base::failbit; if (__beg == __end) __err |= ios_base::eofbit; return __beg; } template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: do_get_monthname(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { const locale& __loc = __io._M_getloc(); const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); const char_type* __months[24]; __tp._M_months_abbreviated(__months); __tp._M_months(__months + 12); int __tmpmon; ios_base::iostate __tmperr = ios_base::goodbit; __beg = _M_extract_wday_or_month(__beg, __end, __tmpmon, __months, 12, __io, __tmperr); if (!__tmperr) __tm->tm_mon = __tmpmon; else __err |= ios_base::failbit; if (__beg == __end) __err |= ios_base::eofbit; return __beg; } template<typename _CharT, typename _InIter> _InIter time_get<_CharT, _InIter>:: do_get_year(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { int __tmpyear; ios_base::iostate __tmperr = ios_base::goodbit; __beg = _M_extract_num(__beg, __end, __tmpyear, 0, 9999, 4, __io, __tmperr); if (!__tmperr) __tm->tm_year = __tmpyear < 0 ? __tmpyear + 100 : __tmpyear - 1900; else __err |= ios_base::failbit; if (__beg == __end) __err |= ios_base::eofbit; return __beg; } #if __cplusplus >= 201103L template<typename _CharT, typename _InIter> inline _InIter time_get<_CharT, _InIter>:: get(iter_type __s, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm, const char_type* __fmt, const char_type* __fmtend) const { const locale& __loc = __io._M_getloc(); ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); __err = ios_base::goodbit; while (__fmt != __fmtend && __err == ios_base::goodbit) { if (__s == __end) { __err = ios_base::eofbit | ios_base::failbit; break; } else if (__ctype.narrow(*__fmt, 0) == '%') { char __format; char __mod = 0; if (++__fmt == __fmtend) { __err = ios_base::failbit; break; } const char __c = __ctype.narrow(*__fmt, 0); if (__c != 'E' && __c != 'O') __format = __c; else if (++__fmt != __fmtend) { __mod = __c; __format = __ctype.narrow(*__fmt, 0); } else { __err = ios_base::failbit; break; } __s = this->do_get(__s, __end, __io, __err, __tm, __format, __mod); ++__fmt; } else if (__ctype.is(ctype_base::space, *__fmt)) { ++__fmt; while (__fmt != __fmtend && __ctype.is(ctype_base::space, *__fmt)) ++__fmt; while (__s != __end && __ctype.is(ctype_base::space, *__s)) ++__s; } // TODO real case-insensitive comparison else if (__ctype.tolower(*__s) == __ctype.tolower(*__fmt) || __ctype.toupper(*__s) == __ctype.toupper(*__fmt)) { ++__s; ++__fmt; } else { __err = ios_base::failbit; break; } } return __s; } template<typename _CharT, typename _InIter> inline _InIter time_get<_CharT, _InIter>:: do_get(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm, char __format, char __mod) const { const locale& __loc = __io._M_getloc(); ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); __err = ios_base::goodbit; char_type __fmt[4]; __fmt[0] = __ctype.widen('%'); if (!__mod) { __fmt[1] = __format; __fmt[2] = char_type(); } else { __fmt[1] = __mod; __fmt[2] = __format; __fmt[3] = char_type(); } __beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __fmt); if (__beg == __end) __err |= ios_base::eofbit; return __beg; } #endif // __cplusplus >= 201103L template<typename _CharT, typename _OutIter> _OutIter time_put<_CharT, _OutIter>:: put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, const _CharT* __beg, const _CharT* __end) const { const locale& __loc = __io._M_getloc(); ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); for (; __beg != __end; ++__beg) if (__ctype.narrow(*__beg, 0) != '%') { *__s = *__beg; ++__s; } else if (++__beg != __end) { char __format; char __mod = 0; const char __c = __ctype.narrow(*__beg, 0); if (__c != 'E' && __c != 'O') __format = __c; else if (++__beg != __end) { __mod = __c; __format = __ctype.narrow(*__beg, 0); } else break; __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); } else break; return __s; } template<typename _CharT, typename _OutIter> _OutIter time_put<_CharT, _OutIter>:: do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, char __format, char __mod) const { const locale& __loc = __io._M_getloc(); ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); // NB: This size is arbitrary. Should this be a data member, // initialized at construction? const size_t __maxlen = 128; char_type __res[__maxlen]; // NB: In IEE 1003.1-200x, and perhaps other locale models, it // is possible that the format character will be longer than one // character. Possibilities include 'E' or 'O' followed by a // format character: if __mod is not the default argument, assume // it's a valid modifier. char_type __fmt[4]; __fmt[0] = __ctype.widen('%'); if (!__mod) { __fmt[1] = __format; __fmt[2] = char_type(); } else { __fmt[1] = __mod; __fmt[2] = __format; __fmt[3] = char_type(); } __tp._M_put(__res, __maxlen, __fmt, __tm); // Write resulting, fully-formatted string to output iterator. return std::__write(__s, __res, char_traits<char_type>::length(__res)); } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template class moneypunct<char, false>; extern template class moneypunct<char, true>; extern template class moneypunct_byname<char, false>; extern template class moneypunct_byname<char, true>; extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get<char>; extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put<char>; extern template class __timepunct<char>; extern template class time_put<char>; extern template class time_put_byname<char>; extern template class time_get<char>; extern template class time_get_byname<char>; extern template class messages<char>; extern template class messages_byname<char>; extern template const moneypunct<char, true>& use_facet<moneypunct<char, true> >(const locale&); extern template const moneypunct<char, false>& use_facet<moneypunct<char, false> >(const locale&); extern template const money_put<char>& use_facet<money_put<char> >(const locale&); extern template const money_get<char>& use_facet<money_get<char> >(const locale&); extern template const __timepunct<char>& use_facet<__timepunct<char> >(const locale&); extern template const time_put<char>& use_facet<time_put<char> >(const locale&); extern template const time_get<char>& use_facet<time_get<char> >(const locale&); extern template const messages<char>& use_facet<messages<char> >(const locale&); extern template bool has_facet<moneypunct<char> >(const locale&); extern template bool has_facet<money_put<char> >(const locale&); extern template bool has_facet<money_get<char> >(const locale&); extern template bool has_facet<__timepunct<char> >(const locale&); extern template bool has_facet<time_put<char> >(const locale&); extern template bool has_facet<time_get<char> >(const locale&); extern template bool has_facet<messages<char> >(const locale&); #ifdef _GLIBCXX_USE_WCHAR_T extern template class moneypunct<wchar_t, false>; extern template class moneypunct<wchar_t, true>; extern template class moneypunct_byname<wchar_t, false>; extern template class moneypunct_byname<wchar_t, true>; extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get<wchar_t>; extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put<wchar_t>; extern template class __timepunct<wchar_t>; extern template class time_put<wchar_t>; extern template class time_put_byname<wchar_t>; extern template class time_get<wchar_t>; extern template class time_get_byname<wchar_t>; extern template class messages<wchar_t>; extern template class messages_byname<wchar_t>; extern template const moneypunct<wchar_t, true>& use_facet<moneypunct<wchar_t, true> >(const locale&); extern template const moneypunct<wchar_t, false>& use_facet<moneypunct<wchar_t, false> >(const locale&); extern template const money_put<wchar_t>& use_facet<money_put<wchar_t> >(const locale&); extern template const money_get<wchar_t>& use_facet<money_get<wchar_t> >(const locale&); extern template const __timepunct<wchar_t>& use_facet<__timepunct<wchar_t> >(const locale&); extern template const time_put<wchar_t>& use_facet<time_put<wchar_t> >(const locale&); extern template const time_get<wchar_t>& use_facet<time_get<wchar_t> >(const locale&); extern template const messages<wchar_t>& use_facet<messages<wchar_t> >(const locale&); extern template bool has_facet<moneypunct<wchar_t> >(const locale&); extern template bool has_facet<money_put<wchar_t> >(const locale&); extern template bool has_facet<money_get<wchar_t> >(const locale&); extern template bool has_facet<__timepunct<wchar_t> >(const locale&); extern template bool has_facet<time_put<wchar_t> >(const locale&); extern template bool has_facet<time_get<wchar_t> >(const locale&); extern template bool has_facet<messages<wchar_t> >(const locale&); #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/uses_allocator.h 0000644 00000014575 15146341150 0011430 0 ustar 00 // Uses-allocator Construction -*- C++ -*- // Copyright (C) 2010-2018 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/>. #ifndef _USES_ALLOCATOR_H #define _USES_ALLOCATOR_H 1 #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <type_traits> #include <bits/move.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __erased_type { }; template<typename _Alloc, typename _Tp> using __is_erased_or_convertible = __or_<is_same<_Tp, __erased_type>, is_convertible<_Alloc, _Tp>>; /// [allocator.tag] struct allocator_arg_t { explicit allocator_arg_t() = default; }; _GLIBCXX17_INLINE constexpr allocator_arg_t allocator_arg = allocator_arg_t(); template<typename _Tp, typename _Alloc, typename = __void_t<>> struct __uses_allocator_helper : false_type { }; template<typename _Tp, typename _Alloc> struct __uses_allocator_helper<_Tp, _Alloc, __void_t<typename _Tp::allocator_type>> : __is_erased_or_convertible<_Alloc, typename _Tp::allocator_type>::type { }; /// [allocator.uses.trait] template<typename _Tp, typename _Alloc> struct uses_allocator : __uses_allocator_helper<_Tp, _Alloc>::type { }; struct __uses_alloc_base { }; struct __uses_alloc0 : __uses_alloc_base { struct _Sink { void operator=(const void*) { } } _M_a; }; template<typename _Alloc> struct __uses_alloc1 : __uses_alloc_base { const _Alloc* _M_a; }; template<typename _Alloc> struct __uses_alloc2 : __uses_alloc_base { const _Alloc* _M_a; }; template<bool, typename _Tp, typename _Alloc, typename... _Args> struct __uses_alloc; template<typename _Tp, typename _Alloc, typename... _Args> struct __uses_alloc<true, _Tp, _Alloc, _Args...> : conditional< is_constructible<_Tp, allocator_arg_t, const _Alloc&, _Args...>::value, __uses_alloc1<_Alloc>, __uses_alloc2<_Alloc>>::type { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2586. Wrong value category used in scoped_allocator_adaptor::construct static_assert(__or_< is_constructible<_Tp, allocator_arg_t, const _Alloc&, _Args...>, is_constructible<_Tp, _Args..., const _Alloc&>>::value, "construction with an allocator must be possible" " if uses_allocator is true"); }; template<typename _Tp, typename _Alloc, typename... _Args> struct __uses_alloc<false, _Tp, _Alloc, _Args...> : __uses_alloc0 { }; template<typename _Tp, typename _Alloc, typename... _Args> using __uses_alloc_t = __uses_alloc<uses_allocator<_Tp, _Alloc>::value, _Tp, _Alloc, _Args...>; template<typename _Tp, typename _Alloc, typename... _Args> inline __uses_alloc_t<_Tp, _Alloc, _Args...> __use_alloc(const _Alloc& __a) { __uses_alloc_t<_Tp, _Alloc, _Args...> __ret; __ret._M_a = std::__addressof(__a); return __ret; } template<typename _Tp, typename _Alloc, typename... _Args> void __use_alloc(const _Alloc&&) = delete; #if __cplusplus > 201402L template <typename _Tp, typename _Alloc> inline constexpr bool uses_allocator_v = uses_allocator<_Tp, _Alloc>::value; #endif // C++17 template<template<typename...> class _Predicate, typename _Tp, typename _Alloc, typename... _Args> struct __is_uses_allocator_predicate : conditional<uses_allocator<_Tp, _Alloc>::value, __or_<_Predicate<_Tp, allocator_arg_t, _Alloc, _Args...>, _Predicate<_Tp, _Args..., _Alloc>>, _Predicate<_Tp, _Args...>>::type { }; template<typename _Tp, typename _Alloc, typename... _Args> struct __is_uses_allocator_constructible : __is_uses_allocator_predicate<is_constructible, _Tp, _Alloc, _Args...> { }; #if __cplusplus >= 201402L template<typename _Tp, typename _Alloc, typename... _Args> _GLIBCXX17_INLINE constexpr bool __is_uses_allocator_constructible_v = __is_uses_allocator_constructible<_Tp, _Alloc, _Args...>::value; #endif // C++14 template<typename _Tp, typename _Alloc, typename... _Args> struct __is_nothrow_uses_allocator_constructible : __is_uses_allocator_predicate<is_nothrow_constructible, _Tp, _Alloc, _Args...> { }; #if __cplusplus >= 201402L template<typename _Tp, typename _Alloc, typename... _Args> _GLIBCXX17_INLINE constexpr bool __is_nothrow_uses_allocator_constructible_v = __is_nothrow_uses_allocator_constructible<_Tp, _Alloc, _Args...>::value; #endif // C++14 template<typename _Tp, typename... _Args> void __uses_allocator_construct_impl(__uses_alloc0 __a, _Tp* __ptr, _Args&&... __args) { ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)...); } template<typename _Tp, typename _Alloc, typename... _Args> void __uses_allocator_construct_impl(__uses_alloc1<_Alloc> __a, _Tp* __ptr, _Args&&... __args) { ::new ((void*)__ptr) _Tp(allocator_arg, *__a._M_a, std::forward<_Args>(__args)...); } template<typename _Tp, typename _Alloc, typename... _Args> void __uses_allocator_construct_impl(__uses_alloc2<_Alloc> __a, _Tp* __ptr, _Args&&... __args) { ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)..., *__a._M_a); } template<typename _Tp, typename _Alloc, typename... _Args> void __uses_allocator_construct(const _Alloc& __a, _Tp* __ptr, _Args&&... __args) { __uses_allocator_construct_impl(__use_alloc<_Tp, _Alloc, _Args...>(__a), __ptr, std::forward<_Args>(__args)...); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif #endif c++/8/bits/stl_raw_storage_iter.h 0000644 00000007366 15146341150 0012633 0 ustar 00 // -*- C++ -*- // Copyright (C) 2001-2018 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 * 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/stl_raw_storage_iter.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _STL_RAW_STORAGE_ITERATOR_H #define _STL_RAW_STORAGE_ITERATOR_H 1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * This iterator class lets algorithms store their results into * uninitialized memory. */ template <class _OutputIterator, class _Tp> class raw_storage_iterator : public iterator<output_iterator_tag, void, void, void, void> { protected: _OutputIterator _M_iter; public: explicit raw_storage_iterator(_OutputIterator __x) : _M_iter(__x) {} raw_storage_iterator& operator*() { return *this; } raw_storage_iterator& operator=(const _Tp& __element) { std::_Construct(std::__addressof(*_M_iter), __element); return *this; } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2127. Move-construction with raw_storage_iterator raw_storage_iterator& operator=(_Tp&& __element) { std::_Construct(std::__addressof(*_M_iter), std::move(__element)); return *this; } #endif raw_storage_iterator& operator++() { ++_M_iter; return *this; } raw_storage_iterator operator++(int) { raw_storage_iterator __tmp = *this; ++_M_iter; return __tmp; } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2454. Add raw_storage_iterator::base() member _OutputIterator base() const { return _M_iter; } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/bits/stl_multiset.h 0000644 00000105741 15146341150 0011135 0 ustar 00 // Multiset implementation -*- C++ -*- // Copyright (C) 2001-2018 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 * 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/stl_multiset.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{set} */ #ifndef _STL_MULTISET_H #define _STL_MULTISET_H 1 #include <bits/concept_check.h> #if __cplusplus >= 201103L #include <initializer_list> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Key, typename _Compare, typename _Alloc> class set; /** * @brief A standard container made up of elements, which can be retrieved * in logarithmic time. * * @ingroup associative_containers * * * @tparam _Key Type of key objects. * @tparam _Compare Comparison function object type, defaults to less<_Key>. * @tparam _Alloc Allocator type, defaults to allocator<_Key>. * * Meets the requirements of a <a href="tables.html#65">container</a>, a * <a href="tables.html#66">reversible container</a>, and an * <a href="tables.html#69">associative container</a> (using equivalent * keys). For a @c multiset<Key> the key_type and value_type are Key. * * Multisets support bidirectional iterators. * * The private tree data is declared exactly the same way for set and * multiset; the distinction is made entirely in how the tree functions are * called (*_unique versus *_equal, same as the standard). */ template <typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key> > class multiset { #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename _Alloc::value_type _Alloc_value_type; # if __cplusplus < 201103L __glibcxx_class_requires(_Key, _SGIAssignableConcept) # endif __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept) #endif #if __cplusplus >= 201103L static_assert(is_same<typename remove_cv<_Key>::type, _Key>::value, "std::multiset must have a non-const, non-volatile value_type"); # ifdef __STRICT_ANSI__ static_assert(is_same<typename _Alloc::value_type, _Key>::value, "std::multiset must have the same value_type as its allocator"); # endif #endif public: // typedefs: typedef _Key key_type; typedef _Key value_type; typedef _Compare key_compare; typedef _Compare value_compare; typedef _Alloc allocator_type; private: /// This turns a red-black tree into a [multi]set. typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Key>::other _Key_alloc_type; typedef _Rb_tree<key_type, value_type, _Identity<value_type>, key_compare, _Key_alloc_type> _Rep_type; /// The actual tree structure. _Rep_type _M_t; typedef __gnu_cxx::__alloc_traits<_Key_alloc_type> _Alloc_traits; public: 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; // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 103. set::iterator is required to be modifiable, // but this allows modification of keys. typedef typename _Rep_type::const_iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; typedef typename _Rep_type::const_reverse_iterator reverse_iterator; typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; typedef typename _Rep_type::size_type size_type; typedef typename _Rep_type::difference_type difference_type; #if __cplusplus > 201402L using node_type = typename _Rep_type::node_type; #endif // allocation/deallocation /** * @brief Default constructor creates no elements. */ #if __cplusplus < 201103L multiset() : _M_t() { } #else multiset() = default; #endif /** * @brief Creates a %multiset with no elements. * @param __comp Comparator to use. * @param __a An allocator object. */ explicit multiset(const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Key_alloc_type(__a)) { } /** * @brief Builds a %multiset from a range. * @param __first An input iterator. * @param __last An input iterator. * * Create a %multiset consisting of copies of the elements from * [first,last). This is linear in N if the range is already sorted, * and NlogN otherwise (where N is distance(__first,__last)). */ template<typename _InputIterator> multiset(_InputIterator __first, _InputIterator __last) : _M_t() { _M_t._M_insert_equal(__first, __last); } /** * @brief Builds a %multiset from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __comp A comparison functor. * @param __a An allocator object. * * Create a %multiset consisting of copies of the elements from * [__first,__last). This is linear in N if the range is already sorted, * and NlogN otherwise (where N is distance(__first,__last)). */ template<typename _InputIterator> multiset(_InputIterator __first, _InputIterator __last, const _Compare& __comp, const allocator_type& __a = allocator_type()) : _M_t(__comp, _Key_alloc_type(__a)) { _M_t._M_insert_equal(__first, __last); } /** * @brief %Multiset copy constructor. * * Whether the allocator is copied depends on the allocator traits. */ #if __cplusplus < 201103L multiset(const multiset& __x) : _M_t(__x._M_t) { } #else multiset(const multiset&) = default; /** * @brief %Multiset move constructor. * * The newly-created %multiset contains the exact contents of the * moved instance. The moved instance is a valid, but unspecified * %multiset. */ multiset(multiset&&) = default; /** * @brief Builds a %multiset from an initializer_list. * @param __l An initializer_list. * @param __comp A comparison functor. * @param __a An allocator object. * * Create a %multiset consisting of copies of the elements from * the list. This is linear in N if the list is already sorted, * and NlogN otherwise (where N is @a __l.size()). */ multiset(initializer_list<value_type> __l, const _Compare& __comp = _Compare(), const allocator_type& __a = allocator_type()) : _M_t(__comp, _Key_alloc_type(__a)) { _M_t._M_insert_equal(__l.begin(), __l.end()); } /// Allocator-extended default constructor. explicit multiset(const allocator_type& __a) : _M_t(_Compare(), _Key_alloc_type(__a)) { } /// Allocator-extended copy constructor. multiset(const multiset& __m, const allocator_type& __a) : _M_t(__m._M_t, _Key_alloc_type(__a)) { } /// Allocator-extended move constructor. multiset(multiset&& __m, const allocator_type& __a) noexcept(is_nothrow_copy_constructible<_Compare>::value && _Alloc_traits::_S_always_equal()) : _M_t(std::move(__m._M_t), _Key_alloc_type(__a)) { } /// Allocator-extended initialier-list constructor. multiset(initializer_list<value_type> __l, const allocator_type& __a) : _M_t(_Compare(), _Key_alloc_type(__a)) { _M_t._M_insert_equal(__l.begin(), __l.end()); } /// Allocator-extended range constructor. template<typename _InputIterator> multiset(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : _M_t(_Compare(), _Key_alloc_type(__a)) { _M_t._M_insert_equal(__first, __last); } /** * The dtor only erases the elements, and note that if the elements * themselves are pointers, the pointed-to memory is not touched in any * way. Managing the pointer is the user's responsibility. */ ~multiset() = default; #endif /** * @brief %Multiset assignment operator. * * Whether the allocator is copied depends on the allocator traits. */ #if __cplusplus < 201103L multiset& operator=(const multiset& __x) { _M_t = __x._M_t; return *this; } #else multiset& operator=(const multiset&) = default; /// Move assignment operator. multiset& operator=(multiset&&) = default; /** * @brief %Multiset list assignment operator. * @param __l An initializer_list. * * This function fills a %multiset with copies of the elements in the * initializer list @a __l. * * Note that the assignment completely changes the %multiset and * that the resulting %multiset's size is the same as the number * of elements assigned. */ multiset& operator=(initializer_list<value_type> __l) { _M_t._M_assign_equal(__l.begin(), __l.end()); return *this; } #endif // accessors: /// Returns the comparison object. key_compare key_comp() const { return _M_t.key_comp(); } /// Returns the comparison object. value_compare value_comp() const { return _M_t.key_comp(); } /// Returns the memory allocation object. allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_t.get_allocator()); } /** * Returns a read-only (constant) iterator that points to the first * element in the %multiset. Iteration is done in ascending order * according to the keys. */ iterator begin() const _GLIBCXX_NOEXCEPT { return _M_t.begin(); } /** * Returns a read-only (constant) iterator that points one past the last * element in the %multiset. Iteration is done in ascending order * according to the keys. */ iterator end() const _GLIBCXX_NOEXCEPT { return _M_t.end(); } /** * Returns a read-only (constant) reverse iterator that points to the * last element in the %multiset. Iteration is done in descending order * according to the keys. */ reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return _M_t.rbegin(); } /** * Returns a read-only (constant) reverse iterator that points to the * last element in the %multiset. Iteration is done in descending order * according to the keys. */ reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return _M_t.rend(); } #if __cplusplus >= 201103L /** * Returns a read-only (constant) iterator that points to the first * element in the %multiset. Iteration is done in ascending order * according to the keys. */ iterator cbegin() const noexcept { return _M_t.begin(); } /** * Returns a read-only (constant) iterator that points one past the last * element in the %multiset. Iteration is done in ascending order * according to the keys. */ iterator cend() const noexcept { return _M_t.end(); } /** * Returns a read-only (constant) reverse iterator that points to the * last element in the %multiset. Iteration is done in descending order * according to the keys. */ reverse_iterator crbegin() const noexcept { return _M_t.rbegin(); } /** * Returns a read-only (constant) reverse iterator that points to the * last element in the %multiset. Iteration is done in descending order * according to the keys. */ reverse_iterator crend() const noexcept { return _M_t.rend(); } #endif /// Returns true if the %set is empty. bool empty() const _GLIBCXX_NOEXCEPT { return _M_t.empty(); } /// Returns the size of the %set. size_type size() const _GLIBCXX_NOEXCEPT { return _M_t.size(); } /// Returns the maximum size of the %set. size_type max_size() const _GLIBCXX_NOEXCEPT { return _M_t.max_size(); } /** * @brief Swaps data with another %multiset. * @param __x A %multiset of the same element and allocator types. * * This exchanges the elements between two multisets in constant time. * (It is only swapping a pointer, an integer, and an instance of the @c * Compare type (which itself is often stateless and empty), so it should * be quite fast.) * Note that the global std::swap() function is specialized such that * std::swap(s1,s2) will feed to this function. * * Whether the allocators are swapped depends on the allocator traits. */ void swap(multiset& __x) _GLIBCXX_NOEXCEPT_IF(__is_nothrow_swappable<_Compare>::value) { _M_t.swap(__x._M_t); } // insert/erase #if __cplusplus >= 201103L /** * @brief Builds and inserts an element into the %multiset. * @param __args Arguments used to generate the element instance to be * inserted. * @return An iterator that points to the inserted element. * * This function inserts an element into the %multiset. Contrary * to a std::set the %multiset does not rely on unique keys and thus * multiple copies of the same element can be inserted. * * Insertion requires logarithmic time. */ template<typename... _Args> iterator emplace(_Args&&... __args) { return _M_t._M_emplace_equal(std::forward<_Args>(__args)...); } /** * @brief Builds and inserts an element into the %multiset. * @param __pos An iterator that serves as a hint as to where the * element should be inserted. * @param __args Arguments used to generate the element instance to be * inserted. * @return An iterator that points to the inserted element. * * This function inserts an element into the %multiset. Contrary * to a std::set the %multiset does not rely on unique keys and thus * multiple copies of the same element can be inserted. * * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires logarithmic time (if the hint is not taken). */ template<typename... _Args> iterator emplace_hint(const_iterator __pos, _Args&&... __args) { return _M_t._M_emplace_hint_equal(__pos, std::forward<_Args>(__args)...); } #endif /** * @brief Inserts an element into the %multiset. * @param __x Element to be inserted. * @return An iterator that points to the inserted element. * * This function inserts an element into the %multiset. Contrary * to a std::set the %multiset does not rely on unique keys and thus * multiple copies of the same element can be inserted. * * Insertion requires logarithmic time. */ iterator insert(const value_type& __x) { return _M_t._M_insert_equal(__x); } #if __cplusplus >= 201103L iterator insert(value_type&& __x) { return _M_t._M_insert_equal(std::move(__x)); } #endif /** * @brief Inserts an element into the %multiset. * @param __position An iterator that serves as a hint as to where the * element should be inserted. * @param __x Element to be inserted. * @return An iterator that points to the inserted element. * * This function inserts an element into the %multiset. Contrary * to a std::set the %multiset does not rely on unique keys and thus * multiple copies of the same element can be inserted. * * Note that the first parameter is only a hint and can potentially * improve the performance of the insertion process. A bad hint would * cause no gains in efficiency. * * See https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints * for more on @a hinting. * * Insertion requires logarithmic time (if the hint is not taken). */ iterator insert(const_iterator __position, const value_type& __x) { return _M_t._M_insert_equal_(__position, __x); } #if __cplusplus >= 201103L iterator insert(const_iterator __position, value_type&& __x) { return _M_t._M_insert_equal_(__position, std::move(__x)); } #endif /** * @brief A template function that tries to insert a range of elements. * @param __first Iterator pointing to the start of the range to be * inserted. * @param __last Iterator pointing to the end of the range. * * Complexity similar to that of the range constructor. */ template<typename _InputIterator> void insert(_InputIterator __first, _InputIterator __last) { _M_t._M_insert_equal(__first, __last); } #if __cplusplus >= 201103L /** * @brief Attempts to insert a list of elements into the %multiset. * @param __l A std::initializer_list<value_type> of elements * to be inserted. * * Complexity similar to that of the range constructor. */ void insert(initializer_list<value_type> __l) { this->insert(__l.begin(), __l.end()); } #endif #if __cplusplus > 201402L /// Extract a node. node_type extract(const_iterator __pos) { __glibcxx_assert(__pos != end()); return _M_t.extract(__pos); } /// Extract a node. node_type extract(const key_type& __x) { return _M_t.extract(__x); } /// Re-insert an extracted node. iterator insert(node_type&& __nh) { return _M_t._M_reinsert_node_equal(std::move(__nh)); } /// Re-insert an extracted node. iterator insert(const_iterator __hint, node_type&& __nh) { return _M_t._M_reinsert_node_hint_equal(__hint, std::move(__nh)); } template<typename, typename> friend class std::_Rb_tree_merge_helper; template<typename _Compare1> void merge(multiset<_Key, _Compare1, _Alloc>& __source) { using _Merge_helper = _Rb_tree_merge_helper<multiset, _Compare1>; _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source)); } template<typename _Compare1> void merge(multiset<_Key, _Compare1, _Alloc>&& __source) { merge(__source); } template<typename _Compare1> void merge(set<_Key, _Compare1, _Alloc>& __source) { using _Merge_helper = _Rb_tree_merge_helper<multiset, _Compare1>; _M_t._M_merge_equal(_Merge_helper::_S_get_tree(__source)); } template<typename _Compare1> void merge(set<_Key, _Compare1, _Alloc>&& __source) { merge(__source); } #endif // C++17 #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. /** * @brief Erases an element from a %multiset. * @param __position An iterator pointing to the element to be erased. * @return An iterator pointing to the element immediately following * @a position prior to the element being erased. If no such * element exists, end() is returned. * * This function erases an element, pointed to by the given iterator, * from a %multiset. Note that this function only erases the element, * and that if the element is itself a pointer, the pointed-to memory is * not touched in any way. Managing the pointer is the user's * responsibility. */ _GLIBCXX_ABI_TAG_CXX11 iterator erase(const_iterator __position) { return _M_t.erase(__position); } #else /** * @brief Erases an element from a %multiset. * @param __position An iterator pointing to the element to be erased. * * This function erases an element, pointed to by the given iterator, * from a %multiset. Note that this function only erases the element, * and that if the element is itself a pointer, the pointed-to memory is * not touched in any way. Managing the pointer is the user's * responsibility. */ void erase(iterator __position) { _M_t.erase(__position); } #endif /** * @brief Erases elements according to the provided key. * @param __x Key of element to be erased. * @return The number of elements erased. * * This function erases all elements located by the given key from a * %multiset. * Note that this function only erases the element, and that if * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibility. */ size_type erase(const key_type& __x) { return _M_t.erase(__x); } #if __cplusplus >= 201103L // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 130. Associative erase should return an iterator. /** * @brief Erases a [first,last) range of elements from a %multiset. * @param __first Iterator pointing to the start of the range to be * erased. * @param __last Iterator pointing to the end of the range to * be erased. * @return The iterator @a last. * * This function erases a sequence of elements from a %multiset. * Note that this function only erases the elements, and that if * the elements themselves are pointers, the pointed-to memory is not * touched in any way. Managing the pointer is the user's * responsibility. */ _GLIBCXX_ABI_TAG_CXX11 iterator erase(const_iterator __first, const_iterator __last) { return _M_t.erase(__first, __last); } #else /** * @brief Erases a [first,last) range of elements from a %multiset. * @param first Iterator pointing to the start of the range to be * erased. * @param last Iterator pointing to the end of the range to be erased. * * This function erases a sequence of elements from a %multiset. * Note that this function only erases the elements, and that if * the elements themselves are pointers, the pointed-to memory is not * touched in any way. Managing the pointer is the user's * responsibility. */ void erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } #endif /** * Erases all elements in a %multiset. Note that this function only * erases the elements, and that if the elements themselves are pointers, * the pointed-to memory is not touched in any way. Managing the pointer * is the user's responsibility. */ void clear() _GLIBCXX_NOEXCEPT { _M_t.clear(); } // multiset operations: //@{ /** * @brief Finds the number of elements with given key. * @param __x Key of elements to be located. * @return Number of elements with specified key. */ size_type count(const key_type& __x) const { return _M_t.count(__x); } #if __cplusplus > 201103L template<typename _Kt> auto count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x)) { return _M_t._M_count_tr(__x); } #endif //@} // _GLIBCXX_RESOLVE_LIB_DEFECTS // 214. set::find() missing const overload //@{ /** * @brief Tries to locate an element in a %set. * @param __x Element to be located. * @return Iterator pointing to sought-after element, or end() if not * found. * * This function takes a key and tries to locate the element with which * the key matches. If successful the function returns an iterator * pointing to the sought after element. If unsuccessful it returns the * past-the-end ( @c end() ) iterator. */ iterator find(const key_type& __x) { return _M_t.find(__x); } const_iterator find(const key_type& __x) const { return _M_t.find(__x); } #if __cplusplus > 201103L template<typename _Kt> auto find(const _Kt& __x) -> decltype(iterator{_M_t._M_find_tr(__x)}) { return iterator{_M_t._M_find_tr(__x)}; } template<typename _Kt> auto find(const _Kt& __x) const -> decltype(const_iterator{_M_t._M_find_tr(__x)}) { return const_iterator{_M_t._M_find_tr(__x)}; } #endif //@} //@{ /** * @brief Finds the beginning of a subsequence matching given key. * @param __x Key to be located. * @return Iterator pointing to first element equal to or greater * than key, or end(). * * This function returns the first element of a subsequence of elements * that matches the given key. If unsuccessful it returns an iterator * pointing to the first element that has a greater value than given key * or end() if no such element exists. */ iterator lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); } const_iterator lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto lower_bound(const _Kt& __x) -> decltype(iterator(_M_t._M_lower_bound_tr(__x))) { return iterator(_M_t._M_lower_bound_tr(__x)); } template<typename _Kt> auto lower_bound(const _Kt& __x) const -> decltype(iterator(_M_t._M_lower_bound_tr(__x))) { return iterator(_M_t._M_lower_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds the end of a subsequence matching given key. * @param __x Key to be located. * @return Iterator pointing to the first element * greater than key, or end(). */ iterator upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); } const_iterator upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } #if __cplusplus > 201103L template<typename _Kt> auto upper_bound(const _Kt& __x) -> decltype(iterator(_M_t._M_upper_bound_tr(__x))) { return iterator(_M_t._M_upper_bound_tr(__x)); } template<typename _Kt> auto upper_bound(const _Kt& __x) const -> decltype(iterator(_M_t._M_upper_bound_tr(__x))) { return iterator(_M_t._M_upper_bound_tr(__x)); } #endif //@} //@{ /** * @brief Finds a subsequence matching given key. * @param __x Key to be located. * @return Pair of iterators that possibly points to the subsequence * matching given key. * * This function is equivalent to * @code * std::make_pair(c.lower_bound(val), * c.upper_bound(val)) * @endcode * (but is faster than making the calls separately). * * This function probably only makes sense for multisets. */ std::pair<iterator, iterator> equal_range(const key_type& __x) { return _M_t.equal_range(__x); } std::pair<const_iterator, const_iterator> equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } #if __cplusplus > 201103L template<typename _Kt> auto equal_range(const _Kt& __x) -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x))) { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); } template<typename _Kt> auto equal_range(const _Kt& __x) const -> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x))) { return pair<iterator, iterator>(_M_t._M_equal_range_tr(__x)); } #endif //@} template<typename _K1, typename _C1, typename _A1> friend bool operator==(const multiset<_K1, _C1, _A1>&, const multiset<_K1, _C1, _A1>&); template<typename _K1, typename _C1, typename _A1> friend bool operator< (const multiset<_K1, _C1, _A1>&, const multiset<_K1, _C1, _A1>&); }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _Compare = less<typename iterator_traits<_InputIterator>::value_type>, typename _Allocator = allocator<typename iterator_traits<_InputIterator>::value_type>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) -> multiset<typename iterator_traits<_InputIterator>::value_type, _Compare, _Allocator>; template<typename _Key, typename _Compare = less<_Key>, typename _Allocator = allocator<_Key>, typename = _RequireAllocator<_Allocator>> multiset(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) -> multiset<_Key, _Compare, _Allocator>; template<typename _InputIterator, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> multiset(_InputIterator, _InputIterator, _Allocator) -> multiset<typename iterator_traits<_InputIterator>::value_type, less<typename iterator_traits<_InputIterator>::value_type>, _Allocator>; template<typename _Key, typename _Allocator, typename = _RequireAllocator<_Allocator>> multiset(initializer_list<_Key>, _Allocator) -> multiset<_Key, less<_Key>, _Allocator>; #endif /** * @brief Multiset equality comparison. * @param __x A %multiset. * @param __y A %multiset of the same type as @a __x. * @return True iff the size and elements of the multisets are equal. * * This is an equivalence relation. It is linear in the size of the * multisets. * Multisets are considered equivalent if their sizes are equal, and if * corresponding elements compare equal. */ template<typename _Key, typename _Compare, typename _Alloc> inline bool operator==(const multiset<_Key, _Compare, _Alloc>& __x, const multiset<_Key, _Compare, _Alloc>& __y) { return __x._M_t == __y._M_t; } /** * @brief Multiset ordering relation. * @param __x A %multiset. * @param __y A %multiset of the same type as @a __x. * @return True iff @a __x is lexicographically less than @a __y. * * This is a total ordering relation. It is linear in the size of the * sets. The elements must be comparable with @c <. * * See std::lexicographical_compare() for how the determination is made. */ template<typename _Key, typename _Compare, typename _Alloc> inline bool operator<(const multiset<_Key, _Compare, _Alloc>& __x, const multiset<_Key, _Compare, _Alloc>& __y) { return __x._M_t < __y._M_t; } /// Returns !(x == y). template<typename _Key, typename _Compare, typename _Alloc> inline bool operator!=(const multiset<_Key, _Compare, _Alloc>& __x, const multiset<_Key, _Compare, _Alloc>& __y) { return !(__x == __y); } /// Returns y < x. template<typename _Key, typename _Compare, typename _Alloc> inline bool operator>(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) { return __y < __x; } /// Returns !(y < x) template<typename _Key, typename _Compare, typename _Alloc> inline bool operator<=(const multiset<_Key, _Compare, _Alloc>& __x, const multiset<_Key, _Compare, _Alloc>& __y) { return !(__y < __x); } /// Returns !(x < y) template<typename _Key, typename _Compare, typename _Alloc> inline bool operator>=(const multiset<_Key, _Compare, _Alloc>& __x, const multiset<_Key, _Compare, _Alloc>& __y) { return !(__x < __y); } /// See std::multiset::swap(). template<typename _Key, typename _Compare, typename _Alloc> inline void swap(multiset<_Key, _Compare, _Alloc>& __x, multiset<_Key, _Compare, _Alloc>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER #if __cplusplus > 201402L // Allow std::multiset access to internals of compatible sets. template<typename _Val, typename _Cmp1, typename _Alloc, typename _Cmp2> struct _Rb_tree_merge_helper<_GLIBCXX_STD_C::multiset<_Val, _Cmp1, _Alloc>, _Cmp2> { private: friend class _GLIBCXX_STD_C::multiset<_Val, _Cmp1, _Alloc>; static auto& _S_get_tree(_GLIBCXX_STD_C::set<_Val, _Cmp2, _Alloc>& __set) { return __set._M_t; } static auto& _S_get_tree(_GLIBCXX_STD_C::multiset<_Val, _Cmp2, _Alloc>& __set) { return __set._M_t; } }; #endif // C++17 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _STL_MULTISET_H */ c++/8/bits/exception.h 0000644 00000004350 15146341150 0010375 0 ustar 00 // Exception Handling support header for -*- C++ -*- // Copyright (C) 2016-2018 Free Software Foundation, Inc. // // This file is part of GCC. // // GCC is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3, or (at your option) // any later version. // // GCC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/exception.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. */ #ifndef __EXCEPTION_H #define __EXCEPTION_H 1 #pragma GCC system_header #pragma GCC visibility push(default) #include <bits/c++config.h> extern "C++" { namespace std { /** * @defgroup exceptions Exceptions * @ingroup diagnostics * * Classes and functions for reporting errors via exception classes. * @{ */ /** * @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_USE_NOEXCEPT { } virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause * of the current error. */ virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; }; } // namespace std } #pragma GCC visibility pop #endif c++/8/bits/unique_ptr.h 0000644 00000062600 15146341150 0010574 0 ustar 00 // unique_ptr implementation -*- C++ -*- // Copyright (C) 2008-2018 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/unique_ptr.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _UNIQUE_PTR_H #define _UNIQUE_PTR_H 1 #include <bits/c++config.h> #include <debug/assertions.h> #include <type_traits> #include <utility> #include <tuple> #include <bits/stl_function.h> #include <bits/functional_hash.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @addtogroup pointer_abstractions * @{ */ #if _GLIBCXX_USE_DEPRECATED #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" template<typename> class auto_ptr; #pragma GCC diagnostic pop #endif /// Primary template of default_delete, used by unique_ptr template<typename _Tp> struct default_delete { /// Default constructor constexpr default_delete() noexcept = default; /** @brief Converting constructor. * * Allows conversion from a deleter for arrays of another type, @p _Up, * only if @p _Up* is convertible to @p _Tp*. */ template<typename _Up, typename = typename enable_if<is_convertible<_Up*, _Tp*>::value>::type> default_delete(const default_delete<_Up>&) noexcept { } /// Calls @c delete @p __ptr void operator()(_Tp* __ptr) const { static_assert(!is_void<_Tp>::value, "can't delete pointer to incomplete type"); static_assert(sizeof(_Tp)>0, "can't delete pointer to incomplete type"); delete __ptr; } }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 740 - omit specialization for array objects with a compile time length /// Specialization for arrays, default_delete. template<typename _Tp> struct default_delete<_Tp[]> { public: /// Default constructor constexpr default_delete() noexcept = default; /** @brief Converting constructor. * * Allows conversion from a deleter for arrays of another type, such as * a const-qualified version of @p _Tp. * * Conversions from types derived from @c _Tp are not allowed because * it is unsafe to @c delete[] an array of derived types through a * pointer to the base type. */ template<typename _Up, typename = typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type> default_delete(const default_delete<_Up[]>&) noexcept { } /// Calls @c delete[] @p __ptr template<typename _Up> typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type operator()(_Up* __ptr) const { static_assert(sizeof(_Tp)>0, "can't delete pointer to incomplete type"); delete [] __ptr; } }; template <typename _Tp, typename _Dp> class __uniq_ptr_impl { template <typename _Up, typename _Ep, typename = void> struct _Ptr { using type = _Up*; }; template <typename _Up, typename _Ep> struct _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>> { using type = typename remove_reference<_Ep>::type::pointer; }; public: using _DeleterConstraint = enable_if< __and_<__not_<is_pointer<_Dp>>, is_default_constructible<_Dp>>::value>; using pointer = typename _Ptr<_Tp, _Dp>::type; __uniq_ptr_impl() = default; __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; } template<typename _Del> __uniq_ptr_impl(pointer __p, _Del&& __d) : _M_t(__p, std::forward<_Del>(__d)) { } pointer& _M_ptr() { return std::get<0>(_M_t); } pointer _M_ptr() const { return std::get<0>(_M_t); } _Dp& _M_deleter() { return std::get<1>(_M_t); } const _Dp& _M_deleter() const { return std::get<1>(_M_t); } void swap(__uniq_ptr_impl& __rhs) noexcept { using std::swap; swap(this->_M_ptr(), __rhs._M_ptr()); swap(this->_M_deleter(), __rhs._M_deleter()); } private: tuple<pointer, _Dp> _M_t; }; /// 20.7.1.2 unique_ptr for single objects. template <typename _Tp, typename _Dp = default_delete<_Tp>> class unique_ptr { template <class _Up> using _DeleterConstraint = typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; __uniq_ptr_impl<_Tp, _Dp> _M_t; public: using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; using element_type = _Tp; using deleter_type = _Dp; // helper template for detecting a safe conversion from another // unique_ptr template<typename _Up, typename _Ep> using __safe_conversion_up = __and_< is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, __not_<is_array<_Up>> >; // Constructors. /// Default constructor, creates a unique_ptr that owns nothing. template <typename _Up = _Dp, typename = _DeleterConstraint<_Up>> constexpr unique_ptr() noexcept : _M_t() { } /** Takes ownership of a pointer. * * @param __p A pointer to an object of @c element_type * * The deleter will be value-initialized. */ template <typename _Up = _Dp, typename = _DeleterConstraint<_Up>> explicit unique_ptr(pointer __p) noexcept : _M_t(__p) { } /** Takes ownership of a pointer. * * @param __p A pointer to an object of @c element_type * @param __d A reference to a deleter. * * The deleter will be initialized with @p __d */ unique_ptr(pointer __p, typename conditional<is_reference<deleter_type>::value, deleter_type, const deleter_type&>::type __d) noexcept : _M_t(__p, __d) { } /** Takes ownership of a pointer. * * @param __p A pointer to an object of @c element_type * @param __d An rvalue reference to a deleter. * * The deleter will be initialized with @p std::move(__d) */ unique_ptr(pointer __p, typename remove_reference<deleter_type>::type&& __d) noexcept : _M_t(std::move(__p), std::move(__d)) { static_assert(!std::is_reference<deleter_type>::value, "rvalue deleter bound to reference"); } /// Creates a unique_ptr that owns nothing. template <typename _Up = _Dp, typename = _DeleterConstraint<_Up>> constexpr unique_ptr(nullptr_t) noexcept : _M_t() { } // Move constructors. /// Move constructor. unique_ptr(unique_ptr&& __u) noexcept : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } /** @brief Converting constructor from another type * * Requires that the pointer owned by @p __u is convertible to the * type of pointer owned by this object, @p __u does not own an array, * and @p __u has a compatible deleter type. */ template<typename _Up, typename _Ep, typename = _Require< __safe_conversion_up<_Up, _Ep>, typename conditional<is_reference<_Dp>::value, is_same<_Ep, _Dp>, is_convertible<_Ep, _Dp>>::type>> unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) { } #if _GLIBCXX_USE_DEPRECATED #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" /// Converting constructor from @c auto_ptr template<typename _Up, typename = _Require< is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> unique_ptr(auto_ptr<_Up>&& __u) noexcept; #pragma GCC diagnostic pop #endif /// Destructor, invokes the deleter if the stored pointer is not null. ~unique_ptr() noexcept { auto& __ptr = _M_t._M_ptr(); if (__ptr != nullptr) get_deleter()(__ptr); __ptr = pointer(); } // Assignment. /** @brief Move assignment operator. * * @param __u The object to transfer ownership from. * * Invokes the deleter first if this object owns a pointer. */ unique_ptr& operator=(unique_ptr&& __u) noexcept { reset(__u.release()); get_deleter() = std::forward<deleter_type>(__u.get_deleter()); return *this; } /** @brief Assignment from another type. * * @param __u The object to transfer ownership from, which owns a * convertible pointer to a non-array object. * * Invokes the deleter first if this object owns a pointer. */ template<typename _Up, typename _Ep> typename enable_if< __and_< __safe_conversion_up<_Up, _Ep>, is_assignable<deleter_type&, _Ep&&> >::value, unique_ptr&>::type operator=(unique_ptr<_Up, _Ep>&& __u) noexcept { reset(__u.release()); get_deleter() = std::forward<_Ep>(__u.get_deleter()); return *this; } /// Reset the %unique_ptr to empty, invoking the deleter if necessary. unique_ptr& operator=(nullptr_t) noexcept { reset(); return *this; } // Observers. /// Dereference the stored pointer. typename add_lvalue_reference<element_type>::type operator*() const { __glibcxx_assert(get() != pointer()); return *get(); } /// Return the stored pointer. pointer operator->() const noexcept { _GLIBCXX_DEBUG_PEDASSERT(get() != pointer()); return get(); } /// Return the stored pointer. pointer get() const noexcept { return _M_t._M_ptr(); } /// Return a reference to the stored deleter. deleter_type& get_deleter() noexcept { return _M_t._M_deleter(); } /// Return a reference to the stored deleter. const deleter_type& get_deleter() const noexcept { return _M_t._M_deleter(); } /// Return @c true if the stored pointer is not null. explicit operator bool() const noexcept { return get() == pointer() ? false : true; } // Modifiers. /// Release ownership of any stored pointer. pointer release() noexcept { pointer __p = get(); _M_t._M_ptr() = pointer(); return __p; } /** @brief Replace the stored pointer. * * @param __p The new pointer to store. * * The deleter will be invoked if a pointer is already owned. */ void reset(pointer __p = pointer()) noexcept { using std::swap; swap(_M_t._M_ptr(), __p); if (__p != pointer()) get_deleter()(__p); } /// Exchange the pointer and deleter with another object. void swap(unique_ptr& __u) noexcept { static_assert(__is_swappable<_Dp>::value, "deleter must be swappable"); _M_t.swap(__u._M_t); } // Disable copy from lvalue. unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; }; /// 20.7.1.3 unique_ptr for array objects with a runtime length // [unique.ptr.runtime] // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 740 - omit specialization for array objects with a compile time length template<typename _Tp, typename _Dp> class unique_ptr<_Tp[], _Dp> { template <typename _Up> using _DeleterConstraint = typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; __uniq_ptr_impl<_Tp, _Dp> _M_t; template<typename _Up> using __remove_cv = typename remove_cv<_Up>::type; // like is_base_of<_Tp, _Up> but false if unqualified types are the same template<typename _Up> using __is_derived_Tp = __and_< is_base_of<_Tp, _Up>, __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; public: using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; using element_type = _Tp; using deleter_type = _Dp; // helper template for detecting a safe conversion from another // unique_ptr template<typename _Up, typename _Ep, typename _UPtr = unique_ptr<_Up, _Ep>, typename _UP_pointer = typename _UPtr::pointer, typename _UP_element_type = typename _UPtr::element_type> using __safe_conversion_up = __and_< is_array<_Up>, is_same<pointer, element_type*>, is_same<_UP_pointer, _UP_element_type*>, is_convertible<_UP_element_type(*)[], element_type(*)[]> >; // helper template for detecting a safe conversion from a raw pointer template<typename _Up> using __safe_conversion_raw = __and_< __or_<__or_<is_same<_Up, pointer>, is_same<_Up, nullptr_t>>, __and_<is_pointer<_Up>, is_same<pointer, element_type*>, is_convertible< typename remove_pointer<_Up>::type(*)[], element_type(*)[]> > > >; // Constructors. /// Default constructor, creates a unique_ptr that owns nothing. template <typename _Up = _Dp, typename = _DeleterConstraint<_Up>> constexpr unique_ptr() noexcept : _M_t() { } /** Takes ownership of a pointer. * * @param __p A pointer to an array of a type safely convertible * to an array of @c element_type * * The deleter will be value-initialized. */ template<typename _Up, typename _Vp = _Dp, typename = _DeleterConstraint<_Vp>, typename = typename enable_if< __safe_conversion_raw<_Up>::value, bool>::type> explicit unique_ptr(_Up __p) noexcept : _M_t(__p) { } /** Takes ownership of a pointer. * * @param __p A pointer to an array of a type safely convertible * to an array of @c element_type * @param __d A reference to a deleter. * * The deleter will be initialized with @p __d */ template<typename _Up, typename = typename enable_if< __safe_conversion_raw<_Up>::value, bool>::type> unique_ptr(_Up __p, typename conditional<is_reference<deleter_type>::value, deleter_type, const deleter_type&>::type __d) noexcept : _M_t(__p, __d) { } /** Takes ownership of a pointer. * * @param __p A pointer to an array of a type safely convertible * to an array of @c element_type * @param __d A reference to a deleter. * * The deleter will be initialized with @p std::move(__d) */ template<typename _Up, typename = typename enable_if< __safe_conversion_raw<_Up>::value, bool>::type> unique_ptr(_Up __p, typename remove_reference<deleter_type>::type&& __d) noexcept : _M_t(std::move(__p), std::move(__d)) { static_assert(!is_reference<deleter_type>::value, "rvalue deleter bound to reference"); } /// Move constructor. unique_ptr(unique_ptr&& __u) noexcept : _M_t(__u.release(), std::forward<deleter_type>(__u.get_deleter())) { } /// Creates a unique_ptr that owns nothing. template <typename _Up = _Dp, typename = _DeleterConstraint<_Up>> constexpr unique_ptr(nullptr_t) noexcept : _M_t() { } template<typename _Up, typename _Ep, typename = _Require< __safe_conversion_up<_Up, _Ep>, typename conditional<is_reference<_Dp>::value, is_same<_Ep, _Dp>, is_convertible<_Ep, _Dp>>::type>> unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) { } /// Destructor, invokes the deleter if the stored pointer is not null. ~unique_ptr() { auto& __ptr = _M_t._M_ptr(); if (__ptr != nullptr) get_deleter()(__ptr); __ptr = pointer(); } // Assignment. /** @brief Move assignment operator. * * @param __u The object to transfer ownership from. * * Invokes the deleter first if this object owns a pointer. */ unique_ptr& operator=(unique_ptr&& __u) noexcept { reset(__u.release()); get_deleter() = std::forward<deleter_type>(__u.get_deleter()); return *this; } /** @brief Assignment from another type. * * @param __u The object to transfer ownership from, which owns a * convertible pointer to an array object. * * Invokes the deleter first if this object owns a pointer. */ template<typename _Up, typename _Ep> typename enable_if<__and_<__safe_conversion_up<_Up, _Ep>, is_assignable<deleter_type&, _Ep&&> >::value, unique_ptr&>::type operator=(unique_ptr<_Up, _Ep>&& __u) noexcept { reset(__u.release()); get_deleter() = std::forward<_Ep>(__u.get_deleter()); return *this; } /// Reset the %unique_ptr to empty, invoking the deleter if necessary. unique_ptr& operator=(nullptr_t) noexcept { reset(); return *this; } // Observers. /// Access an element of owned array. typename std::add_lvalue_reference<element_type>::type operator[](size_t __i) const { __glibcxx_assert(get() != pointer()); return get()[__i]; } /// Return the stored pointer. pointer get() const noexcept { return _M_t._M_ptr(); } /// Return a reference to the stored deleter. deleter_type& get_deleter() noexcept { return _M_t._M_deleter(); } /// Return a reference to the stored deleter. const deleter_type& get_deleter() const noexcept { return _M_t._M_deleter(); } /// Return @c true if the stored pointer is not null. explicit operator bool() const noexcept { return get() == pointer() ? false : true; } // Modifiers. /// Release ownership of any stored pointer. pointer release() noexcept { pointer __p = get(); _M_t._M_ptr() = pointer(); return __p; } /** @brief Replace the stored pointer. * * @param __p The new pointer to store. * * The deleter will be invoked if a pointer is already owned. */ template <typename _Up, typename = _Require< __or_<is_same<_Up, pointer>, __and_<is_same<pointer, element_type*>, is_pointer<_Up>, is_convertible< typename remove_pointer<_Up>::type(*)[], element_type(*)[] > > > >> void reset(_Up __p) noexcept { pointer __ptr = __p; using std::swap; swap(_M_t._M_ptr(), __ptr); if (__ptr != nullptr) get_deleter()(__ptr); } void reset(nullptr_t = nullptr) noexcept { reset(pointer()); } /// Exchange the pointer and deleter with another object. void swap(unique_ptr& __u) noexcept { static_assert(__is_swappable<_Dp>::value, "deleter must be swappable"); _M_t.swap(__u._M_t); } // Disable copy from lvalue. unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; }; template<typename _Tp, typename _Dp> inline #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 // Constrained free swap overload, see p0185r1 typename enable_if<__is_swappable<_Dp>::value>::type #else void #endif swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) noexcept { __x.swap(__y); } #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 template<typename _Tp, typename _Dp> typename enable_if<!__is_swappable<_Dp>::value>::type swap(unique_ptr<_Tp, _Dp>&, unique_ptr<_Tp, _Dp>&) = delete; #endif template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator==(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { return __x.get() == __y.get(); } template<typename _Tp, typename _Dp> inline bool operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept { return !__x; } template<typename _Tp, typename _Dp> inline bool operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept { return !__x; } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator!=(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { return __x.get() != __y.get(); } template<typename _Tp, typename _Dp> inline bool operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept { return (bool)__x; } template<typename _Tp, typename _Dp> inline bool operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept { return (bool)__x; } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator<(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { typedef typename std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, typename unique_ptr<_Up, _Ep>::pointer>::type _CT; return std::less<_CT>()(__x.get(), __y.get()); } template<typename _Tp, typename _Dp> inline bool operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), nullptr); } template<typename _Tp, typename _Dp> inline bool operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, __x.get()); } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator<=(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { return !(__y < __x); } template<typename _Tp, typename _Dp> inline bool operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) { return !(nullptr < __x); } template<typename _Tp, typename _Dp> inline bool operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) { return !(__x < nullptr); } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator>(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { return (__y < __x); } template<typename _Tp, typename _Dp> inline bool operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, __x.get()); } template<typename _Tp, typename _Dp> inline bool operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) { return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), nullptr); } template<typename _Tp, typename _Dp, typename _Up, typename _Ep> inline bool operator>=(const unique_ptr<_Tp, _Dp>& __x, const unique_ptr<_Up, _Ep>& __y) { return !(__x < __y); } template<typename _Tp, typename _Dp> inline bool operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) { return !(__x < nullptr); } template<typename _Tp, typename _Dp> inline bool operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) { return !(nullptr < __x); } /// std::hash specialization for unique_ptr. template<typename _Tp, typename _Dp> struct hash<unique_ptr<_Tp, _Dp>> : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>, private __poison_hash<typename unique_ptr<_Tp, _Dp>::pointer> { size_t operator()(const unique_ptr<_Tp, _Dp>& __u) const noexcept { typedef unique_ptr<_Tp, _Dp> _UP; return std::hash<typename _UP::pointer>()(__u.get()); } }; #if __cplusplus > 201103L #define __cpp_lib_make_unique 201304 template<typename _Tp> struct _MakeUniq { typedef unique_ptr<_Tp> __single_object; }; template<typename _Tp> struct _MakeUniq<_Tp[]> { typedef unique_ptr<_Tp[]> __array; }; template<typename _Tp, size_t _Bound> struct _MakeUniq<_Tp[_Bound]> { struct __invalid_type { }; }; /// std::make_unique for single objects template<typename _Tp, typename... _Args> inline typename _MakeUniq<_Tp>::__single_object make_unique(_Args&&... __args) { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } /// std::make_unique for arrays of unknown bound template<typename _Tp> inline typename _MakeUniq<_Tp>::__array make_unique(size_t __num) { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); } /// Disable std::make_unique for arrays of known bound template<typename _Tp, typename... _Args> inline typename _MakeUniq<_Tp>::__invalid_type make_unique(_Args&&...) = delete; #endif // @} group pointer_abstractions _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _UNIQUE_PTR_H */ c++/8/bits/stl_list.h 0000644 00000203746 15146341150 0010246 0 ustar 00 // List implementation -*- C++ -*- // Copyright (C) 2001-2018 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 bits/stl_list.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{list} */ #ifndef _STL_LIST_H #define _STL_LIST_H 1 #include <bits/concept_check.h> #include <ext/alloc_traits.h> #if __cplusplus >= 201103L #include <initializer_list> #include <bits/allocated_ptr.h> #include <ext/aligned_buffer.h> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { // Supporting structures are split into common and templated // types; the latter publicly inherits from the former in an // effort to reduce code duplication. This results in some // "needless" static_cast'ing later on, but it's all safe // downcasting. /// Common part of a node in the %list. struct _List_node_base { _List_node_base* _M_next; _List_node_base* _M_prev; static void swap(_List_node_base& __x, _List_node_base& __y) _GLIBCXX_USE_NOEXCEPT; void _M_transfer(_List_node_base* const __first, _List_node_base* const __last) _GLIBCXX_USE_NOEXCEPT; void _M_reverse() _GLIBCXX_USE_NOEXCEPT; void _M_hook(_List_node_base* const __position) _GLIBCXX_USE_NOEXCEPT; void _M_unhook() _GLIBCXX_USE_NOEXCEPT; }; /// The %list node header. struct _List_node_header : public _List_node_base { #if _GLIBCXX_USE_CXX11_ABI std::size_t _M_size; #endif _List_node_header() _GLIBCXX_NOEXCEPT { _M_init(); } #if __cplusplus >= 201103L _List_node_header(_List_node_header&& __x) noexcept : _List_node_base{ __x._M_next, __x._M_prev } # if _GLIBCXX_USE_CXX11_ABI , _M_size(__x._M_size) # endif { if (__x._M_base()->_M_next == __x._M_base()) this->_M_next = this->_M_prev = this; else { this->_M_next->_M_prev = this->_M_prev->_M_next = this->_M_base(); __x._M_init(); } } void _M_move_nodes(_List_node_header&& __x) { _List_node_base* const __xnode = __x._M_base(); if (__xnode->_M_next == __xnode) _M_init(); else { _List_node_base* const __node = this->_M_base(); __node->_M_next = __xnode->_M_next; __node->_M_prev = __xnode->_M_prev; __node->_M_next->_M_prev = __node->_M_prev->_M_next = __node; # if _GLIBCXX_USE_CXX11_ABI _M_size = __x._M_size; # endif __x._M_init(); } } #endif void _M_init() _GLIBCXX_NOEXCEPT { this->_M_next = this->_M_prev = this; #if _GLIBCXX_USE_CXX11_ABI this->_M_size = 0; #endif } private: _List_node_base* _M_base() { return this; } }; } // namespace detail _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /// An actual node in the %list. template<typename _Tp> struct _List_node : public __detail::_List_node_base { #if __cplusplus >= 201103L __gnu_cxx::__aligned_membuf<_Tp> _M_storage; _Tp* _M_valptr() { return _M_storage._M_ptr(); } _Tp const* _M_valptr() const { return _M_storage._M_ptr(); } #else _Tp _M_data; _Tp* _M_valptr() { return std::__addressof(_M_data); } _Tp const* _M_valptr() const { return std::__addressof(_M_data); } #endif }; /** * @brief A list::iterator. * * All the functions are op overloads. */ template<typename _Tp> struct _List_iterator { typedef _List_iterator<_Tp> _Self; typedef _List_node<_Tp> _Node; typedef ptrdiff_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; typedef _Tp value_type; typedef _Tp* pointer; typedef _Tp& reference; _List_iterator() _GLIBCXX_NOEXCEPT : _M_node() { } explicit _List_iterator(__detail::_List_node_base* __x) _GLIBCXX_NOEXCEPT : _M_node(__x) { } _Self _M_const_cast() const _GLIBCXX_NOEXCEPT { return *this; } // Must downcast from _List_node_base to _List_node to get to value. reference operator*() const _GLIBCXX_NOEXCEPT { return *static_cast<_Node*>(_M_node)->_M_valptr(); } pointer operator->() const _GLIBCXX_NOEXCEPT { return static_cast<_Node*>(_M_node)->_M_valptr(); } _Self& operator++() _GLIBCXX_NOEXCEPT { _M_node = _M_node->_M_next; return *this; } _Self operator++(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _M_node->_M_next; return __tmp; } _Self& operator--() _GLIBCXX_NOEXCEPT { _M_node = _M_node->_M_prev; return *this; } _Self operator--(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _M_node->_M_prev; return __tmp; } bool operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node == __x._M_node; } bool operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node != __x._M_node; } // The only member points to the %list element. __detail::_List_node_base* _M_node; }; /** * @brief A list::const_iterator. * * All the functions are op overloads. */ template<typename _Tp> struct _List_const_iterator { typedef _List_const_iterator<_Tp> _Self; typedef const _List_node<_Tp> _Node; typedef _List_iterator<_Tp> iterator; typedef ptrdiff_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; typedef _Tp value_type; typedef const _Tp* pointer; typedef const _Tp& reference; _List_const_iterator() _GLIBCXX_NOEXCEPT : _M_node() { } explicit _List_const_iterator(const __detail::_List_node_base* __x) _GLIBCXX_NOEXCEPT : _M_node(__x) { } _List_const_iterator(const iterator& __x) _GLIBCXX_NOEXCEPT : _M_node(__x._M_node) { } iterator _M_const_cast() const _GLIBCXX_NOEXCEPT { return iterator(const_cast<__detail::_List_node_base*>(_M_node)); } // Must downcast from List_node_base to _List_node to get to value. reference operator*() const _GLIBCXX_NOEXCEPT { return *static_cast<_Node*>(_M_node)->_M_valptr(); } pointer operator->() const _GLIBCXX_NOEXCEPT { return static_cast<_Node*>(_M_node)->_M_valptr(); } _Self& operator++() _GLIBCXX_NOEXCEPT { _M_node = _M_node->_M_next; return *this; } _Self operator++(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _M_node->_M_next; return __tmp; } _Self& operator--() _GLIBCXX_NOEXCEPT { _M_node = _M_node->_M_prev; return *this; } _Self operator--(int) _GLIBCXX_NOEXCEPT { _Self __tmp = *this; _M_node = _M_node->_M_prev; return __tmp; } bool operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node == __x._M_node; } bool operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT { return _M_node != __x._M_node; } // The only member points to the %list element. const __detail::_List_node_base* _M_node; }; template<typename _Val> inline bool operator==(const _List_iterator<_Val>& __x, const _List_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT { return __x._M_node == __y._M_node; } template<typename _Val> inline bool operator!=(const _List_iterator<_Val>& __x, const _List_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT { return __x._M_node != __y._M_node; } _GLIBCXX_BEGIN_NAMESPACE_CXX11 /// See bits/stl_deque.h's _Deque_base for an explanation. template<typename _Tp, typename _Alloc> class _List_base { protected: typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type; typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tp_alloc_traits; typedef typename _Tp_alloc_traits::template rebind<_List_node<_Tp> >::other _Node_alloc_type; typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits; #if !_GLIBCXX_INLINE_VERSION static size_t _S_distance(const __detail::_List_node_base* __first, const __detail::_List_node_base* __last) { size_t __n = 0; while (__first != __last) { __first = __first->_M_next; ++__n; } return __n; } #endif struct _List_impl : public _Node_alloc_type { __detail::_List_node_header _M_node; _List_impl() _GLIBCXX_NOEXCEPT_IF( is_nothrow_default_constructible<_Node_alloc_type>::value) : _Node_alloc_type() { } _List_impl(const _Node_alloc_type& __a) _GLIBCXX_NOEXCEPT : _Node_alloc_type(__a) { } #if __cplusplus >= 201103L _List_impl(_List_impl&&) = default; _List_impl(_Node_alloc_type&& __a, _List_impl&& __x) : _Node_alloc_type(std::move(__a)), _M_node(std::move(__x._M_node)) { } _List_impl(_Node_alloc_type&& __a) noexcept : _Node_alloc_type(std::move(__a)) { } #endif }; _List_impl _M_impl; #if _GLIBCXX_USE_CXX11_ABI size_t _M_get_size() const { return _M_impl._M_node._M_size; } void _M_set_size(size_t __n) { _M_impl._M_node._M_size = __n; } void _M_inc_size(size_t __n) { _M_impl._M_node._M_size += __n; } void _M_dec_size(size_t __n) { _M_impl._M_node._M_size -= __n; } # if !_GLIBCXX_INLINE_VERSION size_t _M_distance(const __detail::_List_node_base* __first, const __detail::_List_node_base* __last) const { return _S_distance(__first, __last); } // return the stored size size_t _M_node_count() const { return _M_get_size(); } # endif #else // dummy implementations used when the size is not stored size_t _M_get_size() const { return 0; } void _M_set_size(size_t) { } void _M_inc_size(size_t) { } void _M_dec_size(size_t) { } # if !_GLIBCXX_INLINE_VERSION size_t _M_distance(const void*, const void*) const { return 0; } // count the number of nodes size_t _M_node_count() const { return _S_distance(_M_impl._M_node._M_next, std::__addressof(_M_impl._M_node)); } # endif #endif typename _Node_alloc_traits::pointer _M_get_node() { return _Node_alloc_traits::allocate(_M_impl, 1); } void _M_put_node(typename _Node_alloc_traits::pointer __p) _GLIBCXX_NOEXCEPT { _Node_alloc_traits::deallocate(_M_impl, __p, 1); } public: typedef _Alloc allocator_type; _Node_alloc_type& _M_get_Node_allocator() _GLIBCXX_NOEXCEPT { return _M_impl; } const _Node_alloc_type& _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT { return _M_impl; } #if __cplusplus >= 201103L _List_base() = default; #else _List_base() { } #endif _List_base(const _Node_alloc_type& __a) _GLIBCXX_NOEXCEPT : _M_impl(__a) { } #if __cplusplus >= 201103L _List_base(_List_base&&) = default; # if !_GLIBCXX_INLINE_VERSION _List_base(_List_base&& __x, _Node_alloc_type&& __a) : _M_impl(std::move(__a)) { if (__x._M_get_Node_allocator() == _M_get_Node_allocator()) _M_move_nodes(std::move(__x)); // else caller must move individual elements. } # endif // Used when allocator is_always_equal. _List_base(_Node_alloc_type&& __a, _List_base&& __x) : _M_impl(std::move(__a), std::move(__x._M_impl)) { } // Used when allocator !is_always_equal. _List_base(_Node_alloc_type&& __a) : _M_impl(std::move(__a)) { } void _M_move_nodes(_List_base&& __x) { _M_impl._M_node._M_move_nodes(std::move(__x._M_impl._M_node)); } #endif // This is what actually destroys the list. ~_List_base() _GLIBCXX_NOEXCEPT { _M_clear(); } void _M_clear() _GLIBCXX_NOEXCEPT; void _M_init() _GLIBCXX_NOEXCEPT { this->_M_impl._M_node._M_init(); } }; /** * @brief A standard container with linear time access to elements, * and fixed time insertion/deletion at any point in the sequence. * * @ingroup sequences * * @tparam _Tp Type of element. * @tparam _Alloc Allocator type, defaults to allocator<_Tp>. * * 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>, including the * <a href="tables.html#68">optional sequence requirements</a> with the * %exception of @c at and @c operator[]. * * This is a @e doubly @e linked %list. Traversal up and down the * %list requires linear time, but adding and removing elements (or * @e nodes) is done in constant time, regardless of where the * change takes place. Unlike std::vector and std::deque, * random-access iterators are not provided, so subscripting ( @c * [] ) access is not allowed. For algorithms which only need * sequential access, this lack makes no difference. * * Also unlike the other standard containers, std::list provides * specialized algorithms %unique to linked lists, such as * splicing, sorting, and in-place reversal. * * A couple points on memory allocation for list<Tp>: * * First, we never actually allocate a Tp, we allocate * List_node<Tp>'s and trust [20.1.5]/4 to DTRT. This is to ensure * that after elements from %list<X,Alloc1> are spliced into * %list<X,Alloc2>, destroying the memory of the second %list is a * valid operation, i.e., Alloc1 giveth and Alloc2 taketh away. * * Second, a %list conceptually represented as * @code * A <---> B <---> C <---> D * @endcode * is actually circular; a link exists between A and D. The %list * class holds (as its only data member) a private list::iterator * pointing to @e D, not to @e A! To get to the head of the %list, * we start at the tail and move forward by one. When this member * iterator's next/previous pointers refer to itself, the %list is * %empty. */ template<typename _Tp, typename _Alloc = std::allocator<_Tp> > class list : protected _List_base<_Tp, _Alloc> { #ifdef _GLIBCXX_CONCEPT_CHECKS // concept requirements typedef typename _Alloc::value_type _Alloc_value_type; # if __cplusplus < 201103L __glibcxx_class_requires(_Tp, _SGIAssignableConcept) # endif __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) #endif #if __cplusplus >= 201103L static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value, "std::list must have a non-const, non-volatile value_type"); # ifdef __STRICT_ANSI__ static_assert(is_same<typename _Alloc::value_type, _Tp>::value, "std::list must have the same value_type as its allocator"); # endif #endif typedef _List_base<_Tp, _Alloc> _Base; typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; typedef typename _Base::_Tp_alloc_traits _Tp_alloc_traits; typedef typename _Base::_Node_alloc_type _Node_alloc_type; typedef typename _Base::_Node_alloc_traits _Node_alloc_traits; public: typedef _Tp value_type; typedef typename _Tp_alloc_traits::pointer pointer; typedef typename _Tp_alloc_traits::const_pointer const_pointer; typedef typename _Tp_alloc_traits::reference reference; typedef typename _Tp_alloc_traits::const_reference const_reference; typedef _List_iterator<_Tp> iterator; typedef _List_const_iterator<_Tp> const_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Alloc allocator_type; protected: // Note that pointers-to-_Node's can be ctor-converted to // iterator types. typedef _List_node<_Tp> _Node; using _Base::_M_impl; using _Base::_M_put_node; using _Base::_M_get_node; using _Base::_M_get_Node_allocator; /** * @param __args An instance of user data. * * Allocates space for a new node and constructs a copy of * @a __args in it. */ #if __cplusplus < 201103L _Node* _M_create_node(const value_type& __x) { _Node* __p = this->_M_get_node(); __try { _Tp_alloc_type __alloc(_M_get_Node_allocator()); __alloc.construct(__p->_M_valptr(), __x); } __catch(...) { _M_put_node(__p); __throw_exception_again; } return __p; } #else template<typename... _Args> _Node* _M_create_node(_Args&&... __args) { auto __p = this->_M_get_node(); auto& __alloc = _M_get_Node_allocator(); __allocated_ptr<_Node_alloc_type> __guard{__alloc, __p}; _Node_alloc_traits::construct(__alloc, __p->_M_valptr(), std::forward<_Args>(__args)...); __guard = nullptr; return __p; } #endif #if _GLIBCXX_USE_CXX11_ABI static size_t _S_distance(const_iterator __first, const_iterator __last) { return std::distance(__first, __last); } // return the stored size size_t _M_node_count() const { return this->_M_get_size(); } #else // dummy implementations used when the size is not stored static size_t _S_distance(const_iterator, const_iterator) { return 0; } // count the number of nodes size_t _M_node_count() const { return std::distance(begin(), end()); } #endif public: // [23.2.2.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) /** * @brief Creates a %list with no elements. */ #if __cplusplus >= 201103L list() = default; #else list() { } #endif /** * @brief Creates a %list with no elements. * @param __a An allocator object. */ explicit list(const allocator_type& __a) _GLIBCXX_NOEXCEPT : _Base(_Node_alloc_type(__a)) { } #if __cplusplus >= 201103L /** * @brief Creates a %list with default constructed elements. * @param __n The number of elements to initially create. * @param __a An allocator object. * * This constructor fills the %list with @a __n default * constructed elements. */ explicit list(size_type __n, const allocator_type& __a = allocator_type()) : _Base(_Node_alloc_type(__a)) { _M_default_initialize(__n); } /** * @brief Creates a %list with copies of an exemplar element. * @param __n The number of elements to initially create. * @param __value An element to copy. * @param __a An allocator object. * * This constructor fills the %list with @a __n copies of @a __value. */ list(size_type __n, const value_type& __value, const allocator_type& __a = allocator_type()) : _Base(_Node_alloc_type(__a)) { _M_fill_initialize(__n, __value); } #else /** * @brief Creates a %list with copies of an exemplar element. * @param __n The number of elements to initially create. * @param __value An element to copy. * @param __a An allocator object. * * This constructor fills the %list with @a __n copies of @a __value. */ explicit list(size_type __n, const value_type& __value = value_type(), const allocator_type& __a = allocator_type()) : _Base(_Node_alloc_type(__a)) { _M_fill_initialize(__n, __value); } #endif /** * @brief %List copy constructor. * @param __x A %list of identical element and allocator types. * * The newly-created %list uses a copy of the allocation object used * by @a __x (unless the allocator traits dictate a different object). */ list(const list& __x) : _Base(_Node_alloc_traits:: _S_select_on_copy(__x._M_get_Node_allocator())) { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); } #if __cplusplus >= 201103L /** * @brief %List move constructor. * * The newly-created %list contains the exact contents of the moved * instance. The contents of the moved instance are a valid, but * unspecified %list. */ list(list&&) = default; /** * @brief Builds a %list from an initializer_list * @param __l An initializer_list of value_type. * @param __a An allocator object. * * Create a %list consisting of copies of the elements in the * initializer_list @a __l. This is linear in __l.size(). */ list(initializer_list<value_type> __l, const allocator_type& __a = allocator_type()) : _Base(_Node_alloc_type(__a)) { _M_initialize_dispatch(__l.begin(), __l.end(), __false_type()); } list(const list& __x, const allocator_type& __a) : _Base(_Node_alloc_type(__a)) { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); } private: list(list&& __x, const allocator_type& __a, true_type) noexcept : _Base(_Node_alloc_type(__a), std::move(__x)) { } list(list&& __x, const allocator_type& __a, false_type) : _Base(_Node_alloc_type(__a)) { if (__x._M_get_Node_allocator() == this->_M_get_Node_allocator()) this->_M_move_nodes(std::move(__x)); else insert(begin(), std::__make_move_if_noexcept_iterator(__x.begin()), std::__make_move_if_noexcept_iterator(__x.end())); } public: list(list&& __x, const allocator_type& __a) noexcept(_Node_alloc_traits::_S_always_equal()) : list(std::move(__x), __a, typename _Node_alloc_traits::is_always_equal{}) { } #endif /** * @brief Builds a %list from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __a An allocator object. * * Create a %list consisting of copies of the elements from * [@a __first,@a __last). This is linear in N (where N is * distance(@a __first,@a __last)). */ #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> list(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(_Node_alloc_type(__a)) { _M_initialize_dispatch(__first, __last, __false_type()); } #else template<typename _InputIterator> list(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(_Node_alloc_type(__a)) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } #endif #if __cplusplus >= 201103L /** * No explicit dtor needed as the _Base dtor takes care of * things. The _Base dtor only erases the elements, and note * that if the elements themselves are pointers, the pointed-to * memory is not touched in any way. Managing the pointer is * the user's responsibility. */ ~list() = default; #endif /** * @brief %List assignment operator. * @param __x A %list of identical element and allocator types. * * All the elements of @a __x are copied. * * Whether the allocator is copied depends on the allocator traits. */ list& operator=(const list& __x); #if __cplusplus >= 201103L /** * @brief %List move assignment operator. * @param __x A %list of identical element and allocator types. * * The contents of @a __x are moved into this %list (without copying). * * Afterwards @a __x is a valid, but unspecified %list * * Whether the allocator is moved depends on the allocator traits. */ list& operator=(list&& __x) noexcept(_Node_alloc_traits::_S_nothrow_move()) { constexpr bool __move_storage = _Node_alloc_traits::_S_propagate_on_move_assign() || _Node_alloc_traits::_S_always_equal(); _M_move_assign(std::move(__x), __bool_constant<__move_storage>()); return *this; } /** * @brief %List initializer list assignment operator. * @param __l An initializer_list of value_type. * * Replace the contents of the %list with copies of the elements * in the initializer_list @a __l. This is linear in l.size(). */ list& operator=(initializer_list<value_type> __l) { this->assign(__l.begin(), __l.end()); return *this; } #endif /** * @brief Assigns a given value to a %list. * @param __n Number of elements to be assigned. * @param __val Value to be assigned. * * This function fills a %list with @a __n copies of the given * value. Note that the assignment completely changes the %list * and that the resulting %list's size is the same as the number * of elements assigned. */ void assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); } /** * @brief Assigns a range to a %list. * @param __first An input iterator. * @param __last An input iterator. * * This function fills a %list with copies of the elements in the * range [@a __first,@a __last). * * Note that the assignment completely changes the %list and * that the resulting %list's size is the same as the number of * elements assigned. */ #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> void assign(_InputIterator __first, _InputIterator __last) { _M_assign_dispatch(__first, __last, __false_type()); } #else template<typename _InputIterator> void assign(_InputIterator __first, _InputIterator __last) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_assign_dispatch(__first, __last, _Integral()); } #endif #if __cplusplus >= 201103L /** * @brief Assigns an initializer_list to a %list. * @param __l An initializer_list of value_type. * * Replace the contents of the %list with copies of the elements * in the initializer_list @a __l. This is linear in __l.size(). */ void assign(initializer_list<value_type> __l) { this->_M_assign_dispatch(__l.begin(), __l.end(), __false_type()); } #endif /// Get a copy of the memory allocation object. allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_Base::_M_get_Node_allocator()); } // iterators /** * Returns a read/write iterator that points to the first element in the * %list. Iteration is done in ordinary element order. */ iterator begin() _GLIBCXX_NOEXCEPT { return iterator(this->_M_impl._M_node._M_next); } /** * Returns a read-only (constant) iterator that points to the * first element in the %list. Iteration is done in ordinary * element order. */ const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(this->_M_impl._M_node._M_next); } /** * Returns a read/write iterator that points one past the last * element in the %list. Iteration is done in ordinary element * order. */ iterator end() _GLIBCXX_NOEXCEPT { return iterator(&this->_M_impl._M_node); } /** * Returns a read-only (constant) iterator that points one past * the last element in the %list. Iteration is done in ordinary * element order. */ const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(&this->_M_impl._M_node); } /** * Returns a read/write reverse iterator that points to the last * element in the %list. Iteration is done in reverse element * order. */ reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return reverse_iterator(end()); } /** * Returns a read-only (constant) reverse iterator that points to * the last element in the %list. Iteration is done in reverse * element order. */ const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(end()); } /** * Returns a read/write reverse iterator that points to one * before the first element in the %list. Iteration is done in * reverse element order. */ reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(begin()); } /** * Returns a read-only (constant) reverse iterator that points to one * before the first element in the %list. Iteration is done in reverse * element order. */ const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L /** * Returns a read-only (constant) iterator that points to the * first element in the %list. Iteration is done in ordinary * element order. */ const_iterator cbegin() const noexcept { return const_iterator(this->_M_impl._M_node._M_next); } /** * Returns a read-only (constant) iterator that points one past * the last element in the %list. Iteration is done in ordinary * element order. */ const_iterator cend() const noexcept { return const_iterator(&this->_M_impl._M_node); } /** * Returns a read-only (constant) reverse iterator that points to * the last element in the %list. Iteration is done in reverse * element order. */ const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } /** * Returns a read-only (constant) reverse iterator that points to one * before the first element in the %list. Iteration is done in reverse * element order. */ const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } #endif // [23.2.2.2] capacity /** * Returns true if the %list is empty. (Thus begin() would equal * end().) */ bool empty() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; } /** Returns the number of elements in the %list. */ size_type size() const _GLIBCXX_NOEXCEPT { return _M_node_count(); } /** Returns the size() of the largest possible %list. */ size_type max_size() const _GLIBCXX_NOEXCEPT { return _Node_alloc_traits::max_size(_M_get_Node_allocator()); } #if __cplusplus >= 201103L /** * @brief Resizes the %list to the specified number of elements. * @param __new_size Number of elements the %list should contain. * * This function will %resize the %list to the specified number * of elements. If the number is smaller than the %list's * current size the %list is truncated, otherwise default * constructed elements are appended. */ void resize(size_type __new_size); /** * @brief Resizes the %list to the specified number of elements. * @param __new_size Number of elements the %list should contain. * @param __x Data with which new elements should be populated. * * This function will %resize the %list to the specified number * of elements. If the number is smaller than the %list's * current size the %list is truncated, otherwise the %list is * extended and new elements are populated with given data. */ void resize(size_type __new_size, const value_type& __x); #else /** * @brief Resizes the %list to the specified number of elements. * @param __new_size Number of elements the %list should contain. * @param __x Data with which new elements should be populated. * * This function will %resize the %list to the specified number * of elements. If the number is smaller than the %list's * current size the %list is truncated, otherwise the %list is * extended and new elements are populated with given data. */ void resize(size_type __new_size, value_type __x = value_type()); #endif // element access /** * Returns a read/write reference to the data at the first * element of the %list. */ reference front() _GLIBCXX_NOEXCEPT { return *begin(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %list. */ const_reference front() const _GLIBCXX_NOEXCEPT { return *begin(); } /** * Returns a read/write reference to the data at the last element * of the %list. */ reference back() _GLIBCXX_NOEXCEPT { iterator __tmp = end(); --__tmp; return *__tmp; } /** * Returns a read-only (constant) reference to the data at the last * element of the %list. */ const_reference back() const _GLIBCXX_NOEXCEPT { const_iterator __tmp = end(); --__tmp; return *__tmp; } // [23.2.2.3] modifiers /** * @brief Add data to the front of the %list. * @param __x Data to be added. * * This is a typical stack operation. The function creates an * element at the front of the %list and assigns the given data * to it. Due to the nature of a %list this operation can be * done in constant time, and does not invalidate iterators and * references. */ void push_front(const value_type& __x) { this->_M_insert(begin(), __x); } #if __cplusplus >= 201103L void push_front(value_type&& __x) { this->_M_insert(begin(), std::move(__x)); } template<typename... _Args> #if __cplusplus > 201402L reference #else void #endif emplace_front(_Args&&... __args) { this->_M_insert(begin(), std::forward<_Args>(__args)...); #if __cplusplus > 201402L return front(); #endif } #endif /** * @brief Removes first element. * * This is a typical stack operation. It shrinks the %list by * one. Due to the nature of a %list this operation can be done * in constant time, and only invalidates iterators/references to * the element being removed. * * Note that no data is returned, and if the first element's data * is needed, it should be retrieved before pop_front() is * called. */ void pop_front() _GLIBCXX_NOEXCEPT { this->_M_erase(begin()); } /** * @brief Add data to the end of the %list. * @param __x Data to be added. * * This is a typical stack operation. The function creates an * element at the end of the %list and assigns the given data to * it. Due to the nature of a %list this operation can be done * in constant time, and does not invalidate iterators and * references. */ void push_back(const value_type& __x) { this->_M_insert(end(), __x); } #if __cplusplus >= 201103L void push_back(value_type&& __x) { this->_M_insert(end(), std::move(__x)); } template<typename... _Args> #if __cplusplus > 201402L reference #else void #endif emplace_back(_Args&&... __args) { this->_M_insert(end(), std::forward<_Args>(__args)...); #if __cplusplus > 201402L return back(); #endif } #endif /** * @brief Removes last element. * * This is a typical stack operation. It shrinks the %list by * one. Due to the nature of a %list this operation can be done * in constant time, and only invalidates iterators/references to * the element being removed. * * Note that no data is returned, and if the last element's data * is needed, it should be retrieved before pop_back() is called. */ void pop_back() _GLIBCXX_NOEXCEPT { this->_M_erase(iterator(this->_M_impl._M_node._M_prev)); } #if __cplusplus >= 201103L /** * @brief Constructs object in %list before specified iterator. * @param __position A const_iterator into the %list. * @param __args Arguments. * @return An iterator that points to the inserted data. * * This function will insert an object of type T constructed * with T(std::forward<Args>(args)...) before the specified * location. Due to the nature of a %list this operation can * be done in constant time, and does not invalidate iterators * and references. */ template<typename... _Args> iterator emplace(const_iterator __position, _Args&&... __args); /** * @brief Inserts given value into %list before specified iterator. * @param __position A const_iterator into the %list. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given value before * the specified location. Due to the nature of a %list this * operation can be done in constant time, and does not * invalidate iterators and references. */ iterator insert(const_iterator __position, const value_type& __x); #else /** * @brief Inserts given value into %list before specified iterator. * @param __position An iterator into the %list. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given value before * the specified location. Due to the nature of a %list this * operation can be done in constant time, and does not * invalidate iterators and references. */ iterator insert(iterator __position, const value_type& __x); #endif #if __cplusplus >= 201103L /** * @brief Inserts given rvalue into %list before specified iterator. * @param __position A const_iterator into the %list. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given rvalue before * the specified location. Due to the nature of a %list this * operation can be done in constant time, and does not * invalidate iterators and references. */ iterator insert(const_iterator __position, value_type&& __x) { return emplace(__position, std::move(__x)); } /** * @brief Inserts the contents of an initializer_list into %list * before specified const_iterator. * @param __p A const_iterator into the %list. * @param __l An initializer_list of value_type. * @return An iterator pointing to the first element inserted * (or __position). * * This function will insert copies of the data in the * initializer_list @a l into the %list before the location * specified by @a p. * * This operation is linear in the number of elements inserted and * does not invalidate iterators and references. */ iterator insert(const_iterator __p, initializer_list<value_type> __l) { return this->insert(__p, __l.begin(), __l.end()); } #endif #if __cplusplus >= 201103L /** * @brief Inserts a number of copies of given data into the %list. * @param __position A const_iterator into the %list. * @param __n Number of elements to be inserted. * @param __x Data to be inserted. * @return An iterator pointing to the first element inserted * (or __position). * * This function will insert a specified number of copies of the * given data before the location specified by @a position. * * This operation is linear in the number of elements inserted and * does not invalidate iterators and references. */ iterator insert(const_iterator __position, size_type __n, const value_type& __x); #else /** * @brief Inserts a number of copies of given data into the %list. * @param __position An iterator into the %list. * @param __n Number of elements to be inserted. * @param __x Data to be inserted. * * This function will insert a specified number of copies of the * given data before the location specified by @a position. * * This operation is linear in the number of elements inserted and * does not invalidate iterators and references. */ void insert(iterator __position, size_type __n, const value_type& __x) { list __tmp(__n, __x, get_allocator()); splice(__position, __tmp); } #endif #if __cplusplus >= 201103L /** * @brief Inserts a range into the %list. * @param __position A const_iterator into the %list. * @param __first An input iterator. * @param __last An input iterator. * @return An iterator pointing to the first element inserted * (or __position). * * This function will insert copies of the data in the range [@a * first,@a last) into the %list before the location specified by * @a position. * * This operation is linear in the number of elements inserted and * does not invalidate iterators and references. */ template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> iterator insert(const_iterator __position, _InputIterator __first, _InputIterator __last); #else /** * @brief Inserts a range into the %list. * @param __position An iterator into the %list. * @param __first An input iterator. * @param __last An input iterator. * * This function will insert copies of the data in the range [@a * first,@a last) into the %list before the location specified by * @a position. * * This operation is linear in the number of elements inserted and * does not invalidate iterators and references. */ template<typename _InputIterator> void insert(iterator __position, _InputIterator __first, _InputIterator __last) { list __tmp(__first, __last, get_allocator()); splice(__position, __tmp); } #endif /** * @brief Remove element at given position. * @param __position Iterator pointing to element to be erased. * @return An iterator pointing to the next element (or end()). * * This function will erase the element at the given position and thus * shorten the %list by one. * * Due to the nature of a %list this operation can be done in * constant time, and only invalidates iterators/references to * the element being removed. The user is also cautioned that * this function only erases the element, and that if the element * is itself a pointer, the pointed-to memory is not touched in * any way. Managing the pointer is the user's responsibility. */ iterator #if __cplusplus >= 201103L erase(const_iterator __position) noexcept; #else erase(iterator __position); #endif /** * @brief Remove a range of elements. * @param __first Iterator pointing to the first element to be erased. * @param __last Iterator pointing to one past the last element to be * erased. * @return An iterator pointing to the element pointed to by @a last * prior to erasing (or end()). * * This function will erase the elements in the range @a * [first,last) and shorten the %list accordingly. * * This operation is linear time in the size of the range and only * invalidates iterators/references to the element being removed. * The user is also cautioned that this function only erases the * elements, and that if the elements themselves are pointers, the * pointed-to memory is not touched in any way. Managing the pointer * is the user's responsibility. */ iterator #if __cplusplus >= 201103L erase(const_iterator __first, const_iterator __last) noexcept #else erase(iterator __first, iterator __last) #endif { while (__first != __last) __first = erase(__first); return __last._M_const_cast(); } /** * @brief Swaps data with another %list. * @param __x A %list of the same element and allocator types. * * This exchanges the elements between two lists in constant * time. Note that the global std::swap() function is * specialized such that std::swap(l1,l2) will feed to this * function. * * Whether the allocators are swapped depends on the allocator traits. */ void swap(list& __x) _GLIBCXX_NOEXCEPT { __detail::_List_node_base::swap(this->_M_impl._M_node, __x._M_impl._M_node); size_t __xsize = __x._M_get_size(); __x._M_set_size(this->_M_get_size()); this->_M_set_size(__xsize); _Node_alloc_traits::_S_on_swap(this->_M_get_Node_allocator(), __x._M_get_Node_allocator()); } /** * Erases all the elements. Note that this function only erases * the elements, and that if the elements themselves are * pointers, the pointed-to memory is not touched in any way. * Managing the pointer is the user's responsibility. */ void clear() _GLIBCXX_NOEXCEPT { _Base::_M_clear(); _Base::_M_init(); } // [23.2.2.4] list operations /** * @brief Insert contents of another %list. * @param __position Iterator referencing the element to insert before. * @param __x Source list. * * The elements of @a __x are inserted in constant time in front of * the element referenced by @a __position. @a __x becomes an empty * list. * * Requires this != @a __x. */ void #if __cplusplus >= 201103L splice(const_iterator __position, list&& __x) noexcept #else splice(iterator __position, list& __x) #endif { if (!__x.empty()) { _M_check_equal_allocators(__x); this->_M_transfer(__position._M_const_cast(), __x.begin(), __x.end()); this->_M_inc_size(__x._M_get_size()); __x._M_set_size(0); } } #if __cplusplus >= 201103L void splice(const_iterator __position, list& __x) noexcept { splice(__position, std::move(__x)); } #endif #if __cplusplus >= 201103L /** * @brief Insert element from another %list. * @param __position Const_iterator referencing the element to * insert before. * @param __x Source list. * @param __i Const_iterator referencing the element to move. * * Removes the element in list @a __x referenced by @a __i and * inserts it into the current list before @a __position. */ void splice(const_iterator __position, list&& __x, const_iterator __i) noexcept #else /** * @brief Insert element from another %list. * @param __position Iterator referencing the element to insert before. * @param __x Source list. * @param __i Iterator referencing the element to move. * * Removes the element in list @a __x referenced by @a __i and * inserts it into the current list before @a __position. */ void splice(iterator __position, list& __x, iterator __i) #endif { iterator __j = __i._M_const_cast(); ++__j; if (__position == __i || __position == __j) return; if (this != std::__addressof(__x)) _M_check_equal_allocators(__x); this->_M_transfer(__position._M_const_cast(), __i._M_const_cast(), __j); this->_M_inc_size(1); __x._M_dec_size(1); } #if __cplusplus >= 201103L /** * @brief Insert element from another %list. * @param __position Const_iterator referencing the element to * insert before. * @param __x Source list. * @param __i Const_iterator referencing the element to move. * * Removes the element in list @a __x referenced by @a __i and * inserts it into the current list before @a __position. */ void splice(const_iterator __position, list& __x, const_iterator __i) noexcept { splice(__position, std::move(__x), __i); } #endif #if __cplusplus >= 201103L /** * @brief Insert range from another %list. * @param __position Const_iterator referencing the element to * insert before. * @param __x Source list. * @param __first Const_iterator referencing the start of range in x. * @param __last Const_iterator referencing the end of range in x. * * Removes elements in the range [__first,__last) and inserts them * before @a __position in constant time. * * Undefined if @a __position is in [__first,__last). */ void splice(const_iterator __position, list&& __x, const_iterator __first, const_iterator __last) noexcept #else /** * @brief Insert range from another %list. * @param __position Iterator referencing the element to insert before. * @param __x Source list. * @param __first Iterator referencing the start of range in x. * @param __last Iterator referencing the end of range in x. * * Removes elements in the range [__first,__last) and inserts them * before @a __position in constant time. * * Undefined if @a __position is in [__first,__last). */ void splice(iterator __position, list& __x, iterator __first, iterator __last) #endif { if (__first != __last) { if (this != std::__addressof(__x)) _M_check_equal_allocators(__x); size_t __n = _S_distance(__first, __last); this->_M_inc_size(__n); __x._M_dec_size(__n); this->_M_transfer(__position._M_const_cast(), __first._M_const_cast(), __last._M_const_cast()); } } #if __cplusplus >= 201103L /** * @brief Insert range from another %list. * @param __position Const_iterator referencing the element to * insert before. * @param __x Source list. * @param __first Const_iterator referencing the start of range in x. * @param __last Const_iterator referencing the end of range in x. * * Removes elements in the range [__first,__last) and inserts them * before @a __position in constant time. * * Undefined if @a __position is in [__first,__last). */ void splice(const_iterator __position, list& __x, const_iterator __first, const_iterator __last) noexcept { splice(__position, std::move(__x), __first, __last); } #endif /** * @brief Remove all elements equal to value. * @param __value The value to remove. * * Removes every element in the list equal to @a value. * Remaining elements stay in list order. Note that this * function only erases the elements, and that if the elements * themselves are pointers, the pointed-to memory is not * touched in any way. Managing the pointer is the user's * responsibility. */ void remove(const _Tp& __value); /** * @brief Remove all elements satisfying a predicate. * @tparam _Predicate Unary predicate function or object. * * Removes every element in the list for which the predicate * returns true. Remaining elements stay in list order. Note * that this function only erases the elements, and that if the * elements themselves are pointers, the pointed-to memory is * not touched in any way. Managing the pointer is the user's * responsibility. */ template<typename _Predicate> void remove_if(_Predicate); /** * @brief Remove consecutive duplicate elements. * * For each consecutive set of elements with the same value, * remove all but the first one. Remaining elements stay in * list order. Note that this function only erases the * elements, and that if the elements themselves are pointers, * the pointed-to memory is not touched in any way. Managing * the pointer is the user's responsibility. */ void unique(); /** * @brief Remove consecutive elements satisfying a predicate. * @tparam _BinaryPredicate Binary predicate function or object. * * For each consecutive set of elements [first,last) that * satisfy predicate(first,i) where i is an iterator in * [first,last), remove all but the first one. Remaining * elements stay in list order. Note that this function only * erases the elements, and that if the elements themselves are * pointers, the pointed-to memory is not touched in any way. * Managing the pointer is the user's responsibility. */ template<typename _BinaryPredicate> void unique(_BinaryPredicate); /** * @brief Merge sorted lists. * @param __x Sorted list to merge. * * Assumes that both @a __x and this list are sorted according to * operator<(). Merges elements of @a __x into this list in * sorted order, leaving @a __x empty when complete. Elements in * this list precede elements in @a __x that are equal. */ #if __cplusplus >= 201103L void merge(list&& __x); void merge(list& __x) { merge(std::move(__x)); } #else void merge(list& __x); #endif /** * @brief Merge sorted lists according to comparison function. * @tparam _StrictWeakOrdering Comparison function defining * sort order. * @param __x Sorted list to merge. * @param __comp Comparison functor. * * Assumes that both @a __x and this list are sorted according to * StrictWeakOrdering. Merges elements of @a __x into this list * in sorted order, leaving @a __x empty when complete. Elements * in this list precede elements in @a __x that are equivalent * according to StrictWeakOrdering(). */ #if __cplusplus >= 201103L template<typename _StrictWeakOrdering> void merge(list&& __x, _StrictWeakOrdering __comp); template<typename _StrictWeakOrdering> void merge(list& __x, _StrictWeakOrdering __comp) { merge(std::move(__x), __comp); } #else template<typename _StrictWeakOrdering> void merge(list& __x, _StrictWeakOrdering __comp); #endif /** * @brief Reverse the elements in list. * * Reverse the order of elements in the list in linear time. */ void reverse() _GLIBCXX_NOEXCEPT { this->_M_impl._M_node._M_reverse(); } /** * @brief Sort the elements. * * Sorts the elements of this list in NlogN time. Equivalent * elements remain in list order. */ void sort(); /** * @brief Sort the elements according to comparison function. * * Sorts the elements of this list in NlogN time. Equivalent * elements remain in list order. */ template<typename _StrictWeakOrdering> void sort(_StrictWeakOrdering); protected: // Internal constructor functions follow. // Called by the range constructor to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { _M_fill_initialize(static_cast<size_type>(__n), __x); } // Called by the range constructor to implement [23.1.1]/9 template<typename _InputIterator> void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { for (; __first != __last; ++__first) #if __cplusplus >= 201103L emplace_back(*__first); #else push_back(*__first); #endif } // Called by list(n,v,a), and the range constructor when it turns out // to be the same thing. void _M_fill_initialize(size_type __n, const value_type& __x) { for (; __n; --__n) push_back(__x); } #if __cplusplus >= 201103L // Called by list(n). void _M_default_initialize(size_type __n) { for (; __n; --__n) emplace_back(); } // Called by resize(sz). void _M_default_append(size_type __n); #endif // Internal assign functions follow. // Called by the range assign to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign(__n, __val); } // Called by the range assign to implement [23.1.1]/9 template<typename _InputIterator> void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type); // Called by assign(n,t), and the range assign when it turns out // to be the same thing. void _M_fill_assign(size_type __n, const value_type& __val); // Moves the elements from [first,last) before position. void _M_transfer(iterator __position, iterator __first, iterator __last) { __position._M_node->_M_transfer(__first._M_node, __last._M_node); } // Inserts new element at position given and with value given. #if __cplusplus < 201103L void _M_insert(iterator __position, const value_type& __x) { _Node* __tmp = _M_create_node(__x); __tmp->_M_hook(__position._M_node); this->_M_inc_size(1); } #else template<typename... _Args> void _M_insert(iterator __position, _Args&&... __args) { _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...); __tmp->_M_hook(__position._M_node); this->_M_inc_size(1); } #endif // Erases element at position given. void _M_erase(iterator __position) _GLIBCXX_NOEXCEPT { this->_M_dec_size(1); __position._M_node->_M_unhook(); _Node* __n = static_cast<_Node*>(__position._M_node); #if __cplusplus >= 201103L _Node_alloc_traits::destroy(_M_get_Node_allocator(), __n->_M_valptr()); #else _Tp_alloc_type(_M_get_Node_allocator()).destroy(__n->_M_valptr()); #endif _M_put_node(__n); } // To implement the splice (and merge) bits of N1599. void _M_check_equal_allocators(list& __x) _GLIBCXX_NOEXCEPT { if (std::__alloc_neq<typename _Base::_Node_alloc_type>:: _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator())) __builtin_abort(); } // Used to implement resize. const_iterator _M_resize_pos(size_type& __new_size) const; #if __cplusplus >= 201103L void _M_move_assign(list&& __x, true_type) noexcept { this->_M_clear(); this->_M_move_nodes(std::move(__x)); std::__alloc_on_move(this->_M_get_Node_allocator(), __x._M_get_Node_allocator()); } void _M_move_assign(list&& __x, false_type) { if (__x._M_get_Node_allocator() == this->_M_get_Node_allocator()) _M_move_assign(std::move(__x), true_type{}); else // The rvalue's allocator cannot be moved, or is not equal, // so we need to individually move each element. _M_assign_dispatch(std::__make_move_if_noexcept_iterator(__x.begin()), std::__make_move_if_noexcept_iterator(__x.end()), __false_type{}); } #endif }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _ValT = typename iterator_traits<_InputIterator>::value_type, typename _Allocator = allocator<_ValT>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> list(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> list<_ValT, _Allocator>; #endif _GLIBCXX_END_NAMESPACE_CXX11 /** * @brief List equality comparison. * @param __x A %list. * @param __y A %list of the same type as @a __x. * @return True iff the size and elements of the lists are equal. * * This is an equivalence relation. It is linear in the size of * the lists. Lists are considered equivalent if their sizes are * equal, and if corresponding elements compare equal. */ template<typename _Tp, typename _Alloc> inline bool operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { #if _GLIBCXX_USE_CXX11_ABI if (__x.size() != __y.size()) return false; #endif typedef typename list<_Tp, _Alloc>::const_iterator const_iterator; const_iterator __end1 = __x.end(); const_iterator __end2 = __y.end(); const_iterator __i1 = __x.begin(); const_iterator __i2 = __y.begin(); while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { ++__i1; ++__i2; } return __i1 == __end1 && __i2 == __end2; } /** * @brief List ordering relation. * @param __x A %list. * @param __y A %list of the same type as @a __x. * @return True iff @a __x is lexicographically less than @a __y. * * This is a total ordering relation. It is linear in the size of the * lists. The elements must be comparable with @c <. * * See std::lexicographical_compare() for how the determination is made. */ template<typename _Tp, typename _Alloc> inline bool operator<(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } /// Based on operator== template<typename _Tp, typename _Alloc> inline bool operator!=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return !(__x == __y); } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return __y < __x; } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return !(__y < __x); } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) { return !(__x < __y); } /// See std::list::swap(). template<typename _Tp, typename _Alloc> inline void swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER #if _GLIBCXX_USE_CXX11_ABI // Detect when distance is used to compute the size of the whole list. template<typename _Tp> inline ptrdiff_t __distance(_GLIBCXX_STD_C::_List_iterator<_Tp> __first, _GLIBCXX_STD_C::_List_iterator<_Tp> __last, input_iterator_tag __tag) { typedef _GLIBCXX_STD_C::_List_const_iterator<_Tp> _CIter; return std::__distance(_CIter(__first), _CIter(__last), __tag); } template<typename _Tp> inline ptrdiff_t __distance(_GLIBCXX_STD_C::_List_const_iterator<_Tp> __first, _GLIBCXX_STD_C::_List_const_iterator<_Tp> __last, input_iterator_tag) { typedef __detail::_List_node_header _Sentinel; _GLIBCXX_STD_C::_List_const_iterator<_Tp> __beyond = __last; ++__beyond; const bool __whole = __first == __beyond; if (__builtin_constant_p (__whole) && __whole) return static_cast<const _Sentinel*>(__last._M_node)->_M_size; ptrdiff_t __n = 0; while (__first != __last) { ++__first; ++__n; } return __n; } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _STL_LIST_H */ c++/8/bits/stl_relops.h 0000644 00000010762 15146341150 0010571 0 ustar 00 // std::rel_ops implementation -*- C++ -*- // Copyright (C) 2001-2018 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, 2009 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 * * 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/stl_relops.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{utility} * * Inclusion of this file has been removed from * all of the other STL headers for safety reasons, except std_utility.h. * For more information, see the thread of about twenty messages starting * with http://gcc.gnu.org/ml/libstdc++/2001-01/msg00223.html, or * http://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.ambiguous_overloads * * Short summary: the rel_ops operators should be avoided for the present. */ #ifndef _STL_RELOPS_H #define _STL_RELOPS_H 1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace rel_ops { /** @namespace std::rel_ops * @brief The generated relational operators are sequestered here. */ /** * @brief Defines @c != for arbitrary types, in terms of @c ==. * @param __x A thing. * @param __y Another thing. * @return __x != __y * * This function uses @c == to determine its result. */ template <class _Tp> inline bool operator!=(const _Tp& __x, const _Tp& __y) { return !(__x == __y); } /** * @brief Defines @c > for arbitrary types, in terms of @c <. * @param __x A thing. * @param __y Another thing. * @return __x > __y * * This function uses @c < to determine its result. */ template <class _Tp> inline bool operator>(const _Tp& __x, const _Tp& __y) { return __y < __x; } /** * @brief Defines @c <= for arbitrary types, in terms of @c <. * @param __x A thing. * @param __y Another thing. * @return __x <= __y * * This function uses @c < to determine its result. */ template <class _Tp> inline bool operator<=(const _Tp& __x, const _Tp& __y) { return !(__y < __x); } /** * @brief Defines @c >= for arbitrary types, in terms of @c <. * @param __x A thing. * @param __y Another thing. * @return __x >= __y * * This function uses @c < to determine its result. */ template <class _Tp> inline bool operator>=(const _Tp& __x, const _Tp& __y) { return !(__x < __y); } } // namespace rel_ops _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _STL_RELOPS_H */ c++/8/bits/regex_constants.h 0000644 00000034564 15146341150 0011617 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2010-2018 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/regex_constants.h * @brief Constant definitions for the std regex library. * * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup regex Regular Expressions * * A facility for performing regular expression pattern matching. * @{ */ /** * @namespace std::regex_constants * @brief ISO C++-0x entities sub namespace for regex. */ namespace regex_constants { /** * @name 5.1 Regular Expression Syntax Options */ //@{ enum __syntax_option { _S_icase, _S_nosubs, _S_optimize, _S_collate, _S_ECMAScript, _S_basic, _S_extended, _S_awk, _S_grep, _S_egrep, _S_polynomial, _S_syntax_last }; /** * @brief This is a bitmask type indicating how to interpret the regex. * * The @c syntax_option_type is implementation defined but it is valid to * perform bitwise operations on these values and expect the right thing to * happen. * * A valid value of type syntax_option_type shall have exactly one of the * elements @c ECMAScript, @c basic, @c extended, @c awk, @c grep, @c egrep * %set. */ enum syntax_option_type : unsigned int { }; /** * Specifies that the matching of regular expressions against a character * sequence shall be performed without regard to case. */ _GLIBCXX17_INLINE constexpr syntax_option_type icase = static_cast<syntax_option_type>(1 << _S_icase); /** * Specifies that when a regular expression is matched against a character * container sequence, no sub-expression matches are to be stored in the * supplied match_results structure. */ _GLIBCXX17_INLINE constexpr syntax_option_type nosubs = static_cast<syntax_option_type>(1 << _S_nosubs); /** * Specifies that the regular expression engine should pay more attention to * the speed with which regular expressions are matched, and less to the * speed with which regular expression objects are constructed. Otherwise * it has no detectable effect on the program output. */ _GLIBCXX17_INLINE constexpr syntax_option_type optimize = static_cast<syntax_option_type>(1 << _S_optimize); /** * Specifies that character ranges of the form [a-b] should be locale * sensitive. */ _GLIBCXX17_INLINE constexpr syntax_option_type collate = static_cast<syntax_option_type>(1 << _S_collate); /** * Specifies that the grammar recognized by the regular expression engine is * that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript * Language Specification, Standard Ecma-262, third edition, 1999], as * modified in section [28.13]. This grammar is similar to that defined * in the PERL scripting language but extended with elements found in the * POSIX regular expression grammar. */ _GLIBCXX17_INLINE constexpr syntax_option_type ECMAScript = static_cast<syntax_option_type>(1 << _S_ECMAScript); /** * Specifies that the grammar recognized by the regular expression engine is * that used by POSIX basic regular expressions in IEEE Std 1003.1-2001, * Portable Operating System Interface (POSIX), Base Definitions and * Headers, Section 9, Regular Expressions [IEEE, Information Technology -- * Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001]. */ _GLIBCXX17_INLINE constexpr syntax_option_type basic = static_cast<syntax_option_type>(1 << _S_basic); /** * Specifies that the grammar recognized by the regular expression engine is * that used by POSIX extended regular expressions in IEEE Std 1003.1-2001, * Portable Operating System Interface (POSIX), Base Definitions and * Headers, Section 9, Regular Expressions. */ _GLIBCXX17_INLINE constexpr syntax_option_type extended = static_cast<syntax_option_type>(1 << _S_extended); /** * Specifies that the grammar recognized by the regular expression engine is * that used by POSIX utility awk in IEEE Std 1003.1-2001. This option is * identical to syntax_option_type extended, except that C-style escape * sequences are supported. These sequences are: * \\\\, \\a, \\b, \\f, \\n, \\r, \\t , \\v, \\&apos,, &apos,, * and \\ddd (where ddd is one, two, or three octal digits). */ _GLIBCXX17_INLINE constexpr syntax_option_type awk = static_cast<syntax_option_type>(1 << _S_awk); /** * Specifies that the grammar recognized by the regular expression engine is * that used by POSIX utility grep in IEEE Std 1003.1-2001. This option is * identical to syntax_option_type basic, except that newlines are treated * as whitespace. */ _GLIBCXX17_INLINE constexpr syntax_option_type grep = static_cast<syntax_option_type>(1 << _S_grep); /** * Specifies that the grammar recognized by the regular expression engine is * that used by POSIX utility grep when given the -E option in * IEEE Std 1003.1-2001. This option is identical to syntax_option_type * extended, except that newlines are treated as whitespace. */ _GLIBCXX17_INLINE constexpr syntax_option_type egrep = static_cast<syntax_option_type>(1 << _S_egrep); /** * Extension: Ensure both space complexity of compiled regex and * time complexity execution are not exponential. * If specified in a regex with back-references, the exception * regex_constants::error_complexity will be thrown. */ _GLIBCXX17_INLINE constexpr syntax_option_type __polynomial = static_cast<syntax_option_type>(1 << _S_polynomial); constexpr inline syntax_option_type operator&(syntax_option_type __a, syntax_option_type __b) { return (syntax_option_type)(static_cast<unsigned int>(__a) & static_cast<unsigned int>(__b)); } constexpr inline syntax_option_type operator|(syntax_option_type __a, syntax_option_type __b) { return (syntax_option_type)(static_cast<unsigned int>(__a) | static_cast<unsigned int>(__b)); } constexpr inline syntax_option_type operator^(syntax_option_type __a, syntax_option_type __b) { return (syntax_option_type)(static_cast<unsigned int>(__a) ^ static_cast<unsigned int>(__b)); } constexpr inline syntax_option_type operator~(syntax_option_type __a) { return (syntax_option_type)(~static_cast<unsigned int>(__a)); } inline syntax_option_type& operator&=(syntax_option_type& __a, syntax_option_type __b) { return __a = __a & __b; } inline syntax_option_type& operator|=(syntax_option_type& __a, syntax_option_type __b) { return __a = __a | __b; } inline syntax_option_type& operator^=(syntax_option_type& __a, syntax_option_type __b) { return __a = __a ^ __b; } //@} /** * @name 5.2 Matching Rules * * Matching a regular expression against a sequence of characters [first, * last) proceeds according to the rules of the grammar specified for the * regular expression object, modified according to the effects listed * below for any bitmask elements set. * */ //@{ enum __match_flag { _S_not_bol, _S_not_eol, _S_not_bow, _S_not_eow, _S_any, _S_not_null, _S_continuous, _S_prev_avail, _S_sed, _S_no_copy, _S_first_only, _S_match_flag_last }; /** * @brief This is a bitmask type indicating regex matching rules. * * The @c match_flag_type is implementation defined but it is valid to * perform bitwise operations on these values and expect the right thing to * happen. */ enum match_flag_type : unsigned int { }; /** * The default matching rules. */ _GLIBCXX17_INLINE constexpr match_flag_type match_default = static_cast<match_flag_type>(0); /** * The first character in the sequence [first, last) is treated as though it * is not at the beginning of a line, so the character (^) in the regular * expression shall not match [first, first). */ _GLIBCXX17_INLINE constexpr match_flag_type match_not_bol = static_cast<match_flag_type>(1 << _S_not_bol); /** * The last character in the sequence [first, last) is treated as though it * is not at the end of a line, so the character ($) in the regular * expression shall not match [last, last). */ _GLIBCXX17_INLINE constexpr match_flag_type match_not_eol = static_cast<match_flag_type>(1 << _S_not_eol); /** * The expression \\b is not matched against the sub-sequence * [first,first). */ _GLIBCXX17_INLINE constexpr match_flag_type match_not_bow = static_cast<match_flag_type>(1 << _S_not_bow); /** * The expression \\b should not be matched against the sub-sequence * [last,last). */ _GLIBCXX17_INLINE constexpr match_flag_type match_not_eow = static_cast<match_flag_type>(1 << _S_not_eow); /** * If more than one match is possible then any match is an acceptable * result. */ _GLIBCXX17_INLINE constexpr match_flag_type match_any = static_cast<match_flag_type>(1 << _S_any); /** * The expression does not match an empty sequence. */ _GLIBCXX17_INLINE constexpr match_flag_type match_not_null = static_cast<match_flag_type>(1 << _S_not_null); /** * The expression only matches a sub-sequence that begins at first . */ _GLIBCXX17_INLINE constexpr match_flag_type match_continuous = static_cast<match_flag_type>(1 << _S_continuous); /** * --first is a valid iterator position. When this flag is set then the * flags match_not_bol and match_not_bow are ignored by the regular * expression algorithms 28.11 and iterators 28.12. */ _GLIBCXX17_INLINE constexpr match_flag_type match_prev_avail = static_cast<match_flag_type>(1 << _S_prev_avail); /** * When a regular expression match is to be replaced by a new string, the * new string is constructed using the rules used by the ECMAScript replace * function in ECMA- 262 [Ecma International, ECMAScript Language * Specification, Standard Ecma-262, third edition, 1999], part 15.5.4.11 * String.prototype.replace. In addition, during search and replace * operations all non-overlapping occurrences of the regular expression * are located and replaced, and sections of the input that did not match * the expression are copied unchanged to the output string. * * Format strings (from ECMA-262 [15.5.4.11]): * @li $$ The dollar-sign itself ($) * @li $& The matched substring. * @li $` The portion of @a string that precedes the matched substring. * This would be match_results::prefix(). * @li $' The portion of @a string that follows the matched substring. * This would be match_results::suffix(). * @li $n The nth capture, where n is in [1,9] and $n is not followed by a * decimal digit. If n <= match_results::size() and the nth capture * is undefined, use the empty string instead. If n > * match_results::size(), the result is implementation-defined. * @li $nn The nnth capture, where nn is a two-digit decimal number on * [01, 99]. If nn <= match_results::size() and the nth capture is * undefined, use the empty string instead. If * nn > match_results::size(), the result is implementation-defined. */ _GLIBCXX17_INLINE constexpr match_flag_type format_default = static_cast<match_flag_type>(0); /** * When a regular expression match is to be replaced by a new string, the * new string is constructed using the rules used by the POSIX sed utility * in IEEE Std 1003.1- 2001 [IEEE, Information Technology -- Portable * Operating System Interface (POSIX), IEEE Standard 1003.1-2001]. */ _GLIBCXX17_INLINE constexpr match_flag_type format_sed = static_cast<match_flag_type>(1 << _S_sed); /** * During a search and replace operation, sections of the character * container sequence being searched that do not match the regular * expression shall not be copied to the output string. */ _GLIBCXX17_INLINE constexpr match_flag_type format_no_copy = static_cast<match_flag_type>(1 << _S_no_copy); /** * When specified during a search and replace operation, only the first * occurrence of the regular expression shall be replaced. */ _GLIBCXX17_INLINE constexpr match_flag_type format_first_only = static_cast<match_flag_type>(1 << _S_first_only); constexpr inline match_flag_type operator&(match_flag_type __a, match_flag_type __b) { return (match_flag_type)(static_cast<unsigned int>(__a) & static_cast<unsigned int>(__b)); } constexpr inline match_flag_type operator|(match_flag_type __a, match_flag_type __b) { return (match_flag_type)(static_cast<unsigned int>(__a) | static_cast<unsigned int>(__b)); } constexpr inline match_flag_type operator^(match_flag_type __a, match_flag_type __b) { return (match_flag_type)(static_cast<unsigned int>(__a) ^ static_cast<unsigned int>(__b)); } constexpr inline match_flag_type operator~(match_flag_type __a) { return (match_flag_type)(~static_cast<unsigned int>(__a)); } inline match_flag_type& operator&=(match_flag_type& __a, match_flag_type __b) { return __a = __a & __b; } inline match_flag_type& operator|=(match_flag_type& __a, match_flag_type __b) { return __a = __a | __b; } inline match_flag_type& operator^=(match_flag_type& __a, match_flag_type __b) { return __a = __a ^ __b; } //@} } // namespace regex_constants /* @} */ // group regex _GLIBCXX_END_NAMESPACE_VERSION } // namespace std c++/8/bits/allocated_ptr.h 0000644 00000006335 15146341150 0011221 0 ustar 00 // Guarded Allocation -*- C++ -*- // Copyright (C) 2014-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/allocated_ptr.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _ALLOCATED_PTR_H #define _ALLOCATED_PTR_H 1 #if __cplusplus < 201103L # include <bits/c++0xwarning.h> #else # include <type_traits> # include <bits/ptr_traits.h> # include <bits/alloc_traits.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Non-standard RAII type for managing pointers obtained from allocators. template<typename _Alloc> struct __allocated_ptr { using pointer = typename allocator_traits<_Alloc>::pointer; using value_type = typename allocator_traits<_Alloc>::value_type; /// Take ownership of __ptr __allocated_ptr(_Alloc& __a, pointer __ptr) noexcept : _M_alloc(std::__addressof(__a)), _M_ptr(__ptr) { } /// Convert __ptr to allocator's pointer type and take ownership of it template<typename _Ptr, typename _Req = _Require<is_same<_Ptr, value_type*>>> __allocated_ptr(_Alloc& __a, _Ptr __ptr) : _M_alloc(std::__addressof(__a)), _M_ptr(pointer_traits<pointer>::pointer_to(*__ptr)) { } /// Transfer ownership of the owned pointer __allocated_ptr(__allocated_ptr&& __gd) noexcept : _M_alloc(__gd._M_alloc), _M_ptr(__gd._M_ptr) { __gd._M_ptr = nullptr; } /// Deallocate the owned pointer ~__allocated_ptr() { if (_M_ptr != nullptr) std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1); } /// Release ownership of the owned pointer __allocated_ptr& operator=(std::nullptr_t) noexcept { _M_ptr = nullptr; return *this; } /// Get the address that the owned pointer refers to. value_type* get() { return std::__to_address(_M_ptr); } private: _Alloc* _M_alloc; pointer _M_ptr; }; /// Allocate space for a single object using __a template<typename _Alloc> __allocated_ptr<_Alloc> __allocate_guarded(_Alloc& __a) { return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) }; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif #endif c++/8/bits/fs_dir.h 0000644 00000034604 15146341150 0007652 0 ustar 00 // Filesystem directory utilities -*- C++ -*- // Copyright (C) 2014-2018 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> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace filesystem { /** * @ingroup filesystem * @{ */ 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; } private: file_type _M_type; perms _M_perms; }; _GLIBCXX_BEGIN_NAMESPACE_CXX11 struct _Dir; class directory_iterator; class recursive_directory_iterator; 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; } 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; } private: friend class _Dir; friend class directory_iterator; friend class recursive_directory_iterator; 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; }; 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; }; 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; const directory_entry* operator->() const { return &**this; } directory_iterator& operator++(); directory_iterator& increment(error_code& __ec); __directory_iterator_proxy operator++(int) { __directory_iterator_proxy __pr{**this}; ++*this; return __pr; } private: directory_iterator(const path&, directory_options, error_code*); friend bool operator==(const directory_iterator& __lhs, const directory_iterator& __rhs); friend class recursive_directory_iterator; std::shared_ptr<_Dir> _M_dir; }; inline directory_iterator begin(directory_iterator __iter) noexcept { return __iter; } inline directory_iterator end(directory_iterator) noexcept { return directory_iterator(); } inline bool operator==(const directory_iterator& __lhs, const directory_iterator& __rhs) { return !__rhs._M_dir.owner_before(__lhs._M_dir) && !__lhs._M_dir.owner_before(__rhs._M_dir); } inline bool operator!=(const directory_iterator& __lhs, const directory_iterator& __rhs) { return !(__lhs == __rhs); } 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 { return _M_options; } int depth() const; bool recursion_pending() const { return _M_pending; } const directory_entry& operator*() const; const directory_entry* operator->() const { 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() { _M_pending = false; } private: recursive_directory_iterator(const path&, directory_options, error_code*); friend bool operator==(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs); struct _Dir_stack; std::shared_ptr<_Dir_stack> _M_dirs; directory_options _M_options = {}; bool _M_pending = false; }; inline recursive_directory_iterator begin(recursive_directory_iterator __iter) noexcept { return __iter; } inline recursive_directory_iterator end(recursive_directory_iterator) noexcept { return recursive_directory_iterator(); } inline bool operator==(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs) { return !__rhs._M_dirs.owner_before(__lhs._M_dirs) && !__lhs._M_dirs.owner_before(__rhs._M_dirs); } inline bool operator!=(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs) { return !(__lhs == __rhs); } _GLIBCXX_END_NAMESPACE_CXX11 // @} group filesystem } // namespace filesystem _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++17 #endif // _GLIBCXX_FS_DIR_H c++/8/bits/stl_vector.h 0000644 00000166166 15146341150 0010601 0 ustar 00 // Vector implementation -*- C++ -*- // Copyright (C) 2001-2018 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 * 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/stl_vector.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{vector} */ #ifndef _STL_VECTOR_H #define _STL_VECTOR_H 1 #include <bits/stl_iterator_base_funcs.h> #include <bits/functexcept.h> #include <bits/concept_check.h> #if __cplusplus >= 201103L #include <initializer_list> #endif #include <debug/assertions.h> #if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR extern "C" void __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*); #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /// See bits/stl_deque.h's _Deque_base for an explanation. template<typename _Tp, typename _Alloc> struct _Vector_base { typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type; typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer pointer; struct _Vector_impl : public _Tp_alloc_type { pointer _M_start; pointer _M_finish; pointer _M_end_of_storage; _Vector_impl() : _Tp_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage() { } _Vector_impl(_Tp_alloc_type const& __a) _GLIBCXX_NOEXCEPT : _Tp_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage() { } #if __cplusplus >= 201103L _Vector_impl(_Tp_alloc_type&& __a) noexcept : _Tp_alloc_type(std::move(__a)), _M_start(), _M_finish(), _M_end_of_storage() { } #endif void _M_swap_data(_Vector_impl& __x) _GLIBCXX_NOEXCEPT { std::swap(_M_start, __x._M_start); std::swap(_M_finish, __x._M_finish); std::swap(_M_end_of_storage, __x._M_end_of_storage); } #if _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR template<typename = _Tp_alloc_type> struct _Asan { typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type> ::size_type size_type; static void _S_shrink(_Vector_impl&, size_type) { } static void _S_on_dealloc(_Vector_impl&) { } typedef _Vector_impl& _Reinit; struct _Grow { _Grow(_Vector_impl&, size_type) { } void _M_grew(size_type) { } }; }; // Enable ASan annotations for memory obtained from std::allocator. template<typename _Up> struct _Asan<allocator<_Up> > { typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type> ::size_type size_type; // Adjust ASan annotation for [_M_start, _M_end_of_storage) to // mark end of valid region as __curr instead of __prev. static void _S_adjust(_Vector_impl& __impl, pointer __prev, pointer __curr) { __sanitizer_annotate_contiguous_container(__impl._M_start, __impl._M_end_of_storage, __prev, __curr); } static void _S_grow(_Vector_impl& __impl, size_type __n) { _S_adjust(__impl, __impl._M_finish, __impl._M_finish + __n); } static void _S_shrink(_Vector_impl& __impl, size_type __n) { _S_adjust(__impl, __impl._M_finish + __n, __impl._M_finish); } static void _S_on_dealloc(_Vector_impl& __impl) { if (__impl._M_start) _S_adjust(__impl, __impl._M_finish, __impl._M_end_of_storage); } // Used on reallocation to tell ASan unused capacity is invalid. struct _Reinit { explicit _Reinit(_Vector_impl& __impl) : _M_impl(__impl) { // Mark unused capacity as valid again before deallocating it. _S_on_dealloc(_M_impl); } ~_Reinit() { // Mark unused capacity as invalid after reallocation. if (_M_impl._M_start) _S_adjust(_M_impl, _M_impl._M_end_of_storage, _M_impl._M_finish); } _Vector_impl& _M_impl; #if __cplusplus >= 201103L _Reinit(const _Reinit&) = delete; _Reinit& operator=(const _Reinit&) = delete; #endif }; // Tell ASan when unused capacity is initialized to be valid. struct _Grow { _Grow(_Vector_impl& __impl, size_type __n) : _M_impl(__impl), _M_n(__n) { _S_grow(_M_impl, __n); } ~_Grow() { if (_M_n) _S_shrink(_M_impl, _M_n); } void _M_grew(size_type __n) { _M_n -= __n; } #if __cplusplus >= 201103L _Grow(const _Grow&) = delete; _Grow& operator=(const _Grow&) = delete; #endif private: _Vector_impl& _M_impl; size_type _M_n; }; }; #define _GLIBCXX_ASAN_ANNOTATE_REINIT \ typename _Base::_Vector_impl::template _Asan<>::_Reinit const \ __attribute__((__unused__)) __reinit_guard(this->_M_impl) #define _GLIBCXX_ASAN_ANNOTATE_GROW(n) \ typename _Base::_Vector_impl::template _Asan<>::_Grow \ __attribute__((__unused__)) __grow_guard(this->_M_impl, (n)) #define _GLIBCXX_ASAN_ANNOTATE_GREW(n) __grow_guard._M_grew(n) #define _GLIBCXX_ASAN_ANNOTATE_SHRINK(n) \ _Base::_Vector_impl::template _Asan<>::_S_shrink(this->_M_impl, n) #define _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC \ _Base::_Vector_impl::template _Asan<>::_S_on_dealloc(this->_M_impl) #else // ! (_GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR) #define _GLIBCXX_ASAN_ANNOTATE_REINIT #define _GLIBCXX_ASAN_ANNOTATE_GROW(n) #define _GLIBCXX_ASAN_ANNOTATE_GREW(n) #define _GLIBCXX_ASAN_ANNOTATE_SHRINK(n) #define _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC #endif // _GLIBCXX_SANITIZE_STD_ALLOCATOR && _GLIBCXX_SANITIZE_VECTOR }; public: typedef _Alloc allocator_type; _Tp_alloc_type& _M_get_Tp_allocator() _GLIBCXX_NOEXCEPT { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); } const _Tp_alloc_type& _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); } allocator_type get_allocator() const _GLIBCXX_NOEXCEPT { return allocator_type(_M_get_Tp_allocator()); } _Vector_base() : _M_impl() { } _Vector_base(const allocator_type& __a) _GLIBCXX_NOEXCEPT : _M_impl(__a) { } _Vector_base(size_t __n) : _M_impl() { _M_create_storage(__n); } _Vector_base(size_t __n, const allocator_type& __a) : _M_impl(__a) { _M_create_storage(__n); } #if __cplusplus >= 201103L _Vector_base(_Tp_alloc_type&& __a) noexcept : _M_impl(std::move(__a)) { } _Vector_base(_Vector_base&& __x) noexcept : _M_impl(std::move(__x._M_get_Tp_allocator())) { this->_M_impl._M_swap_data(__x._M_impl); } _Vector_base(_Vector_base&& __x, const allocator_type& __a) : _M_impl(__a) { if (__x.get_allocator() == __a) this->_M_impl._M_swap_data(__x._M_impl); else { size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start; _M_create_storage(__n); } } #endif ~_Vector_base() _GLIBCXX_NOEXCEPT { _M_deallocate(_M_impl._M_start, _M_impl._M_end_of_storage - _M_impl._M_start); } public: _Vector_impl _M_impl; pointer _M_allocate(size_t __n) { typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr; return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer(); } void _M_deallocate(pointer __p, size_t __n) { typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr; if (__p) _Tr::deallocate(_M_impl, __p, __n); } private: void _M_create_storage(size_t __n) { this->_M_impl._M_start = this->_M_allocate(__n); this->_M_impl._M_finish = this->_M_impl._M_start; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; } }; /** * @brief A standard container which offers fixed time access to * individual elements in any order. * * @ingroup sequences * * @tparam _Tp Type of element. * @tparam _Alloc Allocator type, defaults to allocator<_Tp>. * * 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>, including the * <a href="tables.html#68">optional sequence requirements</a> with the * %exception of @c push_front and @c pop_front. * * In some terminology a %vector can be described as a dynamic * C-style array, it offers fast and efficient access to individual * elements in any order and saves the user from worrying about * memory and size allocation. Subscripting ( @c [] ) access is * also provided as with C-style arrays. */ template<typename _Tp, typename _Alloc = std::allocator<_Tp> > class vector : protected _Vector_base<_Tp, _Alloc> { #ifdef _GLIBCXX_CONCEPT_CHECKS // Concept requirements. typedef typename _Alloc::value_type _Alloc_value_type; # if __cplusplus < 201103L __glibcxx_class_requires(_Tp, _SGIAssignableConcept) # endif __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) #endif #if __cplusplus >= 201103L static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value, "std::vector must have a non-const, non-volatile value_type"); # ifdef __STRICT_ANSI__ static_assert(is_same<typename _Alloc::value_type, _Tp>::value, "std::vector must have the same value_type as its allocator"); # endif #endif typedef _Vector_base<_Tp, _Alloc> _Base; typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Alloc_traits; public: typedef _Tp value_type; typedef typename _Base::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 __gnu_cxx::__normal_iterator<pointer, vector> iterator; typedef __gnu_cxx::__normal_iterator<const_pointer, vector> const_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef _Alloc allocator_type; protected: using _Base::_M_allocate; using _Base::_M_deallocate; using _Base::_M_impl; using _Base::_M_get_Tp_allocator; public: // [23.2.4.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) /** * @brief Creates a %vector with no elements. */ vector() #if __cplusplus >= 201103L noexcept(is_nothrow_default_constructible<_Alloc>::value) #endif : _Base() { } /** * @brief Creates a %vector with no elements. * @param __a An allocator object. */ explicit vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT : _Base(__a) { } #if __cplusplus >= 201103L /** * @brief Creates a %vector with default constructed elements. * @param __n The number of elements to initially create. * @param __a An allocator. * * This constructor fills the %vector with @a __n default * constructed elements. */ explicit vector(size_type __n, const allocator_type& __a = allocator_type()) : _Base(__n, __a) { _M_default_initialize(__n); } /** * @brief Creates a %vector with copies of an exemplar element. * @param __n The number of elements to initially create. * @param __value An element to copy. * @param __a An allocator. * * This constructor fills the %vector with @a __n copies of @a __value. */ vector(size_type __n, const value_type& __value, const allocator_type& __a = allocator_type()) : _Base(__n, __a) { _M_fill_initialize(__n, __value); } #else /** * @brief Creates a %vector with copies of an exemplar element. * @param __n The number of elements to initially create. * @param __value An element to copy. * @param __a An allocator. * * This constructor fills the %vector with @a __n copies of @a __value. */ explicit vector(size_type __n, const value_type& __value = value_type(), const allocator_type& __a = allocator_type()) : _Base(__n, __a) { _M_fill_initialize(__n, __value); } #endif /** * @brief %Vector copy constructor. * @param __x A %vector of identical element and allocator types. * * All the elements of @a __x are copied, but any unused capacity in * @a __x will not be copied * (i.e. capacity() == size() in the new %vector). * * The newly-created %vector uses a copy of the allocator object used * by @a __x (unless the allocator traits dictate a different object). */ vector(const vector& __x) : _Base(__x.size(), _Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator())) { this->_M_impl._M_finish = std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); } #if __cplusplus >= 201103L /** * @brief %Vector move constructor. * @param __x A %vector of identical element and allocator types. * * The newly-created %vector contains the exact contents of @a __x. * The contents of @a __x are a valid, but unspecified %vector. */ vector(vector&& __x) noexcept : _Base(std::move(__x)) { } /// Copy constructor with alternative allocator vector(const vector& __x, const allocator_type& __a) : _Base(__x.size(), __a) { this->_M_impl._M_finish = std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); } /// Move constructor with alternative allocator vector(vector&& __rv, const allocator_type& __m) noexcept(_Alloc_traits::_S_always_equal()) : _Base(std::move(__rv), __m) { if (__rv.get_allocator() != __m) { this->_M_impl._M_finish = std::__uninitialized_move_a(__rv.begin(), __rv.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); __rv.clear(); } } /** * @brief Builds a %vector from an initializer list. * @param __l An initializer_list. * @param __a An allocator. * * Create a %vector consisting of copies of the elements in the * initializer_list @a __l. * * This will call the element type's copy constructor N times * (where N is @a __l.size()) and do no memory reallocation. */ vector(initializer_list<value_type> __l, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_range_initialize(__l.begin(), __l.end(), random_access_iterator_tag()); } #endif /** * @brief Builds a %vector from a range. * @param __first An input iterator. * @param __last An input iterator. * @param __a An allocator. * * Create a %vector consisting of copies of the elements from * [first,last). * * If the iterators are forward, bidirectional, or * random-access, then this will call the elements' copy * constructor N times (where N is distance(first,last)) and do * no memory reallocation. But if only input iterators are * used, then this will do at most 2N calls to the copy * constructor, and logN memory reallocations. */ #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { _M_initialize_dispatch(__first, __last, __false_type()); } #else template<typename _InputIterator> vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a = allocator_type()) : _Base(__a) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } #endif /** * The dtor only erases the elements, and note that if the * elements themselves are pointers, the pointed-to memory is * not touched in any way. Managing the pointer is the user's * responsibility. */ ~vector() _GLIBCXX_NOEXCEPT { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC; } /** * @brief %Vector assignment operator. * @param __x A %vector of identical element and allocator types. * * All the elements of @a __x are copied, but any unused capacity in * @a __x will not be copied. * * Whether the allocator is copied depends on the allocator traits. */ vector& operator=(const vector& __x); #if __cplusplus >= 201103L /** * @brief %Vector move assignment operator. * @param __x A %vector of identical element and allocator types. * * The contents of @a __x are moved into this %vector (without copying, * if the allocators permit it). * Afterwards @a __x is a valid, but unspecified %vector. * * Whether the allocator is moved depends on the allocator traits. */ vector& operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move()) { constexpr bool __move_storage = _Alloc_traits::_S_propagate_on_move_assign() || _Alloc_traits::_S_always_equal(); _M_move_assign(std::move(__x), __bool_constant<__move_storage>()); return *this; } /** * @brief %Vector list assignment operator. * @param __l An initializer_list. * * This function fills a %vector with copies of the elements in the * initializer list @a __l. * * Note that the assignment completely changes the %vector and * that the resulting %vector's size is the same as the number * of elements assigned. */ vector& operator=(initializer_list<value_type> __l) { this->_M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); return *this; } #endif /** * @brief Assigns a given value to a %vector. * @param __n Number of elements to be assigned. * @param __val Value to be assigned. * * This function fills a %vector with @a __n copies of the given * value. Note that the assignment completely changes the * %vector and that the resulting %vector's size is the same as * the number of elements assigned. */ void assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); } /** * @brief Assigns a range to a %vector. * @param __first An input iterator. * @param __last An input iterator. * * This function fills a %vector with copies of the elements in the * range [__first,__last). * * Note that the assignment completely changes the %vector and * that the resulting %vector's size is the same as the number * of elements assigned. */ #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> void assign(_InputIterator __first, _InputIterator __last) { _M_assign_dispatch(__first, __last, __false_type()); } #else template<typename _InputIterator> void assign(_InputIterator __first, _InputIterator __last) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_assign_dispatch(__first, __last, _Integral()); } #endif #if __cplusplus >= 201103L /** * @brief Assigns an initializer list to a %vector. * @param __l An initializer_list. * * This function fills a %vector with copies of the elements in the * initializer list @a __l. * * Note that the assignment completely changes the %vector and * that the resulting %vector's size is the same as the number * of elements assigned. */ void assign(initializer_list<value_type> __l) { this->_M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); } #endif /// Get a copy of the memory allocation object. using _Base::get_allocator; // iterators /** * Returns a read/write iterator that points to the first * element in the %vector. Iteration is done in ordinary * element order. */ iterator begin() _GLIBCXX_NOEXCEPT { return iterator(this->_M_impl._M_start); } /** * Returns a read-only (constant) iterator that points to the * first element in the %vector. Iteration is done in ordinary * element order. */ const_iterator begin() const _GLIBCXX_NOEXCEPT { return const_iterator(this->_M_impl._M_start); } /** * Returns a read/write iterator that points one past the last * element in the %vector. Iteration is done in ordinary * element order. */ iterator end() _GLIBCXX_NOEXCEPT { return iterator(this->_M_impl._M_finish); } /** * Returns a read-only (constant) iterator that points one past * the last element in the %vector. Iteration is done in * ordinary element order. */ const_iterator end() const _GLIBCXX_NOEXCEPT { return const_iterator(this->_M_impl._M_finish); } /** * Returns a read/write reverse iterator that points to the * last element in the %vector. Iteration is done in reverse * element order. */ reverse_iterator rbegin() _GLIBCXX_NOEXCEPT { return reverse_iterator(end()); } /** * Returns a read-only (constant) reverse iterator that points * to the last element in the %vector. Iteration is done in * reverse element order. */ const_reverse_iterator rbegin() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(end()); } /** * Returns a read/write reverse iterator that points to one * before the first element in the %vector. Iteration is done * in reverse element order. */ reverse_iterator rend() _GLIBCXX_NOEXCEPT { return reverse_iterator(begin()); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first element in the %vector. Iteration * is done in reverse element order. */ const_reverse_iterator rend() const _GLIBCXX_NOEXCEPT { return const_reverse_iterator(begin()); } #if __cplusplus >= 201103L /** * Returns a read-only (constant) iterator that points to the * first element in the %vector. Iteration is done in ordinary * element order. */ const_iterator cbegin() const noexcept { return const_iterator(this->_M_impl._M_start); } /** * Returns a read-only (constant) iterator that points one past * the last element in the %vector. Iteration is done in * ordinary element order. */ const_iterator cend() const noexcept { return const_iterator(this->_M_impl._M_finish); } /** * Returns a read-only (constant) reverse iterator that points * to the last element in the %vector. Iteration is done in * reverse element order. */ const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } /** * Returns a read-only (constant) reverse iterator that points * to one before the first element in the %vector. Iteration * is done in reverse element order. */ const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } #endif // [23.2.4.2] capacity /** Returns the number of elements in the %vector. */ size_type size() const _GLIBCXX_NOEXCEPT { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); } /** Returns the size() of the largest possible %vector. */ size_type max_size() const _GLIBCXX_NOEXCEPT { return _Alloc_traits::max_size(_M_get_Tp_allocator()); } #if __cplusplus >= 201103L /** * @brief Resizes the %vector to the specified number of elements. * @param __new_size Number of elements the %vector should contain. * * This function will %resize the %vector to the specified * number of elements. If the number is smaller than the * %vector's current size the %vector is truncated, otherwise * default constructed elements are appended. */ void resize(size_type __new_size) { if (__new_size > size()) _M_default_append(__new_size - size()); else if (__new_size < size()) _M_erase_at_end(this->_M_impl._M_start + __new_size); } /** * @brief Resizes the %vector to the specified number of elements. * @param __new_size Number of elements the %vector should contain. * @param __x Data with which new elements should be populated. * * This function will %resize the %vector to the specified * number of elements. If the number is smaller than the * %vector's current size the %vector is truncated, otherwise * the %vector is extended and new elements are populated with * given data. */ void resize(size_type __new_size, const value_type& __x) { if (__new_size > size()) _M_fill_insert(end(), __new_size - size(), __x); else if (__new_size < size()) _M_erase_at_end(this->_M_impl._M_start + __new_size); } #else /** * @brief Resizes the %vector to the specified number of elements. * @param __new_size Number of elements the %vector should contain. * @param __x Data with which new elements should be populated. * * This function will %resize the %vector to the specified * number of elements. If the number is smaller than the * %vector's current size the %vector is truncated, otherwise * the %vector is extended and new elements are populated with * given data. */ void resize(size_type __new_size, value_type __x = value_type()) { if (__new_size > size()) _M_fill_insert(end(), __new_size - size(), __x); else if (__new_size < size()) _M_erase_at_end(this->_M_impl._M_start + __new_size); } #endif #if __cplusplus >= 201103L /** A non-binding request to reduce capacity() to size(). */ void shrink_to_fit() { _M_shrink_to_fit(); } #endif /** * Returns the total number of elements that the %vector can * hold before needing to allocate more memory. */ size_type capacity() const _GLIBCXX_NOEXCEPT { return size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } /** * Returns true if the %vector is empty. (Thus begin() would * equal end().) */ bool empty() const _GLIBCXX_NOEXCEPT { return begin() == end(); } /** * @brief Attempt to preallocate enough memory for specified number of * elements. * @param __n Number of elements required. * @throw std::length_error If @a n exceeds @c max_size(). * * This function attempts to reserve enough memory for the * %vector to hold the specified number of elements. If the * number requested is more than max_size(), length_error is * thrown. * * The advantage of this function is that if optimal code is a * necessity and the user can determine the number of elements * that will be required, the user can reserve the memory in * %advance, and thus prevent a possible reallocation of memory * and copying of %vector data. */ void reserve(size_type __n); // element access /** * @brief Subscript access to the data contained in the %vector. * @param __n The index of the element for which data should be * accessed. * @return Read/write reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ reference operator[](size_type __n) _GLIBCXX_NOEXCEPT { __glibcxx_requires_subscript(__n); return *(this->_M_impl._M_start + __n); } /** * @brief Subscript access to the data contained in the %vector. * @param __n The index of the element for which data should be * accessed. * @return Read-only (constant) reference to data. * * This operator allows for easy, array-style, data access. * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) */ const_reference operator[](size_type __n) const _GLIBCXX_NOEXCEPT { __glibcxx_requires_subscript(__n); return *(this->_M_impl._M_start + __n); } protected: /// Safety check used only from at(). void _M_range_check(size_type __n) const { if (__n >= this->size()) __throw_out_of_range_fmt(__N("vector::_M_range_check: __n " "(which is %zu) >= this->size() " "(which is %zu)"), __n, this->size()); } public: /** * @brief Provides access to the data contained in the %vector. * @param __n The index of the element for which data should be * accessed. * @return Read/write reference to data. * @throw std::out_of_range If @a __n is an invalid index. * * This function provides for safer data access. The parameter * is first checked that it is in the range of the vector. The * function throws out_of_range if the check fails. */ reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } /** * @brief Provides access to the data contained in the %vector. * @param __n The index of the element for which data should be * accessed. * @return Read-only (constant) reference to data. * @throw std::out_of_range If @a __n is an invalid index. * * This function provides for safer data access. The parameter * is first checked that it is in the range of the vector. The * function throws out_of_range if the check fails. */ const_reference at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } /** * Returns a read/write reference to the data at the first * element of the %vector. */ reference front() _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); return *begin(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %vector. */ const_reference front() const _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); return *begin(); } /** * Returns a read/write reference to the data at the last * element of the %vector. */ reference back() _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); return *(end() - 1); } /** * Returns a read-only (constant) reference to the data at the * last element of the %vector. */ const_reference back() const _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); return *(end() - 1); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 464. Suggestion for new member functions in standard containers. // data access /** * Returns a pointer such that [data(), data() + size()) is a valid * range. For a non-empty %vector, data() == &front(). */ _Tp* data() _GLIBCXX_NOEXCEPT { return _M_data_ptr(this->_M_impl._M_start); } const _Tp* data() const _GLIBCXX_NOEXCEPT { return _M_data_ptr(this->_M_impl._M_start); } // [23.2.4.3] modifiers /** * @brief Add data to the end of the %vector. * @param __x Data to be added. * * This is a typical stack operation. The function creates an * element at the end of the %vector and assigns the given data * to it. Due to the nature of a %vector this operation can be * done in constant time if the %vector has preallocated space * available. */ void push_back(const value_type& __x) { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { _GLIBCXX_ASAN_ANNOTATE_GROW(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x); ++this->_M_impl._M_finish; _GLIBCXX_ASAN_ANNOTATE_GREW(1); } else _M_realloc_insert(end(), __x); } #if __cplusplus >= 201103L void push_back(value_type&& __x) { emplace_back(std::move(__x)); } template<typename... _Args> #if __cplusplus > 201402L reference #else void #endif emplace_back(_Args&&... __args); #endif /** * @brief Removes last element. * * This is a typical stack operation. It shrinks the %vector by one. * * Note that no data is returned, and if the last element's * data is needed, it should be retrieved before pop_back() is * called. */ void pop_back() _GLIBCXX_NOEXCEPT { __glibcxx_requires_nonempty(); --this->_M_impl._M_finish; _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); _GLIBCXX_ASAN_ANNOTATE_SHRINK(1); } #if __cplusplus >= 201103L /** * @brief Inserts an object in %vector before specified iterator. * @param __position A const_iterator into the %vector. * @param __args Arguments. * @return An iterator that points to the inserted data. * * This function will insert an object of type T constructed * with T(std::forward<Args>(args)...) before the specified location. * Note that this kind of operation could be expensive for a %vector * and if it is frequently used the user should consider using * std::list. */ template<typename... _Args> iterator emplace(const_iterator __position, _Args&&... __args) { return _M_emplace_aux(__position, std::forward<_Args>(__args)...); } /** * @brief Inserts given value into %vector before specified iterator. * @param __position A const_iterator into the %vector. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given value before * the specified location. Note that this kind of operation * could be expensive for a %vector and if it is frequently * used the user should consider using std::list. */ iterator insert(const_iterator __position, const value_type& __x); #else /** * @brief Inserts given value into %vector before specified iterator. * @param __position An iterator into the %vector. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given value before * the specified location. Note that this kind of operation * could be expensive for a %vector and if it is frequently * used the user should consider using std::list. */ iterator insert(iterator __position, const value_type& __x); #endif #if __cplusplus >= 201103L /** * @brief Inserts given rvalue into %vector before specified iterator. * @param __position A const_iterator into the %vector. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a copy of the given rvalue before * the specified location. Note that this kind of operation * could be expensive for a %vector and if it is frequently * used the user should consider using std::list. */ iterator insert(const_iterator __position, value_type&& __x) { return _M_insert_rval(__position, std::move(__x)); } /** * @brief Inserts an initializer_list into the %vector. * @param __position An iterator into the %vector. * @param __l An initializer_list. * * This function will insert copies of the data in the * initializer_list @a l into the %vector before the location * specified by @a position. * * Note that this kind of operation could be expensive for a * %vector and if it is frequently used the user should * consider using std::list. */ iterator insert(const_iterator __position, initializer_list<value_type> __l) { auto __offset = __position - cbegin(); _M_range_insert(begin() + __offset, __l.begin(), __l.end(), std::random_access_iterator_tag()); return begin() + __offset; } #endif #if __cplusplus >= 201103L /** * @brief Inserts a number of copies of given data into the %vector. * @param __position A const_iterator into the %vector. * @param __n Number of elements to be inserted. * @param __x Data to be inserted. * @return An iterator that points to the inserted data. * * This function will insert a specified number of copies of * the given data before the location specified by @a position. * * Note that this kind of operation could be expensive for a * %vector and if it is frequently used the user should * consider using std::list. */ iterator insert(const_iterator __position, size_type __n, const value_type& __x) { difference_type __offset = __position - cbegin(); _M_fill_insert(begin() + __offset, __n, __x); return begin() + __offset; } #else /** * @brief Inserts a number of copies of given data into the %vector. * @param __position An iterator into the %vector. * @param __n Number of elements to be inserted. * @param __x Data to be inserted. * * This function will insert a specified number of copies of * the given data before the location specified by @a position. * * Note that this kind of operation could be expensive for a * %vector and if it is frequently used the user should * consider using std::list. */ void insert(iterator __position, size_type __n, const value_type& __x) { _M_fill_insert(__position, __n, __x); } #endif #if __cplusplus >= 201103L /** * @brief Inserts a range into the %vector. * @param __position A const_iterator into the %vector. * @param __first An input iterator. * @param __last An input iterator. * @return An iterator that points to the inserted data. * * This function will insert copies of the data in the range * [__first,__last) into the %vector before the location specified * by @a pos. * * Note that this kind of operation could be expensive for a * %vector and if it is frequently used the user should * consider using std::list. */ template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> iterator insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { difference_type __offset = __position - cbegin(); _M_insert_dispatch(begin() + __offset, __first, __last, __false_type()); return begin() + __offset; } #else /** * @brief Inserts a range into the %vector. * @param __position An iterator into the %vector. * @param __first An input iterator. * @param __last An input iterator. * * This function will insert copies of the data in the range * [__first,__last) into the %vector before the location specified * by @a pos. * * Note that this kind of operation could be expensive for a * %vector and if it is frequently used the user should * consider using std::list. */ template<typename _InputIterator> void insert(iterator __position, _InputIterator __first, _InputIterator __last) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); } #endif /** * @brief Remove element at given position. * @param __position Iterator pointing to element to be erased. * @return An iterator pointing to the next element (or end()). * * This function will erase the element at the given position and thus * shorten the %vector by one. * * Note This operation could be expensive and if it is * frequently used the user should consider using std::list. * The user is also cautioned that this function only erases * the element, and that if the element is itself a pointer, * the pointed-to memory is not touched in any way. Managing * the pointer is the user's responsibility. */ iterator #if __cplusplus >= 201103L erase(const_iterator __position) { return _M_erase(begin() + (__position - cbegin())); } #else erase(iterator __position) { return _M_erase(__position); } #endif /** * @brief Remove a range of elements. * @param __first Iterator pointing to the first element to be erased. * @param __last Iterator pointing to one past the last element to be * erased. * @return An iterator pointing to the element pointed to by @a __last * prior to erasing (or end()). * * This function will erase the elements in the range * [__first,__last) and shorten the %vector accordingly. * * Note This operation could be expensive and if it is * frequently used the user should consider using std::list. * The user is also cautioned that this function only erases * the elements, and that if the elements themselves are * pointers, the pointed-to memory is not touched in any way. * Managing the pointer is the user's responsibility. */ iterator #if __cplusplus >= 201103L erase(const_iterator __first, const_iterator __last) { const auto __beg = begin(); const auto __cbeg = cbegin(); return _M_erase(__beg + (__first - __cbeg), __beg + (__last - __cbeg)); } #else erase(iterator __first, iterator __last) { return _M_erase(__first, __last); } #endif /** * @brief Swaps data with another %vector. * @param __x A %vector of the same element and allocator types. * * This exchanges the elements between two vectors in constant time. * (Three pointers, so it should be quite fast.) * Note that the global std::swap() function is specialized such that * std::swap(v1,v2) will feed to this function. * * Whether the allocators are swapped depends on the allocator traits. */ void swap(vector& __x) _GLIBCXX_NOEXCEPT { #if __cplusplus >= 201103L __glibcxx_assert(_Alloc_traits::propagate_on_container_swap::value || _M_get_Tp_allocator() == __x._M_get_Tp_allocator()); #endif this->_M_impl._M_swap_data(__x._M_impl); _Alloc_traits::_S_on_swap(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); } /** * Erases all the elements. Note that this function only erases the * elements, and that if the elements themselves are pointers, the * pointed-to memory is not touched in any way. Managing the pointer is * the user's responsibility. */ void clear() _GLIBCXX_NOEXCEPT { _M_erase_at_end(this->_M_impl._M_start); } protected: /** * Memory expansion handler. Uses the member allocation function to * obtain @a n bytes of memory, and then copies [first,last) into it. */ template<typename _ForwardIterator> pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first, _ForwardIterator __last) { pointer __result = this->_M_allocate(__n); __try { std::__uninitialized_copy_a(__first, __last, __result, _M_get_Tp_allocator()); return __result; } __catch(...) { _M_deallocate(__result, __n); __throw_exception_again; } } // Internal constructor functions follow. // Called by the range constructor to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) { this->_M_impl._M_start = _M_allocate(static_cast<size_type>(__n)); this->_M_impl._M_end_of_storage = this->_M_impl._M_start + static_cast<size_type>(__n); _M_fill_initialize(static_cast<size_type>(__n), __value); } // Called by the range constructor to implement [23.1.1]/9 template<typename _InputIterator> void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { typedef typename std::iterator_traits<_InputIterator>:: iterator_category _IterCategory; _M_range_initialize(__first, __last, _IterCategory()); } // Called by the second initialize_dispatch above template<typename _InputIterator> void _M_range_initialize(_InputIterator __first, _InputIterator __last, std::input_iterator_tag) { __try { for (; __first != __last; ++__first) #if __cplusplus >= 201103L emplace_back(*__first); #else push_back(*__first); #endif } __catch(...) { clear(); __throw_exception_again; } } // Called by the second initialize_dispatch above template<typename _ForwardIterator> void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag) { const size_type __n = std::distance(__first, __last); this->_M_impl._M_start = this->_M_allocate(__n); this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; this->_M_impl._M_finish = std::__uninitialized_copy_a(__first, __last, this->_M_impl._M_start, _M_get_Tp_allocator()); } // Called by the first initialize_dispatch above and by the // vector(n,value,a) constructor. void _M_fill_initialize(size_type __n, const value_type& __value) { this->_M_impl._M_finish = std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, _M_get_Tp_allocator()); } #if __cplusplus >= 201103L // Called by the vector(n) constructor. void _M_default_initialize(size_type __n) { this->_M_impl._M_finish = std::__uninitialized_default_n_a(this->_M_impl._M_start, __n, _M_get_Tp_allocator()); } #endif // Internal assign functions follow. The *_aux functions do the actual // assignment work for the range versions. // Called by the range assign to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { _M_fill_assign(__n, __val); } // Called by the range assign to implement [23.1.1]/9 template<typename _InputIterator> void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) { _M_assign_aux(__first, __last, std::__iterator_category(__first)); } // Called by the second assign_dispatch above template<typename _InputIterator> void _M_assign_aux(_InputIterator __first, _InputIterator __last, std::input_iterator_tag); // Called by the second assign_dispatch above template<typename _ForwardIterator> void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag); // Called by assign(n,t), and the range assign when it turns out // to be the same thing. void _M_fill_assign(size_type __n, const value_type& __val); // Internal insert functions follow. // Called by the range insert to implement [23.1.1]/9 // _GLIBCXX_RESOLVE_LIB_DEFECTS // 438. Ambiguity in the "do the right thing" clause template<typename _Integer> void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type) { _M_fill_insert(__pos, __n, __val); } // Called by the range insert to implement [23.1.1]/9 template<typename _InputIterator> void _M_insert_dispatch(iterator __pos, _InputIterator __first, _InputIterator __last, __false_type) { _M_range_insert(__pos, __first, __last, std::__iterator_category(__first)); } // Called by the second insert_dispatch above template<typename _InputIterator> void _M_range_insert(iterator __pos, _InputIterator __first, _InputIterator __last, std::input_iterator_tag); // Called by the second insert_dispatch above template<typename _ForwardIterator> void _M_range_insert(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, std::forward_iterator_tag); // Called by insert(p,n,x), and the range insert when it turns out to be // the same thing. void _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); #if __cplusplus >= 201103L // Called by resize(n). void _M_default_append(size_type __n); bool _M_shrink_to_fit(); #endif #if __cplusplus < 201103L // Called by insert(p,x) void _M_insert_aux(iterator __position, const value_type& __x); void _M_realloc_insert(iterator __position, const value_type& __x); #else // A value_type object constructed with _Alloc_traits::construct() // and destroyed with _Alloc_traits::destroy(). struct _Temporary_value { template<typename... _Args> explicit _Temporary_value(vector* __vec, _Args&&... __args) : _M_this(__vec) { _Alloc_traits::construct(_M_this->_M_impl, _M_ptr(), std::forward<_Args>(__args)...); } ~_Temporary_value() { _Alloc_traits::destroy(_M_this->_M_impl, _M_ptr()); } value_type& _M_val() { return *_M_ptr(); } private: _Tp* _M_ptr() { return reinterpret_cast<_Tp*>(&__buf); } vector* _M_this; typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __buf; }; // Called by insert(p,x) and other functions when insertion needs to // reallocate or move existing elements. _Arg is either _Tp& or _Tp. template<typename _Arg> void _M_insert_aux(iterator __position, _Arg&& __arg); template<typename... _Args> void _M_realloc_insert(iterator __position, _Args&&... __args); // Either move-construct at the end, or forward to _M_insert_aux. iterator _M_insert_rval(const_iterator __position, value_type&& __v); // Try to emplace at the end, otherwise forward to _M_insert_aux. template<typename... _Args> iterator _M_emplace_aux(const_iterator __position, _Args&&... __args); // Emplacing an rvalue of the correct type can use _M_insert_rval. iterator _M_emplace_aux(const_iterator __position, value_type&& __v) { return _M_insert_rval(__position, std::move(__v)); } #endif // Called by _M_fill_insert, _M_insert_aux etc. size_type _M_check_len(size_type __n, const char* __s) const { if (max_size() - size() < __n) __throw_length_error(__N(__s)); const size_type __len = size() + std::max(size(), __n); return (__len < size() || __len > max_size()) ? max_size() : __len; } // Internal erase functions follow. // Called by erase(q1,q2), clear(), resize(), _M_fill_assign, // _M_assign_aux. void _M_erase_at_end(pointer __pos) _GLIBCXX_NOEXCEPT { if (size_type __n = this->_M_impl._M_finish - __pos) { std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __pos; _GLIBCXX_ASAN_ANNOTATE_SHRINK(__n); } } iterator _M_erase(iterator __position); iterator _M_erase(iterator __first, iterator __last); #if __cplusplus >= 201103L private: // Constant-time move assignment when source object's memory can be // moved, either because the source's allocator will move too // or because the allocators are equal. void _M_move_assign(vector&& __x, std::true_type) noexcept { vector __tmp(get_allocator()); this->_M_impl._M_swap_data(__tmp._M_impl); this->_M_impl._M_swap_data(__x._M_impl); std::__alloc_on_move(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); } // Do move assignment when it might not be possible to move source // object's memory, resulting in a linear-time operation. void _M_move_assign(vector&& __x, std::false_type) { if (__x._M_get_Tp_allocator() == this->_M_get_Tp_allocator()) _M_move_assign(std::move(__x), std::true_type()); else { // The rvalue's allocator cannot be moved and is not equal, // so we need to individually move each element. this->assign(std::__make_move_if_noexcept_iterator(__x.begin()), std::__make_move_if_noexcept_iterator(__x.end())); __x.clear(); } } #endif template<typename _Up> _Up* _M_data_ptr(_Up* __ptr) const _GLIBCXX_NOEXCEPT { return __ptr; } #if __cplusplus >= 201103L template<typename _Ptr> typename std::pointer_traits<_Ptr>::element_type* _M_data_ptr(_Ptr __ptr) const { return empty() ? nullptr : std::__to_address(__ptr); } #else template<typename _Up> _Up* _M_data_ptr(_Up* __ptr) _GLIBCXX_NOEXCEPT { return __ptr; } template<typename _Ptr> value_type* _M_data_ptr(_Ptr __ptr) { return empty() ? (value_type*)0 : __ptr.operator->(); } template<typename _Ptr> const value_type* _M_data_ptr(_Ptr __ptr) const { return empty() ? (const value_type*)0 : __ptr.operator->(); } #endif }; #if __cpp_deduction_guides >= 201606 template<typename _InputIterator, typename _ValT = typename iterator_traits<_InputIterator>::value_type, typename _Allocator = allocator<_ValT>, typename = _RequireInputIter<_InputIterator>, typename = _RequireAllocator<_Allocator>> vector(_InputIterator, _InputIterator, _Allocator = _Allocator()) -> vector<_ValT, _Allocator>; #endif /** * @brief Vector equality comparison. * @param __x A %vector. * @param __y A %vector of the same type as @a __x. * @return True iff the size and elements of the vectors are equal. * * This is an equivalence relation. It is linear in the size of the * vectors. Vectors are considered equivalent if their sizes are equal, * and if corresponding elements compare equal. */ template<typename _Tp, typename _Alloc> inline bool operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return (__x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin())); } /** * @brief Vector ordering relation. * @param __x A %vector. * @param __y A %vector of the same type as @a __x. * @return True iff @a __x is lexicographically less than @a __y. * * This is a total ordering relation. It is linear in the size of the * vectors. The elements must be comparable with @c <. * * See std::lexicographical_compare() for how the determination is made. */ template<typename _Tp, typename _Alloc> inline bool operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); } /// Based on operator== template<typename _Tp, typename _Alloc> inline bool operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__x == __y); } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return __y < __x; } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__y < __x); } /// Based on operator< template<typename _Tp, typename _Alloc> inline bool operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__x < __y); } /// See std::vector::swap(). template<typename _Tp, typename _Alloc> inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y))) { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _STL_VECTOR_H */ c++/8/bits/regex_automaton.tcc 0000644 00000017236 15146341150 0012131 0 ustar 00 // class template regex -*- C++ -*- // Copyright (C) 2013-2018 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/regex_automaton.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{regex} */ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __detail { #ifdef _GLIBCXX_DEBUG inline std::ostream& _State_base::_M_print(std::ostream& ostr) const { switch (_M_opcode) { case _S_opcode_alternative: case _S_opcode_repeat: ostr << "alt next=" << _M_next << " alt=" << _M_alt; break; case _S_opcode_subexpr_begin: ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr; break; case _S_opcode_subexpr_end: ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr; break; case _S_opcode_backref: ostr << "backref next=" << _M_next << " index=" << _M_backref_index; break; case _S_opcode_match: ostr << "match next=" << _M_next; break; case _S_opcode_accept: ostr << "accept next=" << _M_next; break; default: ostr << "unknown next=" << _M_next; break; } return ostr; } // Prints graphviz dot commands for state. inline std::ostream& _State_base::_M_dot(std::ostream& __ostr, _StateIdT __id) const { switch (_M_opcode) { case _S_opcode_alternative: case _S_opcode_repeat: __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n" << __id << " -> " << _M_next << " [label=\"next\", tailport=\"s\"];\n" << __id << " -> " << _M_alt << " [label=\"alt\", tailport=\"n\"];\n"; break; case _S_opcode_backref: __ostr << __id << " [label=\"" << __id << "\\nBACKREF " << _M_subexpr << "\"];\n" << __id << " -> " << _M_next << " [label=\"<match>\"];\n"; break; case _S_opcode_line_begin_assertion: __ostr << __id << " [label=\"" << __id << "\\nLINE_BEGIN \"];\n" << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; break; case _S_opcode_line_end_assertion: __ostr << __id << " [label=\"" << __id << "\\nLINE_END \"];\n" << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; break; case _S_opcode_word_boundary: __ostr << __id << " [label=\"" << __id << "\\nWORD_BOUNDRY " << _M_neg << "\"];\n" << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; break; case _S_opcode_subexpr_lookahead: __ostr << __id << " [label=\"" << __id << "\\nLOOK_AHEAD\"];\n" << __id << " -> " << _M_next << " [label=\"epsilon\", tailport=\"s\"];\n" << __id << " -> " << _M_alt << " [label=\"<assert>\", tailport=\"n\"];\n"; break; case _S_opcode_subexpr_begin: __ostr << __id << " [label=\"" << __id << "\\nSBEGIN " << _M_subexpr << "\"];\n" << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; break; case _S_opcode_subexpr_end: __ostr << __id << " [label=\"" << __id << "\\nSEND " << _M_subexpr << "\"];\n" << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; break; case _S_opcode_dummy: break; case _S_opcode_match: __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n" << __id << " -> " << _M_next << " [label=\"<match>\"];\n"; break; case _S_opcode_accept: __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ; break; default: _GLIBCXX_DEBUG_ASSERT(false); break; } return __ostr; } template<typename _TraitsT> std::ostream& _NFA<_TraitsT>::_M_dot(std::ostream& __ostr) const { __ostr << "digraph _Nfa {\n" " rankdir=LR;\n"; for (size_t __i = 0; __i < this->size(); ++__i) (*this)[__i]._M_dot(__ostr, __i); __ostr << "}\n"; return __ostr; } #endif template<typename _TraitsT> _StateIdT _NFA<_TraitsT>::_M_insert_backref(size_t __index) { if (this->_M_flags & regex_constants::__polynomial) __throw_regex_error(regex_constants::error_complexity, "Unexpected back-reference in polynomial mode."); // To figure out whether a backref is valid, a stack is used to store // unfinished sub-expressions. For example, when parsing // "(a(b)(c\\1(d)))" at '\\1', _M_subexpr_count is 3, indicating that 3 // sub expressions are parsed or partially parsed(in the stack), aka, // "(a..", "(b)" and "(c.."). // _M_paren_stack is {1, 3}, for incomplete "(a.." and "(c..". At this // time, "\\2" is valid, but "\\1" and "\\3" are not. if (__index >= _M_subexpr_count) __throw_regex_error( regex_constants::error_backref, "Back-reference index exceeds current sub-expression count."); for (auto __it : this->_M_paren_stack) if (__index == __it) __throw_regex_error( regex_constants::error_backref, "Back-reference referred to an opened sub-expression."); this->_M_has_backref = true; _StateT __tmp(_S_opcode_backref); __tmp._M_backref_index = __index; return _M_insert_state(std::move(__tmp)); } template<typename _TraitsT> void _NFA<_TraitsT>::_M_eliminate_dummy() { for (auto& __it : *this) { while (__it._M_next >= 0 && (*this)[__it._M_next]._M_opcode() == _S_opcode_dummy) __it._M_next = (*this)[__it._M_next]._M_next; if (__it._M_has_alt()) while (__it._M_alt >= 0 && (*this)[__it._M_alt]._M_opcode() == _S_opcode_dummy) __it._M_alt = (*this)[__it._M_alt]._M_next; } } // Just apply DFS on the sequence and re-link their links. template<typename _TraitsT> _StateSeq<_TraitsT> _StateSeq<_TraitsT>::_M_clone() { std::map<_StateIdT, _StateIdT> __m; std::stack<_StateIdT> __stack; __stack.push(_M_start); while (!__stack.empty()) { auto __u = __stack.top(); __stack.pop(); auto __dup = _M_nfa[__u]; // _M_insert_state() never return -1 auto __id = _M_nfa._M_insert_state(std::move(__dup)); __m[__u] = __id; if (__dup._M_has_alt()) if (__dup._M_alt != _S_invalid_state_id && __m.count(__dup._M_alt) == 0) __stack.push(__dup._M_alt); if (__u == _M_end) continue; if (__dup._M_next != _S_invalid_state_id && __m.count(__dup._M_next) == 0) __stack.push(__dup._M_next); } for (auto __it : __m) { auto __v = __it.second; auto& __ref = _M_nfa[__v]; if (__ref._M_next != _S_invalid_state_id) { __glibcxx_assert(__m.count(__ref._M_next) > 0); __ref._M_next = __m[__ref._M_next]; } if (__ref._M_has_alt()) if (__ref._M_alt != _S_invalid_state_id) { __glibcxx_assert(__m.count(__ref._M_alt) > 0); __ref._M_alt = __m[__ref._M_alt]; } } return _StateSeq(_M_nfa, __m[_M_start], __m[_M_end]); } } // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/bits/locale_classes.tcc 0000644 00000020267 15146341150 0011702 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 2007-2018 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/locale_classes.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.1 Locales // #ifndef _LOCALE_CLASSES_TCC #define _LOCALE_CLASSES_TCC 1 #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Facet> locale:: locale(const locale& __other, _Facet* __f) { _M_impl = new _Impl(*__other._M_impl, 1); __try { _M_impl->_M_install_facet(&_Facet::id, __f); } __catch(...) { _M_impl->_M_remove_reference(); __throw_exception_again; } delete [] _M_impl->_M_names[0]; _M_impl->_M_names[0] = 0; // Unnamed. } template<typename _Facet> locale locale:: combine(const locale& __other) const { _Impl* __tmp = new _Impl(*_M_impl, 1); __try { __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); } __catch(...) { __tmp->_M_remove_reference(); __throw_exception_again; } return locale(__tmp); } template<typename _CharT, typename _Traits, typename _Alloc> bool locale:: operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, const basic_string<_CharT, _Traits, _Alloc>& __s2) const { typedef std::collate<_CharT> __collate_type; const __collate_type& __collate = use_facet<__collate_type>(*this); return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), __s2.data(), __s2.data() + __s2.length()) < 0); } /** * @brief Test for the presence of a facet. * @ingroup locales * * has_facet tests the locale argument for the presence of the facet type * provided as the template parameter. Facets derived from the facet * parameter will also return true. * * @tparam _Facet The facet type to test the presence of. * @param __loc The locale to test. * @return true if @p __loc contains a facet of type _Facet, else false. */ template<typename _Facet> bool has_facet(const locale& __loc) throw() { const size_t __i = _Facet::id._M_id(); const locale::facet** __facets = __loc._M_impl->_M_facets; return (__i < __loc._M_impl->_M_facets_size #if __cpp_rtti && dynamic_cast<const _Facet*>(__facets[__i])); #else && static_cast<const _Facet*>(__facets[__i])); #endif } /** * @brief Return a facet. * @ingroup locales * * use_facet looks for and returns a reference to a facet of type Facet * where Facet is the template parameter. If has_facet(locale) is true, * there is a suitable facet to return. It throws std::bad_cast if the * locale doesn't contain a facet of type Facet. * * @tparam _Facet The facet type to access. * @param __loc The locale to use. * @return Reference to facet of type Facet. * @throw std::bad_cast if @p __loc doesn't contain a facet of type _Facet. */ template<typename _Facet> const _Facet& use_facet(const locale& __loc) { const size_t __i = _Facet::id._M_id(); const locale::facet** __facets = __loc._M_impl->_M_facets; if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i]) __throw_bad_cast(); #if __cpp_rtti return dynamic_cast<const _Facet&>(*__facets[__i]); #else return static_cast<const _Facet&>(*__facets[__i]); #endif } // Generic version does nothing. template<typename _CharT> int collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw () { return 0; } // Generic version does nothing. template<typename _CharT> size_t collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw () { return 0; } template<typename _CharT> int collate<_CharT>:: do_compare(const _CharT* __lo1, const _CharT* __hi1, const _CharT* __lo2, const _CharT* __hi2) const { // strcoll assumes zero-terminated strings so we make a copy // and then put a zero at the end. const string_type __one(__lo1, __hi1); const string_type __two(__lo2, __hi2); const _CharT* __p = __one.c_str(); const _CharT* __pend = __one.data() + __one.length(); const _CharT* __q = __two.c_str(); const _CharT* __qend = __two.data() + __two.length(); // strcoll stops when it sees a nul character so we break // the strings into zero-terminated substrings and pass those // to strcoll. for (;;) { const int __res = _M_compare(__p, __q); if (__res) return __res; __p += char_traits<_CharT>::length(__p); __q += char_traits<_CharT>::length(__q); if (__p == __pend && __q == __qend) return 0; else if (__p == __pend) return -1; else if (__q == __qend) return 1; __p++; __q++; } } template<typename _CharT> typename collate<_CharT>::string_type collate<_CharT>:: do_transform(const _CharT* __lo, const _CharT* __hi) const { string_type __ret; // strxfrm assumes zero-terminated strings so we make a copy const string_type __str(__lo, __hi); const _CharT* __p = __str.c_str(); const _CharT* __pend = __str.data() + __str.length(); size_t __len = (__hi - __lo) * 2; _CharT* __c = new _CharT[__len]; __try { // strxfrm stops when it sees a nul character so we break // the string into zero-terminated substrings and pass those // to strxfrm. for (;;) { // First try a buffer perhaps big enough. size_t __res = _M_transform(__c, __p, __len); // If the buffer was not large enough, try again with the // correct size. if (__res >= __len) { __len = __res + 1; delete [] __c, __c = 0; __c = new _CharT[__len]; __res = _M_transform(__c, __p, __len); } __ret.append(__c, __res); __p += char_traits<_CharT>::length(__p); if (__p == __pend) break; __p++; __ret.push_back(_CharT()); } } __catch(...) { delete [] __c; __throw_exception_again; } delete [] __c; return __ret; } template<typename _CharT> long collate<_CharT>:: do_hash(const _CharT* __lo, const _CharT* __hi) const { unsigned long __val = 0; for (; __lo < __hi; ++__lo) __val = *__lo + ((__val << 7) | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>:: __digits - 7))); return static_cast<long>(__val); } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template class collate<char>; extern template class collate_byname<char>; extern template const collate<char>& use_facet<collate<char> >(const locale&); extern template bool has_facet<collate<char> >(const locale&); #ifdef _GLIBCXX_USE_WCHAR_T extern template class collate<wchar_t>; extern template class collate_byname<wchar_t>; extern template const collate<wchar_t>& use_facet<collate<wchar_t> >(const locale&); extern template bool has_facet<collate<wchar_t> >(const locale&); #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/stl_algo.h 0000644 00000642426 15146341150 0010217 0 ustar 00 // Algorithm implementation -*- C++ -*- // Copyright (C) 2001-2018 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 * 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/stl_algo.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{algorithm} */ #ifndef _STL_ALGO_H #define _STL_ALGO_H 1 #include <cstdlib> // for rand #include <bits/algorithmfwd.h> #include <bits/stl_heap.h> #include <bits/stl_tempbuf.h> // for _Temporary_buffer #include <bits/predefined_ops.h> #if __cplusplus >= 201103L #include <bits/uniform_int_dist.h> #endif // See concept_check.h for the __glibcxx_*_requires macros. namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Swaps the median value of *__a, *__b and *__c under __comp to *__result template<typename _Iterator, typename _Compare> void __move_median_to_first(_Iterator __result,_Iterator __a, _Iterator __b, _Iterator __c, _Compare __comp) { if (__comp(__a, __b)) { if (__comp(__b, __c)) std::iter_swap(__result, __b); else if (__comp(__a, __c)) std::iter_swap(__result, __c); else std::iter_swap(__result, __a); } else if (__comp(__a, __c)) std::iter_swap(__result, __a); else if (__comp(__b, __c)) std::iter_swap(__result, __c); else std::iter_swap(__result, __b); } /// This is an overload used by find algos for the Input Iterator case. template<typename _InputIterator, typename _Predicate> inline _InputIterator __find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred, input_iterator_tag) { while (__first != __last && !__pred(__first)) ++__first; return __first; } /// This is an overload used by find algos for the RAI case. template<typename _RandomAccessIterator, typename _Predicate> _RandomAccessIterator __find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, _Predicate __pred, random_access_iterator_tag) { typename iterator_traits<_RandomAccessIterator>::difference_type __trip_count = (__last - __first) >> 2; for (; __trip_count > 0; --__trip_count) { if (__pred(__first)) return __first; ++__first; if (__pred(__first)) return __first; ++__first; if (__pred(__first)) return __first; ++__first; if (__pred(__first)) return __first; ++__first; } switch (__last - __first) { case 3: if (__pred(__first)) return __first; ++__first; case 2: if (__pred(__first)) return __first; ++__first; case 1: if (__pred(__first)) return __first; ++__first; case 0: default: return __last; } } template<typename _Iterator, typename _Predicate> inline _Iterator __find_if(_Iterator __first, _Iterator __last, _Predicate __pred) { return __find_if(__first, __last, __pred, std::__iterator_category(__first)); } /// Provided for stable_partition to use. template<typename _InputIterator, typename _Predicate> inline _InputIterator __find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { return std::__find_if(__first, __last, __gnu_cxx::__ops::__negate(__pred), std::__iterator_category(__first)); } /// Like find_if_not(), but uses and updates a count of the /// remaining range length instead of comparing against an end /// iterator. template<typename _InputIterator, typename _Predicate, typename _Distance> _InputIterator __find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred) { for (; __len; --__len, (void) ++__first) if (!__pred(__first)) break; return __first; } // set_difference // set_intersection // set_symmetric_difference // set_union // for_each // find // find_if // find_first_of // adjacent_find // count // count_if // search template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> _ForwardIterator1 __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __predicate) { // Test for empty ranges if (__first1 == __last1 || __first2 == __last2) return __first1; // Test for a pattern of length 1. _ForwardIterator2 __p1(__first2); if (++__p1 == __last2) return std::__find_if(__first1, __last1, __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); // General case. _ForwardIterator2 __p; _ForwardIterator1 __current = __first1; for (;;) { __first1 = std::__find_if(__first1, __last1, __gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2)); if (__first1 == __last1) return __last1; __p = __p1; __current = __first1; if (++__current == __last1) return __last1; while (__predicate(__current, __p)) { if (++__p == __last2) return __first1; if (++__current == __last1) return __last1; } ++__first1; } return __first1; } // search_n /** * This is an helper function for search_n overloaded for forward iterators. */ template<typename _ForwardIterator, typename _Integer, typename _UnaryPredicate> _ForwardIterator __search_n_aux(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, _UnaryPredicate __unary_pred, std::forward_iterator_tag) { __first = std::__find_if(__first, __last, __unary_pred); while (__first != __last) { typename iterator_traits<_ForwardIterator>::difference_type __n = __count; _ForwardIterator __i = __first; ++__i; while (__i != __last && __n != 1 && __unary_pred(__i)) { ++__i; --__n; } if (__n == 1) return __first; if (__i == __last) return __last; __first = std::__find_if(++__i, __last, __unary_pred); } return __last; } /** * This is an helper function for search_n overloaded for random access * iterators. */ template<typename _RandomAccessIter, typename _Integer, typename _UnaryPredicate> _RandomAccessIter __search_n_aux(_RandomAccessIter __first, _RandomAccessIter __last, _Integer __count, _UnaryPredicate __unary_pred, std::random_access_iterator_tag) { typedef typename std::iterator_traits<_RandomAccessIter>::difference_type _DistanceType; _DistanceType __tailSize = __last - __first; _DistanceType __remainder = __count; while (__remainder <= __tailSize) // the main loop... { __first += __remainder; __tailSize -= __remainder; // __first here is always pointing to one past the last element of // next possible match. _RandomAccessIter __backTrack = __first; while (__unary_pred(--__backTrack)) { if (--__remainder == 0) return (__first - __count); // Success } __remainder = __count + 1 - (__first - __backTrack); } return __last; // Failure } template<typename _ForwardIterator, typename _Integer, typename _UnaryPredicate> _ForwardIterator __search_n(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, _UnaryPredicate __unary_pred) { if (__count <= 0) return __first; if (__count == 1) return std::__find_if(__first, __last, __unary_pred); return std::__search_n_aux(__first, __last, __count, __unary_pred, std::__iterator_category(__first)); } // find_end for forward iterators. template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> _ForwardIterator1 __find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, forward_iterator_tag, forward_iterator_tag, _BinaryPredicate __comp) { if (__first2 == __last2) return __last1; _ForwardIterator1 __result = __last1; while (1) { _ForwardIterator1 __new_result = std::__search(__first1, __last1, __first2, __last2, __comp); if (__new_result == __last1) return __result; else { __result = __new_result; __first1 = __new_result; ++__first1; } } } // find_end for bidirectional iterators (much faster). template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, typename _BinaryPredicate> _BidirectionalIterator1 __find_end(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag, _BinaryPredicate __comp) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept< _BidirectionalIterator1>) __glibcxx_function_requires(_BidirectionalIteratorConcept< _BidirectionalIterator2>) typedef reverse_iterator<_BidirectionalIterator1> _RevIterator1; typedef reverse_iterator<_BidirectionalIterator2> _RevIterator2; _RevIterator1 __rlast1(__first1); _RevIterator2 __rlast2(__first2); _RevIterator1 __rresult = std::__search(_RevIterator1(__last1), __rlast1, _RevIterator2(__last2), __rlast2, __comp); if (__rresult == __rlast1) return __last1; else { _BidirectionalIterator1 __result = __rresult.base(); std::advance(__result, -std::distance(__first2, __last2)); return __result; } } /** * @brief Find last matching subsequence in a sequence. * @ingroup non_mutating_algorithms * @param __first1 Start of range to search. * @param __last1 End of range to search. * @param __first2 Start of sequence to match. * @param __last2 End of sequence to match. * @return The last iterator @c i in the range * @p [__first1,__last1-(__last2-__first2)) such that @c *(i+N) == * @p *(__first2+N) for each @c N in the range @p * [0,__last2-__first2), or @p __last1 if no such iterator exists. * * Searches the range @p [__first1,__last1) for a sub-sequence that * compares equal value-by-value with the sequence given by @p * [__first2,__last2) and returns an iterator to the __first * element of the sub-sequence, or @p __last1 if the sub-sequence * is not found. The sub-sequence will be the last such * subsequence contained in [__first1,__last1). * * Because the sub-sequence must lie completely within the range @p * [__first1,__last1) it must start at a position less than @p * __last1-(__last2-__first2) where @p __last2-__first2 is the * length of the sub-sequence. This means that the returned * iterator @c i will be in the range @p * [__first1,__last1-(__last2-__first2)) */ template<typename _ForwardIterator1, typename _ForwardIterator2> inline _ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return std::__find_end(__first1, __last1, __first2, __last2, std::__iterator_category(__first1), std::__iterator_category(__first2), __gnu_cxx::__ops::__iter_equal_to_iter()); } /** * @brief Find last matching subsequence in a sequence using a predicate. * @ingroup non_mutating_algorithms * @param __first1 Start of range to search. * @param __last1 End of range to search. * @param __first2 Start of sequence to match. * @param __last2 End of sequence to match. * @param __comp The predicate to use. * @return The last iterator @c i in the range @p * [__first1,__last1-(__last2-__first2)) such that @c * predicate(*(i+N), @p (__first2+N)) is true for each @c N in the * range @p [0,__last2-__first2), or @p __last1 if no such iterator * exists. * * Searches the range @p [__first1,__last1) for a sub-sequence that * compares equal value-by-value with the sequence given by @p * [__first2,__last2) using comp as a predicate and returns an * iterator to the first element of the sub-sequence, or @p __last1 * if the sub-sequence is not found. The sub-sequence will be the * last such subsequence contained in [__first,__last1). * * Because the sub-sequence must lie completely within the range @p * [__first1,__last1) it must start at a position less than @p * __last1-(__last2-__first2) where @p __last2-__first2 is the * length of the sub-sequence. This means that the returned * iterator @c i will be in the range @p * [__first1,__last1-(__last2-__first2)) */ template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> inline _ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return std::__find_end(__first1, __last1, __first2, __last2, std::__iterator_category(__first1), std::__iterator_category(__first2), __gnu_cxx::__ops::__iter_comp_iter(__comp)); } #if __cplusplus >= 201103L /** * @brief Checks that a predicate is true for all the elements * of a sequence. * @ingroup non_mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __pred A predicate. * @return True if the check is true, false otherwise. * * Returns true if @p __pred is true for each element in the range * @p [__first,__last), and false otherwise. */ template<typename _InputIterator, typename _Predicate> inline bool all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { return __last == std::find_if_not(__first, __last, __pred); } /** * @brief Checks that a predicate is false for all the elements * of a sequence. * @ingroup non_mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __pred A predicate. * @return True if the check is true, false otherwise. * * Returns true if @p __pred is false for each element in the range * @p [__first,__last), and false otherwise. */ template<typename _InputIterator, typename _Predicate> inline bool none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { return __last == _GLIBCXX_STD_A::find_if(__first, __last, __pred); } /** * @brief Checks that a predicate is false for at least an element * of a sequence. * @ingroup non_mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __pred A predicate. * @return True if the check is true, false otherwise. * * Returns true if an element exists in the range @p * [__first,__last) such that @p __pred is true, and false * otherwise. */ template<typename _InputIterator, typename _Predicate> inline bool any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { return !std::none_of(__first, __last, __pred); } /** * @brief Find the first element in a sequence for which a * predicate is false. * @ingroup non_mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __pred A predicate. * @return The first iterator @c i in the range @p [__first,__last) * such that @p __pred(*i) is false, or @p __last if no such iterator exists. */ template<typename _InputIterator, typename _Predicate> inline _InputIterator find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__find_if_not(__first, __last, __gnu_cxx::__ops::__pred_iter(__pred)); } /** * @brief Checks whether the sequence is partitioned. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __pred A predicate. * @return True if the range @p [__first,__last) is partioned by @p __pred, * i.e. if all elements that satisfy @p __pred appear before those that * do not. */ template<typename _InputIterator, typename _Predicate> inline bool is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) { __first = std::find_if_not(__first, __last, __pred); if (__first == __last) return true; ++__first; return std::none_of(__first, __last, __pred); } /** * @brief Find the partition point of a partitioned range. * @ingroup mutating_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __pred A predicate. * @return An iterator @p mid such that @p all_of(__first, mid, __pred) * and @p none_of(mid, __last, __pred) are both true. */ template<typename _ForwardIterator, typename _Predicate> _ForwardIterator partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_ForwardIterator>::value_type>) // A specific debug-mode test will be necessary... __glibcxx_requires_valid_range(__first, __last); typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType; _DistanceType __len = std::distance(__first, __last); _DistanceType __half; _ForwardIterator __middle; while (__len > 0) { __half = __len >> 1; __middle = __first; std::advance(__middle, __half); if (__pred(*__middle)) { __first = __middle; ++__first; __len = __len - __half - 1; } else __len = __half; } return __first; } #endif template<typename _InputIterator, typename _OutputIterator, typename _Predicate> _OutputIterator __remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(__first)) { *__result = *__first; ++__result; } return __result; } /** * @brief Copy a sequence, removing elements of a given value. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @param __value The value to be removed. * @return An iterator designating the end of the resulting sequence. * * Copies each element in the range @p [__first,__last) not equal * to @p __value to the range beginning at @p __result. * remove_copy() is stable, so the relative order of elements that * are copied is unchanged. */ template<typename _InputIterator, typename _OutputIterator, typename _Tp> inline _OutputIterator remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); return std::__remove_copy_if(__first, __last, __result, __gnu_cxx::__ops::__iter_equals_val(__value)); } /** * @brief Copy a sequence, removing elements for which a predicate is true. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @param __pred A predicate. * @return An iterator designating the end of the resulting sequence. * * Copies each element in the range @p [__first,__last) for which * @p __pred returns false to the range beginning at @p __result. * * remove_copy_if() is stable, so the relative order of elements that are * copied is unchanged. */ template<typename _InputIterator, typename _OutputIterator, typename _Predicate> inline _OutputIterator remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__remove_copy_if(__first, __last, __result, __gnu_cxx::__ops::__pred_iter(__pred)); } #if __cplusplus >= 201103L /** * @brief Copy the elements of a sequence for which a predicate is true. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @param __pred A predicate. * @return An iterator designating the end of the resulting sequence. * * Copies each element in the range @p [__first,__last) for which * @p __pred returns true to the range beginning at @p __result. * * copy_if() is stable, so the relative order of elements that are * copied is unchanged. */ template<typename _InputIterator, typename _OutputIterator, typename _Predicate> _OutputIterator copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first) if (__pred(*__first)) { *__result = *__first; ++__result; } return __result; } template<typename _InputIterator, typename _Size, typename _OutputIterator> _OutputIterator __copy_n(_InputIterator __first, _Size __n, _OutputIterator __result, input_iterator_tag) { if (__n > 0) { while (true) { *__result = *__first; ++__result; if (--__n > 0) ++__first; else break; } } return __result; } template<typename _RandomAccessIterator, typename _Size, typename _OutputIterator> inline _OutputIterator __copy_n(_RandomAccessIterator __first, _Size __n, _OutputIterator __result, random_access_iterator_tag) { return std::copy(__first, __first + __n, __result); } /** * @brief Copies the range [first,first+n) into [result,result+n). * @ingroup mutating_algorithms * @param __first An input iterator. * @param __n The number of elements to copy. * @param __result An output iterator. * @return result+n. * * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the * loop count will be known (and therefore a candidate for compiler * optimizations such as unrolling). */ template<typename _InputIterator, typename _Size, typename _OutputIterator> inline _OutputIterator copy_n(_InputIterator __first, _Size __n, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) return std::__copy_n(__first, __n, __result, std::__iterator_category(__first)); } /** * @brief Copy the elements of a sequence to separate output sequences * depending on the truth value of a predicate. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __out_true An output iterator. * @param __out_false An output iterator. * @param __pred A predicate. * @return A pair designating the ends of the resulting sequences. * * Copies each element in the range @p [__first,__last) for which * @p __pred returns true to the range beginning at @p out_true * and each element for which @p __pred returns false to @p __out_false. */ template<typename _InputIterator, typename _OutputIterator1, typename _OutputIterator2, typename _Predicate> pair<_OutputIterator1, _OutputIterator2> partition_copy(_InputIterator __first, _InputIterator __last, _OutputIterator1 __out_true, _OutputIterator2 __out_false, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator1, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator2, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first) if (__pred(*__first)) { *__out_true = *__first; ++__out_true; } else { *__out_false = *__first; ++__out_false; } return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); } #endif template<typename _ForwardIterator, typename _Predicate> _ForwardIterator __remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { __first = std::__find_if(__first, __last, __pred); if (__first == __last) return __first; _ForwardIterator __result = __first; ++__first; for (; __first != __last; ++__first) if (!__pred(__first)) { *__result = _GLIBCXX_MOVE(*__first); ++__result; } return __result; } /** * @brief Remove elements from a sequence. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __value The value to be removed. * @return An iterator designating the end of the resulting sequence. * * All elements equal to @p __value are removed from the range * @p [__first,__last). * * remove() is stable, so the relative order of elements that are * not removed is unchanged. * * Elements between the end of the resulting sequence and @p __last * are still present, but their value is unspecified. */ template<typename _ForwardIterator, typename _Tp> inline _ForwardIterator remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); return std::__remove_if(__first, __last, __gnu_cxx::__ops::__iter_equals_val(__value)); } /** * @brief Remove elements from a sequence using a predicate. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __pred A predicate. * @return An iterator designating the end of the resulting sequence. * * All elements for which @p __pred returns true are removed from the range * @p [__first,__last). * * remove_if() is stable, so the relative order of elements that are * not removed is unchanged. * * Elements between the end of the resulting sequence and @p __last * are still present, but their value is unspecified. */ template<typename _ForwardIterator, typename _Predicate> inline _ForwardIterator remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__remove_if(__first, __last, __gnu_cxx::__ops::__pred_iter(__pred)); } template<typename _ForwardIterator, typename _BinaryPredicate> _ForwardIterator __adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred) { if (__first == __last) return __last; _ForwardIterator __next = __first; while (++__next != __last) { if (__binary_pred(__first, __next)) return __first; __first = __next; } return __last; } template<typename _ForwardIterator, typename _BinaryPredicate> _ForwardIterator __unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred) { // Skip the beginning, if already unique. __first = std::__adjacent_find(__first, __last, __binary_pred); if (__first == __last) return __last; // Do the real copy work. _ForwardIterator __dest = __first; ++__first; while (++__first != __last) if (!__binary_pred(__dest, __first)) *++__dest = _GLIBCXX_MOVE(*__first); return ++__dest; } /** * @brief Remove consecutive duplicate values from a sequence. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @return An iterator designating the end of the resulting sequence. * * Removes all but the first element from each group of consecutive * values that compare equal. * unique() is stable, so the relative order of elements that are * not removed is unchanged. * Elements between the end of the resulting sequence and @p __last * are still present, but their value is unspecified. */ template<typename _ForwardIterator> inline _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__unique(__first, __last, __gnu_cxx::__ops::__iter_equal_to_iter()); } /** * @brief Remove consecutive values from a sequence using a predicate. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __binary_pred A binary predicate. * @return An iterator designating the end of the resulting sequence. * * Removes all but the first element from each group of consecutive * values for which @p __binary_pred returns true. * unique() is stable, so the relative order of elements that are * not removed is unchanged. * Elements between the end of the resulting sequence and @p __last * are still present, but their value is unspecified. */ template<typename _ForwardIterator, typename _BinaryPredicate> inline _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__unique(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); } /** * This is an uglified * unique_copy(_InputIterator, _InputIterator, _OutputIterator, * _BinaryPredicate) * overloaded for forward iterators and output iterator as result. */ template<typename _ForwardIterator, typename _OutputIterator, typename _BinaryPredicate> _OutputIterator __unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __binary_pred, forward_iterator_tag, output_iterator_tag) { // concept requirements -- iterators already checked __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) _ForwardIterator __next = __first; *__result = *__first; while (++__next != __last) if (!__binary_pred(__first, __next)) { __first = __next; *++__result = *__first; } return ++__result; } /** * This is an uglified * unique_copy(_InputIterator, _InputIterator, _OutputIterator, * _BinaryPredicate) * overloaded for input iterators and output iterator as result. */ template<typename _InputIterator, typename _OutputIterator, typename _BinaryPredicate> _OutputIterator __unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __binary_pred, input_iterator_tag, output_iterator_tag) { // concept requirements -- iterators already checked __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_InputIterator>::value_type, typename iterator_traits<_InputIterator>::value_type>) typename iterator_traits<_InputIterator>::value_type __value = *__first; __decltype(__gnu_cxx::__ops::__iter_comp_val(__binary_pred)) __rebound_pred = __gnu_cxx::__ops::__iter_comp_val(__binary_pred); *__result = __value; while (++__first != __last) if (!__rebound_pred(__first, __value)) { __value = *__first; *++__result = __value; } return ++__result; } /** * This is an uglified * unique_copy(_InputIterator, _InputIterator, _OutputIterator, * _BinaryPredicate) * overloaded for input iterators and forward iterator as result. */ template<typename _InputIterator, typename _ForwardIterator, typename _BinaryPredicate> _ForwardIterator __unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, _BinaryPredicate __binary_pred, input_iterator_tag, forward_iterator_tag) { // concept requirements -- iterators already checked __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_InputIterator>::value_type>) *__result = *__first; while (++__first != __last) if (!__binary_pred(__result, __first)) *++__result = *__first; return ++__result; } /** * This is an uglified reverse(_BidirectionalIterator, * _BidirectionalIterator) * overloaded for bidirectional iterators. */ template<typename _BidirectionalIterator> void __reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) { while (true) if (__first == __last || __first == --__last) return; else { std::iter_swap(__first, __last); ++__first; } } /** * This is an uglified reverse(_BidirectionalIterator, * _BidirectionalIterator) * overloaded for random access iterators. */ template<typename _RandomAccessIterator> void __reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { if (__first == __last) return; --__last; while (__first < __last) { std::iter_swap(__first, __last); ++__first; --__last; } } /** * @brief Reverse a sequence. * @ingroup mutating_algorithms * @param __first A bidirectional iterator. * @param __last A bidirectional iterator. * @return reverse() returns no value. * * Reverses the order of the elements in the range @p [__first,__last), * so that the first element becomes the last etc. * For every @c i such that @p 0<=i<=(__last-__first)/2), @p reverse() * swaps @p *(__first+i) and @p *(__last-(i+1)) */ template<typename _BidirectionalIterator> inline void reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< _BidirectionalIterator>) __glibcxx_requires_valid_range(__first, __last); std::__reverse(__first, __last, std::__iterator_category(__first)); } /** * @brief Copy a sequence, reversing its elements. * @ingroup mutating_algorithms * @param __first A bidirectional iterator. * @param __last A bidirectional iterator. * @param __result An output iterator. * @return An iterator designating the end of the resulting sequence. * * Copies the elements in the range @p [__first,__last) to the * range @p [__result,__result+(__last-__first)) such that the * order of the elements is reversed. For every @c i such that @p * 0<=i<=(__last-__first), @p reverse_copy() performs the * assignment @p *(__result+(__last-__first)-1-i) = *(__first+i). * The ranges @p [__first,__last) and @p * [__result,__result+(__last-__first)) must not overlap. */ template<typename _BidirectionalIterator, typename _OutputIterator> _OutputIterator reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept< _BidirectionalIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); while (__first != __last) { --__last; *__result = *__last; ++__result; } return __result; } /** * This is a helper function for the rotate algorithm specialized on RAIs. * It returns the greatest common divisor of two integer values. */ template<typename _EuclideanRingElement> _EuclideanRingElement __gcd(_EuclideanRingElement __m, _EuclideanRingElement __n) { while (__n != 0) { _EuclideanRingElement __t = __m % __n; __m = __n; __n = __t; } return __m; } inline namespace _V2 { /// This is a helper function for the rotate algorithm. template<typename _ForwardIterator> _ForwardIterator __rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, forward_iterator_tag) { if (__first == __middle) return __last; else if (__last == __middle) return __first; _ForwardIterator __first2 = __middle; do { std::iter_swap(__first, __first2); ++__first; ++__first2; if (__first == __middle) __middle = __first2; } while (__first2 != __last); _ForwardIterator __ret = __first; __first2 = __middle; while (__first2 != __last) { std::iter_swap(__first, __first2); ++__first; ++__first2; if (__first == __middle) __middle = __first2; else if (__first2 == __last) __first2 = __middle; } return __ret; } /// This is a helper function for the rotate algorithm. template<typename _BidirectionalIterator> _BidirectionalIterator __rotate(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, bidirectional_iterator_tag) { // concept requirements __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< _BidirectionalIterator>) if (__first == __middle) return __last; else if (__last == __middle) return __first; std::__reverse(__first, __middle, bidirectional_iterator_tag()); std::__reverse(__middle, __last, bidirectional_iterator_tag()); while (__first != __middle && __middle != __last) { std::iter_swap(__first, --__last); ++__first; } if (__first == __middle) { std::__reverse(__middle, __last, bidirectional_iterator_tag()); return __last; } else { std::__reverse(__first, __middle, bidirectional_iterator_tag()); return __first; } } /// This is a helper function for the rotate algorithm. template<typename _RandomAccessIterator> _RandomAccessIterator __rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, random_access_iterator_tag) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) if (__first == __middle) return __last; else if (__last == __middle) return __first; typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance; typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; _Distance __n = __last - __first; _Distance __k = __middle - __first; if (__k == __n - __k) { std::swap_ranges(__first, __middle, __middle); return __middle; } _RandomAccessIterator __p = __first; _RandomAccessIterator __ret = __first + (__last - __middle); for (;;) { if (__k < __n - __k) { if (__is_pod(_ValueType) && __k == 1) { _ValueType __t = _GLIBCXX_MOVE(*__p); _GLIBCXX_MOVE3(__p + 1, __p + __n, __p); *(__p + __n - 1) = _GLIBCXX_MOVE(__t); return __ret; } _RandomAccessIterator __q = __p + __k; for (_Distance __i = 0; __i < __n - __k; ++ __i) { std::iter_swap(__p, __q); ++__p; ++__q; } __n %= __k; if (__n == 0) return __ret; std::swap(__n, __k); __k = __n - __k; } else { __k = __n - __k; if (__is_pod(_ValueType) && __k == 1) { _ValueType __t = _GLIBCXX_MOVE(*(__p + __n - 1)); _GLIBCXX_MOVE_BACKWARD3(__p, __p + __n - 1, __p + __n); *__p = _GLIBCXX_MOVE(__t); return __ret; } _RandomAccessIterator __q = __p + __n; __p = __q - __k; for (_Distance __i = 0; __i < __n - __k; ++ __i) { --__p; --__q; std::iter_swap(__p, __q); } __n %= __k; if (__n == 0) return __ret; std::swap(__n, __k); } } } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 488. rotate throws away useful information /** * @brief Rotate the elements of a sequence. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __middle A forward iterator. * @param __last A forward iterator. * @return first + (last - middle). * * Rotates the elements of the range @p [__first,__last) by * @p (__middle - __first) positions so that the element at @p __middle * is moved to @p __first, the element at @p __middle+1 is moved to * @p __first+1 and so on for each element in the range * @p [__first,__last). * * This effectively swaps the ranges @p [__first,__middle) and * @p [__middle,__last). * * Performs * @p *(__first+(n+(__last-__middle))%(__last-__first))=*(__first+n) * for each @p n in the range @p [0,__last-__first). */ template<typename _ForwardIterator> inline _ForwardIterator rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_requires_valid_range(__first, __middle); __glibcxx_requires_valid_range(__middle, __last); return std::__rotate(__first, __middle, __last, std::__iterator_category(__first)); } } // namespace _V2 /** * @brief Copy a sequence, rotating its elements. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __middle A forward iterator. * @param __last A forward iterator. * @param __result An output iterator. * @return An iterator designating the end of the resulting sequence. * * Copies the elements of the range @p [__first,__last) to the * range beginning at @result, rotating the copied elements by * @p (__middle-__first) positions so that the element at @p __middle * is moved to @p __result, the element at @p __middle+1 is moved * to @p __result+1 and so on for each element in the range @p * [__first,__last). * * Performs * @p *(__result+(n+(__last-__middle))%(__last-__first))=*(__first+n) * for each @p n in the range @p [0,__last-__first). */ template<typename _ForwardIterator, typename _OutputIterator> inline _OutputIterator rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __middle); __glibcxx_requires_valid_range(__middle, __last); return std::copy(__first, __middle, std::copy(__middle, __last, __result)); } /// This is a helper function... template<typename _ForwardIterator, typename _Predicate> _ForwardIterator __partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) { if (__first == __last) return __first; while (__pred(*__first)) if (++__first == __last) return __first; _ForwardIterator __next = __first; while (++__next != __last) if (__pred(*__next)) { std::iter_swap(__first, __next); ++__first; } return __first; } /// This is a helper function... template<typename _BidirectionalIterator, typename _Predicate> _BidirectionalIterator __partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, bidirectional_iterator_tag) { while (true) { while (true) if (__first == __last) return __first; else if (__pred(*__first)) ++__first; else break; --__last; while (true) if (__first == __last) return __first; else if (!bool(__pred(*__last))) --__last; else break; std::iter_swap(__first, __last); ++__first; } } // partition /// This is a helper function... /// Requires __first != __last and !__pred(__first) /// and __len == distance(__first, __last). /// /// !__pred(__first) allows us to guarantee that we don't /// move-assign an element onto itself. template<typename _ForwardIterator, typename _Pointer, typename _Predicate, typename _Distance> _ForwardIterator __stable_partition_adaptive(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, _Distance __len, _Pointer __buffer, _Distance __buffer_size) { if (__len == 1) return __first; if (__len <= __buffer_size) { _ForwardIterator __result1 = __first; _Pointer __result2 = __buffer; // The precondition guarantees that !__pred(__first), so // move that element to the buffer before starting the loop. // This ensures that we only call __pred once per element. *__result2 = _GLIBCXX_MOVE(*__first); ++__result2; ++__first; for (; __first != __last; ++__first) if (__pred(__first)) { *__result1 = _GLIBCXX_MOVE(*__first); ++__result1; } else { *__result2 = _GLIBCXX_MOVE(*__first); ++__result2; } _GLIBCXX_MOVE3(__buffer, __result2, __result1); return __result1; } _ForwardIterator __middle = __first; std::advance(__middle, __len / 2); _ForwardIterator __left_split = std::__stable_partition_adaptive(__first, __middle, __pred, __len / 2, __buffer, __buffer_size); // Advance past true-predicate values to satisfy this // function's preconditions. _Distance __right_len = __len - __len / 2; _ForwardIterator __right_split = std::__find_if_not_n(__middle, __right_len, __pred); if (__right_len) __right_split = std::__stable_partition_adaptive(__right_split, __last, __pred, __right_len, __buffer, __buffer_size); std::rotate(__left_split, __middle, __right_split); std::advance(__left_split, std::distance(__middle, __right_split)); return __left_split; } template<typename _ForwardIterator, typename _Predicate> _ForwardIterator __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { __first = std::__find_if_not(__first, __last, __pred); if (__first == __last) return __first; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType; _Temporary_buffer<_ForwardIterator, _ValueType> __buf(__first, __last); return std::__stable_partition_adaptive(__first, __last, __pred, _DistanceType(__buf.requested_size()), __buf.begin(), _DistanceType(__buf.size())); } /** * @brief Move elements for which a predicate is true to the beginning * of a sequence, preserving relative ordering. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __pred A predicate functor. * @return An iterator @p middle such that @p __pred(i) is true for each * iterator @p i in the range @p [first,middle) and false for each @p i * in the range @p [middle,last). * * Performs the same function as @p partition() with the additional * guarantee that the relative ordering of elements in each group is * preserved, so any two elements @p x and @p y in the range * @p [__first,__last) such that @p __pred(x)==__pred(y) will have the same * relative ordering after calling @p stable_partition(). */ template<typename _ForwardIterator, typename _Predicate> inline _ForwardIterator stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__stable_partition(__first, __last, __gnu_cxx::__ops::__pred_iter(__pred)); } /// This is a helper function for the sort routines. template<typename _RandomAccessIterator, typename _Compare> void __heap_select(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { std::__make_heap(__first, __middle, __comp); for (_RandomAccessIterator __i = __middle; __i < __last; ++__i) if (__comp(__i, __first)) std::__pop_heap(__first, __middle, __i, __comp); } // partial_sort template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare> _RandomAccessIterator __partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) { typedef typename iterator_traits<_InputIterator>::value_type _InputValueType; typedef iterator_traits<_RandomAccessIterator> _RItTraits; typedef typename _RItTraits::difference_type _DistanceType; if (__result_first == __result_last) return __result_last; _RandomAccessIterator __result_real_last = __result_first; while (__first != __last && __result_real_last != __result_last) { *__result_real_last = *__first; ++__result_real_last; ++__first; } std::__make_heap(__result_first, __result_real_last, __comp); while (__first != __last) { if (__comp(__first, __result_first)) std::__adjust_heap(__result_first, _DistanceType(0), _DistanceType(__result_real_last - __result_first), _InputValueType(*__first), __comp); ++__first; } std::__sort_heap(__result_first, __result_real_last, __comp); return __result_real_last; } /** * @brief Copy the smallest elements of a sequence. * @ingroup sorting_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __result_first A random-access iterator. * @param __result_last Another random-access iterator. * @return An iterator indicating the end of the resulting sequence. * * Copies and sorts the smallest N values from the range @p [__first,__last) * to the range beginning at @p __result_first, where the number of * elements to be copied, @p N, is the smaller of @p (__last-__first) and * @p (__result_last-__result_first). * After the sort if @e i and @e j are iterators in the range * @p [__result_first,__result_first+N) such that i precedes j then * *j<*i is false. * The value returned is @p __result_first+N. */ template<typename _InputIterator, typename _RandomAccessIterator> inline _RandomAccessIterator partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) { #ifdef _GLIBCXX_CONCEPT_CHECKS typedef typename iterator_traits<_InputIterator>::value_type _InputValueType; typedef typename iterator_traits<_RandomAccessIterator>::value_type _OutputValueType; #endif // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>) __glibcxx_function_requires(_LessThanOpConcept<_InputValueType, _OutputValueType>) __glibcxx_function_requires(_LessThanComparableConcept<_OutputValueType>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); __glibcxx_requires_valid_range(__result_first, __result_last); return std::__partial_sort_copy(__first, __last, __result_first, __result_last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Copy the smallest elements of a sequence using a predicate for * comparison. * @ingroup sorting_algorithms * @param __first An input iterator. * @param __last Another input iterator. * @param __result_first A random-access iterator. * @param __result_last Another random-access iterator. * @param __comp A comparison functor. * @return An iterator indicating the end of the resulting sequence. * * Copies and sorts the smallest N values from the range @p [__first,__last) * to the range beginning at @p result_first, where the number of * elements to be copied, @p N, is the smaller of @p (__last-__first) and * @p (__result_last-__result_first). * After the sort if @e i and @e j are iterators in the range * @p [__result_first,__result_first+N) such that i precedes j then * @p __comp(*j,*i) is false. * The value returned is @p __result_first+N. */ template<typename _InputIterator, typename _RandomAccessIterator, typename _Compare> inline _RandomAccessIterator partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) { #ifdef _GLIBCXX_CONCEPT_CHECKS typedef typename iterator_traits<_InputIterator>::value_type _InputValueType; typedef typename iterator_traits<_RandomAccessIterator>::value_type _OutputValueType; #endif // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_ConvertibleConcept<_InputValueType, _OutputValueType>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _InputValueType, _OutputValueType>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _OutputValueType, _OutputValueType>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); __glibcxx_requires_valid_range(__result_first, __result_last); return std::__partial_sort_copy(__first, __last, __result_first, __result_last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Compare> void __unguarded_linear_insert(_RandomAccessIterator __last, _Compare __comp) { typename iterator_traits<_RandomAccessIterator>::value_type __val = _GLIBCXX_MOVE(*__last); _RandomAccessIterator __next = __last; --__next; while (__comp(__val, __next)) { *__last = _GLIBCXX_MOVE(*__next); __last = __next; --__next; } *__last = _GLIBCXX_MOVE(__val); } /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Compare> void __insertion_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { if (__first == __last) return; for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) { if (__comp(__i, __first)) { typename iterator_traits<_RandomAccessIterator>::value_type __val = _GLIBCXX_MOVE(*__i); _GLIBCXX_MOVE_BACKWARD3(__first, __i, __i + 1); *__first = _GLIBCXX_MOVE(__val); } else std::__unguarded_linear_insert(__i, __gnu_cxx::__ops::__val_comp_iter(__comp)); } } /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Compare> inline void __unguarded_insertion_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { for (_RandomAccessIterator __i = __first; __i != __last; ++__i) std::__unguarded_linear_insert(__i, __gnu_cxx::__ops::__val_comp_iter(__comp)); } /** * @doctodo * This controls some aspect of the sort routines. */ enum { _S_threshold = 16 }; /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Compare> void __final_insertion_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { if (__last - __first > int(_S_threshold)) { std::__insertion_sort(__first, __first + int(_S_threshold), __comp); std::__unguarded_insertion_sort(__first + int(_S_threshold), __last, __comp); } else std::__insertion_sort(__first, __last, __comp); } /// This is a helper function... template<typename _RandomAccessIterator, typename _Compare> _RandomAccessIterator __unguarded_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __pivot, _Compare __comp) { while (true) { while (__comp(__first, __pivot)) ++__first; --__last; while (__comp(__pivot, __last)) --__last; if (!(__first < __last)) return __first; std::iter_swap(__first, __last); ++__first; } } /// This is a helper function... template<typename _RandomAccessIterator, typename _Compare> inline _RandomAccessIterator __unguarded_partition_pivot(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { _RandomAccessIterator __mid = __first + (__last - __first) / 2; std::__move_median_to_first(__first, __first + 1, __mid, __last - 1, __comp); return std::__unguarded_partition(__first + 1, __last, __first, __comp); } template<typename _RandomAccessIterator, typename _Compare> inline void __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { std::__heap_select(__first, __middle, __last, __comp); std::__sort_heap(__first, __middle, __comp); } /// This is a helper function for the sort routine. template<typename _RandomAccessIterator, typename _Size, typename _Compare> void __introsort_loop(_RandomAccessIterator __first, _RandomAccessIterator __last, _Size __depth_limit, _Compare __comp) { while (__last - __first > int(_S_threshold)) { if (__depth_limit == 0) { std::__partial_sort(__first, __last, __last, __comp); return; } --__depth_limit; _RandomAccessIterator __cut = std::__unguarded_partition_pivot(__first, __last, __comp); std::__introsort_loop(__cut, __last, __depth_limit, __comp); __last = __cut; } } // sort template<typename _RandomAccessIterator, typename _Compare> inline void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { if (__first != __last) { std::__introsort_loop(__first, __last, std::__lg(__last - __first) * 2, __comp); std::__final_insertion_sort(__first, __last, __comp); } } template<typename _RandomAccessIterator, typename _Size, typename _Compare> void __introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Size __depth_limit, _Compare __comp) { while (__last - __first > 3) { if (__depth_limit == 0) { std::__heap_select(__first, __nth + 1, __last, __comp); // Place the nth largest element in its final position. std::iter_swap(__first, __nth); return; } --__depth_limit; _RandomAccessIterator __cut = std::__unguarded_partition_pivot(__first, __last, __comp); if (__cut <= __nth) __first = __cut; else __last = __cut; } std::__insertion_sort(__first, __last, __comp); } // nth_element // lower_bound moved to stl_algobase.h /** * @brief Finds the first position in which @p __val could be inserted * without changing the ordering. * @ingroup binary_search_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __val The search term. * @param __comp A functor to use for comparisons. * @return An iterator pointing to the first element <em>not less * than</em> @p __val, or end() if every element is less * than @p __val. * @ingroup binary_search_algorithms * * The comparison function should have the same effects on ordering as * the function used for the initial sort. */ template<typename _ForwardIterator, typename _Tp, typename _Compare> inline _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_requires_partitioned_lower_pred(__first, __last, __val, __comp); return std::__lower_bound(__first, __last, __val, __gnu_cxx::__ops::__iter_comp_val(__comp)); } template<typename _ForwardIterator, typename _Tp, typename _Compare> _ForwardIterator __upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType; _DistanceType __len = std::distance(__first, __last); while (__len > 0) { _DistanceType __half = __len >> 1; _ForwardIterator __middle = __first; std::advance(__middle, __half); if (__comp(__val, __middle)) __len = __half; else { __first = __middle; ++__first; __len = __len - __half - 1; } } return __first; } /** * @brief Finds the last position in which @p __val could be inserted * without changing the ordering. * @ingroup binary_search_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __val The search term. * @return An iterator pointing to the first element greater than @p __val, * or end() if no elements are greater than @p __val. * @ingroup binary_search_algorithms */ template<typename _ForwardIterator, typename _Tp> inline _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanOpConcept< _Tp, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_partitioned_upper(__first, __last, __val); return std::__upper_bound(__first, __last, __val, __gnu_cxx::__ops::__val_less_iter()); } /** * @brief Finds the last position in which @p __val could be inserted * without changing the ordering. * @ingroup binary_search_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __val The search term. * @param __comp A functor to use for comparisons. * @return An iterator pointing to the first element greater than @p __val, * or end() if no elements are greater than @p __val. * @ingroup binary_search_algorithms * * The comparison function should have the same effects on ordering as * the function used for the initial sort. */ template<typename _ForwardIterator, typename _Tp, typename _Compare> inline _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _Tp, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_partitioned_upper_pred(__first, __last, __val, __comp); return std::__upper_bound(__first, __last, __val, __gnu_cxx::__ops::__val_comp_iter(__comp)); } template<typename _ForwardIterator, typename _Tp, typename _CompareItTp, typename _CompareTpIt> pair<_ForwardIterator, _ForwardIterator> __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _CompareItTp __comp_it_val, _CompareTpIt __comp_val_it) { typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType; _DistanceType __len = std::distance(__first, __last); while (__len > 0) { _DistanceType __half = __len >> 1; _ForwardIterator __middle = __first; std::advance(__middle, __half); if (__comp_it_val(__middle, __val)) { __first = __middle; ++__first; __len = __len - __half - 1; } else if (__comp_val_it(__val, __middle)) __len = __half; else { _ForwardIterator __left = std::__lower_bound(__first, __middle, __val, __comp_it_val); std::advance(__first, __len); _ForwardIterator __right = std::__upper_bound(++__middle, __first, __val, __comp_val_it); return pair<_ForwardIterator, _ForwardIterator>(__left, __right); } } return pair<_ForwardIterator, _ForwardIterator>(__first, __first); } /** * @brief Finds the largest subrange in which @p __val could be inserted * at any place in it without changing the ordering. * @ingroup binary_search_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __val The search term. * @return An pair of iterators defining the subrange. * @ingroup binary_search_algorithms * * This is equivalent to * @code * std::make_pair(lower_bound(__first, __last, __val), * upper_bound(__first, __last, __val)) * @endcode * but does not actually call those functions. */ template<typename _ForwardIterator, typename _Tp> inline pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_function_requires(_LessThanOpConcept< _Tp, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_partitioned_lower(__first, __last, __val); __glibcxx_requires_partitioned_upper(__first, __last, __val); return std::__equal_range(__first, __last, __val, __gnu_cxx::__ops::__iter_less_val(), __gnu_cxx::__ops::__val_less_iter()); } /** * @brief Finds the largest subrange in which @p __val could be inserted * at any place in it without changing the ordering. * @param __first An iterator. * @param __last Another iterator. * @param __val The search term. * @param __comp A functor to use for comparisons. * @return An pair of iterators defining the subrange. * @ingroup binary_search_algorithms * * This is equivalent to * @code * std::make_pair(lower_bound(__first, __last, __val, __comp), * upper_bound(__first, __last, __val, __comp)) * @endcode * but does not actually call those functions. */ template<typename _ForwardIterator, typename _Tp, typename _Compare> inline pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _Tp, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_partitioned_lower_pred(__first, __last, __val, __comp); __glibcxx_requires_partitioned_upper_pred(__first, __last, __val, __comp); return std::__equal_range(__first, __last, __val, __gnu_cxx::__ops::__iter_comp_val(__comp), __gnu_cxx::__ops::__val_comp_iter(__comp)); } /** * @brief Determines whether an element exists in a range. * @ingroup binary_search_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __val The search term. * @return True if @p __val (or its equivalent) is in [@p * __first,@p __last ]. * * Note that this does not actually return an iterator to @p __val. For * that, use std::find or a container's specialized find member functions. */ template<typename _ForwardIterator, typename _Tp> bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanOpConcept< _Tp, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_partitioned_lower(__first, __last, __val); __glibcxx_requires_partitioned_upper(__first, __last, __val); _ForwardIterator __i = std::__lower_bound(__first, __last, __val, __gnu_cxx::__ops::__iter_less_val()); return __i != __last && !(__val < *__i); } /** * @brief Determines whether an element exists in a range. * @ingroup binary_search_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __val The search term. * @param __comp A functor to use for comparisons. * @return True if @p __val (or its equivalent) is in @p [__first,__last]. * * Note that this does not actually return an iterator to @p __val. For * that, use std::find or a container's specialized find member functions. * * The comparison function should have the same effects on ordering as * the function used for the initial sort. */ template<typename _ForwardIterator, typename _Tp, typename _Compare> bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, _Tp, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_partitioned_lower_pred(__first, __last, __val, __comp); __glibcxx_requires_partitioned_upper_pred(__first, __last, __val, __comp); _ForwardIterator __i = std::__lower_bound(__first, __last, __val, __gnu_cxx::__ops::__iter_comp_val(__comp)); return __i != __last && !bool(__comp(__val, *__i)); } // merge /// This is a helper function for the __merge_adaptive routines. template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> void __move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { while (__first1 != __last1 && __first2 != __last2) { if (__comp(__first2, __first1)) { *__result = _GLIBCXX_MOVE(*__first2); ++__first2; } else { *__result = _GLIBCXX_MOVE(*__first1); ++__first1; } ++__result; } if (__first1 != __last1) _GLIBCXX_MOVE3(__first1, __last1, __result); } /// This is a helper function for the __merge_adaptive routines. template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, typename _BidirectionalIterator3, typename _Compare> void __move_merge_adaptive_backward(_BidirectionalIterator1 __first1, _BidirectionalIterator1 __last1, _BidirectionalIterator2 __first2, _BidirectionalIterator2 __last2, _BidirectionalIterator3 __result, _Compare __comp) { if (__first1 == __last1) { _GLIBCXX_MOVE_BACKWARD3(__first2, __last2, __result); return; } else if (__first2 == __last2) return; --__last1; --__last2; while (true) { if (__comp(__last2, __last1)) { *--__result = _GLIBCXX_MOVE(*__last1); if (__first1 == __last1) { _GLIBCXX_MOVE_BACKWARD3(__first2, ++__last2, __result); return; } --__last1; } else { *--__result = _GLIBCXX_MOVE(*__last2); if (__first2 == __last2) return; --__last2; } } } /// This is a helper function for the merge routines. template<typename _BidirectionalIterator1, typename _BidirectionalIterator2, typename _Distance> _BidirectionalIterator1 __rotate_adaptive(_BidirectionalIterator1 __first, _BidirectionalIterator1 __middle, _BidirectionalIterator1 __last, _Distance __len1, _Distance __len2, _BidirectionalIterator2 __buffer, _Distance __buffer_size) { _BidirectionalIterator2 __buffer_end; if (__len1 > __len2 && __len2 <= __buffer_size) { if (__len2) { __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer); _GLIBCXX_MOVE_BACKWARD3(__first, __middle, __last); return _GLIBCXX_MOVE3(__buffer, __buffer_end, __first); } else return __first; } else if (__len1 <= __buffer_size) { if (__len1) { __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer); _GLIBCXX_MOVE3(__middle, __last, __first); return _GLIBCXX_MOVE_BACKWARD3(__buffer, __buffer_end, __last); } else return __last; } else { std::rotate(__first, __middle, __last); std::advance(__first, std::distance(__middle, __last)); return __first; } } /// This is a helper function for the merge routines. template<typename _BidirectionalIterator, typename _Distance, typename _Pointer, typename _Compare> void __merge_adaptive(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Distance __len1, _Distance __len2, _Pointer __buffer, _Distance __buffer_size, _Compare __comp) { if (__len1 <= __len2 && __len1 <= __buffer_size) { _Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer); std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last, __first, __comp); } else if (__len2 <= __buffer_size) { _Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer); std::__move_merge_adaptive_backward(__first, __middle, __buffer, __buffer_end, __last, __comp); } else { _BidirectionalIterator __first_cut = __first; _BidirectionalIterator __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; std::advance(__first_cut, __len11); __second_cut = std::__lower_bound(__middle, __last, *__first_cut, __gnu_cxx::__ops::__iter_comp_val(__comp)); __len22 = std::distance(__middle, __second_cut); } else { __len22 = __len2 / 2; std::advance(__second_cut, __len22); __first_cut = std::__upper_bound(__first, __middle, *__second_cut, __gnu_cxx::__ops::__val_comp_iter(__comp)); __len11 = std::distance(__first, __first_cut); } _BidirectionalIterator __new_middle = std::__rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, __len22, __buffer, __buffer_size); std::__merge_adaptive(__first, __first_cut, __new_middle, __len11, __len22, __buffer, __buffer_size, __comp); std::__merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __buffer, __buffer_size, __comp); } } /// This is a helper function for the merge routines. template<typename _BidirectionalIterator, typename _Distance, typename _Compare> void __merge_without_buffer(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Distance __len1, _Distance __len2, _Compare __comp) { if (__len1 == 0 || __len2 == 0) return; if (__len1 + __len2 == 2) { if (__comp(__middle, __first)) std::iter_swap(__first, __middle); return; } _BidirectionalIterator __first_cut = __first; _BidirectionalIterator __second_cut = __middle; _Distance __len11 = 0; _Distance __len22 = 0; if (__len1 > __len2) { __len11 = __len1 / 2; std::advance(__first_cut, __len11); __second_cut = std::__lower_bound(__middle, __last, *__first_cut, __gnu_cxx::__ops::__iter_comp_val(__comp)); __len22 = std::distance(__middle, __second_cut); } else { __len22 = __len2 / 2; std::advance(__second_cut, __len22); __first_cut = std::__upper_bound(__first, __middle, *__second_cut, __gnu_cxx::__ops::__val_comp_iter(__comp)); __len11 = std::distance(__first, __first_cut); } std::rotate(__first_cut, __middle, __second_cut); _BidirectionalIterator __new_middle = __first_cut; std::advance(__new_middle, std::distance(__middle, __second_cut)); std::__merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22, __comp); std::__merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, __len2 - __len22, __comp); } template<typename _BidirectionalIterator, typename _Compare> void __inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp) { typedef typename iterator_traits<_BidirectionalIterator>::value_type _ValueType; typedef typename iterator_traits<_BidirectionalIterator>::difference_type _DistanceType; if (__first == __middle || __middle == __last) return; const _DistanceType __len1 = std::distance(__first, __middle); const _DistanceType __len2 = std::distance(__middle, __last); typedef _Temporary_buffer<_BidirectionalIterator, _ValueType> _TmpBuf; _TmpBuf __buf(__first, __last); if (__buf.begin() == 0) std::__merge_without_buffer (__first, __middle, __last, __len1, __len2, __comp); else std::__merge_adaptive (__first, __middle, __last, __len1, __len2, __buf.begin(), _DistanceType(__buf.size()), __comp); } /** * @brief Merges two sorted ranges in place. * @ingroup sorting_algorithms * @param __first An iterator. * @param __middle Another iterator. * @param __last Another iterator. * @return Nothing. * * Merges two sorted and consecutive ranges, [__first,__middle) and * [__middle,__last), and puts the result in [__first,__last). The * output will be sorted. The sort is @e stable, that is, for * equivalent elements in the two ranges, elements from the first * range will always come before elements from the second. * * If enough additional memory is available, this takes (__last-__first)-1 * comparisons. Otherwise an NlogN algorithm is used, where N is * distance(__first,__last). */ template<typename _BidirectionalIterator> inline void inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< _BidirectionalIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_sorted(__first, __middle); __glibcxx_requires_sorted(__middle, __last); __glibcxx_requires_irreflexive(__first, __last); std::__inplace_merge(__first, __middle, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Merges two sorted ranges in place. * @ingroup sorting_algorithms * @param __first An iterator. * @param __middle Another iterator. * @param __last Another iterator. * @param __comp A functor to use for comparisons. * @return Nothing. * * Merges two sorted and consecutive ranges, [__first,__middle) and * [middle,last), and puts the result in [__first,__last). The output will * be sorted. The sort is @e stable, that is, for equivalent * elements in the two ranges, elements from the first range will always * come before elements from the second. * * If enough additional memory is available, this takes (__last-__first)-1 * comparisons. Otherwise an NlogN algorithm is used, where N is * distance(__first,__last). * * The comparison function should have the same effects on ordering as * the function used for the initial sort. */ template<typename _BidirectionalIterator, typename _Compare> inline void inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_Mutable_BidirectionalIteratorConcept< _BidirectionalIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_BidirectionalIterator>::value_type, typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_sorted_pred(__first, __middle, __comp); __glibcxx_requires_sorted_pred(__middle, __last, __comp); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); std::__inplace_merge(__first, __middle, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /// This is a helper function for the __merge_sort_loop routines. template<typename _InputIterator, typename _OutputIterator, typename _Compare> _OutputIterator __move_merge(_InputIterator __first1, _InputIterator __last1, _InputIterator __first2, _InputIterator __last2, _OutputIterator __result, _Compare __comp) { while (__first1 != __last1 && __first2 != __last2) { if (__comp(__first2, __first1)) { *__result = _GLIBCXX_MOVE(*__first2); ++__first2; } else { *__result = _GLIBCXX_MOVE(*__first1); ++__first1; } ++__result; } return _GLIBCXX_MOVE3(__first2, __last2, _GLIBCXX_MOVE3(__first1, __last1, __result)); } template<typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Distance, typename _Compare> void __merge_sort_loop(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, _Distance __step_size, _Compare __comp) { const _Distance __two_step = 2 * __step_size; while (__last - __first >= __two_step) { __result = std::__move_merge(__first, __first + __step_size, __first + __step_size, __first + __two_step, __result, __comp); __first += __two_step; } __step_size = std::min(_Distance(__last - __first), __step_size); std::__move_merge(__first, __first + __step_size, __first + __step_size, __last, __result, __comp); } template<typename _RandomAccessIterator, typename _Distance, typename _Compare> void __chunk_insertion_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance __chunk_size, _Compare __comp) { while (__last - __first >= __chunk_size) { std::__insertion_sort(__first, __first + __chunk_size, __comp); __first += __chunk_size; } std::__insertion_sort(__first, __last, __comp); } enum { _S_chunk_size = 7 }; template<typename _RandomAccessIterator, typename _Pointer, typename _Compare> void __merge_sort_with_buffer(_RandomAccessIterator __first, _RandomAccessIterator __last, _Pointer __buffer, _Compare __comp) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance; const _Distance __len = __last - __first; const _Pointer __buffer_last = __buffer + __len; _Distance __step_size = _S_chunk_size; std::__chunk_insertion_sort(__first, __last, __step_size, __comp); while (__step_size < __len) { std::__merge_sort_loop(__first, __last, __buffer, __step_size, __comp); __step_size *= 2; std::__merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp); __step_size *= 2; } } template<typename _RandomAccessIterator, typename _Pointer, typename _Distance, typename _Compare> void __stable_sort_adaptive(_RandomAccessIterator __first, _RandomAccessIterator __last, _Pointer __buffer, _Distance __buffer_size, _Compare __comp) { const _Distance __len = (__last - __first + 1) / 2; const _RandomAccessIterator __middle = __first + __len; if (__len > __buffer_size) { std::__stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, __comp); std::__stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, __comp); } else { std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp); std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp); } std::__merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), _Distance(__last - __middle), __buffer, __buffer_size, __comp); } /// This is a helper function for the stable sorting routines. template<typename _RandomAccessIterator, typename _Compare> void __inplace_stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { if (__last - __first < 15) { std::__insertion_sort(__first, __last, __comp); return; } _RandomAccessIterator __middle = __first + (__last - __first) / 2; std::__inplace_stable_sort(__first, __middle, __comp); std::__inplace_stable_sort(__middle, __last, __comp); std::__merge_without_buffer(__first, __middle, __last, __middle - __first, __last - __middle, __comp); } // stable_sort // Set algorithms: includes, set_union, set_intersection, set_difference, // set_symmetric_difference. All of these algorithms have the precondition // that their input ranges are sorted and the postcondition that their output // ranges are sorted. template<typename _InputIterator1, typename _InputIterator2, typename _Compare> bool __includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { while (__first1 != __last1 && __first2 != __last2) if (__comp(__first2, __first1)) return false; else if (__comp(__first1, __first2)) ++__first1; else { ++__first1; ++__first2; } return __first2 == __last2; } /** * @brief Determines whether all elements of a sequence exists in a range. * @param __first1 Start of search range. * @param __last1 End of search range. * @param __first2 Start of sequence * @param __last2 End of sequence. * @return True if each element in [__first2,__last2) is contained in order * within [__first1,__last1). False otherwise. * @ingroup set_algorithms * * This operation expects both [__first1,__last1) and * [__first2,__last2) to be sorted. Searches for the presence of * each element in [__first2,__last2) within [__first1,__last1). * The iterators over each range only move forward, so this is a * linear algorithm. If an element in [__first2,__last2) is not * found before the search iterator reaches @p __last2, false is * returned. */ template<typename _InputIterator1, typename _InputIterator2> inline bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); __glibcxx_requires_irreflexive2(__first1, __last1); __glibcxx_requires_irreflexive2(__first2, __last2); return std::__includes(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Determines whether all elements of a sequence exists in a range * using comparison. * @ingroup set_algorithms * @param __first1 Start of search range. * @param __last1 End of search range. * @param __first2 Start of sequence * @param __last2 End of sequence. * @param __comp Comparison function to use. * @return True if each element in [__first2,__last2) is contained * in order within [__first1,__last1) according to comp. False * otherwise. @ingroup set_algorithms * * This operation expects both [__first1,__last1) and * [__first2,__last2) to be sorted. Searches for the presence of * each element in [__first2,__last2) within [__first1,__last1), * using comp to decide. The iterators over each range only move * forward, so this is a linear algorithm. If an element in * [__first2,__last2) is not found before the search iterator * reaches @p __last2, false is returned. */ template<typename _InputIterator1, typename _InputIterator2, typename _Compare> inline bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); return std::__includes(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } // nth_element // merge // set_difference // set_intersection // set_union // stable_sort // set_symmetric_difference // min_element // max_element template<typename _BidirectionalIterator, typename _Compare> bool __next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { if (__first == __last) return false; _BidirectionalIterator __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIterator __ii = __i; --__i; if (__comp(__i, __ii)) { _BidirectionalIterator __j = __last; while (!__comp(__i, --__j)) {} std::iter_swap(__i, __j); std::__reverse(__ii, __last, std::__iterator_category(__first)); return true; } if (__i == __first) { std::__reverse(__first, __last, std::__iterator_category(__first)); return false; } } } /** * @brief Permute range into the next @e dictionary ordering. * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. * @return False if wrapped to first permutation, true otherwise. * * Treats all permutations of the range as a set of @e dictionary sorted * sequences. Permutes the current sequence into the next one of this set. * Returns true if there are more sequences to generate. If the sequence * is the largest of the set, the smallest is generated and false returned. */ template<typename _BidirectionalIterator> inline bool next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept< _BidirectionalIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); return std::__next_permutation (__first, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Permute range into the next @e dictionary ordering using * comparison functor. * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. * @param __comp A comparison functor. * @return False if wrapped to first permutation, true otherwise. * * Treats all permutations of the range [__first,__last) as a set of * @e dictionary sorted sequences ordered by @p __comp. Permutes the current * sequence into the next one of this set. Returns true if there are more * sequences to generate. If the sequence is the largest of the set, the * smallest is generated and false returned. */ template<typename _BidirectionalIterator, typename _Compare> inline bool next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept< _BidirectionalIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_BidirectionalIterator>::value_type, typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); return std::__next_permutation (__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _BidirectionalIterator, typename _Compare> bool __prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { if (__first == __last) return false; _BidirectionalIterator __i = __first; ++__i; if (__i == __last) return false; __i = __last; --__i; for(;;) { _BidirectionalIterator __ii = __i; --__i; if (__comp(__ii, __i)) { _BidirectionalIterator __j = __last; while (!__comp(--__j, __i)) {} std::iter_swap(__i, __j); std::__reverse(__ii, __last, std::__iterator_category(__first)); return true; } if (__i == __first) { std::__reverse(__first, __last, std::__iterator_category(__first)); return false; } } } /** * @brief Permute range into the previous @e dictionary ordering. * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. * @return False if wrapped to last permutation, true otherwise. * * Treats all permutations of the range as a set of @e dictionary sorted * sequences. Permutes the current sequence into the previous one of this * set. Returns true if there are more sequences to generate. If the * sequence is the smallest of the set, the largest is generated and false * returned. */ template<typename _BidirectionalIterator> inline bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept< _BidirectionalIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); return std::__prev_permutation(__first, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Permute range into the previous @e dictionary ordering using * comparison functor. * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. * @param __comp A comparison functor. * @return False if wrapped to last permutation, true otherwise. * * Treats all permutations of the range [__first,__last) as a set of * @e dictionary sorted sequences ordered by @p __comp. Permutes the current * sequence into the previous one of this set. Returns true if there are * more sequences to generate. If the sequence is the smallest of the set, * the largest is generated and false returned. */ template<typename _BidirectionalIterator, typename _Compare> inline bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_BidirectionalIteratorConcept< _BidirectionalIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_BidirectionalIterator>::value_type, typename iterator_traits<_BidirectionalIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); return std::__prev_permutation(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } // replace // replace_if template<typename _InputIterator, typename _OutputIterator, typename _Predicate, typename _Tp> _OutputIterator __replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred, const _Tp& __new_value) { for (; __first != __last; ++__first, (void)++__result) if (__pred(__first)) *__result = __new_value; else *__result = *__first; return __result; } /** * @brief Copy a sequence, replacing each element of one value with another * value. * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @param __old_value The value to be replaced. * @param __new_value The replacement value. * @return The end of the output sequence, @p result+(last-first). * * Copies each element in the input range @p [__first,__last) to the * output range @p [__result,__result+(__last-__first)) replacing elements * equal to @p __old_value with @p __new_value. */ template<typename _InputIterator, typename _OutputIterator, typename _Tp> inline _OutputIterator replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __old_value, const _Tp& __new_value) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); return std::__replace_copy_if(__first, __last, __result, __gnu_cxx::__ops::__iter_equals_val(__old_value), __new_value); } /** * @brief Copy a sequence, replacing each value for which a predicate * returns true with another value. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @param __pred A predicate. * @param __new_value The replacement value. * @return The end of the output sequence, @p __result+(__last-__first). * * Copies each element in the range @p [__first,__last) to the range * @p [__result,__result+(__last-__first)) replacing elements for which * @p __pred returns true with @p __new_value. */ template<typename _InputIterator, typename _OutputIterator, typename _Predicate, typename _Tp> inline _OutputIterator replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred, const _Tp& __new_value) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__replace_copy_if(__first, __last, __result, __gnu_cxx::__ops::__pred_iter(__pred), __new_value); } template<typename _InputIterator, typename _Predicate> typename iterator_traits<_InputIterator>::difference_type __count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { typename iterator_traits<_InputIterator>::difference_type __n = 0; for (; __first != __last; ++__first) if (__pred(__first)) ++__n; return __n; } #if __cplusplus >= 201103L /** * @brief Determines whether the elements of a sequence are sorted. * @ingroup sorting_algorithms * @param __first An iterator. * @param __last Another iterator. * @return True if the elements are sorted, false otherwise. */ template<typename _ForwardIterator> inline bool is_sorted(_ForwardIterator __first, _ForwardIterator __last) { return std::is_sorted_until(__first, __last) == __last; } /** * @brief Determines whether the elements of a sequence are sorted * according to a comparison functor. * @ingroup sorting_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __comp A comparison functor. * @return True if the elements are sorted, false otherwise. */ template<typename _ForwardIterator, typename _Compare> inline bool is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { return std::is_sorted_until(__first, __last, __comp) == __last; } template<typename _ForwardIterator, typename _Compare> _ForwardIterator __is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { if (__first == __last) return __last; _ForwardIterator __next = __first; for (++__next; __next != __last; __first = __next, (void)++__next) if (__comp(__next, __first)) return __next; return __next; } /** * @brief Determines the end of a sorted sequence. * @ingroup sorting_algorithms * @param __first An iterator. * @param __last Another iterator. * @return An iterator pointing to the last iterator i in [__first, __last) * for which the range [__first, i) is sorted. */ template<typename _ForwardIterator> inline _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); return std::__is_sorted_until(__first, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Determines the end of a sorted sequence using comparison functor. * @ingroup sorting_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __comp A comparison functor. * @return An iterator pointing to the last iterator i in [__first, __last) * for which the range [__first, i) is sorted. */ template<typename _ForwardIterator, typename _Compare> inline _ForwardIterator is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); return std::__is_sorted_until(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /** * @brief Determines min and max at once as an ordered pair. * @ingroup sorting_algorithms * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @return A pair(__b, __a) if __b is smaller than __a, pair(__a, * __b) otherwise. */ template<typename _Tp> _GLIBCXX14_CONSTEXPR inline pair<const _Tp&, const _Tp&> minmax(const _Tp& __a, const _Tp& __b) { // concept requirements __glibcxx_function_requires(_LessThanComparableConcept<_Tp>) return __b < __a ? pair<const _Tp&, const _Tp&>(__b, __a) : pair<const _Tp&, const _Tp&>(__a, __b); } /** * @brief Determines min and max at once as an ordered pair. * @ingroup sorting_algorithms * @param __a A thing of arbitrary type. * @param __b Another thing of arbitrary type. * @param __comp A @link comparison_functors comparison functor @endlink. * @return A pair(__b, __a) if __b is smaller than __a, pair(__a, * __b) otherwise. */ template<typename _Tp, typename _Compare> _GLIBCXX14_CONSTEXPR inline pair<const _Tp&, const _Tp&> minmax(const _Tp& __a, const _Tp& __b, _Compare __comp) { return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) : pair<const _Tp&, const _Tp&>(__a, __b); } template<typename _ForwardIterator, typename _Compare> _GLIBCXX14_CONSTEXPR pair<_ForwardIterator, _ForwardIterator> __minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { _ForwardIterator __next = __first; if (__first == __last || ++__next == __last) return std::make_pair(__first, __first); _ForwardIterator __min{}, __max{}; if (__comp(__next, __first)) { __min = __next; __max = __first; } else { __min = __first; __max = __next; } __first = __next; ++__first; while (__first != __last) { __next = __first; if (++__next == __last) { if (__comp(__first, __min)) __min = __first; else if (!__comp(__first, __max)) __max = __first; break; } if (__comp(__next, __first)) { if (__comp(__next, __min)) __min = __next; if (!__comp(__first, __max)) __max = __first; } else { if (__comp(__first, __min)) __min = __first; if (!__comp(__next, __max)) __max = __next; } __first = __next; ++__first; } return std::make_pair(__min, __max); } /** * @brief Return a pair of iterators pointing to the minimum and maximum * elements in a range. * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. * @return make_pair(m, M), where m is the first iterator i in * [__first, __last) such that no other element in the range is * smaller, and where M is the last iterator i in [__first, __last) * such that no other element in the range is larger. */ template<typename _ForwardIterator> _GLIBCXX14_CONSTEXPR inline pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); return std::__minmax_element(__first, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Return a pair of iterators pointing to the minimum and maximum * elements in a range. * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. * @param __comp Comparison functor. * @return make_pair(m, M), where m is the first iterator i in * [__first, __last) such that no other element in the range is * smaller, and where M is the last iterator i in [__first, __last) * such that no other element in the range is larger. */ template<typename _ForwardIterator, typename _Compare> _GLIBCXX14_CONSTEXPR inline pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); return std::__minmax_element(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } // N2722 + DR 915. template<typename _Tp> _GLIBCXX14_CONSTEXPR inline _Tp min(initializer_list<_Tp> __l) { return *std::min_element(__l.begin(), __l.end()); } template<typename _Tp, typename _Compare> _GLIBCXX14_CONSTEXPR inline _Tp min(initializer_list<_Tp> __l, _Compare __comp) { return *std::min_element(__l.begin(), __l.end(), __comp); } template<typename _Tp> _GLIBCXX14_CONSTEXPR inline _Tp max(initializer_list<_Tp> __l) { return *std::max_element(__l.begin(), __l.end()); } template<typename _Tp, typename _Compare> _GLIBCXX14_CONSTEXPR inline _Tp max(initializer_list<_Tp> __l, _Compare __comp) { return *std::max_element(__l.begin(), __l.end(), __comp); } template<typename _Tp> _GLIBCXX14_CONSTEXPR inline pair<_Tp, _Tp> minmax(initializer_list<_Tp> __l) { pair<const _Tp*, const _Tp*> __p = std::minmax_element(__l.begin(), __l.end()); return std::make_pair(*__p.first, *__p.second); } template<typename _Tp, typename _Compare> _GLIBCXX14_CONSTEXPR inline pair<_Tp, _Tp> minmax(initializer_list<_Tp> __l, _Compare __comp) { pair<const _Tp*, const _Tp*> __p = std::minmax_element(__l.begin(), __l.end(), __comp); return std::make_pair(*__p.first, *__p.second); } template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> bool __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) { // Efficiently compare identical prefixes: O(N) if sequences // have the same elements in the same order. for (; __first1 != __last1; ++__first1, (void)++__first2) if (!__pred(__first1, __first2)) break; if (__first1 == __last1) return true; // Establish __last2 assuming equal ranges by iterating over the // rest of the list. _ForwardIterator2 __last2 = __first2; std::advance(__last2, std::distance(__first1, __last1)); for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) { if (__scan != std::__find_if(__first1, __scan, __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan))) continue; // We've seen this one before. auto __matches = std::__count_if(__first2, __last2, __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)); if (0 == __matches || std::__count_if(__scan, __last1, __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)) != __matches) return false; } return true; } /** * @brief Checks whether a permutation of the second sequence is equal * to the first sequence. * @ingroup non_mutating_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @return true if there exists a permutation of the elements in the range * [__first2, __first2 + (__last1 - __first1)), beginning with * ForwardIterator2 begin, such that equal(__first1, __last1, begin) * returns true; otherwise, returns false. */ template<typename _ForwardIterator1, typename _ForwardIterator2> inline bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); return std::__is_permutation(__first1, __last1, __first2, __gnu_cxx::__ops::__iter_equal_to_iter()); } /** * @brief Checks whether a permutation of the second sequence is equal * to the first sequence. * @ingroup non_mutating_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __pred A binary predicate. * @return true if there exists a permutation of the elements in * the range [__first2, __first2 + (__last1 - __first1)), * beginning with ForwardIterator2 begin, such that * equal(__first1, __last1, __begin, __pred) returns true; * otherwise, returns false. */ template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> inline bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); return std::__is_permutation(__first1, __last1, __first2, __gnu_cxx::__ops::__iter_comp_iter(__pred)); } #if __cplusplus > 201103L template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> bool __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) { using _Cat1 = typename iterator_traits<_ForwardIterator1>::iterator_category; using _Cat2 = typename iterator_traits<_ForwardIterator2>::iterator_category; using _It1_is_RA = is_same<_Cat1, random_access_iterator_tag>; using _It2_is_RA = is_same<_Cat2, random_access_iterator_tag>; constexpr bool __ra_iters = _It1_is_RA() && _It2_is_RA(); if (__ra_iters) { auto __d1 = std::distance(__first1, __last1); auto __d2 = std::distance(__first2, __last2); if (__d1 != __d2) return false; } // Efficiently compare identical prefixes: O(N) if sequences // have the same elements in the same order. for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) if (!__pred(__first1, __first2)) break; if (__ra_iters) { if (__first1 == __last1) return true; } else { auto __d1 = std::distance(__first1, __last1); auto __d2 = std::distance(__first2, __last2); if (__d1 == 0 && __d2 == 0) return true; if (__d1 != __d2) return false; } for (_ForwardIterator1 __scan = __first1; __scan != __last1; ++__scan) { if (__scan != std::__find_if(__first1, __scan, __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan))) continue; // We've seen this one before. auto __matches = std::__count_if(__first2, __last2, __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)); if (0 == __matches || std::__count_if(__scan, __last1, __gnu_cxx::__ops::__iter_comp_iter(__pred, __scan)) != __matches) return false; } return true; } /** * @brief Checks whether a permutaion of the second sequence is equal * to the first sequence. * @ingroup non_mutating_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __last2 End of first range. * @return true if there exists a permutation of the elements in the range * [__first2, __last2), beginning with ForwardIterator2 begin, * such that equal(__first1, __last1, begin) returns true; * otherwise, returns false. */ template<typename _ForwardIterator1, typename _ForwardIterator2> inline bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return std::__is_permutation(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_equal_to_iter()); } /** * @brief Checks whether a permutation of the second sequence is equal * to the first sequence. * @ingroup non_mutating_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __last2 End of first range. * @param __pred A binary predicate. * @return true if there exists a permutation of the elements in the range * [__first2, __last2), beginning with ForwardIterator2 begin, * such that equal(__first1, __last1, __begin, __pred) returns true; * otherwise, returns false. */ template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> inline bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) { __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return std::__is_permutation(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_comp_iter(__pred)); } #if __cplusplus > 201402L #define __cpp_lib_clamp 201603 /** * @brief Returns the value clamped between lo and hi. * @ingroup sorting_algorithms * @param __val A value of arbitrary type. * @param __lo A lower limit of arbitrary type. * @param __hi An upper limit of arbitrary type. * @return max(__val, __lo) if __val < __hi or min(__val, __hi) otherwise. */ template<typename _Tp> constexpr const _Tp& clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi) { __glibcxx_assert(!(__hi < __lo)); return (__val < __lo) ? __lo : (__hi < __val) ? __hi : __val; } /** * @brief Returns the value clamped between lo and hi. * @ingroup sorting_algorithms * @param __val A value of arbitrary type. * @param __lo A lower limit of arbitrary type. * @param __hi An upper limit of arbitrary type. * @param __comp A comparison functor. * @return max(__val, __lo, __comp) if __comp(__val, __hi) * or min(__val, __hi, __comp) otherwise. */ template<typename _Tp, typename _Compare> constexpr const _Tp& clamp(const _Tp& __val, const _Tp& __lo, const _Tp& __hi, _Compare __comp) { __glibcxx_assert(!__comp(__hi, __lo)); return __comp(__val, __lo) ? __lo : __comp(__hi, __val) ? __hi : __val; } #endif // C++17 #endif // C++14 #ifdef _GLIBCXX_USE_C99_STDINT_TR1 /** * @brief Generate two uniformly distributed integers using a * single distribution invocation. * @param __b0 The upper bound for the first integer. * @param __b1 The upper bound for the second integer. * @param __g A UniformRandomBitGenerator. * @return A pair (i, j) with i and j uniformly distributed * over [0, __b0) and [0, __b1), respectively. * * Requires: __b0 * __b1 <= __g.max() - __g.min(). * * Using uniform_int_distribution with a range that is very * small relative to the range of the generator ends up wasting * potentially expensively generated randomness, since * uniform_int_distribution does not store leftover randomness * between invocations. * * If we know we want two integers in ranges that are sufficiently * small, we can compose the ranges, use a single distribution * invocation, and significantly reduce the waste. */ template<typename _IntType, typename _UniformRandomBitGenerator> pair<_IntType, _IntType> __gen_two_uniform_ints(_IntType __b0, _IntType __b1, _UniformRandomBitGenerator&& __g) { _IntType __x = uniform_int_distribution<_IntType>{0, (__b0 * __b1) - 1}(__g); return std::make_pair(__x / __b1, __x % __b1); } /** * @brief Shuffle the elements of a sequence using a uniform random * number generator. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __g A UniformRandomNumberGenerator (26.5.1.3). * @return Nothing. * * Reorders the elements in the range @p [__first,__last) using @p __g to * provide random numbers. */ template<typename _RandomAccessIterator, typename _UniformRandomNumberGenerator> void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, _UniformRandomNumberGenerator&& __g) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return; typedef typename iterator_traits<_RandomAccessIterator>::difference_type _DistanceType; typedef typename std::make_unsigned<_DistanceType>::type __ud_type; typedef typename std::uniform_int_distribution<__ud_type> __distr_type; typedef typename __distr_type::param_type __p_type; typedef typename remove_reference<_UniformRandomNumberGenerator>::type _Gen; typedef typename common_type<typename _Gen::result_type, __ud_type>::type __uc_type; const __uc_type __urngrange = __g.max() - __g.min(); const __uc_type __urange = __uc_type(__last - __first); if (__urngrange / __urange >= __urange) // I.e. (__urngrange >= __urange * __urange) but without wrap issues. { _RandomAccessIterator __i = __first + 1; // Since we know the range isn't empty, an even number of elements // means an uneven number of elements /to swap/, in which case we // do the first one up front: if ((__urange % 2) == 0) { __distr_type __d{0, 1}; std::iter_swap(__i++, __first + __d(__g)); } // Now we know that __last - __i is even, so we do the rest in pairs, // using a single distribution invocation to produce swap positions // for two successive elements at a time: while (__i != __last) { const __uc_type __swap_range = __uc_type(__i - __first) + 1; const pair<__uc_type, __uc_type> __pospos = __gen_two_uniform_ints(__swap_range, __swap_range + 1, __g); std::iter_swap(__i++, __first + __pospos.first); std::iter_swap(__i++, __first + __pospos.second); } return; } __distr_type __d; for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) std::iter_swap(__i, __first + __d(__g, __p_type(0, __i - __first))); } #endif #endif // C++11 _GLIBCXX_BEGIN_NAMESPACE_ALGO /** * @brief Apply a function to every element of a sequence. * @ingroup non_mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __f A unary function object. * @return @p __f * * Applies the function object @p __f to each element in the range * @p [first,last). @p __f must not modify the order of the sequence. * If @p __f has a return value it is ignored. */ template<typename _InputIterator, typename _Function> _Function for_each(_InputIterator __first, _InputIterator __last, _Function __f) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first) __f(*__first); return __f; // N.B. [alg.foreach] says std::move(f) but it's redundant. } /** * @brief Find the first occurrence of a value in a sequence. * @ingroup non_mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __val The value to find. * @return The first iterator @c i in the range @p [__first,__last) * such that @c *i == @p __val, or @p __last if no such iterator exists. */ template<typename _InputIterator, typename _Tp> inline _InputIterator find(_InputIterator __first, _InputIterator __last, const _Tp& __val) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); return std::__find_if(__first, __last, __gnu_cxx::__ops::__iter_equals_val(__val)); } /** * @brief Find the first element in a sequence for which a * predicate is true. * @ingroup non_mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __pred A predicate. * @return The first iterator @c i in the range @p [__first,__last) * such that @p __pred(*i) is true, or @p __last if no such iterator exists. */ template<typename _InputIterator, typename _Predicate> inline _InputIterator find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__find_if(__first, __last, __gnu_cxx::__ops::__pred_iter(__pred)); } /** * @brief Find element from a set in a sequence. * @ingroup non_mutating_algorithms * @param __first1 Start of range to search. * @param __last1 End of range to search. * @param __first2 Start of match candidates. * @param __last2 End of match candidates. * @return The first iterator @c i in the range * @p [__first1,__last1) such that @c *i == @p *(i2) such that i2 is an * iterator in [__first2,__last2), or @p __last1 if no such iterator exists. * * Searches the range @p [__first1,__last1) for an element that is * equal to some element in the range [__first2,__last2). If * found, returns an iterator in the range [__first1,__last1), * otherwise returns @p __last1. */ template<typename _InputIterator, typename _ForwardIterator> _InputIterator find_first_of(_InputIterator __first1, _InputIterator __last1, _ForwardIterator __first2, _ForwardIterator __last2) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); for (; __first1 != __last1; ++__first1) for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) if (*__first1 == *__iter) return __first1; return __last1; } /** * @brief Find element from a set in a sequence using a predicate. * @ingroup non_mutating_algorithms * @param __first1 Start of range to search. * @param __last1 End of range to search. * @param __first2 Start of match candidates. * @param __last2 End of match candidates. * @param __comp Predicate to use. * @return The first iterator @c i in the range * @p [__first1,__last1) such that @c comp(*i, @p *(i2)) is true * and i2 is an iterator in [__first2,__last2), or @p __last1 if no * such iterator exists. * * Searches the range @p [__first1,__last1) for an element that is * equal to some element in the range [__first2,__last2). If * found, returns an iterator in the range [__first1,__last1), * otherwise returns @p __last1. */ template<typename _InputIterator, typename _ForwardIterator, typename _BinaryPredicate> _InputIterator find_first_of(_InputIterator __first1, _InputIterator __last1, _ForwardIterator __first2, _ForwardIterator __last2, _BinaryPredicate __comp) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_InputIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); for (; __first1 != __last1; ++__first1) for (_ForwardIterator __iter = __first2; __iter != __last2; ++__iter) if (__comp(*__first1, *__iter)) return __first1; return __last1; } /** * @brief Find two adjacent values in a sequence that are equal. * @ingroup non_mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @return The first iterator @c i such that @c i and @c i+1 are both * valid iterators in @p [__first,__last) and such that @c *i == @c *(i+1), * or @p __last if no such iterator exists. */ template<typename _ForwardIterator> inline _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__adjacent_find(__first, __last, __gnu_cxx::__ops::__iter_equal_to_iter()); } /** * @brief Find two adjacent values in a sequence using a predicate. * @ingroup non_mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __binary_pred A binary predicate. * @return The first iterator @c i such that @c i and @c i+1 are both * valid iterators in @p [__first,__last) and such that * @p __binary_pred(*i,*(i+1)) is true, or @p __last if no such iterator * exists. */ template<typename _ForwardIterator, typename _BinaryPredicate> inline _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__adjacent_find(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__binary_pred)); } /** * @brief Count the number of copies of a value in a sequence. * @ingroup non_mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __value The value to be counted. * @return The number of iterators @c i in the range @p [__first,__last) * for which @c *i == @p __value */ template<typename _InputIterator, typename _Tp> inline typename iterator_traits<_InputIterator>::difference_type count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_InputIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); return std::__count_if(__first, __last, __gnu_cxx::__ops::__iter_equals_val(__value)); } /** * @brief Count the elements of a sequence for which a predicate is true. * @ingroup non_mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __pred A predicate. * @return The number of iterators @c i in the range @p [__first,__last) * for which @p __pred(*i) is true. */ template<typename _InputIterator, typename _Predicate> inline typename iterator_traits<_InputIterator>::difference_type count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__count_if(__first, __last, __gnu_cxx::__ops::__pred_iter(__pred)); } /** * @brief Search a sequence for a matching sub-sequence. * @ingroup non_mutating_algorithms * @param __first1 A forward iterator. * @param __last1 A forward iterator. * @param __first2 A forward iterator. * @param __last2 A forward iterator. * @return The first iterator @c i in the range @p * [__first1,__last1-(__last2-__first2)) such that @c *(i+N) == @p * *(__first2+N) for each @c N in the range @p * [0,__last2-__first2), or @p __last1 if no such iterator exists. * * Searches the range @p [__first1,__last1) for a sub-sequence that * compares equal value-by-value with the sequence given by @p * [__first2,__last2) and returns an iterator to the first element * of the sub-sequence, or @p __last1 if the sub-sequence is not * found. * * Because the sub-sequence must lie completely within the range @p * [__first1,__last1) it must start at a position less than @p * __last1-(__last2-__first2) where @p __last2-__first2 is the * length of the sub-sequence. * * This means that the returned iterator @c i will be in the range * @p [__first1,__last1-(__last2-__first2)) */ template<typename _ForwardIterator1, typename _ForwardIterator2> inline _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return std::__search(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_equal_to_iter()); } /** * @brief Search a sequence for a matching sub-sequence using a predicate. * @ingroup non_mutating_algorithms * @param __first1 A forward iterator. * @param __last1 A forward iterator. * @param __first2 A forward iterator. * @param __last2 A forward iterator. * @param __predicate A binary predicate. * @return The first iterator @c i in the range * @p [__first1,__last1-(__last2-__first2)) such that * @p __predicate(*(i+N),*(__first2+N)) is true for each @c N in the range * @p [0,__last2-__first2), or @p __last1 if no such iterator exists. * * Searches the range @p [__first1,__last1) for a sub-sequence that * compares equal value-by-value with the sequence given by @p * [__first2,__last2), using @p __predicate to determine equality, * and returns an iterator to the first element of the * sub-sequence, or @p __last1 if no such iterator exists. * * @see search(_ForwardIter1, _ForwardIter1, _ForwardIter2, _ForwardIter2) */ template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> inline _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __predicate) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator1>) __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator2>) __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator1>::value_type, typename iterator_traits<_ForwardIterator2>::value_type>) __glibcxx_requires_valid_range(__first1, __last1); __glibcxx_requires_valid_range(__first2, __last2); return std::__search(__first1, __last1, __first2, __last2, __gnu_cxx::__ops::__iter_comp_iter(__predicate)); } /** * @brief Search a sequence for a number of consecutive values. * @ingroup non_mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __count The number of consecutive values. * @param __val The value to find. * @return The first iterator @c i in the range @p * [__first,__last-__count) such that @c *(i+N) == @p __val for * each @c N in the range @p [0,__count), or @p __last if no such * iterator exists. * * Searches the range @p [__first,__last) for @p count consecutive elements * equal to @p __val. */ template<typename _ForwardIterator, typename _Integer, typename _Tp> inline _ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, const _Tp& __val) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); return std::__search_n(__first, __last, __count, __gnu_cxx::__ops::__iter_equals_val(__val)); } /** * @brief Search a sequence for a number of consecutive values using a * predicate. * @ingroup non_mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __count The number of consecutive values. * @param __val The value to find. * @param __binary_pred A binary predicate. * @return The first iterator @c i in the range @p * [__first,__last-__count) such that @p * __binary_pred(*(i+N),__val) is true for each @c N in the range * @p [0,__count), or @p __last if no such iterator exists. * * Searches the range @p [__first,__last) for @p __count * consecutive elements for which the predicate returns true. */ template<typename _ForwardIterator, typename _Integer, typename _Tp, typename _BinaryPredicate> inline _ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Integer __count, const _Tp& __val, _BinaryPredicate __binary_pred) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_requires_valid_range(__first, __last); return std::__search_n(__first, __last, __count, __gnu_cxx::__ops::__iter_comp_val(__binary_pred, __val)); } #if __cplusplus > 201402L /** @brief Search a sequence using a Searcher object. * * @param __first A forward iterator. * @param __last A forward iterator. * @param __searcher A callable object. * @return @p __searcher(__first,__last).first */ template<typename _ForwardIterator, typename _Searcher> inline _ForwardIterator search(_ForwardIterator __first, _ForwardIterator __last, const _Searcher& __searcher) { return __searcher(__first, __last).first; } #endif /** * @brief Perform an operation on a sequence. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @param __unary_op A unary operator. * @return An output iterator equal to @p __result+(__last-__first). * * Applies the operator to each element in the input range and assigns * the results to successive elements of the output sequence. * Evaluates @p *(__result+N)=unary_op(*(__first+N)) for each @c N in the * range @p [0,__last-__first). * * @p unary_op must not alter its argument. */ template<typename _InputIterator, typename _OutputIterator, typename _UnaryOperation> _OutputIterator transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __unary_op) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, // "the type returned by a _UnaryOperation" __typeof__(__unary_op(*__first))>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first, (void)++__result) *__result = __unary_op(*__first); return __result; } /** * @brief Perform an operation on corresponding elements of two sequences. * @ingroup mutating_algorithms * @param __first1 An input iterator. * @param __last1 An input iterator. * @param __first2 An input iterator. * @param __result An output iterator. * @param __binary_op A binary operator. * @return An output iterator equal to @p result+(last-first). * * Applies the operator to the corresponding elements in the two * input ranges and assigns the results to successive elements of the * output sequence. * Evaluates @p * *(__result+N)=__binary_op(*(__first1+N),*(__first2+N)) for each * @c N in the range @p [0,__last1-__first1). * * @p binary_op must not alter either of its arguments. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _BinaryOperation> _OutputIterator transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _OutputIterator __result, _BinaryOperation __binary_op) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, // "the type returned by a _BinaryOperation" __typeof__(__binary_op(*__first1,*__first2))>) __glibcxx_requires_valid_range(__first1, __last1); for (; __first1 != __last1; ++__first1, (void)++__first2, ++__result) *__result = __binary_op(*__first1, *__first2); return __result; } /** * @brief Replace each occurrence of one value in a sequence with another * value. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __old_value The value to be replaced. * @param __new_value The replacement value. * @return replace() returns no value. * * For each iterator @c i in the range @p [__first,__last) if @c *i == * @p __old_value then the assignment @c *i = @p __new_value is performed. */ template<typename _ForwardIterator, typename _Tp> void replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_function_requires(_EqualOpConcept< typename iterator_traits<_ForwardIterator>::value_type, _Tp>) __glibcxx_function_requires(_ConvertibleConcept<_Tp, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first) if (*__first == __old_value) *__first = __new_value; } /** * @brief Replace each value in a sequence for which a predicate returns * true with another value. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __pred A predicate. * @param __new_value The replacement value. * @return replace_if() returns no value. * * For each iterator @c i in the range @p [__first,__last) if @p __pred(*i) * is true then the assignment @c *i = @p __new_value is performed. */ template<typename _ForwardIterator, typename _Predicate, typename _Tp> void replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_function_requires(_ConvertibleConcept<_Tp, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first) if (__pred(*__first)) *__first = __new_value; } /** * @brief Assign the result of a function object to each value in a * sequence. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __gen A function object taking no arguments and returning * std::iterator_traits<_ForwardIterator>::value_type * @return generate() returns no value. * * Performs the assignment @c *i = @p __gen() for each @c i in the range * @p [__first,__last). */ template<typename _ForwardIterator, typename _Generator> void generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_GeneratorConcept<_Generator, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first) *__first = __gen(); } /** * @brief Assign the result of a function object to each value in a * sequence. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __n The length of the sequence. * @param __gen A function object taking no arguments and returning * std::iterator_traits<_ForwardIterator>::value_type * @return The end of the sequence, @p __first+__n * * Performs the assignment @c *i = @p __gen() for each @c i in the range * @p [__first,__first+__n). * * _GLIBCXX_RESOLVE_LIB_DEFECTS * DR 865. More algorithms that throw away information */ template<typename _OutputIterator, typename _Size, typename _Generator> _OutputIterator generate_n(_OutputIterator __first, _Size __n, _Generator __gen) { // concept requirements __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, // "the type returned by a _Generator" __typeof__(__gen())>) for (__decltype(__n + 0) __niter = __n; __niter > 0; --__niter, (void) ++__first) *__first = __gen(); return __first; } /** * @brief Copy a sequence, removing consecutive duplicate values. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @return An iterator designating the end of the resulting sequence. * * Copies each element in the range @p [__first,__last) to the range * beginning at @p __result, except that only the first element is copied * from groups of consecutive elements that compare equal. * unique_copy() is stable, so the relative order of elements that are * copied is unchanged. * * _GLIBCXX_RESOLVE_LIB_DEFECTS * DR 241. Does unique_copy() require CopyConstructible and Assignable? * * _GLIBCXX_RESOLVE_LIB_DEFECTS * DR 538. 241 again: Does unique_copy() require CopyConstructible and * Assignable? */ template<typename _InputIterator, typename _OutputIterator> inline _OutputIterator unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_function_requires(_EqualityComparableConcept< typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; return std::__unique_copy(__first, __last, __result, __gnu_cxx::__ops::__iter_equal_to_iter(), std::__iterator_category(__first), std::__iterator_category(__result)); } /** * @brief Copy a sequence, removing consecutive values using a predicate. * @ingroup mutating_algorithms * @param __first An input iterator. * @param __last An input iterator. * @param __result An output iterator. * @param __binary_pred A binary predicate. * @return An iterator designating the end of the resulting sequence. * * Copies each element in the range @p [__first,__last) to the range * beginning at @p __result, except that only the first element is copied * from groups of consecutive elements for which @p __binary_pred returns * true. * unique_copy() is stable, so the relative order of elements that are * copied is unchanged. * * _GLIBCXX_RESOLVE_LIB_DEFECTS * DR 241. Does unique_copy() require CopyConstructible and Assignable? */ template<typename _InputIterator, typename _OutputIterator, typename _BinaryPredicate> inline _OutputIterator unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryPredicate __binary_pred) { // concept requirements -- predicates checked later __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return __result; return std::__unique_copy(__first, __last, __result, __gnu_cxx::__ops::__iter_comp_iter(__binary_pred), std::__iterator_category(__first), std::__iterator_category(__result)); } #if _GLIBCXX_HOSTED /** * @brief Randomly shuffle the elements of a sequence. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @return Nothing. * * Reorder the elements in the range @p [__first,__last) using a random * distribution, so that every possible ordering of the sequence is * equally likely. */ template<typename _RandomAccessIterator> inline void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); if (__first != __last) for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) { // XXX rand() % N is not uniformly distributed _RandomAccessIterator __j = __first + std::rand() % ((__i - __first) + 1); if (__i != __j) std::iter_swap(__i, __j); } } #endif /** * @brief Shuffle the elements of a sequence using a random number * generator. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __rand The RNG functor or function. * @return Nothing. * * Reorders the elements in the range @p [__first,__last) using @p __rand to * provide a random distribution. Calling @p __rand(N) for a positive * integer @p N should return a randomly chosen integer from the * range [0,N). */ template<typename _RandomAccessIterator, typename _RandomNumberGenerator> void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, #if __cplusplus >= 201103L _RandomNumberGenerator&& __rand) #else _RandomNumberGenerator& __rand) #endif { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_requires_valid_range(__first, __last); if (__first == __last) return; for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i) { _RandomAccessIterator __j = __first + __rand((__i - __first) + 1); if (__i != __j) std::iter_swap(__i, __j); } } /** * @brief Move elements for which a predicate is true to the beginning * of a sequence. * @ingroup mutating_algorithms * @param __first A forward iterator. * @param __last A forward iterator. * @param __pred A predicate functor. * @return An iterator @p middle such that @p __pred(i) is true for each * iterator @p i in the range @p [__first,middle) and false for each @p i * in the range @p [middle,__last). * * @p __pred must not modify its operand. @p partition() does not preserve * the relative ordering of elements in each group, use * @p stable_partition() if this is needed. */ template<typename _ForwardIterator, typename _Predicate> inline _ForwardIterator partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { // concept requirements __glibcxx_function_requires(_Mutable_ForwardIteratorConcept< _ForwardIterator>) __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); return std::__partition(__first, __last, __pred, std::__iterator_category(__first)); } /** * @brief Sort the smallest elements of a sequence. * @ingroup sorting_algorithms * @param __first An iterator. * @param __middle Another iterator. * @param __last Another iterator. * @return Nothing. * * Sorts the smallest @p (__middle-__first) elements in the range * @p [first,last) and moves them to the range @p [__first,__middle). The * order of the remaining elements in the range @p [__middle,__last) is * undefined. * After the sort if @e i and @e j are iterators in the range * @p [__first,__middle) such that i precedes j and @e k is an iterator in * the range @p [__middle,__last) then *j<*i and *k<*i are both false. */ template<typename _RandomAccessIterator> inline void partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __middle); __glibcxx_requires_valid_range(__middle, __last); __glibcxx_requires_irreflexive(__first, __last); std::__partial_sort(__first, __middle, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Sort the smallest elements of a sequence using a predicate * for comparison. * @ingroup sorting_algorithms * @param __first An iterator. * @param __middle Another iterator. * @param __last Another iterator. * @param __comp A comparison functor. * @return Nothing. * * Sorts the smallest @p (__middle-__first) elements in the range * @p [__first,__last) and moves them to the range @p [__first,__middle). The * order of the remaining elements in the range @p [__middle,__last) is * undefined. * After the sort if @e i and @e j are iterators in the range * @p [__first,__middle) such that i precedes j and @e k is an iterator in * the range @p [__middle,__last) then @p *__comp(j,*i) and @p __comp(*k,*i) * are both false. */ template<typename _RandomAccessIterator, typename _Compare> inline void partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __middle); __glibcxx_requires_valid_range(__middle, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); std::__partial_sort(__first, __middle, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /** * @brief Sort a sequence just enough to find a particular position. * @ingroup sorting_algorithms * @param __first An iterator. * @param __nth Another iterator. * @param __last Another iterator. * @return Nothing. * * Rearranges the elements in the range @p [__first,__last) so that @p *__nth * is the same element that would have been in that position had the * whole sequence been sorted. The elements either side of @p *__nth are * not completely sorted, but for any iterator @e i in the range * @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it * holds that *j < *i is false. */ template<typename _RandomAccessIterator> inline void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __nth); __glibcxx_requires_valid_range(__nth, __last); __glibcxx_requires_irreflexive(__first, __last); if (__first == __last || __nth == __last) return; std::__introselect(__first, __nth, __last, std::__lg(__last - __first) * 2, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Sort a sequence just enough to find a particular position * using a predicate for comparison. * @ingroup sorting_algorithms * @param __first An iterator. * @param __nth Another iterator. * @param __last Another iterator. * @param __comp A comparison functor. * @return Nothing. * * Rearranges the elements in the range @p [__first,__last) so that @p *__nth * is the same element that would have been in that position had the * whole sequence been sorted. The elements either side of @p *__nth are * not completely sorted, but for any iterator @e i in the range * @p [__first,__nth) and any iterator @e j in the range @p [__nth,__last) it * holds that @p __comp(*j,*i) is false. */ template<typename _RandomAccessIterator, typename _Compare> inline void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __nth); __glibcxx_requires_valid_range(__nth, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); if (__first == __last || __nth == __last) return; std::__introselect(__first, __nth, __last, std::__lg(__last - __first) * 2, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } /** * @brief Sort the elements of a sequence. * @ingroup sorting_algorithms * @param __first An iterator. * @param __last Another iterator. * @return Nothing. * * Sorts the elements in the range @p [__first,__last) in ascending order, * such that for each iterator @e i in the range @p [__first,__last-1), * *(i+1)<*i is false. * * The relative ordering of equivalent elements is not preserved, use * @p stable_sort() if this is needed. */ template<typename _RandomAccessIterator> inline void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); std::__sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Sort the elements of a sequence using a predicate for comparison. * @ingroup sorting_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __comp A comparison functor. * @return Nothing. * * Sorts the elements in the range @p [__first,__last) in ascending order, * such that @p __comp(*(i+1),*i) is false for every iterator @e i in the * range @p [__first,__last-1). * * The relative ordering of equivalent elements is not preserved, use * @p stable_sort() if this is needed. */ template<typename _RandomAccessIterator, typename _Compare> inline void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); std::__sort(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> _OutputIterator __merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { while (__first1 != __last1 && __first2 != __last2) { if (__comp(__first2, __first1)) { *__result = *__first2; ++__first2; } else { *__result = *__first1; ++__first1; } ++__result; } return std::copy(__first2, __last2, std::copy(__first1, __last1, __result)); } /** * @brief Merges two sorted ranges. * @ingroup sorting_algorithms * @param __first1 An iterator. * @param __first2 Another iterator. * @param __last1 Another iterator. * @param __last2 Another iterator. * @param __result An iterator pointing to the end of the merged range. * @return An iterator pointing to the first element <em>not less * than</em> @e val. * * Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into * the sorted range @p [__result, __result + (__last1-__first1) + * (__last2-__first2)). Both input ranges must be sorted, and the * output range must not overlap with either of the input ranges. * The sort is @e stable, that is, for equivalent elements in the * two ranges, elements from the first range will always come * before elements from the second. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator> inline _OutputIterator merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); __glibcxx_requires_irreflexive2(__first1, __last1); __glibcxx_requires_irreflexive2(__first2, __last2); return _GLIBCXX_STD_A::__merge(__first1, __last1, __first2, __last2, __result, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Merges two sorted ranges. * @ingroup sorting_algorithms * @param __first1 An iterator. * @param __first2 Another iterator. * @param __last1 Another iterator. * @param __last2 Another iterator. * @param __result An iterator pointing to the end of the merged range. * @param __comp A functor to use for comparisons. * @return An iterator pointing to the first element "not less * than" @e val. * * Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into * the sorted range @p [__result, __result + (__last1-__first1) + * (__last2-__first2)). Both input ranges must be sorted, and the * output range must not overlap with either of the input ranges. * The sort is @e stable, that is, for equivalent elements in the * two ranges, elements from the first range will always come * before elements from the second. * * The comparison function should have the same effects on ordering as * the function used for the initial sort. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> inline _OutputIterator merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); return _GLIBCXX_STD_A::__merge(__first1, __last1, __first2, __last2, __result, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _RandomAccessIterator, typename _Compare> inline void __stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; typedef typename iterator_traits<_RandomAccessIterator>::difference_type _DistanceType; typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf; _TmpBuf __buf(__first, __last); if (__buf.begin() == 0) std::__inplace_stable_sort(__first, __last, __comp); else std::__stable_sort_adaptive(__first, __last, __buf.begin(), _DistanceType(__buf.size()), __comp); } /** * @brief Sort the elements of a sequence, preserving the relative order * of equivalent elements. * @ingroup sorting_algorithms * @param __first An iterator. * @param __last Another iterator. * @return Nothing. * * Sorts the elements in the range @p [__first,__last) in ascending order, * such that for each iterator @p i in the range @p [__first,__last-1), * @p *(i+1)<*i is false. * * The relative ordering of equivalent elements is preserved, so any two * elements @p x and @p y in the range @p [__first,__last) such that * @p x<y is false and @p y<x is false will have the same relative * ordering after calling @p stable_sort(). */ template<typename _RandomAccessIterator> inline void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); _GLIBCXX_STD_A::__stable_sort(__first, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Sort the elements of a sequence using a predicate for comparison, * preserving the relative order of equivalent elements. * @ingroup sorting_algorithms * @param __first An iterator. * @param __last Another iterator. * @param __comp A comparison functor. * @return Nothing. * * Sorts the elements in the range @p [__first,__last) in ascending order, * such that for each iterator @p i in the range @p [__first,__last-1), * @p __comp(*(i+1),*i) is false. * * The relative ordering of equivalent elements is preserved, so any two * elements @p x and @p y in the range @p [__first,__last) such that * @p __comp(x,y) is false and @p __comp(y,x) is false will have the same * relative ordering after calling @p stable_sort(). */ template<typename _RandomAccessIterator, typename _Compare> inline void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_RandomAccessIterator>::value_type, typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); _GLIBCXX_STD_A::__stable_sort(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> _OutputIterator __set_union(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { while (__first1 != __last1 && __first2 != __last2) { if (__comp(__first1, __first2)) { *__result = *__first1; ++__first1; } else if (__comp(__first2, __first1)) { *__result = *__first2; ++__first2; } else { *__result = *__first1; ++__first1; ++__first2; } ++__result; } return std::copy(__first2, __last2, std::copy(__first1, __last1, __result)); } /** * @brief Return the union of two sorted ranges. * @ingroup set_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __last2 End of second range. * @param __result Start of output range. * @return End of the output range. * @ingroup set_algorithms * * This operation iterates over both ranges, copying elements present in * each range in order to the output range. Iterators increment for each * range. When the current element of one range is less than the other, * that element is copied and the iterator advanced. If an element is * contained in both ranges, the element from the first range is copied and * both ranges advance. The output range may not overlap either input * range. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator> inline _OutputIterator set_union(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); __glibcxx_requires_irreflexive2(__first1, __last1); __glibcxx_requires_irreflexive2(__first2, __last2); return _GLIBCXX_STD_A::__set_union(__first1, __last1, __first2, __last2, __result, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Return the union of two sorted ranges using a comparison functor. * @ingroup set_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __last2 End of second range. * @param __result Start of output range. * @param __comp The comparison functor. * @return End of the output range. * @ingroup set_algorithms * * This operation iterates over both ranges, copying elements present in * each range in order to the output range. Iterators increment for each * range. When the current element of one range is less than the other * according to @p __comp, that element is copied and the iterator advanced. * If an equivalent element according to @p __comp is contained in both * ranges, the element from the first range is copied and both ranges * advance. The output range may not overlap either input range. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> inline _OutputIterator set_union(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); return _GLIBCXX_STD_A::__set_union(__first1, __last1, __first2, __last2, __result, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> _OutputIterator __set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { while (__first1 != __last1 && __first2 != __last2) if (__comp(__first1, __first2)) ++__first1; else if (__comp(__first2, __first1)) ++__first2; else { *__result = *__first1; ++__first1; ++__first2; ++__result; } return __result; } /** * @brief Return the intersection of two sorted ranges. * @ingroup set_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __last2 End of second range. * @param __result Start of output range. * @return End of the output range. * @ingroup set_algorithms * * This operation iterates over both ranges, copying elements present in * both ranges in order to the output range. Iterators increment for each * range. When the current element of one range is less than the other, * that iterator advances. If an element is contained in both ranges, the * element from the first range is copied and both ranges advance. The * output range may not overlap either input range. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator> inline _OutputIterator set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); __glibcxx_requires_irreflexive2(__first1, __last1); __glibcxx_requires_irreflexive2(__first2, __last2); return _GLIBCXX_STD_A::__set_intersection(__first1, __last1, __first2, __last2, __result, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Return the intersection of two sorted ranges using comparison * functor. * @ingroup set_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __last2 End of second range. * @param __result Start of output range. * @param __comp The comparison functor. * @return End of the output range. * @ingroup set_algorithms * * This operation iterates over both ranges, copying elements present in * both ranges in order to the output range. Iterators increment for each * range. When the current element of one range is less than the other * according to @p __comp, that iterator advances. If an element is * contained in both ranges according to @p __comp, the element from the * first range is copied and both ranges advance. The output range may not * overlap either input range. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> inline _OutputIterator set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); return _GLIBCXX_STD_A::__set_intersection(__first1, __last1, __first2, __last2, __result, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> _OutputIterator __set_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { while (__first1 != __last1 && __first2 != __last2) if (__comp(__first1, __first2)) { *__result = *__first1; ++__first1; ++__result; } else if (__comp(__first2, __first1)) ++__first2; else { ++__first1; ++__first2; } return std::copy(__first1, __last1, __result); } /** * @brief Return the difference of two sorted ranges. * @ingroup set_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __last2 End of second range. * @param __result Start of output range. * @return End of the output range. * @ingroup set_algorithms * * This operation iterates over both ranges, copying elements present in * the first range but not the second in order to the output range. * Iterators increment for each range. When the current element of the * first range is less than the second, that element is copied and the * iterator advances. If the current element of the second range is less, * the iterator advances, but no element is copied. If an element is * contained in both ranges, no elements are copied and both ranges * advance. The output range may not overlap either input range. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator> inline _OutputIterator set_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); __glibcxx_requires_irreflexive2(__first1, __last1); __glibcxx_requires_irreflexive2(__first2, __last2); return _GLIBCXX_STD_A::__set_difference(__first1, __last1, __first2, __last2, __result, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Return the difference of two sorted ranges using comparison * functor. * @ingroup set_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __last2 End of second range. * @param __result Start of output range. * @param __comp The comparison functor. * @return End of the output range. * @ingroup set_algorithms * * This operation iterates over both ranges, copying elements present in * the first range but not the second in order to the output range. * Iterators increment for each range. When the current element of the * first range is less than the second according to @p __comp, that element * is copied and the iterator advances. If the current element of the * second range is less, no element is copied and the iterator advances. * If an element is contained in both ranges according to @p __comp, no * elements are copied and both ranges advance. The output range may not * overlap either input range. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> inline _OutputIterator set_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); return _GLIBCXX_STD_A::__set_difference(__first1, __last1, __first2, __last2, __result, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> _OutputIterator __set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { while (__first1 != __last1 && __first2 != __last2) if (__comp(__first1, __first2)) { *__result = *__first1; ++__first1; ++__result; } else if (__comp(__first2, __first1)) { *__result = *__first2; ++__first2; ++__result; } else { ++__first1; ++__first2; } return std::copy(__first2, __last2, std::copy(__first1, __last1, __result)); } /** * @brief Return the symmetric difference of two sorted ranges. * @ingroup set_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __last2 End of second range. * @param __result Start of output range. * @return End of the output range. * @ingroup set_algorithms * * This operation iterates over both ranges, copying elements present in * one range but not the other in order to the output range. Iterators * increment for each range. When the current element of one range is less * than the other, that element is copied and the iterator advances. If an * element is contained in both ranges, no elements are copied and both * ranges advance. The output range may not overlap either input range. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator> inline _OutputIterator set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_LessThanOpConcept< typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set(__first1, __last1, __first2); __glibcxx_requires_sorted_set(__first2, __last2, __first1); __glibcxx_requires_irreflexive2(__first1, __last1); __glibcxx_requires_irreflexive2(__first2, __last2); return _GLIBCXX_STD_A::__set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Return the symmetric difference of two sorted ranges using * comparison functor. * @ingroup set_algorithms * @param __first1 Start of first range. * @param __last1 End of first range. * @param __first2 Start of second range. * @param __last2 End of second range. * @param __result Start of output range. * @param __comp The comparison functor. * @return End of the output range. * @ingroup set_algorithms * * This operation iterates over both ranges, copying elements present in * one range but not the other in order to the output range. Iterators * increment for each range. When the current element of one range is less * than the other according to @p comp, that element is copied and the * iterator advances. If an element is contained in both ranges according * to @p __comp, no elements are copied and both ranges advance. The output * range may not overlap either input range. */ template<typename _InputIterator1, typename _InputIterator2, typename _OutputIterator, typename _Compare> inline _OutputIterator set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>) __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator1>::value_type, typename iterator_traits<_InputIterator2>::value_type>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_InputIterator2>::value_type, typename iterator_traits<_InputIterator1>::value_type>) __glibcxx_requires_sorted_set_pred(__first1, __last1, __first2, __comp); __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); __glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp); __glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp); return _GLIBCXX_STD_A::__set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _ForwardIterator, typename _Compare> _GLIBCXX14_CONSTEXPR _ForwardIterator __min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { if (__first == __last) return __first; _ForwardIterator __result = __first; while (++__first != __last) if (__comp(__first, __result)) __result = __first; return __result; } /** * @brief Return the minimum element in a range. * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. * @return Iterator referencing the first instance of the smallest value. */ template<typename _ForwardIterator> _GLIBCXX14_CONSTEXPR _ForwardIterator inline min_element(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); return _GLIBCXX_STD_A::__min_element(__first, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Return the minimum element in a range using comparison functor. * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. * @param __comp Comparison functor. * @return Iterator referencing the first instance of the smallest value * according to __comp. */ template<typename _ForwardIterator, typename _Compare> _GLIBCXX14_CONSTEXPR inline _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); return _GLIBCXX_STD_A::__min_element(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _ForwardIterator, typename _Compare> _GLIBCXX14_CONSTEXPR _ForwardIterator __max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { if (__first == __last) return __first; _ForwardIterator __result = __first; while (++__first != __last) if (__comp(__result, __first)) __result = __first; return __result; } /** * @brief Return the maximum element in a range. * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. * @return Iterator referencing the first instance of the largest value. */ template<typename _ForwardIterator> _GLIBCXX14_CONSTEXPR inline _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive(__first, __last); return _GLIBCXX_STD_A::__max_element(__first, __last, __gnu_cxx::__ops::__iter_less_iter()); } /** * @brief Return the maximum element in a range using comparison functor. * @ingroup sorting_algorithms * @param __first Start of range. * @param __last End of range. * @param __comp Comparison functor. * @return Iterator referencing the first instance of the largest value * according to __comp. */ template<typename _ForwardIterator, typename _Compare> _GLIBCXX14_CONSTEXPR inline _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { // concept requirements __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) __glibcxx_function_requires(_BinaryPredicateConcept<_Compare, typename iterator_traits<_ForwardIterator>::value_type, typename iterator_traits<_ForwardIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); __glibcxx_requires_irreflexive_pred(__first, __last, __comp); return _GLIBCXX_STD_A::__max_element(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); } #if __cplusplus >= 201402L /// Reservoir sampling algorithm. template<typename _InputIterator, typename _RandomAccessIterator, typename _Size, typename _UniformRandomBitGenerator> _RandomAccessIterator __sample(_InputIterator __first, _InputIterator __last, input_iterator_tag, _RandomAccessIterator __out, random_access_iterator_tag, _Size __n, _UniformRandomBitGenerator&& __g) { using __distrib_type = uniform_int_distribution<_Size>; using __param_type = typename __distrib_type::param_type; __distrib_type __d{}; _Size __sample_sz = 0; while (__first != __last && __sample_sz != __n) { __out[__sample_sz++] = *__first; ++__first; } for (auto __pop_sz = __sample_sz; __first != __last; ++__first, (void) ++__pop_sz) { const auto __k = __d(__g, __param_type{0, __pop_sz}); if (__k < __n) __out[__k] = *__first; } return __out + __sample_sz; } /// Selection sampling algorithm. template<typename _ForwardIterator, typename _OutputIterator, typename _Cat, typename _Size, typename _UniformRandomBitGenerator> _OutputIterator __sample(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag, _OutputIterator __out, _Cat, _Size __n, _UniformRandomBitGenerator&& __g) { using __distrib_type = uniform_int_distribution<_Size>; using __param_type = typename __distrib_type::param_type; using _USize = make_unsigned_t<_Size>; using _Gen = remove_reference_t<_UniformRandomBitGenerator>; using __uc_type = common_type_t<typename _Gen::result_type, _USize>; if (__first == __last) return __out; __distrib_type __d{}; _Size __unsampled_sz = std::distance(__first, __last); __n = std::min(__n, __unsampled_sz); // If possible, we use __gen_two_uniform_ints to efficiently produce // two random numbers using a single distribution invocation: const __uc_type __urngrange = __g.max() - __g.min(); if (__urngrange / __uc_type(__unsampled_sz) >= __uc_type(__unsampled_sz)) // I.e. (__urngrange >= __unsampled_sz * __unsampled_sz) but without // wrapping issues. { while (__n != 0 && __unsampled_sz >= 2) { const pair<_Size, _Size> __p = __gen_two_uniform_ints(__unsampled_sz, __unsampled_sz - 1, __g); --__unsampled_sz; if (__p.first < __n) { *__out++ = *__first; --__n; } ++__first; if (__n == 0) break; --__unsampled_sz; if (__p.second < __n) { *__out++ = *__first; --__n; } ++__first; } } // The loop above is otherwise equivalent to this one-at-a-time version: for (; __n != 0; ++__first) if (__d(__g, __param_type{0, --__unsampled_sz}) < __n) { *__out++ = *__first; --__n; } return __out; } #if __cplusplus > 201402L #define __cpp_lib_sample 201603 /// Take a random sample from a population. template<typename _PopulationIterator, typename _SampleIterator, typename _Distance, typename _UniformRandomBitGenerator> _SampleIterator sample(_PopulationIterator __first, _PopulationIterator __last, _SampleIterator __out, _Distance __n, _UniformRandomBitGenerator&& __g) { using __pop_cat = typename std::iterator_traits<_PopulationIterator>::iterator_category; using __samp_cat = typename std::iterator_traits<_SampleIterator>::iterator_category; static_assert( __or_<is_convertible<__pop_cat, forward_iterator_tag>, is_convertible<__samp_cat, random_access_iterator_tag>>::value, "output range must use a RandomAccessIterator when input range" " does not meet the ForwardIterator requirements"); static_assert(is_integral<_Distance>::value, "sample size must be an integer type"); typename iterator_traits<_PopulationIterator>::difference_type __d = __n; return _GLIBCXX_STD_A:: __sample(__first, __last, __pop_cat{}, __out, __samp_cat{}, __d, std::forward<_UniformRandomBitGenerator>(__g)); } #endif // C++17 #endif // C++14 _GLIBCXX_END_NAMESPACE_ALGO _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif /* _STL_ALGO_H */ c++/8/bits/cpp_type_traits.h 0000644 00000023075 15146341150 0011615 0 ustar 00 // The -*- C++ -*- type traits classes for internal use in libstdc++ // Copyright (C) 2000-2018 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. On has to write lots of // overloaded functions and to hope that the compiler will select the right // one. As a net effect, the overall structure isn't very clear at first // glance. // Thirdly, partial ordering and overload resolution (of function templates) // is highly costly in terms of compiler-resource. It is a Good Thing to // keep these resource consumption as least as possible. // // See valarray_array.h for a case use. // // -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06. // // Update 2005: types are also provided and <bits/type_traits.h> has been // removed. // extern "C++" { namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __true_type { }; struct __false_type { }; template<bool> struct __truth_type { typedef __false_type __type; }; template<> struct __truth_type<true> { typedef __true_type __type; }; // N.B. The conversions to bool are needed due to the issue // explained in c++/19404. template<class _Sp, class _Tp> struct __traitor { enum { __value = bool(_Sp::__value) || bool(_Tp::__value) }; typedef typename __truth_type<__value>::__type __type; }; // Compare for equality of types. template<typename, typename> struct __are_same { enum { __value = 0 }; typedef __false_type __type; }; template<typename _Tp> struct __are_same<_Tp, _Tp> { enum { __value = 1 }; typedef __true_type __type; }; // Holds if the template-argument is a void type. template<typename _Tp> struct __is_void { enum { __value = 0 }; typedef __false_type __type; }; template<> struct __is_void<void> { enum { __value = 1 }; typedef __true_type __type; }; // // Integer types // template<typename _Tp> struct __is_integer { enum { __value = 0 }; typedef __false_type __type; }; // Thirteen specializations (yes there are eleven standard integer // types; <em>long long</em> and <em>unsigned long long</em> are // supported as extensions). Up to four target-specific __int<N> // types are supported as well. template<> struct __is_integer<bool> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<char> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<signed char> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<unsigned char> { enum { __value = 1 }; typedef __true_type __type; }; # ifdef _GLIBCXX_USE_WCHAR_T template<> struct __is_integer<wchar_t> { enum { __value = 1 }; typedef __true_type __type; }; # endif #if __cplusplus >= 201103L template<> struct __is_integer<char16_t> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<char32_t> { enum { __value = 1 }; typedef __true_type __type; }; #endif template<> struct __is_integer<short> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<unsigned short> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<int> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<unsigned int> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<long> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<unsigned long> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<long long> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_integer<unsigned long long> { enum { __value = 1 }; typedef __true_type __type; }; #define __INT_N(TYPE) \ template<> \ struct __is_integer<TYPE> \ { \ enum { __value = 1 }; \ typedef __true_type __type; \ }; \ template<> \ struct __is_integer<unsigned TYPE> \ { \ enum { __value = 1 }; \ typedef __true_type __type; \ }; #ifdef __GLIBCXX_TYPE_INT_N_0 __INT_N(__GLIBCXX_TYPE_INT_N_0) #endif #ifdef __GLIBCXX_TYPE_INT_N_1 __INT_N(__GLIBCXX_TYPE_INT_N_1) #endif #ifdef __GLIBCXX_TYPE_INT_N_2 __INT_N(__GLIBCXX_TYPE_INT_N_2) #endif #ifdef __GLIBCXX_TYPE_INT_N_3 __INT_N(__GLIBCXX_TYPE_INT_N_3) #endif #undef __INT_N // // Floating point types // template<typename _Tp> struct __is_floating { enum { __value = 0 }; typedef __false_type __type; }; // three specializations (float, double and 'long double') template<> struct __is_floating<float> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_floating<double> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_floating<long double> { enum { __value = 1 }; typedef __true_type __type; }; // // Pointer types // template<typename _Tp> struct __is_pointer { enum { __value = 0 }; typedef __false_type __type; }; template<typename _Tp> struct __is_pointer<_Tp*> { enum { __value = 1 }; typedef __true_type __type; }; // // An arithmetic type is an integer type or a floating point type // template<typename _Tp> struct __is_arithmetic : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> > { }; // // A scalar type is an arithmetic type or a pointer type // template<typename _Tp> struct __is_scalar : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > { }; // // For use in std::copy and std::find overloads for streambuf iterators. // template<typename _Tp> struct __is_char { enum { __value = 0 }; typedef __false_type __type; }; template<> struct __is_char<char> { enum { __value = 1 }; typedef __true_type __type; }; #ifdef _GLIBCXX_USE_WCHAR_T template<> struct __is_char<wchar_t> { enum { __value = 1 }; typedef __true_type __type; }; #endif template<typename _Tp> struct __is_byte { enum { __value = 0 }; typedef __false_type __type; }; template<> struct __is_byte<char> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_byte<signed char> { enum { __value = 1 }; typedef __true_type __type; }; template<> struct __is_byte<unsigned char> { enum { __value = 1 }; typedef __true_type __type; }; #if __cplusplus >= 201703L enum class byte : unsigned char; template<> struct __is_byte<byte> { enum { __value = 1 }; typedef __true_type __type; }; #endif // C++17 // // 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> inline _Iterator __miter_base(_Iterator __it) { return __it; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace } // extern "C++" #endif //_CPP_TYPE_TRAITS_H c++/8/bits/istream.tcc 0000644 00000074565 15146341150 0010404 0 ustar 00 // istream classes -*- C++ -*- // Copyright (C) 1997-2018 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/istream.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{istream} */ // // ISO C++ 14882: 27.6.1 Input streams // #ifndef _ISTREAM_TCC #define _ISTREAM_TCC 1 #pragma GCC system_header #include <bits/cxxabi_forced.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>::sentry:: sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false) { ios_base::iostate __err = ios_base::goodbit; if (__in.good()) __try { if (__in.tie()) __in.tie()->flush(); if (!__noskip && bool(__in.flags() & ios_base::skipws)) { const __int_type __eof = traits_type::eof(); __streambuf_type* __sb = __in.rdbuf(); __int_type __c = __sb->sgetc(); const __ctype_type& __ct = __check_facet(__in._M_ctype); while (!traits_type::eq_int_type(__c, __eof) && __ct.is(ctype_base::space, traits_type::to_char_type(__c))) __c = __sb->snextc(); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 195. Should basic_istream::sentry's constructor ever // set eofbit? if (traits_type::eq_int_type(__c, __eof)) __err |= ios_base::eofbit; } } __catch(__cxxabiv1::__forced_unwind&) { __in._M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { __in._M_setstate(ios_base::badbit); } if (__in.good() && __err == ios_base::goodbit) _M_ok = true; else { __err |= ios_base::failbit; __in.setstate(__err); } } template<typename _CharT, typename _Traits> template<typename _ValueT> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: _M_extract(_ValueT& __v) { sentry __cerb(*this, false); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { const __num_get_type& __ng = __check_facet(this->_M_num_get); __ng.get(*this, 0, *this, __err, __v); } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(short& __n) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 118. basic_istream uses nonexistent num_get member functions. sentry __cerb(*this, false); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { long __l; const __num_get_type& __ng = __check_facet(this->_M_num_get); __ng.get(*this, 0, *this, __err, __l); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 696. istream::operator>>(int&) broken. if (__l < __gnu_cxx::__numeric_traits<short>::__min) { __err |= ios_base::failbit; __n = __gnu_cxx::__numeric_traits<short>::__min; } else if (__l > __gnu_cxx::__numeric_traits<short>::__max) { __err |= ios_base::failbit; __n = __gnu_cxx::__numeric_traits<short>::__max; } else __n = short(__l); } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(int& __n) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 118. basic_istream uses nonexistent num_get member functions. sentry __cerb(*this, false); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { long __l; const __num_get_type& __ng = __check_facet(this->_M_num_get); __ng.get(*this, 0, *this, __err, __l); // _GLIBCXX_RESOLVE_LIB_DEFECTS // 696. istream::operator>>(int&) broken. if (__l < __gnu_cxx::__numeric_traits<int>::__min) { __err |= ios_base::failbit; __n = __gnu_cxx::__numeric_traits<int>::__min; } else if (__l > __gnu_cxx::__numeric_traits<int>::__max) { __err |= ios_base::failbit; __n = __gnu_cxx::__numeric_traits<int>::__max; } else __n = int(__l); } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: operator>>(__streambuf_type* __sbout) { ios_base::iostate __err = ios_base::goodbit; sentry __cerb(*this, false); if (__cerb && __sbout) { __try { bool __ineof; if (!__copy_streambufs_eof(this->rdbuf(), __sbout, __ineof)) __err |= ios_base::failbit; if (__ineof) __err |= ios_base::eofbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::failbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::failbit); } } else if (!__sbout) __err |= ios_base::failbit; if (__err) this->setstate(__err); return *this; } template<typename _CharT, typename _Traits> typename basic_istream<_CharT, _Traits>::int_type basic_istream<_CharT, _Traits>:: get(void) { const int_type __eof = traits_type::eof(); int_type __c = __eof; _M_gcount = 0; ios_base::iostate __err = ios_base::goodbit; sentry __cerb(*this, true); if (__cerb) { __try { __c = this->rdbuf()->sbumpc(); // 27.6.1.1 paragraph 3 if (!traits_type::eq_int_type(__c, __eof)) _M_gcount = 1; else __err |= ios_base::eofbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } } if (!_M_gcount) __err |= ios_base::failbit; if (__err) this->setstate(__err); return __c; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: get(char_type& __c) { _M_gcount = 0; ios_base::iostate __err = ios_base::goodbit; sentry __cerb(*this, true); if (__cerb) { __try { const int_type __cb = this->rdbuf()->sbumpc(); // 27.6.1.1 paragraph 3 if (!traits_type::eq_int_type(__cb, traits_type::eof())) { _M_gcount = 1; __c = traits_type::to_char_type(__cb); } else __err |= ios_base::eofbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } } if (!_M_gcount) __err |= ios_base::failbit; if (__err) this->setstate(__err); return *this; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: get(char_type* __s, streamsize __n, char_type __delim) { _M_gcount = 0; ios_base::iostate __err = ios_base::goodbit; sentry __cerb(*this, true); if (__cerb) { __try { const int_type __idelim = traits_type::to_int_type(__delim); const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); int_type __c = __sb->sgetc(); while (_M_gcount + 1 < __n && !traits_type::eq_int_type(__c, __eof) && !traits_type::eq_int_type(__c, __idelim)) { *__s++ = traits_type::to_char_type(__c); ++_M_gcount; __c = __sb->snextc(); } if (traits_type::eq_int_type(__c, __eof)) __err |= ios_base::eofbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 243. get and getline when sentry reports failure. if (__n > 0) *__s = char_type(); if (!_M_gcount) __err |= ios_base::failbit; if (__err) this->setstate(__err); return *this; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: get(__streambuf_type& __sb, char_type __delim) { _M_gcount = 0; ios_base::iostate __err = ios_base::goodbit; sentry __cerb(*this, true); if (__cerb) { __try { const int_type __idelim = traits_type::to_int_type(__delim); const int_type __eof = traits_type::eof(); __streambuf_type* __this_sb = this->rdbuf(); int_type __c = __this_sb->sgetc(); char_type __c2 = traits_type::to_char_type(__c); while (!traits_type::eq_int_type(__c, __eof) && !traits_type::eq_int_type(__c, __idelim) && !traits_type::eq_int_type(__sb.sputc(__c2), __eof)) { ++_M_gcount; __c = __this_sb->snextc(); __c2 = traits_type::to_char_type(__c); } if (traits_type::eq_int_type(__c, __eof)) __err |= ios_base::eofbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } } if (!_M_gcount) __err |= ios_base::failbit; if (__err) this->setstate(__err); return *this; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: getline(char_type* __s, streamsize __n, char_type __delim) { _M_gcount = 0; ios_base::iostate __err = ios_base::goodbit; sentry __cerb(*this, true); if (__cerb) { __try { const int_type __idelim = traits_type::to_int_type(__delim); const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); int_type __c = __sb->sgetc(); while (_M_gcount + 1 < __n && !traits_type::eq_int_type(__c, __eof) && !traits_type::eq_int_type(__c, __idelim)) { *__s++ = traits_type::to_char_type(__c); __c = __sb->snextc(); ++_M_gcount; } if (traits_type::eq_int_type(__c, __eof)) __err |= ios_base::eofbit; else { if (traits_type::eq_int_type(__c, __idelim)) { __sb->sbumpc(); ++_M_gcount; } else __err |= ios_base::failbit; } } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 243. get and getline when sentry reports failure. if (__n > 0) *__s = char_type(); if (!_M_gcount) __err |= ios_base::failbit; if (__err) this->setstate(__err); return *this; } // We provide three overloads, since the first two are much simpler // than the general case. Also, the latter two can thus adopt the // same "batchy" strategy used by getline above. template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: ignore(void) { _M_gcount = 0; sentry __cerb(*this, true); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); if (traits_type::eq_int_type(__sb->sbumpc(), __eof)) __err |= ios_base::eofbit; else _M_gcount = 1; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: ignore(streamsize __n) { _M_gcount = 0; sentry __cerb(*this, true); if (__cerb && __n > 0) { ios_base::iostate __err = ios_base::goodbit; __try { const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); int_type __c = __sb->sgetc(); // N.B. On LFS-enabled platforms streamsize is still 32 bits // wide: if we want to implement the standard mandated behavior // for n == max() (see 27.6.1.3/24) we are at risk of signed // integer overflow: thus these contortions. Also note that, // by definition, when more than 2G chars are actually ignored, // _M_gcount (the return value of gcount, that is) cannot be // really correct, being unavoidably too small. bool __large_ignore = false; while (true) { while (_M_gcount < __n && !traits_type::eq_int_type(__c, __eof)) { ++_M_gcount; __c = __sb->snextc(); } if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max && !traits_type::eq_int_type(__c, __eof)) { _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__min; __large_ignore = true; } else break; } if (__large_ignore) _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; if (traits_type::eq_int_type(__c, __eof)) __err |= ios_base::eofbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: ignore(streamsize __n, int_type __delim) { _M_gcount = 0; sentry __cerb(*this, true); if (__cerb && __n > 0) { ios_base::iostate __err = ios_base::goodbit; __try { const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); int_type __c = __sb->sgetc(); // See comment above. bool __large_ignore = false; while (true) { while (_M_gcount < __n && !traits_type::eq_int_type(__c, __eof) && !traits_type::eq_int_type(__c, __delim)) { ++_M_gcount; __c = __sb->snextc(); } if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max && !traits_type::eq_int_type(__c, __eof) && !traits_type::eq_int_type(__c, __delim)) { _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__min; __large_ignore = true; } else break; } if (__large_ignore) _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; if (traits_type::eq_int_type(__c, __eof)) __err |= ios_base::eofbit; else if (traits_type::eq_int_type(__c, __delim)) { if (_M_gcount < __gnu_cxx::__numeric_traits<streamsize>::__max) ++_M_gcount; __sb->sbumpc(); } } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> typename basic_istream<_CharT, _Traits>::int_type basic_istream<_CharT, _Traits>:: peek(void) { int_type __c = traits_type::eof(); _M_gcount = 0; sentry __cerb(*this, true); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { __c = this->rdbuf()->sgetc(); if (traits_type::eq_int_type(__c, traits_type::eof())) __err |= ios_base::eofbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return __c; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: read(char_type* __s, streamsize __n) { _M_gcount = 0; sentry __cerb(*this, true); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { _M_gcount = this->rdbuf()->sgetn(__s, __n); if (_M_gcount != __n) __err |= (ios_base::eofbit | ios_base::failbit); } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> streamsize basic_istream<_CharT, _Traits>:: readsome(char_type* __s, streamsize __n) { _M_gcount = 0; sentry __cerb(*this, true); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { // Cannot compare int_type with streamsize generically. const streamsize __num = this->rdbuf()->in_avail(); if (__num > 0) _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n)); else if (__num == -1) __err |= ios_base::eofbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return _M_gcount; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: putback(char_type __c) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 60. What is a formatted input function? _M_gcount = 0; // Clear eofbit per N3168. this->clear(this->rdstate() & ~ios_base::eofbit); sentry __cerb(*this, true); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); if (!__sb || traits_type::eq_int_type(__sb->sputbackc(__c), __eof)) __err |= ios_base::badbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: unget(void) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 60. What is a formatted input function? _M_gcount = 0; // Clear eofbit per N3168. this->clear(this->rdstate() & ~ios_base::eofbit); sentry __cerb(*this, true); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { const int_type __eof = traits_type::eof(); __streambuf_type* __sb = this->rdbuf(); if (!__sb || traits_type::eq_int_type(__sb->sungetc(), __eof)) __err |= ios_base::badbit; } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> int basic_istream<_CharT, _Traits>:: sync(void) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR60. Do not change _M_gcount. int __ret = -1; sentry __cerb(*this, true); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { __streambuf_type* __sb = this->rdbuf(); if (__sb) { if (__sb->pubsync() == -1) __err |= ios_base::badbit; else __ret = 0; } } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return __ret; } template<typename _CharT, typename _Traits> typename basic_istream<_CharT, _Traits>::pos_type basic_istream<_CharT, _Traits>:: tellg(void) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR60. Do not change _M_gcount. pos_type __ret = pos_type(-1); sentry __cerb(*this, true); if (__cerb) { __try { if (!this->fail()) __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in); } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } } return __ret; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: seekg(pos_type __pos) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR60. Do not change _M_gcount. // Clear eofbit per N3168. this->clear(this->rdstate() & ~ios_base::eofbit); sentry __cerb(*this, true); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { if (!this->fail()) { // 136. seekp, seekg setting wrong streams? const pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::in); // 129. Need error indication from seekp() and seekg() if (__p == pos_type(off_type(-1))) __err |= ios_base::failbit; } } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>:: seekg(off_type __off, ios_base::seekdir __dir) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR60. Do not change _M_gcount. // Clear eofbit per N3168. this->clear(this->rdstate() & ~ios_base::eofbit); sentry __cerb(*this, true); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { if (!this->fail()) { // 136. seekp, seekg setting wrong streams? const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, ios_base::in); // 129. Need error indication from seekp() and seekg() if (__p == pos_type(off_type(-1))) __err |= ios_base::failbit; } } __catch(__cxxabiv1::__forced_unwind&) { this->_M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { this->_M_setstate(ios_base::badbit); } if (__err) this->setstate(__err); } return *this; } // 27.6.1.2.3 Character extraction templates template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) { typedef basic_istream<_CharT, _Traits> __istream_type; typedef typename __istream_type::int_type __int_type; typename __istream_type::sentry __cerb(__in, false); if (__cerb) { ios_base::iostate __err = ios_base::goodbit; __try { const __int_type __cb = __in.rdbuf()->sbumpc(); if (!_Traits::eq_int_type(__cb, _Traits::eof())) __c = _Traits::to_char_type(__cb); else __err |= (ios_base::eofbit | ios_base::failbit); } __catch(__cxxabiv1::__forced_unwind&) { __in._M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { __in._M_setstate(ios_base::badbit); } if (__err) __in.setstate(__err); } return __in; } template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s) { typedef basic_istream<_CharT, _Traits> __istream_type; typedef basic_streambuf<_CharT, _Traits> __streambuf_type; typedef typename _Traits::int_type int_type; typedef _CharT char_type; typedef ctype<_CharT> __ctype_type; streamsize __extracted = 0; ios_base::iostate __err = ios_base::goodbit; typename __istream_type::sentry __cerb(__in, false); if (__cerb) { __try { // Figure out how many characters to extract. streamsize __num = __in.width(); if (__num <= 0) __num = __gnu_cxx::__numeric_traits<streamsize>::__max; const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); const int_type __eof = _Traits::eof(); __streambuf_type* __sb = __in.rdbuf(); int_type __c = __sb->sgetc(); while (__extracted < __num - 1 && !_Traits::eq_int_type(__c, __eof) && !__ct.is(ctype_base::space, _Traits::to_char_type(__c))) { *__s++ = _Traits::to_char_type(__c); ++__extracted; __c = __sb->snextc(); } if (_Traits::eq_int_type(__c, __eof)) __err |= ios_base::eofbit; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 68. Extractors for char* should store null at end *__s = char_type(); __in.width(0); } __catch(__cxxabiv1::__forced_unwind&) { __in._M_setstate(ios_base::badbit); __throw_exception_again; } __catch(...) { __in._M_setstate(ios_base::badbit); } } if (!__extracted) __err |= ios_base::failbit; if (__err) __in.setstate(__err); return __in; } // 27.6.1.4 Standard basic_istream manipulators template<typename _CharT, typename _Traits> basic_istream<_CharT, _Traits>& ws(basic_istream<_CharT, _Traits>& __in) { typedef basic_istream<_CharT, _Traits> __istream_type; typedef basic_streambuf<_CharT, _Traits> __streambuf_type; typedef typename __istream_type::int_type __int_type; typedef ctype<_CharT> __ctype_type; const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); const __int_type __eof = _Traits::eof(); __streambuf_type* __sb = __in.rdbuf(); __int_type __c = __sb->sgetc(); while (!_Traits::eq_int_type(__c, __eof) && __ct.is(ctype_base::space, _Traits::to_char_type(__c))) __c = __sb->snextc(); if (_Traits::eq_int_type(__c, __eof)) __in.setstate(ios_base::eofbit); return __in; } // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_istream<char>; extern template istream& ws(istream&); extern template istream& operator>>(istream&, char&); extern template istream& operator>>(istream&, char*); extern template istream& operator>>(istream&, unsigned char&); extern template istream& operator>>(istream&, signed char&); extern template istream& operator>>(istream&, unsigned char*); extern template istream& operator>>(istream&, signed char*); extern template istream& istream::_M_extract(unsigned short&); extern template istream& istream::_M_extract(unsigned int&); extern template istream& istream::_M_extract(long&); extern template istream& istream::_M_extract(unsigned long&); extern template istream& istream::_M_extract(bool&); #ifdef _GLIBCXX_USE_LONG_LONG extern template istream& istream::_M_extract(long long&); extern template istream& istream::_M_extract(unsigned long long&); #endif extern template istream& istream::_M_extract(float&); extern template istream& istream::_M_extract(double&); extern template istream& istream::_M_extract(long double&); extern template istream& istream::_M_extract(void*&); extern template class basic_iostream<char>; #ifdef _GLIBCXX_USE_WCHAR_T extern template class basic_istream<wchar_t>; extern template wistream& ws(wistream&); extern template wistream& operator>>(wistream&, wchar_t&); extern template wistream& operator>>(wistream&, wchar_t*); extern template wistream& wistream::_M_extract(unsigned short&); extern template wistream& wistream::_M_extract(unsigned int&); extern template wistream& wistream::_M_extract(long&); extern template wistream& wistream::_M_extract(unsigned long&); extern template wistream& wistream::_M_extract(bool&); #ifdef _GLIBCXX_USE_LONG_LONG extern template wistream& wistream::_M_extract(long long&); extern template wistream& wistream::_M_extract(unsigned long long&); #endif extern template wistream& wistream::_M_extract(float&); extern template wistream& wistream::_M_extract(double&); extern template wistream& wistream::_M_extract(long double&); extern template wistream& wistream::_M_extract(void*&); extern template class basic_iostream<wchar_t>; #endif #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif c++/8/bits/exception_ptr.h 0000644 00000013535 15146341150 0011267 0 ustar 00 // Exception Handling support header (exception_ptr class) for -*- C++ -*- // Copyright (C) 2008-2018 Free Software Foundation, Inc. // // This file is part of GCC. // // GCC is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3, or (at your option) // any later version. // // GCC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/exception_ptr.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{exception} */ #ifndef _EXCEPTION_PTR_H #define _EXCEPTION_PTR_H #pragma GCC visibility push(default) #include <bits/c++config.h> #include <bits/exception_defines.h> #include <bits/cxxabi_init_exception.h> #include <typeinfo> #include <new> extern "C++" { namespace std { class type_info; /** * @addtogroup exceptions * @{ */ namespace __exception_ptr { class exception_ptr; } using __exception_ptr::exception_ptr; /** Obtain an exception_ptr to the currently handled exception. If there * is none, or the currently handled exception is foreign, return the null * value. */ exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT; template<typename _Ex> exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; /// Throw the object pointed to by the exception_ptr. void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__)); namespace __exception_ptr { using std::rethrow_exception; /** * @brief An opaque pointer to an arbitrary exception. * @ingroup exceptions */ class exception_ptr { void* _M_exception_object; explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT; void _M_addref() _GLIBCXX_USE_NOEXCEPT; void _M_release() _GLIBCXX_USE_NOEXCEPT; void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__)); friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT; friend void std::rethrow_exception(exception_ptr); template<typename _Ex> friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT; public: exception_ptr() _GLIBCXX_USE_NOEXCEPT; exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; #if __cplusplus >= 201103L exception_ptr(nullptr_t) noexcept : _M_exception_object(0) { } exception_ptr(exception_ptr&& __o) noexcept : _M_exception_object(__o._M_exception_object) { __o._M_exception_object = 0; } #endif #if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT) typedef void (exception_ptr::*__safe_bool)(); // For construction from nullptr or 0. exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT; #endif exception_ptr& operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT; #if __cplusplus >= 201103L exception_ptr& operator=(exception_ptr&& __o) noexcept { exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this); return *this; } #endif ~exception_ptr() _GLIBCXX_USE_NOEXCEPT; void swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT; #ifdef _GLIBCXX_EH_PTR_COMPAT // Retained for compatibility with CXXABI_1.3. void _M_safe_bool_dummy() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__const__)); bool operator!() const _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT; #endif #if __cplusplus >= 201103L explicit operator bool() const { return _M_exception_object; } #endif friend bool operator==(const exception_ptr&, const exception_ptr&) _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); const class std::type_info* __cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); }; bool operator==(const exception_ptr&, const exception_ptr&) _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); bool operator!=(const exception_ptr&, const exception_ptr&) _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); inline void swap(exception_ptr& __lhs, exception_ptr& __rhs) { __lhs.swap(__rhs); } template<typename _Ex> inline void __dest_thunk(void* __x) { static_cast<_Ex*>(__x)->~_Ex(); } } // namespace __exception_ptr /// Obtain an exception_ptr pointing to a copy of the supplied object. template<typename _Ex> exception_ptr make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT { #if __cpp_exceptions && __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex)); (void) __cxxabiv1::__cxa_init_primary_exception( __e, const_cast<std::type_info*>(&typeid(__ex)), __exception_ptr::__dest_thunk<_Ex>); try { ::new (__e) _Ex(__ex); return exception_ptr(__e); } catch(...) { __cxxabiv1::__cxa_free_exception(__e); return current_exception(); } #elif __cpp_exceptions try { throw __ex; } catch(...) { return current_exception(); } #else // no RTTI and no exceptions return exception_ptr(); #endif } // @} group exceptions } // namespace std } // extern "C++" #pragma GCC visibility pop #endif c++/8/ccomplex 0000644 00000002467 15146341150 0007031 0 ustar 00 // <ccomplex> -*- C++ -*- // Copyright (C) 2007-2018 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/ccomplex * This is a Standard C++ Library header. */ #pragma GCC system_header #ifndef _GLIBCXX_CCOMPLEX #define _GLIBCXX_CCOMPLEX 1 #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #endif extern "C++" { #include <complex> } #endif c++/8/tgmath.h 0000644 00000002520 15146341150 0006717 0 ustar 00 // -*- C++ -*- compatibility header. // Copyright (C) 2007-2018 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 tgmath.h * This is a Standard C++ Library header. */ #include <bits/c++config.h> #if __cplusplus >= 201103L # include <ctgmath> #else # if _GLIBCXX_HAVE_TGMATH_H # include_next <tgmath.h> # endif #endif #ifndef _GLIBCXX_TGMATH_H #define _GLIBCXX_TGMATH_H 1 #endif c++/8/cuchar 0000644 00000004242 15146341150 0006455 0 ustar 00 // -*- C++ -*- forwarding header. // Copyright (C) 2015-2018 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/cuchar * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c uchar.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882:2011 21.8 // #ifndef _GLIBCXX_CUCHAR #define _GLIBCXX_CUCHAR 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <bits/c++config.h> #include <cwchar> #if _GLIBCXX_USE_C11_UCHAR_CXX11 #include <uchar.h> // Get rid of those macros defined in <uchar.h> in lieu of real functions. #undef mbrtoc16 #undef c16rtomb #undef mbrtoc32 #undef c32rtomb namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::mbrtoc16; using ::c16rtomb; using ::mbrtoc32; using ::c32rtomb; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _GLIBCXX_USE_C11_UCHAR_CXX11 #endif // C++11 #endif // _GLIBCXX_CUCHAR c++/8/unordered_map 0000644 00000003470 15146341150 0010036 0 ustar 00 // <unordered_map> -*- C++ -*- // Copyright (C) 2007-2018 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/unordered_map * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_UNORDERED_MAP #define _GLIBCXX_UNORDERED_MAP 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <type_traits> #include <initializer_list> #include <bits/allocator.h> #include <ext/alloc_traits.h> #include <ext/aligned_buffer.h> #include <bits/stl_pair.h> #include <bits/stl_function.h> // equal_to, _Identity, _Select1st #include <bits/functional_hash.h> #include <bits/hashtable.h> #include <bits/unordered_map.h> #include <bits/range_access.h> #ifdef _GLIBCXX_DEBUG # include <debug/unordered_map> #endif #ifdef _GLIBCXX_PROFILE # include <profile/unordered_map> #endif #endif // C++11 #endif // _GLIBCXX_UNORDERED_MAP c++/8/x86_64-redhat-linux/32/ext/opt_random.h 0000644 00000011224 15146341150 0014162 0 ustar 00 // Optimizations for random number extensions, x86 version -*- C++ -*- // Copyright (C) 2012-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/random.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/random} */ #ifndef _EXT_OPT_RANDOM_H #define _EXT_OPT_RANDOM_H 1 #pragma GCC system_header #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #ifdef __SSE2__ namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace { template<size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4> inline __m128i __sse2_recursion(__m128i __a, __m128i __b, __m128i __c, __m128i __d) { __m128i __y = _mm_srli_epi32(__b, __sr1); __m128i __z = _mm_srli_si128(__c, __sr2); __m128i __v = _mm_slli_epi32(__d, __sl1); __z = _mm_xor_si128(__z, __a); __z = _mm_xor_si128(__z, __v); __m128i __x = _mm_slli_si128(__a, __sl2); __y = _mm_and_si128(__y, _mm_set_epi32(__msk4, __msk3, __msk2, __msk1)); __z = _mm_xor_si128(__z, __x); return _mm_xor_si128(__z, __y); } } #define _GLIBCXX_OPT_HAVE_RANDOM_SFMT_GEN_READ 1 template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: _M_gen_rand(void) { __m128i __r1 = _mm_load_si128(&_M_state[_M_nstate - 2]); __m128i __r2 = _mm_load_si128(&_M_state[_M_nstate - 1]); size_t __i; for (__i = 0; __i < _M_nstate - __pos1; ++__i) { __m128i __r = __sse2_recursion<__sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4> (_M_state[__i], _M_state[__i + __pos1], __r1, __r2); _mm_store_si128(&_M_state[__i], __r); __r1 = __r2; __r2 = __r; } for (; __i < _M_nstate; ++__i) { __m128i __r = __sse2_recursion<__sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4> (_M_state[__i], _M_state[__i + __pos1 - _M_nstate], __r1, __r2); _mm_store_si128(&_M_state[__i], __r); __r1 = __r2; __r2 = __r; } _M_pos = 0; } #define _GLIBCXX_OPT_HAVE_RANDOM_SFMT_OPERATOREQUAL 1 template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> bool operator==(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) { __m128i __res = _mm_cmpeq_epi8(__lhs._M_state[0], __rhs._M_state[0]); for (size_t __i = 1; __i < __lhs._M_nstate; ++__i) __res = _mm_and_si128(__res, _mm_cmpeq_epi8(__lhs._M_state[__i], __rhs._M_state[__i])); return (_mm_movemask_epi8(__res) == 0xffff && __lhs._M_pos == __rhs._M_pos); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // __SSE2__ #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #endif // _EXT_OPT_RANDOM_H c++/8/x86_64-redhat-linux/32/bits/extc++.h 0000644 00000005145 15146341150 0013257 0 ustar 00 // C++ includes used for precompiling extensions -*- C++ -*- // Copyright (C) 2006-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file extc++.h * This is an implementation file for a precompiled header. */ #if __cplusplus < 201103L #include <bits/stdtr1c++.h> #else #include <bits/stdc++.h> #endif #include <ext/algorithm> #if __cplusplus >= 201103L # include <ext/aligned_buffer.h> #endif #include <ext/alloc_traits.h> #include <ext/array_allocator.h> #include <ext/atomicity.h> #include <ext/bitmap_allocator.h> #include <ext/cast.h> #if __cplusplus >= 201103L # include <ext/cmath> #endif #include <ext/concurrence.h> #include <ext/debug_allocator.h> #include <ext/extptr_allocator.h> #include <ext/functional> #include <ext/iterator> #include <ext/malloc_allocator.h> #include <ext/memory> #include <ext/mt_allocator.h> #include <ext/new_allocator.h> #include <ext/numeric> #include <ext/numeric_traits.h> #include <ext/pod_char_traits.h> #include <ext/pointer.h> #include <ext/pool_allocator.h> #if __cplusplus >= 201103L # include <ext/random> #endif #include <ext/rb_tree> #include <ext/rope> #include <ext/slist> #include <ext/stdio_filebuf.h> #include <ext/stdio_sync_filebuf.h> #include <ext/throw_allocator.h> #include <ext/typelist.h> #include <ext/type_traits.h> #include <ext/vstring.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/priority_queue.hpp> #include <ext/pb_ds/exception.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/list_update_policy.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/trie_policy.hpp> #ifdef _GLIBCXX_HAVE_ICONV #include <ext/codecvt_specializations.h> #include <ext/enc_filebuf.h> #endif c++/8/x86_64-redhat-linux/32/bits/atomic_word.h 0000644 00000002756 15146341150 0014502 0 ustar 00 // Low-level type for atomic operations -*- C++ -*- // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file atomic_word.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _GLIBCXX_ATOMIC_WORD_H #define _GLIBCXX_ATOMIC_WORD_H 1 typedef int _Atomic_word; // This is a memory order acquire fence. #define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE) // This is a memory order release fence. #define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE) #endif c++/8/x86_64-redhat-linux/32/bits/stdc++.h 0000644 00000005607 15146341150 0013254 0 ustar 00 // C++ includes used for precompiling -*- C++ -*- // Copyright (C) 2003-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file stdc++.h * This is an implementation file for a precompiled header. */ // 17.4.1.2 Headers // C #ifndef _GLIBCXX_NO_ASSERT #include <cassert> #endif #include <cctype> #include <cerrno> #include <cfloat> #include <ciso646> #include <climits> #include <clocale> #include <cmath> #include <csetjmp> #include <csignal> #include <cstdarg> #include <cstddef> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #if __cplusplus >= 201103L #include <ccomplex> #include <cfenv> #include <cinttypes> #include <cstdalign> #include <cstdbool> #include <cstdint> #include <ctgmath> #include <cuchar> #include <cwchar> #include <cwctype> #endif // C++ #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <exception> #include <fstream> #include <functional> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <iterator> #include <limits> #include <list> #include <locale> #include <map> #include <memory> #include <new> #include <numeric> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <stdexcept> #include <streambuf> #include <string> #include <typeinfo> #include <utility> #include <valarray> #include <vector> #if __cplusplus >= 201103L #include <array> #include <atomic> #include <chrono> #include <codecvt> #include <condition_variable> #include <forward_list> #include <future> #include <initializer_list> #include <mutex> #include <random> #include <ratio> #include <regex> #include <scoped_allocator> #include <system_error> #include <thread> #include <tuple> #include <typeindex> #include <type_traits> #include <unordered_map> #include <unordered_set> #endif #if __cplusplus >= 201402L #include <shared_mutex> #endif #if __cplusplus >= 201703L #include <charconv> #include <filesystem> #endif c++/8/x86_64-redhat-linux/32/bits/cxxabi_tweaks.h 0000644 00000004060 15146341150 0015015 0 ustar 00 // Control various target specific ABI tweaks. Generic version. // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/cxxabi_tweaks.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{cxxabi.h} */ #ifndef _CXXABI_TWEAKS_H #define _CXXABI_TWEAKS_H 1 #ifdef __cplusplus namespace __cxxabiv1 { extern "C" { #endif // The generic ABI uses the first byte of a 64-bit guard variable. #define _GLIBCXX_GUARD_TEST(x) (*(char *) (x) != 0) #define _GLIBCXX_GUARD_SET(x) *(char *) (x) = 1 #define _GLIBCXX_GUARD_BIT __guard_test_bit (0, 1) #define _GLIBCXX_GUARD_PENDING_BIT __guard_test_bit (1, 1) #define _GLIBCXX_GUARD_WAITING_BIT __guard_test_bit (2, 1) __extension__ typedef int __guard __attribute__((mode (__DI__))); // __cxa_vec_ctor has void return type. typedef void __cxa_vec_ctor_return_type; #define _GLIBCXX_CXA_VEC_CTOR_RETURN(x) return // Constructors and destructors do not return a value. typedef void __cxa_cdtor_return_type; #ifdef __cplusplus } } // namespace __cxxabiv1 #endif #endif c++/8/x86_64-redhat-linux/32/bits/c++io.h 0000644 00000003110 15146341150 0013054 0 ustar 00 // Underlying io library details -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/c++io.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ios} */ // c_io_stdio.h - Defines for using "C" stdio.h #ifndef _GLIBCXX_CXX_IO_H #define _GLIBCXX_CXX_IO_H 1 #include <cstdio> #include <bits/gthr.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef __gthread_mutex_t __c_lock; // for basic_file.h typedef FILE __c_file; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/x86_64-redhat-linux/32/bits/cpu_defines.h 0000644 00000002465 15146341150 0014454 0 ustar 00 // Specific definitions for generic platforms -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/cpu_defines.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iosfwd} */ #ifndef _GLIBCXX_CPU_DEFINES #define _GLIBCXX_CPU_DEFINES 1 #endif c++/8/x86_64-redhat-linux/32/bits/time_members.h 0000644 00000005554 15146341150 0014642 0 ustar 00 // std::time_get, std::time_put implementation, GNU version -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/time_members.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.2.5.1.2 - time_get functions // ISO C++ 14882: 22.2.5.3.2 - time_put functions // // Written by Benjamin Kosnik <bkoz@redhat.com> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT> __timepunct<_CharT>::__timepunct(size_t __refs) : facet(__refs), _M_data(0), _M_c_locale_timepunct(0), _M_name_timepunct(_S_get_c_name()) { _M_initialize_timepunct(); } template<typename _CharT> __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs) : facet(__refs), _M_data(__cache), _M_c_locale_timepunct(0), _M_name_timepunct(_S_get_c_name()) { _M_initialize_timepunct(); } template<typename _CharT> __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s, size_t __refs) : facet(__refs), _M_data(0), _M_c_locale_timepunct(0), _M_name_timepunct(0) { if (__builtin_strcmp(__s, _S_get_c_name()) != 0) { const size_t __len = __builtin_strlen(__s) + 1; char* __tmp = new char[__len]; __builtin_memcpy(__tmp, __s, __len); _M_name_timepunct = __tmp; } else _M_name_timepunct = _S_get_c_name(); __try { _M_initialize_timepunct(__cloc); } __catch(...) { if (_M_name_timepunct != _S_get_c_name()) delete [] _M_name_timepunct; __throw_exception_again; } } template<typename _CharT> __timepunct<_CharT>::~__timepunct() { if (_M_name_timepunct != _S_get_c_name()) delete [] _M_name_timepunct; delete _M_data; _S_destroy_c_locale(_M_c_locale_timepunct); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/x86_64-redhat-linux/32/bits/stdtr1c++.h 0000644 00000003315 15146341150 0013675 0 ustar 00 // C++ includes used for precompiling TR1 -*- C++ -*- // Copyright (C) 2006-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file stdtr1c++.h * This is an implementation file for a precompiled header. */ #include <bits/stdc++.h> #include <tr1/array> #include <tr1/cctype> #include <tr1/cfenv> #include <tr1/cfloat> #include <tr1/cinttypes> #include <tr1/climits> #include <tr1/cmath> #include <tr1/complex> #include <tr1/cstdarg> #include <tr1/cstdbool> #include <tr1/cstdint> #include <tr1/cstdio> #include <tr1/cstdlib> #include <tr1/ctgmath> #include <tr1/ctime> #include <tr1/cwchar> #include <tr1/cwctype> #include <tr1/functional> #include <tr1/random> #include <tr1/tuple> #include <tr1/unordered_map> #include <tr1/unordered_set> #include <tr1/utility> c++/8/x86_64-redhat-linux/32/bits/c++config.h 0000644 00000160477 15146341150 0013736 0 ustar 00 // Predefined symbols and macros -*- C++ -*- // Copyright (C) 1997-2018 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++config.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iosfwd} */ #ifndef _GLIBCXX_CXX_CONFIG_H #define _GLIBCXX_CXX_CONFIG_H 1 // The major release number for the GCC release the C++ library belongs to. #define _GLIBCXX_RELEASE 8 // The datestamp of the C++ library in compressed ISO date format. #define __GLIBCXX__ 20210514 // Macros for various attributes. // _GLIBCXX_PURE // _GLIBCXX_CONST // _GLIBCXX_NORETURN // _GLIBCXX_NOTHROW // _GLIBCXX_VISIBILITY #ifndef _GLIBCXX_PURE # define _GLIBCXX_PURE __attribute__ ((__pure__)) #endif #ifndef _GLIBCXX_CONST # define _GLIBCXX_CONST __attribute__ ((__const__)) #endif #ifndef _GLIBCXX_NORETURN # define _GLIBCXX_NORETURN __attribute__ ((__noreturn__)) #endif // See below for C++ #ifndef _GLIBCXX_NOTHROW # ifndef __cplusplus # define _GLIBCXX_NOTHROW __attribute__((__nothrow__)) # endif #endif // Macros for visibility attributes. // _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY // _GLIBCXX_VISIBILITY # define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1 #if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY # define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V))) #else // If this is not supplied by the OS-specific or CPU-specific // headers included below, it will be defined to an empty default. # define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V) #endif // Macros for deprecated attributes. // _GLIBCXX_USE_DEPRECATED // _GLIBCXX_DEPRECATED // _GLIBCXX17_DEPRECATED #ifndef _GLIBCXX_USE_DEPRECATED # define _GLIBCXX_USE_DEPRECATED 1 #endif #if defined(__DEPRECATED) && (__cplusplus >= 201103L) # define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) #else # define _GLIBCXX_DEPRECATED #endif #if defined(__DEPRECATED) && (__cplusplus >= 201703L) # define _GLIBCXX17_DEPRECATED [[__deprecated__]] #else # define _GLIBCXX17_DEPRECATED #endif // Macros for ABI tag attributes. #ifndef _GLIBCXX_ABI_TAG_CXX11 # define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) #endif // Macro to warn about unused results. #if __cplusplus >= 201703L # define _GLIBCXX_NODISCARD [[__nodiscard__]] #else # define _GLIBCXX_NODISCARD #endif #if __cplusplus // Macro for constexpr, to support in mixed 03/0x mode. #ifndef _GLIBCXX_CONSTEXPR # if __cplusplus >= 201103L # define _GLIBCXX_CONSTEXPR constexpr # define _GLIBCXX_USE_CONSTEXPR constexpr # else # define _GLIBCXX_CONSTEXPR # define _GLIBCXX_USE_CONSTEXPR const # endif #endif #ifndef _GLIBCXX14_CONSTEXPR # if __cplusplus >= 201402L # define _GLIBCXX14_CONSTEXPR constexpr # else # define _GLIBCXX14_CONSTEXPR # endif #endif #ifndef _GLIBCXX17_CONSTEXPR # if __cplusplus > 201402L # define _GLIBCXX17_CONSTEXPR constexpr # else # define _GLIBCXX17_CONSTEXPR # endif #endif #ifndef _GLIBCXX17_INLINE # if __cplusplus > 201402L # define _GLIBCXX17_INLINE inline # else # define _GLIBCXX17_INLINE # endif #endif // Macro for noexcept, to support in mixed 03/0x mode. #ifndef _GLIBCXX_NOEXCEPT # if __cplusplus >= 201103L # define _GLIBCXX_NOEXCEPT noexcept # define _GLIBCXX_NOEXCEPT_IF(_COND) noexcept(_COND) # define _GLIBCXX_USE_NOEXCEPT noexcept # define _GLIBCXX_THROW(_EXC) # else # define _GLIBCXX_NOEXCEPT # define _GLIBCXX_NOEXCEPT_IF(_COND) # define _GLIBCXX_USE_NOEXCEPT throw() # define _GLIBCXX_THROW(_EXC) throw(_EXC) # endif #endif #ifndef _GLIBCXX_NOTHROW # define _GLIBCXX_NOTHROW _GLIBCXX_USE_NOEXCEPT #endif #ifndef _GLIBCXX_THROW_OR_ABORT # if __cpp_exceptions # define _GLIBCXX_THROW_OR_ABORT(_EXC) (throw (_EXC)) # else # define _GLIBCXX_THROW_OR_ABORT(_EXC) (__builtin_abort()) # endif #endif #if __cpp_noexcept_function_type #define _GLIBCXX_NOEXCEPT_PARM , bool _NE #define _GLIBCXX_NOEXCEPT_QUAL noexcept (_NE) #else #define _GLIBCXX_NOEXCEPT_PARM #define _GLIBCXX_NOEXCEPT_QUAL #endif // Macro for extern template, ie controlling template linkage via use // of extern keyword on template declaration. As documented in the g++ // manual, it inhibits all implicit instantiations and is used // throughout the library to avoid multiple weak definitions for // required types that are already explicitly instantiated in the // library binary. This substantially reduces the binary size of // resulting executables. // Special case: _GLIBCXX_EXTERN_TEMPLATE == -1 disallows extern // templates only in basic_string, thus activating its debug-mode // checks even at -O0. # define _GLIBCXX_EXTERN_TEMPLATE 1 /* Outline of libstdc++ namespaces. namespace std { namespace __debug { } namespace __parallel { } namespace __profile { } namespace __cxx1998 { } namespace __detail { namespace __variant { } // C++17 } namespace rel_ops { } namespace tr1 { namespace placeholders { } namespace regex_constants { } namespace __detail { } } namespace tr2 { } namespace decimal { } namespace chrono { } // C++11 namespace placeholders { } // C++11 namespace regex_constants { } // C++11 namespace this_thread { } // C++11 inline namespace literals { // C++14 inline namespace chrono_literals { } // C++14 inline namespace complex_literals { } // C++14 inline namespace string_literals { } // C++14 inline namespace string_view_literals { } // C++17 } } namespace abi { } namespace __gnu_cxx { namespace __detail { } } For full details see: http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaces.html */ namespace std { typedef __SIZE_TYPE__ size_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; #if __cplusplus >= 201103L typedef decltype(nullptr) nullptr_t; #endif } # define _GLIBCXX_USE_DUAL_ABI 1 #if ! _GLIBCXX_USE_DUAL_ABI // Ignore any pre-defined value of _GLIBCXX_USE_CXX11_ABI # undef _GLIBCXX_USE_CXX11_ABI #endif #ifndef _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_USE_CXX11_ABI 1 #endif #if _GLIBCXX_USE_CXX11_ABI namespace std { inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } } namespace __gnu_cxx { inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } } # define _GLIBCXX_NAMESPACE_CXX11 __cxx11:: # define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 { # define _GLIBCXX_END_NAMESPACE_CXX11 } # define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11 #else # define _GLIBCXX_NAMESPACE_CXX11 # define _GLIBCXX_BEGIN_NAMESPACE_CXX11 # define _GLIBCXX_END_NAMESPACE_CXX11 # define _GLIBCXX_DEFAULT_ABI_TAG #endif // Defined if inline namespaces are used for versioning. # define _GLIBCXX_INLINE_VERSION 0 // Inline namespace for symbol versioning. #if _GLIBCXX_INLINE_VERSION # define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __8 { # define _GLIBCXX_END_NAMESPACE_VERSION } namespace std { inline _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201402L inline namespace literals { inline namespace chrono_literals { } inline namespace complex_literals { } inline namespace string_literals { } #if __cplusplus > 201402L inline namespace string_view_literals { } #endif // C++17 } #endif // C++14 _GLIBCXX_END_NAMESPACE_VERSION } namespace __gnu_cxx { inline _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION } #else # define _GLIBCXX_BEGIN_NAMESPACE_VERSION # define _GLIBCXX_END_NAMESPACE_VERSION #endif // Inline namespaces for special modes: debug, parallel, profile. #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) \ || defined(_GLIBCXX_PROFILE) namespace std { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Non-inline namespace for components replaced by alternates in active mode. namespace __cxx1998 { # if _GLIBCXX_USE_CXX11_ABI inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } # endif } _GLIBCXX_END_NAMESPACE_VERSION // Inline namespace for debug mode. # ifdef _GLIBCXX_DEBUG inline namespace __debug { } # endif // Inline namespaces for parallel mode. # ifdef _GLIBCXX_PARALLEL inline namespace __parallel { } # endif // Inline namespaces for profile mode # ifdef _GLIBCXX_PROFILE inline namespace __profile { } # endif } // Check for invalid usage and unsupported mixed-mode use. # if defined(_GLIBCXX_DEBUG) && defined(_GLIBCXX_PARALLEL) # error illegal use of multiple inlined namespaces # endif # if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_DEBUG) # error illegal use of multiple inlined namespaces # endif # if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_PARALLEL) # error illegal use of multiple inlined namespaces # endif // Check for invalid use due to lack for weak symbols. # if __NO_INLINE__ && !__GXX_WEAK__ # warning currently using inlined namespace mode which may fail \ without inlining due to lack of weak symbols # endif #endif // Macros for namespace scope. Either namespace std:: or the name // of some nested namespace within it corresponding to the active mode. // _GLIBCXX_STD_A // _GLIBCXX_STD_C // // Macros for opening/closing conditional namespaces. // _GLIBCXX_BEGIN_NAMESPACE_ALGO // _GLIBCXX_END_NAMESPACE_ALGO // _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // _GLIBCXX_END_NAMESPACE_CONTAINER #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PROFILE) # define _GLIBCXX_STD_C __cxx1998 # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER \ namespace _GLIBCXX_STD_C { # define _GLIBCXX_END_NAMESPACE_CONTAINER } #else # define _GLIBCXX_STD_C std # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER # define _GLIBCXX_END_NAMESPACE_CONTAINER #endif #ifdef _GLIBCXX_PARALLEL # define _GLIBCXX_STD_A __cxx1998 # define _GLIBCXX_BEGIN_NAMESPACE_ALGO \ namespace _GLIBCXX_STD_A { # define _GLIBCXX_END_NAMESPACE_ALGO } #else # define _GLIBCXX_STD_A std # define _GLIBCXX_BEGIN_NAMESPACE_ALGO # define _GLIBCXX_END_NAMESPACE_ALGO #endif // GLIBCXX_ABI Deprecated // Define if compatibility should be provided for -mlong-double-64. #undef _GLIBCXX_LONG_DOUBLE_COMPAT // Inline namespace for long double 128 mode. #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ namespace std { inline namespace __gnu_cxx_ldbl128 { } } # define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ldbl128:: # define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ldbl128 { # define _GLIBCXX_END_NAMESPACE_LDBL } #else # define _GLIBCXX_NAMESPACE_LDBL # define _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL #endif #if _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_CXX11 # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11 # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_CXX11 #else # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_LDBL # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_LDBL #endif // Debug Mode implies checking assertions. #if defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_ASSERTIONS) # define _GLIBCXX_ASSERTIONS 1 #endif // Disable std::string explicit instantiation declarations in order to assert. #ifdef _GLIBCXX_ASSERTIONS # undef _GLIBCXX_EXTERN_TEMPLATE # define _GLIBCXX_EXTERN_TEMPLATE -1 #endif // Assert. #if defined(_GLIBCXX_ASSERTIONS) \ || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS) namespace std { // Avoid the use of assert, because we're trying to keep the <cassert> // include out of the mix. inline void __replacement_assert(const char* __file, int __line, const char* __function, const char* __condition) { __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, __function, __condition); __builtin_abort(); } } #define __glibcxx_assert_impl(_Condition) \ do \ { \ if (! (_Condition)) \ std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ #_Condition); \ } while (false) #endif #if defined(_GLIBCXX_ASSERTIONS) # define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition) #else # define __glibcxx_assert(_Condition) #endif // Macros for race detectors. // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain // atomic (lock-free) synchronization to race detectors: // the race detector will infer a happens-before arc from the former to the // latter when they share the same argument pointer. // // The most frequent use case for these macros (and the only case in the // current implementation of the library) is atomic reference counting: // void _M_remove_reference() // { // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount); // if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, -1) <= 0) // { // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount); // _M_destroy(__a); // } // } // The annotations in this example tell the race detector that all memory // accesses occurred when the refcount was positive do not race with // memory accesses which occurred after the refcount became zero. #ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE # define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) #endif #ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER # define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) #endif // Macros for C linkage: define extern "C" linkage only when using C++. # define _GLIBCXX_BEGIN_EXTERN_C extern "C" { # define _GLIBCXX_END_EXTERN_C } # define _GLIBCXX_USE_ALLOCATOR_NEW 1 #else // !__cplusplus # define _GLIBCXX_BEGIN_EXTERN_C # define _GLIBCXX_END_EXTERN_C #endif // First includes. // Pick up any OS-specific definitions. #include <bits/os_defines.h> // Pick up any CPU-specific definitions. #include <bits/cpu_defines.h> // If platform uses neither visibility nor psuedo-visibility, // specify empty default for namespace annotation macros. #ifndef _GLIBCXX_PSEUDO_VISIBILITY # define _GLIBCXX_PSEUDO_VISIBILITY(V) #endif // Certain function definitions that are meant to be overridable from // user code are decorated with this macro. For some targets, this // macro causes these definitions to be weak. #ifndef _GLIBCXX_WEAK_DEFINITION # define _GLIBCXX_WEAK_DEFINITION #endif // By default, we assume that __GXX_WEAK__ also means that there is support // for declaring functions as weak while not defining such functions. This // allows for referring to functions provided by other libraries (e.g., // libitm) without depending on them if the respective features are not used. #ifndef _GLIBCXX_USE_WEAK_REF # define _GLIBCXX_USE_WEAK_REF __GXX_WEAK__ #endif // Conditionally enable annotations for the Transactional Memory TS on C++11. // Most of the following conditions are due to limitations in the current // implementation. #if __cplusplus >= 201103L && _GLIBCXX_USE_CXX11_ABI \ && _GLIBCXX_USE_DUAL_ABI && __cpp_transactional_memory >= 201505L \ && !_GLIBCXX_FULLY_DYNAMIC_STRING && _GLIBCXX_USE_WEAK_REF \ && _GLIBCXX_USE_ALLOCATOR_NEW #define _GLIBCXX_TXN_SAFE transaction_safe #define _GLIBCXX_TXN_SAFE_DYN transaction_safe_dynamic #else #define _GLIBCXX_TXN_SAFE #define _GLIBCXX_TXN_SAFE_DYN #endif #if __cplusplus > 201402L // In C++17 mathematical special functions are in namespace std. # define _GLIBCXX_USE_STD_SPEC_FUNCS 1 #elif __cplusplus >= 201103L && __STDCPP_WANT_MATH_SPEC_FUNCS__ != 0 // For C++11 and C++14 they are in namespace std when requested. # define _GLIBCXX_USE_STD_SPEC_FUNCS 1 #endif // The remainder of the prewritten config is automatic; all the // user hooks are listed above. // Create a boolean flag to be used to determine if --fast-math is set. #ifdef __FAST_MATH__ # define _GLIBCXX_FAST_MATH 1 #else # define _GLIBCXX_FAST_MATH 0 #endif // This marks string literals in header files to be extracted for eventual // translation. It is primarily used for messages in thrown exceptions; see // src/functexcept.cc. We use __N because the more traditional _N is used // for something else under certain OSes (see BADNAMES). #define __N(msgid) (msgid) // For example, <windows.h> is known to #define min and max as macros... #undef min #undef max // N.B. these _GLIBCXX_USE_C99_XXX macros are defined unconditionally // so they should be tested with #if not with #ifdef. #if __cplusplus >= 201103L # ifndef _GLIBCXX_USE_C99_MATH # define _GLIBCXX_USE_C99_MATH _GLIBCXX11_USE_C99_MATH # endif # ifndef _GLIBCXX_USE_C99_COMPLEX # define _GLIBCXX_USE_C99_COMPLEX _GLIBCXX11_USE_C99_COMPLEX # endif # ifndef _GLIBCXX_USE_C99_STDIO # define _GLIBCXX_USE_C99_STDIO _GLIBCXX11_USE_C99_STDIO # endif # ifndef _GLIBCXX_USE_C99_STDLIB # define _GLIBCXX_USE_C99_STDLIB _GLIBCXX11_USE_C99_STDLIB # endif # ifndef _GLIBCXX_USE_C99_WCHAR # define _GLIBCXX_USE_C99_WCHAR _GLIBCXX11_USE_C99_WCHAR # endif #else # ifndef _GLIBCXX_USE_C99_MATH # define _GLIBCXX_USE_C99_MATH _GLIBCXX98_USE_C99_MATH # endif # ifndef _GLIBCXX_USE_C99_COMPLEX # define _GLIBCXX_USE_C99_COMPLEX _GLIBCXX98_USE_C99_COMPLEX # endif # ifndef _GLIBCXX_USE_C99_STDIO # define _GLIBCXX_USE_C99_STDIO _GLIBCXX98_USE_C99_STDIO # endif # ifndef _GLIBCXX_USE_C99_STDLIB # define _GLIBCXX_USE_C99_STDLIB _GLIBCXX98_USE_C99_STDLIB # endif # ifndef _GLIBCXX_USE_C99_WCHAR # define _GLIBCXX_USE_C99_WCHAR _GLIBCXX98_USE_C99_WCHAR # endif #endif /* Define if __float128 is supported on this host. */ #if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) #define _GLIBCXX_USE_FLOAT128 1 #endif // End of prewritten config; the settings discovered at configure time follow. /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `acosf' function. */ #define _GLIBCXX_HAVE_ACOSF 1 /* Define to 1 if you have the `acosl' function. */ #define _GLIBCXX_HAVE_ACOSL 1 /* Define to 1 if you have the `aligned_alloc' function. */ #define _GLIBCXX_HAVE_ALIGNED_ALLOC 1 /* Define to 1 if you have the `asinf' function. */ #define _GLIBCXX_HAVE_ASINF 1 /* Define to 1 if you have the `asinl' function. */ #define _GLIBCXX_HAVE_ASINL 1 /* Define to 1 if the target assembler supports .symver directive. */ #define _GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE 1 /* Define to 1 if you have the `atan2f' function. */ #define _GLIBCXX_HAVE_ATAN2F 1 /* Define to 1 if you have the `atan2l' function. */ #define _GLIBCXX_HAVE_ATAN2L 1 /* Define to 1 if you have the `atanf' function. */ #define _GLIBCXX_HAVE_ATANF 1 /* Define to 1 if you have the `atanl' function. */ #define _GLIBCXX_HAVE_ATANL 1 /* Define to 1 if you have the `at_quick_exit' function. */ #define _GLIBCXX_HAVE_AT_QUICK_EXIT 1 /* Define to 1 if the target assembler supports thread-local storage. */ /* #undef _GLIBCXX_HAVE_CC_TLS */ /* Define to 1 if you have the `ceilf' function. */ #define _GLIBCXX_HAVE_CEILF 1 /* Define to 1 if you have the `ceill' function. */ #define _GLIBCXX_HAVE_CEILL 1 /* Define to 1 if you have the <complex.h> header file. */ #define _GLIBCXX_HAVE_COMPLEX_H 1 /* Define to 1 if you have the `cosf' function. */ #define _GLIBCXX_HAVE_COSF 1 /* Define to 1 if you have the `coshf' function. */ #define _GLIBCXX_HAVE_COSHF 1 /* Define to 1 if you have the `coshl' function. */ #define _GLIBCXX_HAVE_COSHL 1 /* Define to 1 if you have the `cosl' function. */ #define _GLIBCXX_HAVE_COSL 1 /* Define to 1 if you have the <dirent.h> header file. */ #define _GLIBCXX_HAVE_DIRENT_H 1 /* Define to 1 if you have the <dlfcn.h> header file. */ #define _GLIBCXX_HAVE_DLFCN_H 1 /* Define if EBADMSG exists. */ #define _GLIBCXX_HAVE_EBADMSG 1 /* Define if ECANCELED exists. */ #define _GLIBCXX_HAVE_ECANCELED 1 /* Define if ECHILD exists. */ #define _GLIBCXX_HAVE_ECHILD 1 /* Define if EIDRM exists. */ #define _GLIBCXX_HAVE_EIDRM 1 /* Define to 1 if you have the <endian.h> header file. */ #define _GLIBCXX_HAVE_ENDIAN_H 1 /* Define if ENODATA exists. */ #define _GLIBCXX_HAVE_ENODATA 1 /* Define if ENOLINK exists. */ #define _GLIBCXX_HAVE_ENOLINK 1 /* Define if ENOSPC exists. */ #define _GLIBCXX_HAVE_ENOSPC 1 /* Define if ENOSR exists. */ #define _GLIBCXX_HAVE_ENOSR 1 /* Define if ENOSTR exists. */ #define _GLIBCXX_HAVE_ENOSTR 1 /* Define if ENOTRECOVERABLE exists. */ #define _GLIBCXX_HAVE_ENOTRECOVERABLE 1 /* Define if ENOTSUP exists. */ #define _GLIBCXX_HAVE_ENOTSUP 1 /* Define if EOVERFLOW exists. */ #define _GLIBCXX_HAVE_EOVERFLOW 1 /* Define if EOWNERDEAD exists. */ #define _GLIBCXX_HAVE_EOWNERDEAD 1 /* Define if EPERM exists. */ #define _GLIBCXX_HAVE_EPERM 1 /* Define if EPROTO exists. */ #define _GLIBCXX_HAVE_EPROTO 1 /* Define if ETIME exists. */ #define _GLIBCXX_HAVE_ETIME 1 /* Define if ETIMEDOUT exists. */ #define _GLIBCXX_HAVE_ETIMEDOUT 1 /* Define if ETXTBSY exists. */ #define _GLIBCXX_HAVE_ETXTBSY 1 /* Define if EWOULDBLOCK exists. */ #define _GLIBCXX_HAVE_EWOULDBLOCK 1 /* Define to 1 if GCC 4.6 supported std::exception_ptr for the target */ #define _GLIBCXX_HAVE_EXCEPTION_PTR_SINCE_GCC46 1 /* Define to 1 if you have the <execinfo.h> header file. */ #define _GLIBCXX_HAVE_EXECINFO_H 1 /* Define to 1 if you have the `expf' function. */ #define _GLIBCXX_HAVE_EXPF 1 /* Define to 1 if you have the `expl' function. */ #define _GLIBCXX_HAVE_EXPL 1 /* Define to 1 if you have the `fabsf' function. */ #define _GLIBCXX_HAVE_FABSF 1 /* Define to 1 if you have the `fabsl' function. */ #define _GLIBCXX_HAVE_FABSL 1 /* Define to 1 if you have the <fcntl.h> header file. */ #define _GLIBCXX_HAVE_FCNTL_H 1 /* Define to 1 if you have the <fenv.h> header file. */ #define _GLIBCXX_HAVE_FENV_H 1 /* Define to 1 if you have the `finite' function. */ #define _GLIBCXX_HAVE_FINITE 1 /* Define to 1 if you have the `finitef' function. */ #define _GLIBCXX_HAVE_FINITEF 1 /* Define to 1 if you have the `finitel' function. */ #define _GLIBCXX_HAVE_FINITEL 1 /* Define to 1 if you have the <float.h> header file. */ #define _GLIBCXX_HAVE_FLOAT_H 1 /* Define to 1 if you have the `floorf' function. */ #define _GLIBCXX_HAVE_FLOORF 1 /* Define to 1 if you have the `floorl' function. */ #define _GLIBCXX_HAVE_FLOORL 1 /* Define to 1 if you have the `fmodf' function. */ #define _GLIBCXX_HAVE_FMODF 1 /* Define to 1 if you have the `fmodl' function. */ #define _GLIBCXX_HAVE_FMODL 1 /* Define to 1 if you have the `fpclass' function. */ /* #undef _GLIBCXX_HAVE_FPCLASS */ /* Define to 1 if you have the <fp.h> header file. */ /* #undef _GLIBCXX_HAVE_FP_H */ /* Define to 1 if you have the `frexpf' function. */ #define _GLIBCXX_HAVE_FREXPF 1 /* Define to 1 if you have the `frexpl' function. */ #define _GLIBCXX_HAVE_FREXPL 1 /* Define if _Unwind_GetIPInfo is available. */ #define _GLIBCXX_HAVE_GETIPINFO 1 /* Define if gets is available in <stdio.h> before C++14. */ #define _GLIBCXX_HAVE_GETS 1 /* Define to 1 if you have the `hypot' function. */ #define _GLIBCXX_HAVE_HYPOT 1 /* Define to 1 if you have the `hypotf' function. */ #define _GLIBCXX_HAVE_HYPOTF 1 /* Define to 1 if you have the `hypotl' function. */ #define _GLIBCXX_HAVE_HYPOTL 1 /* Define if you have the iconv() function. */ #define _GLIBCXX_HAVE_ICONV 1 /* Define to 1 if you have the <ieeefp.h> header file. */ /* #undef _GLIBCXX_HAVE_IEEEFP_H */ /* Define if int64_t is available in <stdint.h>. */ #define _GLIBCXX_HAVE_INT64_T 1 /* Define if int64_t is a long. */ /* #undef _GLIBCXX_HAVE_INT64_T_LONG */ /* Define if int64_t is a long long. */ #define _GLIBCXX_HAVE_INT64_T_LONG_LONG 1 /* Define to 1 if you have the <inttypes.h> header file. */ #define _GLIBCXX_HAVE_INTTYPES_H 1 /* Define to 1 if you have the `isinf' function. */ /* #undef _GLIBCXX_HAVE_ISINF */ /* Define to 1 if you have the `isinff' function. */ #define _GLIBCXX_HAVE_ISINFF 1 /* Define to 1 if you have the `isinfl' function. */ #define _GLIBCXX_HAVE_ISINFL 1 /* Define to 1 if you have the `isnan' function. */ /* #undef _GLIBCXX_HAVE_ISNAN */ /* Define to 1 if you have the `isnanf' function. */ #define _GLIBCXX_HAVE_ISNANF 1 /* Define to 1 if you have the `isnanl' function. */ #define _GLIBCXX_HAVE_ISNANL 1 /* Defined if iswblank exists. */ #define _GLIBCXX_HAVE_ISWBLANK 1 /* Define if LC_MESSAGES is available in <locale.h>. */ #define _GLIBCXX_HAVE_LC_MESSAGES 1 /* Define to 1 if you have the `ldexpf' function. */ #define _GLIBCXX_HAVE_LDEXPF 1 /* Define to 1 if you have the `ldexpl' function. */ #define _GLIBCXX_HAVE_LDEXPL 1 /* Define to 1 if you have the <libintl.h> header file. */ #define _GLIBCXX_HAVE_LIBINTL_H 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_AS 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_DATA 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_FSIZE 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_RSS 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_VMEM 0 /* Define if futex syscall is available. */ #define _GLIBCXX_HAVE_LINUX_FUTEX 1 /* Define to 1 if you have the <linux/random.h> header file. */ #define _GLIBCXX_HAVE_LINUX_RANDOM_H 1 /* Define to 1 if you have the <linux/types.h> header file. */ #define _GLIBCXX_HAVE_LINUX_TYPES_H 1 /* Define to 1 if you have the <locale.h> header file. */ #define _GLIBCXX_HAVE_LOCALE_H 1 /* Define to 1 if you have the `log10f' function. */ #define _GLIBCXX_HAVE_LOG10F 1 /* Define to 1 if you have the `log10l' function. */ #define _GLIBCXX_HAVE_LOG10L 1 /* Define to 1 if you have the `logf' function. */ #define _GLIBCXX_HAVE_LOGF 1 /* Define to 1 if you have the `logl' function. */ #define _GLIBCXX_HAVE_LOGL 1 /* Define to 1 if you have the <machine/endian.h> header file. */ /* #undef _GLIBCXX_HAVE_MACHINE_ENDIAN_H */ /* Define to 1 if you have the <machine/param.h> header file. */ /* #undef _GLIBCXX_HAVE_MACHINE_PARAM_H */ /* Define if mbstate_t exists in wchar.h. */ #define _GLIBCXX_HAVE_MBSTATE_T 1 /* Define to 1 if you have the `memalign' function. */ #define _GLIBCXX_HAVE_MEMALIGN 1 /* Define to 1 if you have the <memory.h> header file. */ #define _GLIBCXX_HAVE_MEMORY_H 1 /* Define to 1 if you have the `modf' function. */ #define _GLIBCXX_HAVE_MODF 1 /* Define to 1 if you have the `modff' function. */ #define _GLIBCXX_HAVE_MODFF 1 /* Define to 1 if you have the `modfl' function. */ #define _GLIBCXX_HAVE_MODFL 1 /* Define to 1 if you have the <nan.h> header file. */ /* #undef _GLIBCXX_HAVE_NAN_H */ /* Define if <math.h> defines obsolete isinf function. */ /* #undef _GLIBCXX_HAVE_OBSOLETE_ISINF */ /* Define if <math.h> defines obsolete isnan function. */ /* #undef _GLIBCXX_HAVE_OBSOLETE_ISNAN */ /* Define if poll is available in <poll.h>. */ #define _GLIBCXX_HAVE_POLL 1 /* Define to 1 if you have the `posix_memalign' function. */ #define _GLIBCXX_HAVE_POSIX_MEMALIGN 1 /* Define to 1 if you have the `powf' function. */ #define _GLIBCXX_HAVE_POWF 1 /* Define to 1 if you have the `powl' function. */ #define _GLIBCXX_HAVE_POWL 1 /* Define to 1 if you have the `qfpclass' function. */ /* #undef _GLIBCXX_HAVE_QFPCLASS */ /* Define to 1 if you have the `quick_exit' function. */ #define _GLIBCXX_HAVE_QUICK_EXIT 1 /* Define to 1 if you have the `setenv' function. */ #define _GLIBCXX_HAVE_SETENV 1 /* Define to 1 if you have the `sincos' function. */ #define _GLIBCXX_HAVE_SINCOS 1 /* Define to 1 if you have the `sincosf' function. */ #define _GLIBCXX_HAVE_SINCOSF 1 /* Define to 1 if you have the `sincosl' function. */ #define _GLIBCXX_HAVE_SINCOSL 1 /* Define to 1 if you have the `sinf' function. */ #define _GLIBCXX_HAVE_SINF 1 /* Define to 1 if you have the `sinhf' function. */ #define _GLIBCXX_HAVE_SINHF 1 /* Define to 1 if you have the `sinhl' function. */ #define _GLIBCXX_HAVE_SINHL 1 /* Define to 1 if you have the `sinl' function. */ #define _GLIBCXX_HAVE_SINL 1 /* Defined if sleep exists. */ /* #undef _GLIBCXX_HAVE_SLEEP */ /* Define to 1 if you have the `sqrtf' function. */ #define _GLIBCXX_HAVE_SQRTF 1 /* Define to 1 if you have the `sqrtl' function. */ #define _GLIBCXX_HAVE_SQRTL 1 /* Define to 1 if you have the <stdalign.h> header file. */ #define _GLIBCXX_HAVE_STDALIGN_H 1 /* Define to 1 if you have the <stdbool.h> header file. */ #define _GLIBCXX_HAVE_STDBOOL_H 1 /* Define to 1 if you have the <stdint.h> header file. */ #define _GLIBCXX_HAVE_STDINT_H 1 /* Define to 1 if you have the <stdlib.h> header file. */ #define _GLIBCXX_HAVE_STDLIB_H 1 /* Define if strerror_l is available in <string.h>. */ #define _GLIBCXX_HAVE_STRERROR_L 1 /* Define if strerror_r is available in <string.h>. */ #define _GLIBCXX_HAVE_STRERROR_R 1 /* Define to 1 if you have the <strings.h> header file. */ #define _GLIBCXX_HAVE_STRINGS_H 1 /* Define to 1 if you have the <string.h> header file. */ #define _GLIBCXX_HAVE_STRING_H 1 /* Define to 1 if you have the `strtof' function. */ #define _GLIBCXX_HAVE_STRTOF 1 /* Define to 1 if you have the `strtold' function. */ #define _GLIBCXX_HAVE_STRTOLD 1 /* Define to 1 if `d_type' is a member of `struct dirent'. */ #define _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE 1 /* Define if strxfrm_l is available in <string.h>. */ #define _GLIBCXX_HAVE_STRXFRM_L 1 /* Define to 1 if the target runtime linker supports binding the same symbol to different versions. */ #define _GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT 1 /* Define to 1 if you have the <sys/filio.h> header file. */ /* #undef _GLIBCXX_HAVE_SYS_FILIO_H */ /* Define to 1 if you have the <sys/ioctl.h> header file. */ #define _GLIBCXX_HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the <sys/ipc.h> header file. */ #define _GLIBCXX_HAVE_SYS_IPC_H 1 /* Define to 1 if you have the <sys/isa_defs.h> header file. */ /* #undef _GLIBCXX_HAVE_SYS_ISA_DEFS_H */ /* Define to 1 if you have the <sys/machine.h> header file. */ /* #undef _GLIBCXX_HAVE_SYS_MACHINE_H */ /* Define to 1 if you have the <sys/param.h> header file. */ #define _GLIBCXX_HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the <sys/resource.h> header file. */ #define _GLIBCXX_HAVE_SYS_RESOURCE_H 1 /* Define to 1 if you have a suitable <sys/sdt.h> header file */ #define _GLIBCXX_HAVE_SYS_SDT_H 1 /* Define to 1 if you have the <sys/sem.h> header file. */ #define _GLIBCXX_HAVE_SYS_SEM_H 1 /* Define to 1 if you have the <sys/statvfs.h> header file. */ #define _GLIBCXX_HAVE_SYS_STATVFS_H 1 /* Define to 1 if you have the <sys/stat.h> header file. */ #define _GLIBCXX_HAVE_SYS_STAT_H 1 /* Define to 1 if you have the <sys/sysinfo.h> header file. */ #define _GLIBCXX_HAVE_SYS_SYSINFO_H 1 /* Define to 1 if you have the <sys/time.h> header file. */ #define _GLIBCXX_HAVE_SYS_TIME_H 1 /* Define to 1 if you have the <sys/types.h> header file. */ #define _GLIBCXX_HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the <sys/uio.h> header file. */ #define _GLIBCXX_HAVE_SYS_UIO_H 1 /* Define if S_IFREG is available in <sys/stat.h>. */ /* #undef _GLIBCXX_HAVE_S_IFREG */ /* Define if S_ISREG is available in <sys/stat.h>. */ #define _GLIBCXX_HAVE_S_ISREG 1 /* Define to 1 if you have the `tanf' function. */ #define _GLIBCXX_HAVE_TANF 1 /* Define to 1 if you have the `tanhf' function. */ #define _GLIBCXX_HAVE_TANHF 1 /* Define to 1 if you have the `tanhl' function. */ #define _GLIBCXX_HAVE_TANHL 1 /* Define to 1 if you have the `tanl' function. */ #define _GLIBCXX_HAVE_TANL 1 /* Define to 1 if you have the <tgmath.h> header file. */ #define _GLIBCXX_HAVE_TGMATH_H 1 /* Define to 1 if the target supports thread-local storage. */ #define _GLIBCXX_HAVE_TLS 1 /* Define to 1 if you have the <uchar.h> header file. */ #define _GLIBCXX_HAVE_UCHAR_H 1 /* Define to 1 if you have the <unistd.h> header file. */ #define _GLIBCXX_HAVE_UNISTD_H 1 /* Defined if usleep exists. */ /* #undef _GLIBCXX_HAVE_USLEEP */ /* Define to 1 if you have the <utime.h> header file. */ #define _GLIBCXX_HAVE_UTIME_H 1 /* Defined if vfwscanf exists. */ #define _GLIBCXX_HAVE_VFWSCANF 1 /* Defined if vswscanf exists. */ #define _GLIBCXX_HAVE_VSWSCANF 1 /* Defined if vwscanf exists. */ #define _GLIBCXX_HAVE_VWSCANF 1 /* Define to 1 if you have the <wchar.h> header file. */ #define _GLIBCXX_HAVE_WCHAR_H 1 /* Defined if wcstof exists. */ #define _GLIBCXX_HAVE_WCSTOF 1 /* Define to 1 if you have the <wctype.h> header file. */ #define _GLIBCXX_HAVE_WCTYPE_H 1 /* Defined if Sleep exists. */ /* #undef _GLIBCXX_HAVE_WIN32_SLEEP */ /* Define if writev is available in <sys/uio.h>. */ #define _GLIBCXX_HAVE_WRITEV 1 /* Define to 1 if you have the `_acosf' function. */ /* #undef _GLIBCXX_HAVE__ACOSF */ /* Define to 1 if you have the `_acosl' function. */ /* #undef _GLIBCXX_HAVE__ACOSL */ /* Define to 1 if you have the `_aligned_malloc' function. */ /* #undef _GLIBCXX_HAVE__ALIGNED_MALLOC */ /* Define to 1 if you have the `_asinf' function. */ /* #undef _GLIBCXX_HAVE__ASINF */ /* Define to 1 if you have the `_asinl' function. */ /* #undef _GLIBCXX_HAVE__ASINL */ /* Define to 1 if you have the `_atan2f' function. */ /* #undef _GLIBCXX_HAVE__ATAN2F */ /* Define to 1 if you have the `_atan2l' function. */ /* #undef _GLIBCXX_HAVE__ATAN2L */ /* Define to 1 if you have the `_atanf' function. */ /* #undef _GLIBCXX_HAVE__ATANF */ /* Define to 1 if you have the `_atanl' function. */ /* #undef _GLIBCXX_HAVE__ATANL */ /* Define to 1 if you have the `_ceilf' function. */ /* #undef _GLIBCXX_HAVE__CEILF */ /* Define to 1 if you have the `_ceill' function. */ /* #undef _GLIBCXX_HAVE__CEILL */ /* Define to 1 if you have the `_cosf' function. */ /* #undef _GLIBCXX_HAVE__COSF */ /* Define to 1 if you have the `_coshf' function. */ /* #undef _GLIBCXX_HAVE__COSHF */ /* Define to 1 if you have the `_coshl' function. */ /* #undef _GLIBCXX_HAVE__COSHL */ /* Define to 1 if you have the `_cosl' function. */ /* #undef _GLIBCXX_HAVE__COSL */ /* Define to 1 if you have the `_expf' function. */ /* #undef _GLIBCXX_HAVE__EXPF */ /* Define to 1 if you have the `_expl' function. */ /* #undef _GLIBCXX_HAVE__EXPL */ /* Define to 1 if you have the `_fabsf' function. */ /* #undef _GLIBCXX_HAVE__FABSF */ /* Define to 1 if you have the `_fabsl' function. */ /* #undef _GLIBCXX_HAVE__FABSL */ /* Define to 1 if you have the `_finite' function. */ /* #undef _GLIBCXX_HAVE__FINITE */ /* Define to 1 if you have the `_finitef' function. */ /* #undef _GLIBCXX_HAVE__FINITEF */ /* Define to 1 if you have the `_finitel' function. */ /* #undef _GLIBCXX_HAVE__FINITEL */ /* Define to 1 if you have the `_floorf' function. */ /* #undef _GLIBCXX_HAVE__FLOORF */ /* Define to 1 if you have the `_floorl' function. */ /* #undef _GLIBCXX_HAVE__FLOORL */ /* Define to 1 if you have the `_fmodf' function. */ /* #undef _GLIBCXX_HAVE__FMODF */ /* Define to 1 if you have the `_fmodl' function. */ /* #undef _GLIBCXX_HAVE__FMODL */ /* Define to 1 if you have the `_fpclass' function. */ /* #undef _GLIBCXX_HAVE__FPCLASS */ /* Define to 1 if you have the `_frexpf' function. */ /* #undef _GLIBCXX_HAVE__FREXPF */ /* Define to 1 if you have the `_frexpl' function. */ /* #undef _GLIBCXX_HAVE__FREXPL */ /* Define to 1 if you have the `_hypot' function. */ /* #undef _GLIBCXX_HAVE__HYPOT */ /* Define to 1 if you have the `_hypotf' function. */ /* #undef _GLIBCXX_HAVE__HYPOTF */ /* Define to 1 if you have the `_hypotl' function. */ /* #undef _GLIBCXX_HAVE__HYPOTL */ /* Define to 1 if you have the `_isinf' function. */ /* #undef _GLIBCXX_HAVE__ISINF */ /* Define to 1 if you have the `_isinff' function. */ /* #undef _GLIBCXX_HAVE__ISINFF */ /* Define to 1 if you have the `_isinfl' function. */ /* #undef _GLIBCXX_HAVE__ISINFL */ /* Define to 1 if you have the `_isnan' function. */ /* #undef _GLIBCXX_HAVE__ISNAN */ /* Define to 1 if you have the `_isnanf' function. */ /* #undef _GLIBCXX_HAVE__ISNANF */ /* Define to 1 if you have the `_isnanl' function. */ /* #undef _GLIBCXX_HAVE__ISNANL */ /* Define to 1 if you have the `_ldexpf' function. */ /* #undef _GLIBCXX_HAVE__LDEXPF */ /* Define to 1 if you have the `_ldexpl' function. */ /* #undef _GLIBCXX_HAVE__LDEXPL */ /* Define to 1 if you have the `_log10f' function. */ /* #undef _GLIBCXX_HAVE__LOG10F */ /* Define to 1 if you have the `_log10l' function. */ /* #undef _GLIBCXX_HAVE__LOG10L */ /* Define to 1 if you have the `_logf' function. */ /* #undef _GLIBCXX_HAVE__LOGF */ /* Define to 1 if you have the `_logl' function. */ /* #undef _GLIBCXX_HAVE__LOGL */ /* Define to 1 if you have the `_modf' function. */ /* #undef _GLIBCXX_HAVE__MODF */ /* Define to 1 if you have the `_modff' function. */ /* #undef _GLIBCXX_HAVE__MODFF */ /* Define to 1 if you have the `_modfl' function. */ /* #undef _GLIBCXX_HAVE__MODFL */ /* Define to 1 if you have the `_powf' function. */ /* #undef _GLIBCXX_HAVE__POWF */ /* Define to 1 if you have the `_powl' function. */ /* #undef _GLIBCXX_HAVE__POWL */ /* Define to 1 if you have the `_qfpclass' function. */ /* #undef _GLIBCXX_HAVE__QFPCLASS */ /* Define to 1 if you have the `_sincos' function. */ /* #undef _GLIBCXX_HAVE__SINCOS */ /* Define to 1 if you have the `_sincosf' function. */ /* #undef _GLIBCXX_HAVE__SINCOSF */ /* Define to 1 if you have the `_sincosl' function. */ /* #undef _GLIBCXX_HAVE__SINCOSL */ /* Define to 1 if you have the `_sinf' function. */ /* #undef _GLIBCXX_HAVE__SINF */ /* Define to 1 if you have the `_sinhf' function. */ /* #undef _GLIBCXX_HAVE__SINHF */ /* Define to 1 if you have the `_sinhl' function. */ /* #undef _GLIBCXX_HAVE__SINHL */ /* Define to 1 if you have the `_sinl' function. */ /* #undef _GLIBCXX_HAVE__SINL */ /* Define to 1 if you have the `_sqrtf' function. */ /* #undef _GLIBCXX_HAVE__SQRTF */ /* Define to 1 if you have the `_sqrtl' function. */ /* #undef _GLIBCXX_HAVE__SQRTL */ /* Define to 1 if you have the `_tanf' function. */ /* #undef _GLIBCXX_HAVE__TANF */ /* Define to 1 if you have the `_tanhf' function. */ /* #undef _GLIBCXX_HAVE__TANHF */ /* Define to 1 if you have the `_tanhl' function. */ /* #undef _GLIBCXX_HAVE__TANHL */ /* Define to 1 if you have the `_tanl' function. */ /* #undef _GLIBCXX_HAVE__TANL */ /* Define to 1 if you have the `__cxa_thread_atexit' function. */ /* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT */ /* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */ #define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1 /* Define as const if the declaration of iconv() needs const. */ #define _GLIBCXX_ICONV_CONST /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Name of package */ /* #undef _GLIBCXX_PACKAGE */ /* Define to the address where bug reports for this package should be sent. */ #define _GLIBCXX_PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define _GLIBCXX_PACKAGE_NAME "package-unused" /* Define to the full name and version of this package. */ #define _GLIBCXX_PACKAGE_STRING "package-unused version-unused" /* Define to the one symbol short name of this package. */ #define _GLIBCXX_PACKAGE_TARNAME "libstdc++" /* Define to the home page for this package. */ #define _GLIBCXX_PACKAGE_URL "" /* Define to the version of this package. */ #define _GLIBCXX_PACKAGE__GLIBCXX_VERSION "version-unused" /* The size of `char', as computed by sizeof. */ /* #undef SIZEOF_CHAR */ /* The size of `int', as computed by sizeof. */ /* #undef SIZEOF_INT */ /* The size of `long', as computed by sizeof. */ /* #undef SIZEOF_LONG */ /* The size of `short', as computed by sizeof. */ /* #undef SIZEOF_SHORT */ /* The size of `void *', as computed by sizeof. */ /* #undef SIZEOF_VOID_P */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ /* #undef _GLIBCXX_VERSION */ /* Number of bits in a file offset, on hosts where this is settable. */ #define _GLIBCXX_FILE_OFFSET_BITS 64 /* Define if C99 functions in <complex.h> should be used in <complex> for C++11. Using compiler builtins for these functions requires corresponding C99 library functions to be present. */ #define _GLIBCXX11_USE_C99_COMPLEX 1 /* Define if C99 functions or macros in <math.h> should be imported in <cmath> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_MATH 1 /* Define if C99 functions or macros in <stdio.h> should be imported in <cstdio> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_STDIO 1 /* Define if C99 functions or macros in <stdlib.h> should be imported in <cstdlib> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_STDLIB 1 /* Define if C99 functions or macros in <wchar.h> should be imported in <cwchar> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_WCHAR 1 /* Define if C99 functions in <complex.h> should be used in <complex> for C++98. Using compiler builtins for these functions requires corresponding C99 library functions to be present. */ #define _GLIBCXX98_USE_C99_COMPLEX 1 /* Define if C99 functions or macros in <math.h> should be imported in <cmath> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_MATH 1 /* Define if C99 functions or macros in <stdio.h> should be imported in <cstdio> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_STDIO 1 /* Define if C99 functions or macros in <stdlib.h> should be imported in <cstdlib> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_STDLIB 1 /* Define if C99 functions or macros in <wchar.h> should be imported in <cwchar> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_WCHAR 1 /* Define if the compiler supports C++11 atomics. */ #define _GLIBCXX_ATOMIC_BUILTINS 1 /* Define to use concept checking code from the boost libraries. */ /* #undef _GLIBCXX_CONCEPT_CHECKS */ /* Define to 1 if a fully dynamic basic_string is wanted, 0 to disable, undefined for platform defaults */ #define _GLIBCXX_FULLY_DYNAMIC_STRING 0 /* Define if gthreads library is available. */ #define _GLIBCXX_HAS_GTHREADS 1 /* Define to 1 if a full hosted library is built, or 0 if freestanding. */ #define _GLIBCXX_HOSTED 1 /* Define if compatibility should be provided for -mlong-double-64. */ /* Define to the letter to which size_t is mangled. */ #define _GLIBCXX_MANGLE_SIZE_T j /* Define if C99 llrint and llround functions are missing from <math.h>. */ /* #undef _GLIBCXX_NO_C99_ROUNDING_FUNCS */ /* Define if ptrdiff_t is int. */ #define _GLIBCXX_PTRDIFF_T_IS_INT 1 /* Define if using setrlimit to set resource limits during "make check" */ #define _GLIBCXX_RES_LIMITS 1 /* Define if size_t is unsigned int. */ #define _GLIBCXX_SIZE_T_IS_UINT 1 /* Define to the value of the EOF integer constant. */ #define _GLIBCXX_STDIO_EOF -1 /* Define to the value of the SEEK_CUR integer constant. */ #define _GLIBCXX_STDIO_SEEK_CUR 1 /* Define to the value of the SEEK_END integer constant. */ #define _GLIBCXX_STDIO_SEEK_END 2 /* Define to use symbol versioning in the shared library. */ #define _GLIBCXX_SYMVER 1 /* Define to use darwin versioning in the shared library. */ /* #undef _GLIBCXX_SYMVER_DARWIN */ /* Define to use GNU versioning in the shared library. */ #define _GLIBCXX_SYMVER_GNU 1 /* Define to use GNU namespace versioning in the shared library. */ /* #undef _GLIBCXX_SYMVER_GNU_NAMESPACE */ /* Define to use Sun versioning in the shared library. */ /* #undef _GLIBCXX_SYMVER_SUN */ /* Define if C11 functions in <uchar.h> should be imported into namespace std in <cuchar>. */ #define _GLIBCXX_USE_C11_UCHAR_CXX11 1 /* Define if C99 functions or macros from <wchar.h>, <math.h>, <complex.h>, <stdio.h>, and <stdlib.h> can be used or exposed. */ #define _GLIBCXX_USE_C99 1 /* Define if C99 functions in <complex.h> should be used in <tr1/complex>. Using compiler builtins for these functions requires corresponding C99 library functions to be present. */ #define _GLIBCXX_USE_C99_COMPLEX_TR1 1 /* Define if C99 functions in <ctype.h> should be imported in <tr1/cctype> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_CTYPE_TR1 1 /* Define if C99 functions in <fenv.h> should be imported in <tr1/cfenv> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_FENV_TR1 1 /* Define if C99 functions in <inttypes.h> should be imported in <tr1/cinttypes> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_INTTYPES_TR1 1 /* Define if wchar_t C99 functions in <inttypes.h> should be imported in <tr1/cinttypes> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1 1 /* Define if C99 functions or macros in <math.h> should be imported in <tr1/cmath> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_MATH_TR1 1 /* Define if C99 types in <stdint.h> should be imported in <tr1/cstdint> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_STDINT_TR1 1 /* Defined if clock_gettime syscall has monotonic and realtime clock support. */ /* #undef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL */ /* Defined if clock_gettime has monotonic clock support. */ #define _GLIBCXX_USE_CLOCK_MONOTONIC 1 /* Defined if clock_gettime has realtime clock support. */ #define _GLIBCXX_USE_CLOCK_REALTIME 1 /* Define if ISO/IEC TR 24733 decimal floating point types are supported on this host. */ #define _GLIBCXX_USE_DECIMAL_FLOAT 1 /* Define if fchmod is available in <sys/stat.h>. */ #define _GLIBCXX_USE_FCHMOD 1 /* Define if fchmodat is available in <sys/stat.h>. */ #define _GLIBCXX_USE_FCHMODAT 1 /* Defined if gettimeofday is available. */ #define _GLIBCXX_USE_GETTIMEOFDAY 1 /* Define if get_nprocs is available in <sys/sysinfo.h>. */ #define _GLIBCXX_USE_GET_NPROCS 1 /* Define if __int128 is supported on this host. */ /* #undef _GLIBCXX_USE_INT128 */ /* Define if LFS support is available. */ #define _GLIBCXX_USE_LFS 1 /* Define if code specialized for long long should be used. */ #define _GLIBCXX_USE_LONG_LONG 1 /* Defined if nanosleep is available. */ #define _GLIBCXX_USE_NANOSLEEP 1 /* Define if NLS translations are to be used. */ #define _GLIBCXX_USE_NLS 1 /* Define if pthreads_num_processors_np is available in <pthread.h>. */ /* #undef _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP */ /* Define if POSIX read/write locks are available in <gthr.h>. */ #define _GLIBCXX_USE_PTHREAD_RWLOCK_T 1 /* Define if /dev/random and /dev/urandom are available for the random_device of TR1 (Chapter 5.1). */ #define _GLIBCXX_USE_RANDOM_TR1 1 /* Define if usable realpath is available in <stdlib.h>. */ #define _GLIBCXX_USE_REALPATH 1 /* Defined if sched_yield is available. */ #define _GLIBCXX_USE_SCHED_YIELD 1 /* Define if _SC_NPROCESSORS_ONLN is available in <unistd.h>. */ #define _GLIBCXX_USE_SC_NPROCESSORS_ONLN 1 /* Define if _SC_NPROC_ONLN is available in <unistd.h>. */ /* #undef _GLIBCXX_USE_SC_NPROC_ONLN */ /* Define if sendfile is available in <sys/sendfile.h>. */ #define _GLIBCXX_USE_SENDFILE 1 /* Define if struct stat has timespec members. */ #define _GLIBCXX_USE_ST_MTIM 1 /* Define if sysctl(), CTL_HW and HW_NCPU are available in <sys/sysctl.h>. */ /* #undef _GLIBCXX_USE_SYSCTL_HW_NCPU */ /* Define if obsolescent tmpnam is available in <stdio.h>. */ #define _GLIBCXX_USE_TMPNAM 1 /* Define if utimensat and UTIME_OMIT are available in <sys/stat.h> and AT_FDCWD in <fcntl.h>. */ #define _GLIBCXX_USE_UTIMENSAT 1 /* Define if code specialized for wchar_t should be used. */ #define _GLIBCXX_USE_WCHAR_T 1 /* Define to 1 if a verbose library is built, or 0 otherwise. */ #define _GLIBCXX_VERBOSE 1 /* Defined if as can handle rdrand. */ #define _GLIBCXX_X86_RDRAND 1 /* Define to 1 if mutex_timedlock is available. */ #define _GTHREAD_USE_MUTEX_TIMEDLOCK 1 /* Define for large files, on AIX-style hosts. */ /* #undef _GLIBCXX_LARGE_FILES */ /* Define if all C++11 floating point overloads are available in <math.h>. */ #if __cplusplus >= 201103L /* #undef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP */ #endif /* Define if all C++11 integral type overloads are available in <math.h>. */ #if __cplusplus >= 201103L /* #undef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT */ #endif #if defined (_GLIBCXX_HAVE__ACOSF) && ! defined (_GLIBCXX_HAVE_ACOSF) # define _GLIBCXX_HAVE_ACOSF 1 # define acosf _acosf #endif #if defined (_GLIBCXX_HAVE__ACOSL) && ! defined (_GLIBCXX_HAVE_ACOSL) # define _GLIBCXX_HAVE_ACOSL 1 # define acosl _acosl #endif #if defined (_GLIBCXX_HAVE__ASINF) && ! defined (_GLIBCXX_HAVE_ASINF) # define _GLIBCXX_HAVE_ASINF 1 # define asinf _asinf #endif #if defined (_GLIBCXX_HAVE__ASINL) && ! defined (_GLIBCXX_HAVE_ASINL) # define _GLIBCXX_HAVE_ASINL 1 # define asinl _asinl #endif #if defined (_GLIBCXX_HAVE__ATAN2F) && ! defined (_GLIBCXX_HAVE_ATAN2F) # define _GLIBCXX_HAVE_ATAN2F 1 # define atan2f _atan2f #endif #if defined (_GLIBCXX_HAVE__ATAN2L) && ! defined (_GLIBCXX_HAVE_ATAN2L) # define _GLIBCXX_HAVE_ATAN2L 1 # define atan2l _atan2l #endif #if defined (_GLIBCXX_HAVE__ATANF) && ! defined (_GLIBCXX_HAVE_ATANF) # define _GLIBCXX_HAVE_ATANF 1 # define atanf _atanf #endif #if defined (_GLIBCXX_HAVE__ATANL) && ! defined (_GLIBCXX_HAVE_ATANL) # define _GLIBCXX_HAVE_ATANL 1 # define atanl _atanl #endif #if defined (_GLIBCXX_HAVE__CEILF) && ! defined (_GLIBCXX_HAVE_CEILF) # define _GLIBCXX_HAVE_CEILF 1 # define ceilf _ceilf #endif #if defined (_GLIBCXX_HAVE__CEILL) && ! defined (_GLIBCXX_HAVE_CEILL) # define _GLIBCXX_HAVE_CEILL 1 # define ceill _ceill #endif #if defined (_GLIBCXX_HAVE__COSF) && ! defined (_GLIBCXX_HAVE_COSF) # define _GLIBCXX_HAVE_COSF 1 # define cosf _cosf #endif #if defined (_GLIBCXX_HAVE__COSHF) && ! defined (_GLIBCXX_HAVE_COSHF) # define _GLIBCXX_HAVE_COSHF 1 # define coshf _coshf #endif #if defined (_GLIBCXX_HAVE__COSHL) && ! defined (_GLIBCXX_HAVE_COSHL) # define _GLIBCXX_HAVE_COSHL 1 # define coshl _coshl #endif #if defined (_GLIBCXX_HAVE__COSL) && ! defined (_GLIBCXX_HAVE_COSL) # define _GLIBCXX_HAVE_COSL 1 # define cosl _cosl #endif #if defined (_GLIBCXX_HAVE__EXPF) && ! defined (_GLIBCXX_HAVE_EXPF) # define _GLIBCXX_HAVE_EXPF 1 # define expf _expf #endif #if defined (_GLIBCXX_HAVE__EXPL) && ! defined (_GLIBCXX_HAVE_EXPL) # define _GLIBCXX_HAVE_EXPL 1 # define expl _expl #endif #if defined (_GLIBCXX_HAVE__FABSF) && ! defined (_GLIBCXX_HAVE_FABSF) # define _GLIBCXX_HAVE_FABSF 1 # define fabsf _fabsf #endif #if defined (_GLIBCXX_HAVE__FABSL) && ! defined (_GLIBCXX_HAVE_FABSL) # define _GLIBCXX_HAVE_FABSL 1 # define fabsl _fabsl #endif #if defined (_GLIBCXX_HAVE__FINITE) && ! defined (_GLIBCXX_HAVE_FINITE) # define _GLIBCXX_HAVE_FINITE 1 # define finite _finite #endif #if defined (_GLIBCXX_HAVE__FINITEF) && ! defined (_GLIBCXX_HAVE_FINITEF) # define _GLIBCXX_HAVE_FINITEF 1 # define finitef _finitef #endif #if defined (_GLIBCXX_HAVE__FINITEL) && ! defined (_GLIBCXX_HAVE_FINITEL) # define _GLIBCXX_HAVE_FINITEL 1 # define finitel _finitel #endif #if defined (_GLIBCXX_HAVE__FLOORF) && ! defined (_GLIBCXX_HAVE_FLOORF) # define _GLIBCXX_HAVE_FLOORF 1 # define floorf _floorf #endif #if defined (_GLIBCXX_HAVE__FLOORL) && ! defined (_GLIBCXX_HAVE_FLOORL) # define _GLIBCXX_HAVE_FLOORL 1 # define floorl _floorl #endif #if defined (_GLIBCXX_HAVE__FMODF) && ! defined (_GLIBCXX_HAVE_FMODF) # define _GLIBCXX_HAVE_FMODF 1 # define fmodf _fmodf #endif #if defined (_GLIBCXX_HAVE__FMODL) && ! defined (_GLIBCXX_HAVE_FMODL) # define _GLIBCXX_HAVE_FMODL 1 # define fmodl _fmodl #endif #if defined (_GLIBCXX_HAVE__FPCLASS) && ! defined (_GLIBCXX_HAVE_FPCLASS) # define _GLIBCXX_HAVE_FPCLASS 1 # define fpclass _fpclass #endif #if defined (_GLIBCXX_HAVE__FREXPF) && ! defined (_GLIBCXX_HAVE_FREXPF) # define _GLIBCXX_HAVE_FREXPF 1 # define frexpf _frexpf #endif #if defined (_GLIBCXX_HAVE__FREXPL) && ! defined (_GLIBCXX_HAVE_FREXPL) # define _GLIBCXX_HAVE_FREXPL 1 # define frexpl _frexpl #endif #if defined (_GLIBCXX_HAVE__HYPOT) && ! defined (_GLIBCXX_HAVE_HYPOT) # define _GLIBCXX_HAVE_HYPOT 1 # define hypot _hypot #endif #if defined (_GLIBCXX_HAVE__HYPOTF) && ! defined (_GLIBCXX_HAVE_HYPOTF) # define _GLIBCXX_HAVE_HYPOTF 1 # define hypotf _hypotf #endif #if defined (_GLIBCXX_HAVE__HYPOTL) && ! defined (_GLIBCXX_HAVE_HYPOTL) # define _GLIBCXX_HAVE_HYPOTL 1 # define hypotl _hypotl #endif #if defined (_GLIBCXX_HAVE__ISINF) && ! defined (_GLIBCXX_HAVE_ISINF) # define _GLIBCXX_HAVE_ISINF 1 # define isinf _isinf #endif #if defined (_GLIBCXX_HAVE__ISINFF) && ! defined (_GLIBCXX_HAVE_ISINFF) # define _GLIBCXX_HAVE_ISINFF 1 # define isinff _isinff #endif #if defined (_GLIBCXX_HAVE__ISINFL) && ! defined (_GLIBCXX_HAVE_ISINFL) # define _GLIBCXX_HAVE_ISINFL 1 # define isinfl _isinfl #endif #if defined (_GLIBCXX_HAVE__ISNAN) && ! defined (_GLIBCXX_HAVE_ISNAN) # define _GLIBCXX_HAVE_ISNAN 1 # define isnan _isnan #endif #if defined (_GLIBCXX_HAVE__ISNANF) && ! defined (_GLIBCXX_HAVE_ISNANF) # define _GLIBCXX_HAVE_ISNANF 1 # define isnanf _isnanf #endif #if defined (_GLIBCXX_HAVE__ISNANL) && ! defined (_GLIBCXX_HAVE_ISNANL) # define _GLIBCXX_HAVE_ISNANL 1 # define isnanl _isnanl #endif #if defined (_GLIBCXX_HAVE__LDEXPF) && ! defined (_GLIBCXX_HAVE_LDEXPF) # define _GLIBCXX_HAVE_LDEXPF 1 # define ldexpf _ldexpf #endif #if defined (_GLIBCXX_HAVE__LDEXPL) && ! defined (_GLIBCXX_HAVE_LDEXPL) # define _GLIBCXX_HAVE_LDEXPL 1 # define ldexpl _ldexpl #endif #if defined (_GLIBCXX_HAVE__LOG10F) && ! defined (_GLIBCXX_HAVE_LOG10F) # define _GLIBCXX_HAVE_LOG10F 1 # define log10f _log10f #endif #if defined (_GLIBCXX_HAVE__LOG10L) && ! defined (_GLIBCXX_HAVE_LOG10L) # define _GLIBCXX_HAVE_LOG10L 1 # define log10l _log10l #endif #if defined (_GLIBCXX_HAVE__LOGF) && ! defined (_GLIBCXX_HAVE_LOGF) # define _GLIBCXX_HAVE_LOGF 1 # define logf _logf #endif #if defined (_GLIBCXX_HAVE__LOGL) && ! defined (_GLIBCXX_HAVE_LOGL) # define _GLIBCXX_HAVE_LOGL 1 # define logl _logl #endif #if defined (_GLIBCXX_HAVE__MODF) && ! defined (_GLIBCXX_HAVE_MODF) # define _GLIBCXX_HAVE_MODF 1 # define modf _modf #endif #if defined (_GLIBCXX_HAVE__MODFF) && ! defined (_GLIBCXX_HAVE_MODFF) # define _GLIBCXX_HAVE_MODFF 1 # define modff _modff #endif #if defined (_GLIBCXX_HAVE__MODFL) && ! defined (_GLIBCXX_HAVE_MODFL) # define _GLIBCXX_HAVE_MODFL 1 # define modfl _modfl #endif #if defined (_GLIBCXX_HAVE__POWF) && ! defined (_GLIBCXX_HAVE_POWF) # define _GLIBCXX_HAVE_POWF 1 # define powf _powf #endif #if defined (_GLIBCXX_HAVE__POWL) && ! defined (_GLIBCXX_HAVE_POWL) # define _GLIBCXX_HAVE_POWL 1 # define powl _powl #endif #if defined (_GLIBCXX_HAVE__QFPCLASS) && ! defined (_GLIBCXX_HAVE_QFPCLASS) # define _GLIBCXX_HAVE_QFPCLASS 1 # define qfpclass _qfpclass #endif #if defined (_GLIBCXX_HAVE__SINCOS) && ! defined (_GLIBCXX_HAVE_SINCOS) # define _GLIBCXX_HAVE_SINCOS 1 # define sincos _sincos #endif #if defined (_GLIBCXX_HAVE__SINCOSF) && ! defined (_GLIBCXX_HAVE_SINCOSF) # define _GLIBCXX_HAVE_SINCOSF 1 # define sincosf _sincosf #endif #if defined (_GLIBCXX_HAVE__SINCOSL) && ! defined (_GLIBCXX_HAVE_SINCOSL) # define _GLIBCXX_HAVE_SINCOSL 1 # define sincosl _sincosl #endif #if defined (_GLIBCXX_HAVE__SINF) && ! defined (_GLIBCXX_HAVE_SINF) # define _GLIBCXX_HAVE_SINF 1 # define sinf _sinf #endif #if defined (_GLIBCXX_HAVE__SINHF) && ! defined (_GLIBCXX_HAVE_SINHF) # define _GLIBCXX_HAVE_SINHF 1 # define sinhf _sinhf #endif #if defined (_GLIBCXX_HAVE__SINHL) && ! defined (_GLIBCXX_HAVE_SINHL) # define _GLIBCXX_HAVE_SINHL 1 # define sinhl _sinhl #endif #if defined (_GLIBCXX_HAVE__SINL) && ! defined (_GLIBCXX_HAVE_SINL) # define _GLIBCXX_HAVE_SINL 1 # define sinl _sinl #endif #if defined (_GLIBCXX_HAVE__SQRTF) && ! defined (_GLIBCXX_HAVE_SQRTF) # define _GLIBCXX_HAVE_SQRTF 1 # define sqrtf _sqrtf #endif #if defined (_GLIBCXX_HAVE__SQRTL) && ! defined (_GLIBCXX_HAVE_SQRTL) # define _GLIBCXX_HAVE_SQRTL 1 # define sqrtl _sqrtl #endif #if defined (_GLIBCXX_HAVE__STRTOF) && ! defined (_GLIBCXX_HAVE_STRTOF) # define _GLIBCXX_HAVE_STRTOF 1 # define strtof _strtof #endif #if defined (_GLIBCXX_HAVE__STRTOLD) && ! defined (_GLIBCXX_HAVE_STRTOLD) # define _GLIBCXX_HAVE_STRTOLD 1 # define strtold _strtold #endif #if defined (_GLIBCXX_HAVE__TANF) && ! defined (_GLIBCXX_HAVE_TANF) # define _GLIBCXX_HAVE_TANF 1 # define tanf _tanf #endif #if defined (_GLIBCXX_HAVE__TANHF) && ! defined (_GLIBCXX_HAVE_TANHF) # define _GLIBCXX_HAVE_TANHF 1 # define tanhf _tanhf #endif #if defined (_GLIBCXX_HAVE__TANHL) && ! defined (_GLIBCXX_HAVE_TANHL) # define _GLIBCXX_HAVE_TANHL 1 # define tanhl _tanhl #endif #if defined (_GLIBCXX_HAVE__TANL) && ! defined (_GLIBCXX_HAVE_TANL) # define _GLIBCXX_HAVE_TANL 1 # define tanl _tanl #endif #endif // _GLIBCXX_CXX_CONFIG_H c++/8/x86_64-redhat-linux/32/bits/gthr-single.h 0000644 00000015230 15146341150 0014405 0 ustar 00 /* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _GLIBCXX_GCC_GTHR_SINGLE_H #define _GLIBCXX_GCC_GTHR_SINGLE_H /* Just provide compatibility for mutex handling. */ typedef int __gthread_key_t; typedef int __gthread_once_t; typedef int __gthread_mutex_t; typedef int __gthread_recursive_mutex_t; #define __GTHREAD_ONCE_INIT 0 #define __GTHREAD_MUTEX_INIT 0 #define __GTHREAD_MUTEX_INIT_FUNCTION(mx) do {} while (0) #define __GTHREAD_RECURSIVE_MUTEX_INIT 0 #define _GLIBCXX_UNUSED __attribute__((__unused__)) #ifdef _LIBOBJC /* Thread local storage for a single thread */ static void *thread_local_storage = NULL; /* Backend initialization functions */ /* Initialize the threads subsystem. */ static inline int __gthread_objc_init_thread_system (void) { /* No thread support available */ return -1; } /* Close the threads subsystem. */ static inline int __gthread_objc_close_thread_system (void) { /* No thread support available */ return -1; } /* Backend thread functions */ /* Create a new thread of execution. */ static inline objc_thread_t __gthread_objc_thread_detach (void (* func)(void *), void * arg _GLIBCXX_UNUSED) { /* No thread support available */ return NULL; } /* Set the current thread's priority. */ static inline int __gthread_objc_thread_set_priority (int priority _GLIBCXX_UNUSED) { /* No thread support available */ return -1; } /* Return the current thread's priority. */ static inline int __gthread_objc_thread_get_priority (void) { return OBJC_THREAD_INTERACTIVE_PRIORITY; } /* Yield our process time to another thread. */ static inline void __gthread_objc_thread_yield (void) { return; } /* Terminate the current thread. */ static inline int __gthread_objc_thread_exit (void) { /* No thread support available */ /* Should we really exit the program */ /* exit (&__objc_thread_exit_status); */ return -1; } /* Returns an integer value which uniquely describes a thread. */ static inline objc_thread_t __gthread_objc_thread_id (void) { /* No thread support, use 1. */ return (objc_thread_t) 1; } /* Sets the thread's local storage pointer. */ static inline int __gthread_objc_thread_set_data (void *value) { thread_local_storage = value; return 0; } /* Returns the thread's local storage pointer. */ static inline void * __gthread_objc_thread_get_data (void) { return thread_local_storage; } /* Backend mutex functions */ /* Allocate a mutex. */ static inline int __gthread_objc_mutex_allocate (objc_mutex_t mutex _GLIBCXX_UNUSED) { return 0; } /* Deallocate a mutex. */ static inline int __gthread_objc_mutex_deallocate (objc_mutex_t mutex _GLIBCXX_UNUSED) { return 0; } /* Grab a lock on a mutex. */ static inline int __gthread_objc_mutex_lock (objc_mutex_t mutex _GLIBCXX_UNUSED) { /* There can only be one thread, so we always get the lock */ return 0; } /* Try to grab a lock on a mutex. */ static inline int __gthread_objc_mutex_trylock (objc_mutex_t mutex _GLIBCXX_UNUSED) { /* There can only be one thread, so we always get the lock */ return 0; } /* Unlock the mutex */ static inline int __gthread_objc_mutex_unlock (objc_mutex_t mutex _GLIBCXX_UNUSED) { return 0; } /* Backend condition mutex functions */ /* Allocate a condition. */ static inline int __gthread_objc_condition_allocate (objc_condition_t condition _GLIBCXX_UNUSED) { return 0; } /* Deallocate a condition. */ static inline int __gthread_objc_condition_deallocate (objc_condition_t condition _GLIBCXX_UNUSED) { return 0; } /* Wait on the condition */ static inline int __gthread_objc_condition_wait (objc_condition_t condition _GLIBCXX_UNUSED, objc_mutex_t mutex _GLIBCXX_UNUSED) { return 0; } /* Wake up all threads waiting on this condition. */ static inline int __gthread_objc_condition_broadcast (objc_condition_t condition _GLIBCXX_UNUSED) { return 0; } /* Wake up one thread waiting on this condition. */ static inline int __gthread_objc_condition_signal (objc_condition_t condition _GLIBCXX_UNUSED) { return 0; } #else /* _LIBOBJC */ static inline int __gthread_active_p (void) { return 0; } static inline int __gthread_once (__gthread_once_t *__once _GLIBCXX_UNUSED, void (*__func) (void) _GLIBCXX_UNUSED) { return 0; } static inline int _GLIBCXX_UNUSED __gthread_key_create (__gthread_key_t *__key _GLIBCXX_UNUSED, void (*__func) (void *) _GLIBCXX_UNUSED) { return 0; } static int _GLIBCXX_UNUSED __gthread_key_delete (__gthread_key_t __key _GLIBCXX_UNUSED) { return 0; } static inline void * __gthread_getspecific (__gthread_key_t __key _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_setspecific (__gthread_key_t __key _GLIBCXX_UNUSED, const void *__v _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_mutex_destroy (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_mutex_lock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_mutex_trylock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_mutex_unlock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_lock (__mutex); } static inline int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_trylock (__mutex); } static inline int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_unlock (__mutex); } static inline int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_destroy (__mutex); } #endif /* _LIBOBJC */ #undef _GLIBCXX_UNUSED #endif /* ! _GLIBCXX_GCC_GTHR_SINGLE_H */ c++/8/x86_64-redhat-linux/32/bits/messages_members.h 0000644 00000010644 15146341150 0015507 0 ustar 00 // std::messages implementation details, GNU version -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/messages_members.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.2.7.1.2 messages functions // // Written by Benjamin Kosnik <bkoz@redhat.com> #include <libintl.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Non-virtual member functions. template<typename _CharT> messages<_CharT>::messages(size_t __refs) : facet(__refs), _M_c_locale_messages(_S_get_c_locale()), _M_name_messages(_S_get_c_name()) { } template<typename _CharT> messages<_CharT>::messages(__c_locale __cloc, const char* __s, size_t __refs) : facet(__refs), _M_c_locale_messages(0), _M_name_messages(0) { if (__builtin_strcmp(__s, _S_get_c_name()) != 0) { const size_t __len = __builtin_strlen(__s) + 1; char* __tmp = new char[__len]; __builtin_memcpy(__tmp, __s, __len); _M_name_messages = __tmp; } else _M_name_messages = _S_get_c_name(); // Last to avoid leaking memory if new throws. _M_c_locale_messages = _S_clone_c_locale(__cloc); } template<typename _CharT> typename messages<_CharT>::catalog messages<_CharT>::open(const basic_string<char>& __s, const locale& __loc, const char* __dir) const { bindtextdomain(__s.c_str(), __dir); return this->do_open(__s, __loc); } // Virtual member functions. template<typename _CharT> messages<_CharT>::~messages() { if (_M_name_messages != _S_get_c_name()) delete [] _M_name_messages; _S_destroy_c_locale(_M_c_locale_messages); } template<typename _CharT> typename messages<_CharT>::catalog messages<_CharT>::do_open(const basic_string<char>& __s, const locale&) const { // No error checking is done, assume the catalog exists and can // be used. textdomain(__s.c_str()); return 0; } template<typename _CharT> void messages<_CharT>::do_close(catalog) const { } // messages_byname template<typename _CharT> messages_byname<_CharT>::messages_byname(const char* __s, size_t __refs) : messages<_CharT>(__refs) { if (this->_M_name_messages != locale::facet::_S_get_c_name()) { delete [] this->_M_name_messages; if (__builtin_strcmp(__s, locale::facet::_S_get_c_name()) != 0) { const size_t __len = __builtin_strlen(__s) + 1; char* __tmp = new char[__len]; __builtin_memcpy(__tmp, __s, __len); this->_M_name_messages = __tmp; } else this->_M_name_messages = locale::facet::_S_get_c_name(); } if (__builtin_strcmp(__s, "C") != 0 && __builtin_strcmp(__s, "POSIX") != 0) { this->_S_destroy_c_locale(this->_M_c_locale_messages); this->_S_create_c_locale(this->_M_c_locale_messages, __s); } } //Specializations. template<> typename messages<char>::catalog messages<char>::do_open(const basic_string<char>&, const locale&) const; template<> void messages<char>::do_close(catalog) const; #ifdef _GLIBCXX_USE_WCHAR_T template<> typename messages<wchar_t>::catalog messages<wchar_t>::do_open(const basic_string<char>&, const locale&) const; template<> void messages<wchar_t>::do_close(catalog) const; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/x86_64-redhat-linux/32/bits/c++locale.h 0000644 00000006353 15146341150 0013720 0 ustar 00 // Wrapper for underlying C-language localization -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/c++locale.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.8 Standard locale categories. // // Written by Benjamin Kosnik <bkoz@redhat.com> #ifndef _GLIBCXX_CXX_LOCALE_H #define _GLIBCXX_CXX_LOCALE_H 1 #pragma GCC system_header #include <clocale> #define _GLIBCXX_C_LOCALE_GNU 1 #define _GLIBCXX_NUM_CATEGORIES 6 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION extern "C" __typeof(uselocale) __uselocale; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef __locale_t __c_locale; // Convert numeric value of type double and long double to string and // return length of string. If vsnprintf is available use it, otherwise // fall back to the unsafe vsprintf which, in general, can be dangerous // and should be avoided. inline int __convert_from_v(const __c_locale& __cloc __attribute__ ((__unused__)), char* __out, const int __size __attribute__ ((__unused__)), const char* __fmt, ...) { #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) __c_locale __old = __gnu_cxx::__uselocale(__cloc); #else char* __old = std::setlocale(LC_NUMERIC, 0); char* __sav = 0; if (__builtin_strcmp(__old, "C")) { const size_t __len = __builtin_strlen(__old) + 1; __sav = new char[__len]; __builtin_memcpy(__sav, __old, __len); std::setlocale(LC_NUMERIC, "C"); } #endif __builtin_va_list __args; __builtin_va_start(__args, __fmt); #if _GLIBCXX_USE_C99_STDIO const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args); #else const int __ret = __builtin_vsprintf(__out, __fmt, __args); #endif __builtin_va_end(__args); #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) __gnu_cxx::__uselocale(__old); #else if (__sav) { std::setlocale(LC_NUMERIC, __sav); delete [] __sav; } #endif return __ret; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/x86_64-redhat-linux/32/bits/c++allocator.h 0000644 00000003673 15146341150 0014443 0 ustar 00 // Base to std::allocator -*- C++ -*- // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/c++allocator.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _GLIBCXX_CXX_ALLOCATOR_H #define _GLIBCXX_CXX_ALLOCATOR_H 1 #include <ext/new_allocator.h> #if __cplusplus >= 201103L namespace std { /** * @brief An alias to the base class for std::allocator. * @ingroup allocators * * Used to set the std::allocator base class to * __gnu_cxx::new_allocator. * * @tparam _Tp Type of allocated object. */ template<typename _Tp> using __allocator_base = __gnu_cxx::new_allocator<_Tp>; } #else // Define new_allocator as the base class to std::allocator. # define __allocator_base __gnu_cxx::new_allocator #endif #if defined(__SANITIZE_ADDRESS__) && !defined(_GLIBCXX_SANITIZE_STD_ALLOCATOR) # define _GLIBCXX_SANITIZE_STD_ALLOCATOR 1 #endif #endif c++/8/x86_64-redhat-linux/32/bits/gthr.h 0000644 00000012750 15146341150 0013132 0 ustar 00 /* Threads compatibility routines for libgcc2. */ /* Compile this one with gcc. */ /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _GLIBCXX_GCC_GTHR_H #define _GLIBCXX_GCC_GTHR_H #ifndef _GLIBCXX_HIDE_EXPORTS #pragma GCC visibility push(default) #endif /* If this file is compiled with threads support, it must #define __GTHREADS 1 to indicate that threads support is present. Also it has define function int __gthread_active_p () that returns 1 if thread system is active, 0 if not. The threads interface must define the following types: __gthread_key_t __gthread_once_t __gthread_mutex_t __gthread_recursive_mutex_t The threads interface must define the following macros: __GTHREAD_ONCE_INIT to initialize __gthread_once_t __GTHREAD_MUTEX_INIT to initialize __gthread_mutex_t to get a fast non-recursive mutex. __GTHREAD_MUTEX_INIT_FUNCTION to initialize __gthread_mutex_t to get a fast non-recursive mutex. Define this to a function which looks like this: void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *) Some systems can't initialize a mutex without a function call. Don't define __GTHREAD_MUTEX_INIT in this case. __GTHREAD_RECURSIVE_MUTEX_INIT __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION as above, but for a recursive mutex. The threads interface must define the following static functions: int __gthread_once (__gthread_once_t *once, void (*func) ()) int __gthread_key_create (__gthread_key_t *keyp, void (*dtor) (void *)) int __gthread_key_delete (__gthread_key_t key) void *__gthread_getspecific (__gthread_key_t key) int __gthread_setspecific (__gthread_key_t key, const void *ptr) int __gthread_mutex_destroy (__gthread_mutex_t *mutex); int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *mutex); int __gthread_mutex_lock (__gthread_mutex_t *mutex); int __gthread_mutex_trylock (__gthread_mutex_t *mutex); int __gthread_mutex_unlock (__gthread_mutex_t *mutex); int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex); int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex); int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex); The following are supported in POSIX threads only. They are required to fix a deadlock in static initialization inside libsupc++. The header file gthr-posix.h defines a symbol __GTHREAD_HAS_COND to signify that these extra features are supported. Types: __gthread_cond_t Macros: __GTHREAD_COND_INIT __GTHREAD_COND_INIT_FUNCTION Interface: int __gthread_cond_broadcast (__gthread_cond_t *cond); int __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex); int __gthread_cond_wait_recursive (__gthread_cond_t *cond, __gthread_recursive_mutex_t *mutex); All functions returning int should return zero on success or the error number. If the operation is not supported, -1 is returned. If the following are also defined, you should #define __GTHREADS_CXX0X 1 to enable the c++0x thread library. Types: __gthread_t __gthread_time_t Interface: int __gthread_create (__gthread_t *thread, void *(*func) (void*), void *args); int __gthread_join (__gthread_t thread, void **value_ptr); int __gthread_detach (__gthread_t thread); int __gthread_equal (__gthread_t t1, __gthread_t t2); __gthread_t __gthread_self (void); int __gthread_yield (void); int __gthread_mutex_timedlock (__gthread_mutex_t *m, const __gthread_time_t *abs_timeout); int __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *m, const __gthread_time_t *abs_time); int __gthread_cond_signal (__gthread_cond_t *cond); int __gthread_cond_timedwait (__gthread_cond_t *cond, __gthread_mutex_t *mutex, const __gthread_time_t *abs_timeout); */ #if __GXX_WEAK__ /* The pe-coff weak support isn't fully compatible to ELF's weak. For static libraries it might would work, but as we need to deal with shared versions too, we disable it for mingw-targets. */ #ifdef __MINGW32__ #undef _GLIBCXX_GTHREAD_USE_WEAK #define _GLIBCXX_GTHREAD_USE_WEAK 0 #endif #ifndef _GLIBCXX_GTHREAD_USE_WEAK #define _GLIBCXX_GTHREAD_USE_WEAK 1 #endif #endif #include <bits/gthr-default.h> #ifndef _GLIBCXX_HIDE_EXPORTS #pragma GCC visibility pop #endif #endif /* ! _GLIBCXX_GCC_GTHR_H */ c++/8/x86_64-redhat-linux/32/bits/error_constants.h 0000644 00000012067 15146341150 0015414 0 ustar 00 // Specific definitions for generic platforms -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/error_constants.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{system_error} */ #ifndef _GLIBCXX_ERROR_CONSTANTS #define _GLIBCXX_ERROR_CONSTANTS 1 #include <bits/c++config.h> #include <cerrno> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION enum class errc { address_family_not_supported = EAFNOSUPPORT, address_in_use = EADDRINUSE, address_not_available = EADDRNOTAVAIL, already_connected = EISCONN, argument_list_too_long = E2BIG, argument_out_of_domain = EDOM, bad_address = EFAULT, bad_file_descriptor = EBADF, #ifdef _GLIBCXX_HAVE_EBADMSG bad_message = EBADMSG, #endif broken_pipe = EPIPE, connection_aborted = ECONNABORTED, connection_already_in_progress = EALREADY, connection_refused = ECONNREFUSED, connection_reset = ECONNRESET, cross_device_link = EXDEV, destination_address_required = EDESTADDRREQ, device_or_resource_busy = EBUSY, directory_not_empty = ENOTEMPTY, executable_format_error = ENOEXEC, file_exists = EEXIST, file_too_large = EFBIG, filename_too_long = ENAMETOOLONG, function_not_supported = ENOSYS, host_unreachable = EHOSTUNREACH, #ifdef _GLIBCXX_HAVE_EIDRM identifier_removed = EIDRM, #endif illegal_byte_sequence = EILSEQ, inappropriate_io_control_operation = ENOTTY, interrupted = EINTR, invalid_argument = EINVAL, invalid_seek = ESPIPE, io_error = EIO, is_a_directory = EISDIR, message_size = EMSGSIZE, network_down = ENETDOWN, network_reset = ENETRESET, network_unreachable = ENETUNREACH, no_buffer_space = ENOBUFS, no_child_process = ECHILD, #ifdef _GLIBCXX_HAVE_ENOLINK no_link = ENOLINK, #endif no_lock_available = ENOLCK, #ifdef _GLIBCXX_HAVE_ENODATA no_message_available = ENODATA, #endif no_message = ENOMSG, no_protocol_option = ENOPROTOOPT, no_space_on_device = ENOSPC, #ifdef _GLIBCXX_HAVE_ENOSR no_stream_resources = ENOSR, #endif no_such_device_or_address = ENXIO, no_such_device = ENODEV, no_such_file_or_directory = ENOENT, no_such_process = ESRCH, not_a_directory = ENOTDIR, not_a_socket = ENOTSOCK, #ifdef _GLIBCXX_HAVE_ENOSTR not_a_stream = ENOSTR, #endif not_connected = ENOTCONN, not_enough_memory = ENOMEM, #ifdef _GLIBCXX_HAVE_ENOTSUP not_supported = ENOTSUP, #endif #ifdef _GLIBCXX_HAVE_ECANCELED operation_canceled = ECANCELED, #endif operation_in_progress = EINPROGRESS, operation_not_permitted = EPERM, operation_not_supported = EOPNOTSUPP, operation_would_block = EWOULDBLOCK, #ifdef _GLIBCXX_HAVE_EOWNERDEAD owner_dead = EOWNERDEAD, #endif permission_denied = EACCES, #ifdef _GLIBCXX_HAVE_EPROTO protocol_error = EPROTO, #endif protocol_not_supported = EPROTONOSUPPORT, read_only_file_system = EROFS, resource_deadlock_would_occur = EDEADLK, resource_unavailable_try_again = EAGAIN, result_out_of_range = ERANGE, #ifdef _GLIBCXX_HAVE_ENOTRECOVERABLE state_not_recoverable = ENOTRECOVERABLE, #endif #ifdef _GLIBCXX_HAVE_ETIME stream_timeout = ETIME, #endif #ifdef _GLIBCXX_HAVE_ETXTBSY text_file_busy = ETXTBSY, #endif timed_out = ETIMEDOUT, too_many_files_open_in_system = ENFILE, too_many_files_open = EMFILE, too_many_links = EMLINK, too_many_symbolic_link_levels = ELOOP, #ifdef _GLIBCXX_HAVE_EOVERFLOW value_too_large = EOVERFLOW, #endif wrong_protocol_type = EPROTOTYPE }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/x86_64-redhat-linux/32/bits/gthr-default.h 0000644 00000057255 15146341150 0014565 0 ustar 00 /* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _GLIBCXX_GCC_GTHR_POSIX_H #define _GLIBCXX_GCC_GTHR_POSIX_H /* POSIX threads specific definitions. Easy, since the interface is just one-to-one mapping. */ #define __GTHREADS 1 #define __GTHREADS_CXX0X 1 #include <pthread.h> #if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \ || !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK)) # include <unistd.h> # if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0 # define _GTHREAD_USE_MUTEX_TIMEDLOCK 1 # else # define _GTHREAD_USE_MUTEX_TIMEDLOCK 0 # endif #endif typedef pthread_t __gthread_t; typedef pthread_key_t __gthread_key_t; typedef pthread_once_t __gthread_once_t; typedef pthread_mutex_t __gthread_mutex_t; typedef pthread_mutex_t __gthread_recursive_mutex_t; typedef pthread_cond_t __gthread_cond_t; typedef struct timespec __gthread_time_t; /* POSIX like conditional variables are supported. Please look at comments in gthr.h for details. */ #define __GTHREAD_HAS_COND 1 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP #else #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function #endif #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER #define __GTHREAD_TIME_INIT {0,0} #ifdef _GTHREAD_USE_MUTEX_INIT_FUNC # undef __GTHREAD_MUTEX_INIT #endif #ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC # undef __GTHREAD_RECURSIVE_MUTEX_INIT # undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION # define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function #endif #ifdef _GTHREAD_USE_COND_INIT_FUNC # undef __GTHREAD_COND_INIT # define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function #endif #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK # ifndef __gthrw_pragma # define __gthrw_pragma(pragma) # endif # define __gthrw2(name,name2,type) \ static __typeof(type) name __attribute__ ((__weakref__(#name2))); \ __gthrw_pragma(weak type) # define __gthrw_(name) __gthrw_ ## name #else # define __gthrw2(name,name2,type) # define __gthrw_(name) name #endif /* Typically, __gthrw_foo is a weak reference to symbol foo. */ #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name) __gthrw(pthread_once) __gthrw(pthread_getspecific) __gthrw(pthread_setspecific) __gthrw(pthread_create) __gthrw(pthread_join) __gthrw(pthread_equal) __gthrw(pthread_self) __gthrw(pthread_detach) #ifndef __BIONIC__ __gthrw(pthread_cancel) #endif __gthrw(sched_yield) __gthrw(pthread_mutex_lock) __gthrw(pthread_mutex_trylock) #if _GTHREAD_USE_MUTEX_TIMEDLOCK __gthrw(pthread_mutex_timedlock) #endif __gthrw(pthread_mutex_unlock) __gthrw(pthread_mutex_init) __gthrw(pthread_mutex_destroy) __gthrw(pthread_cond_init) __gthrw(pthread_cond_broadcast) __gthrw(pthread_cond_signal) __gthrw(pthread_cond_wait) __gthrw(pthread_cond_timedwait) __gthrw(pthread_cond_destroy) __gthrw(pthread_key_create) __gthrw(pthread_key_delete) __gthrw(pthread_mutexattr_init) __gthrw(pthread_mutexattr_settype) __gthrw(pthread_mutexattr_destroy) #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) /* Objective-C. */ __gthrw(pthread_exit) #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING __gthrw(sched_get_priority_max) __gthrw(sched_get_priority_min) #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ __gthrw(pthread_attr_destroy) __gthrw(pthread_attr_init) __gthrw(pthread_attr_setdetachstate) #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING __gthrw(pthread_getschedparam) __gthrw(pthread_setschedparam) #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _LIBOBJC || _LIBOBJC_WEAK */ #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if -pthreads is not specified. The functions are dummies and most return an error value. However pthread_once returns 0 without invoking the routine it is passed so we cannot pretend that the interface is active if -pthreads is not specified. On Solaris 2.5.1, the interface is not exposed at all so we need to play the usual game with weak symbols. On Solaris 10 and up, a working interface is always exposed. On FreeBSD 6 and later, libc also exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc, which means the alternate __gthread_active_p below cannot be used there. */ #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) static volatile int __gthread_active = -1; static void __gthread_trigger (void) { __gthread_active = 1; } static inline int __gthread_active_p (void) { static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT; /* Avoid reading __gthread_active twice on the main code path. */ int __gthread_active_latest_value = __gthread_active; /* This test is not protected to avoid taking a lock on the main code path so every update of __gthread_active in a threaded program must be atomic with regard to the result of the test. */ if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { if (__gthrw_(pthread_once)) { /* If this really is a threaded program, then we must ensure that __gthread_active has been set to 1 before exiting this block. */ __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger); __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); } /* Make sure we'll never enter this block again. */ if (__gthread_active < 0) __gthread_active = 0; __gthread_active_latest_value = __gthread_active; } return __gthread_active_latest_value != 0; } #else /* neither FreeBSD nor Solaris */ /* For a program to be multi-threaded the only thing that it certainly must be using is pthread_create. However, there may be other libraries that intercept pthread_create with their own definitions to wrap pthreads functionality for some purpose. In those cases, pthread_create being defined might not necessarily mean that libpthread is actually linked in. For the GNU C library, we can use a known internal name. This is always available in the ABI, but no other library would define it. That is ideal, since any public pthread function might be intercepted just as pthread_create might be. __pthread_key_create is an "internal" implementation symbol, but it is part of the public exported ABI. Also, it's among the symbols that the static libpthread.a always links in whenever pthread_create is used, so there is no danger of a false negative result in any statically-linked, multi-threaded program. For others, we choose pthread_cancel as a function that seems unlikely to be redefined by an interceptor library. The bionic (Android) C library does not provide pthread_cancel, so we do use pthread_create there (and interceptor libraries lose). */ #ifdef __GLIBC__ __gthrw2(__gthrw_(__pthread_key_create), __pthread_key_create, pthread_key_create) # define GTHR_ACTIVE_PROXY __gthrw_(__pthread_key_create) #elif defined (__BIONIC__) # define GTHR_ACTIVE_PROXY __gthrw_(pthread_create) #else # define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel) #endif static inline int __gthread_active_p (void) { static void *const __gthread_active_ptr = __extension__ (void *) >HR_ACTIVE_PROXY; return __gthread_active_ptr != 0; } #endif /* FreeBSD or Solaris */ #else /* not __GXX_WEAK__ */ /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread calls in shared flavors of the HP-UX C library. Most of the stubs have no functionality. The details are described in the "libc cumulative patch" for each subversion of HP-UX 11. There are two special interfaces provided for checking whether an application is linked to a shared pthread library or not. However, these interfaces aren't available in early libpthread libraries. We also need a test that works for archive libraries. We can't use pthread_once as some libc versions call the init function. We also can't use pthread_create or pthread_attr_init as these create a thread and thereby prevent changing the default stack size. The function pthread_default_stacksize_np is available in both the archive and shared versions of libpthread. It can be used to determine the default pthread stack size. There is a stub in some shared libc versions which returns a zero size if pthreads are not active. We provide an equivalent stub to handle cases where libc doesn't provide one. */ #if defined(__hppa__) && defined(__hpux__) static volatile int __gthread_active = -1; static inline int __gthread_active_p (void) { /* Avoid reading __gthread_active twice on the main code path. */ int __gthread_active_latest_value = __gthread_active; size_t __s; if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { pthread_default_stacksize_np (0, &__s); __gthread_active = __s ? 1 : 0; __gthread_active_latest_value = __gthread_active; } return __gthread_active_latest_value != 0; } #else /* not hppa-hpux */ static inline int __gthread_active_p (void) { return 1; } #endif /* hppa-hpux */ #endif /* __GXX_WEAK__ */ #ifdef _LIBOBJC /* This is the config.h file in libobjc/ */ #include <config.h> #ifdef HAVE_SCHED_H # include <sched.h> #endif /* Key structure for maintaining thread specific storage */ static pthread_key_t _objc_thread_storage; static pthread_attr_t _objc_thread_attribs; /* Thread local storage for a single thread */ static void *thread_local_storage = NULL; /* Backend initialization functions */ /* Initialize the threads subsystem. */ static inline int __gthread_objc_init_thread_system (void) { if (__gthread_active_p ()) { /* Initialize the thread storage key. */ if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) { /* The normal default detach state for threads is * PTHREAD_CREATE_JOINABLE which causes threads to not die * when you think they should. */ if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, PTHREAD_CREATE_DETACHED) == 0) return 0; } } return -1; } /* Close the threads subsystem. */ static inline int __gthread_objc_close_thread_system (void) { if (__gthread_active_p () && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) return 0; return -1; } /* Backend thread functions */ /* Create a new thread of execution. */ static inline objc_thread_t __gthread_objc_thread_detach (void (*func)(void *), void *arg) { objc_thread_t thread_id; pthread_t new_thread_handle; if (!__gthread_active_p ()) return NULL; if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs, (void *) func, arg))) thread_id = (objc_thread_t) new_thread_handle; else thread_id = NULL; return thread_id; } /* Set the current thread's priority. */ static inline int __gthread_objc_thread_set_priority (int priority) { if (!__gthread_active_p ()) return -1; else { #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING pthread_t thread_id = __gthrw_(pthread_self) (); int policy; struct sched_param params; int priority_min, priority_max; if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) { if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) return -1; if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) return -1; if (priority > priority_max) priority = priority_max; else if (priority < priority_min) priority = priority_min; params.sched_priority = priority; /* * The solaris 7 and several other man pages incorrectly state that * this should be a pointer to policy but pthread.h is universally * at odds with this. */ if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) return 0; } #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ return -1; } } /* Return the current thread's priority. */ static inline int __gthread_objc_thread_get_priority (void) { #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING if (__gthread_active_p ()) { int policy; struct sched_param params; if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) return params.sched_priority; else return -1; } else #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ return OBJC_THREAD_INTERACTIVE_PRIORITY; } /* Yield our process time to another thread. */ static inline void __gthread_objc_thread_yield (void) { if (__gthread_active_p ()) __gthrw_(sched_yield) (); } /* Terminate the current thread. */ static inline int __gthread_objc_thread_exit (void) { if (__gthread_active_p ()) /* exit the thread */ __gthrw_(pthread_exit) (&__objc_thread_exit_status); /* Failed if we reached here */ return -1; } /* Returns an integer value which uniquely describes a thread. */ static inline objc_thread_t __gthread_objc_thread_id (void) { if (__gthread_active_p ()) return (objc_thread_t) __gthrw_(pthread_self) (); else return (objc_thread_t) 1; } /* Sets the thread's local storage pointer. */ static inline int __gthread_objc_thread_set_data (void *value) { if (__gthread_active_p ()) return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); else { thread_local_storage = value; return 0; } } /* Returns the thread's local storage pointer. */ static inline void * __gthread_objc_thread_get_data (void) { if (__gthread_active_p ()) return __gthrw_(pthread_getspecific) (_objc_thread_storage); else return thread_local_storage; } /* Backend mutex functions */ /* Allocate a mutex. */ static inline int __gthread_objc_mutex_allocate (objc_mutex_t mutex) { if (__gthread_active_p ()) { mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) { objc_free (mutex->backend); mutex->backend = NULL; return -1; } } return 0; } /* Deallocate a mutex. */ static inline int __gthread_objc_mutex_deallocate (objc_mutex_t mutex) { if (__gthread_active_p ()) { int count; /* * Posix Threads specifically require that the thread be unlocked * for __gthrw_(pthread_mutex_destroy) to work. */ do { count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); if (count < 0) return -1; } while (count); if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) return -1; objc_free (mutex->backend); mutex->backend = NULL; } return 0; } /* Grab a lock on a mutex. */ static inline int __gthread_objc_mutex_lock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Try to grab a lock on a mutex. */ static inline int __gthread_objc_mutex_trylock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Unlock the mutex */ static inline int __gthread_objc_mutex_unlock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Backend condition mutex functions */ /* Allocate a condition. */ static inline int __gthread_objc_condition_allocate (objc_condition_t condition) { if (__gthread_active_p ()) { condition->backend = objc_malloc (sizeof (pthread_cond_t)); if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) { objc_free (condition->backend); condition->backend = NULL; return -1; } } return 0; } /* Deallocate a condition. */ static inline int __gthread_objc_condition_deallocate (objc_condition_t condition) { if (__gthread_active_p ()) { if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) return -1; objc_free (condition->backend); condition->backend = NULL; } return 0; } /* Wait on the condition */ static inline int __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, (pthread_mutex_t *) mutex->backend); else return 0; } /* Wake up all threads waiting on this condition. */ static inline int __gthread_objc_condition_broadcast (objc_condition_t condition) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); else return 0; } /* Wake up one thread waiting on this condition. */ static inline int __gthread_objc_condition_signal (objc_condition_t condition) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); else return 0; } #else /* _LIBOBJC */ static inline int __gthread_create (__gthread_t *__threadid, void *(*__func) (void*), void *__args) { return __gthrw_(pthread_create) (__threadid, NULL, __func, __args); } static inline int __gthread_join (__gthread_t __threadid, void **__value_ptr) { return __gthrw_(pthread_join) (__threadid, __value_ptr); } static inline int __gthread_detach (__gthread_t __threadid) { return __gthrw_(pthread_detach) (__threadid); } static inline int __gthread_equal (__gthread_t __t1, __gthread_t __t2) { return __gthrw_(pthread_equal) (__t1, __t2); } static inline __gthread_t __gthread_self (void) { return __gthrw_(pthread_self) (); } static inline int __gthread_yield (void) { return __gthrw_(sched_yield) (); } static inline int __gthread_once (__gthread_once_t *__once, void (*__func) (void)) { if (__gthread_active_p ()) return __gthrw_(pthread_once) (__once, __func); else return -1; } static inline int __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) { return __gthrw_(pthread_key_create) (__key, __dtor); } static inline int __gthread_key_delete (__gthread_key_t __key) { return __gthrw_(pthread_key_delete) (__key); } static inline void * __gthread_getspecific (__gthread_key_t __key) { return __gthrw_(pthread_getspecific) (__key); } static inline int __gthread_setspecific (__gthread_key_t __key, const void *__ptr) { return __gthrw_(pthread_setspecific) (__key, __ptr); } static inline void __gthread_mutex_init_function (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) __gthrw_(pthread_mutex_init) (__mutex, NULL); } static inline int __gthread_mutex_destroy (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_destroy) (__mutex); else return 0; } static inline int __gthread_mutex_lock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_lock) (__mutex); else return 0; } static inline int __gthread_mutex_trylock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_trylock) (__mutex); else return 0; } #if _GTHREAD_USE_MUTEX_TIMEDLOCK static inline int __gthread_mutex_timedlock (__gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout); else return 0; } #endif static inline int __gthread_mutex_unlock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_unlock) (__mutex); else return 0; } #if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \ || defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC) static inline int __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) { if (__gthread_active_p ()) { pthread_mutexattr_t __attr; int __r; __r = __gthrw_(pthread_mutexattr_init) (&__attr); if (!__r) __r = __gthrw_(pthread_mutexattr_settype) (&__attr, PTHREAD_MUTEX_RECURSIVE); if (!__r) __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr); if (!__r) __r = __gthrw_(pthread_mutexattr_destroy) (&__attr); return __r; } return 0; } #endif static inline int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_lock (__mutex); } static inline int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_trylock (__mutex); } #if _GTHREAD_USE_MUTEX_TIMEDLOCK static inline int __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { return __gthread_mutex_timedlock (__mutex, __abs_timeout); } #endif static inline int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_unlock (__mutex); } static inline int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_destroy (__mutex); } #ifdef _GTHREAD_USE_COND_INIT_FUNC static inline void __gthread_cond_init_function (__gthread_cond_t *__cond) { if (__gthread_active_p ()) __gthrw_(pthread_cond_init) (__cond, NULL); } #endif static inline int __gthread_cond_broadcast (__gthread_cond_t *__cond) { return __gthrw_(pthread_cond_broadcast) (__cond); } static inline int __gthread_cond_signal (__gthread_cond_t *__cond) { return __gthrw_(pthread_cond_signal) (__cond); } static inline int __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex) { return __gthrw_(pthread_cond_wait) (__cond, __mutex); } static inline int __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout); } static inline int __gthread_cond_wait_recursive (__gthread_cond_t *__cond, __gthread_recursive_mutex_t *__mutex) { return __gthread_cond_wait (__cond, __mutex); } static inline int __gthread_cond_destroy (__gthread_cond_t* __cond) { return __gthrw_(pthread_cond_destroy) (__cond); } #endif /* _LIBOBJC */ #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ c++/8/x86_64-redhat-linux/32/bits/ctype_base.h 0000644 00000004414 15146341150 0014302 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/ctype_base.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.1 Locales // // Information as gleaned from /usr/include/ctype.h namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @brief Base class for ctype. struct ctype_base { // Non-standard typedefs. typedef const int* __to_type; // NB: Offsets into ctype<char>::_M_table force a particular size // on the mask type. Because of this, we don't use an enum. typedef unsigned short mask; static const mask upper = _ISupper; static const mask lower = _ISlower; static const mask alpha = _ISalpha; static const mask digit = _ISdigit; static const mask xdigit = _ISxdigit; static const mask space = _ISspace; static const mask print = _ISprint; static const mask graph = _ISalpha | _ISdigit | _ISpunct; static const mask cntrl = _IScntrl; static const mask punct = _ISpunct; static const mask alnum = _ISalpha | _ISdigit; #if __cplusplus >= 201103L static const mask blank = _ISblank; #endif }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/x86_64-redhat-linux/32/bits/ctype_inline.h 0000644 00000004354 15146341150 0014651 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/ctype_inline.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.1 Locales // // ctype bits to be inlined go here. Non-inlinable (ie virtual do_*) // functions go in ctype.cc namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION bool ctype<char>:: is(mask __m, char __c) const { return _M_table[static_cast<unsigned char>(__c)] & __m; } const char* ctype<char>:: is(const char* __low, const char* __high, mask* __vec) const { while (__low < __high) *__vec++ = _M_table[static_cast<unsigned char>(*__low++)]; return __high; } const char* ctype<char>:: scan_is(mask __m, const char* __low, const char* __high) const { while (__low < __high && !(_M_table[static_cast<unsigned char>(*__low)] & __m)) ++__low; return __low; } const char* ctype<char>:: scan_not(mask __m, const char* __low, const char* __high) const { while (__low < __high && (_M_table[static_cast<unsigned char>(*__low)] & __m) != 0) ++__low; return __low; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/x86_64-redhat-linux/32/bits/os_defines.h 0000644 00000003727 15146341150 0014310 0 ustar 00 // Specific definitions for GNU/Linux -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/os_defines.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iosfwd} */ #ifndef _GLIBCXX_OS_DEFINES #define _GLIBCXX_OS_DEFINES 1 // System-specific #define, typedefs, corrections, etc, go here. This // file will come before all others. // This keeps isanum, et al from being propagated as macros. #define __NO_CTYPE 1 #include <features.h> // Provide a declaration for the possibly deprecated gets function, as // glibc 2.15 and later does not declare gets for ISO C11 when // __GNU_SOURCE is defined. #if __GLIBC_PREREQ(2,15) && defined(_GNU_SOURCE) # undef _GLIBCXX_HAVE_GETS #endif // Glibc 2.23 removed the obsolete isinf and isnan declarations. Check the // version dynamically in case it has changed since libstdc++ was configured. #define _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC __GLIBC_PREREQ(2,23) #endif c++/8/x86_64-redhat-linux/32/bits/basic_file.h 0000644 00000006553 15146341150 0014252 0 ustar 00 // Wrapper of C-language FILE struct -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. // // ISO C++ 14882: 27.8 File-based streams // /** @file bits/basic_file.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ios} */ #ifndef _GLIBCXX_BASIC_FILE_STDIO_H #define _GLIBCXX_BASIC_FILE_STDIO_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/c++io.h> // for __c_lock and __c_file #include <bits/move.h> // for swap #include <ios> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Generic declaration. template<typename _CharT> class __basic_file; // Specialization. template<> class __basic_file<char> { // Underlying data source/sink. __c_file* _M_cfile; // True iff we opened _M_cfile, and thus must close it ourselves. bool _M_cfile_created; public: __basic_file(__c_lock* __lock = 0) throw (); #if __cplusplus >= 201103L __basic_file(__basic_file&& __rv, __c_lock* = 0) noexcept : _M_cfile(__rv._M_cfile), _M_cfile_created(__rv._M_cfile_created) { __rv._M_cfile = nullptr; __rv._M_cfile_created = false; } __basic_file& operator=(const __basic_file&) = delete; __basic_file& operator=(__basic_file&&) = delete; void swap(__basic_file& __f) noexcept { std::swap(_M_cfile, __f._M_cfile); std::swap(_M_cfile_created, __f._M_cfile_created); } #endif __basic_file* open(const char* __name, ios_base::openmode __mode, int __prot = 0664); __basic_file* sys_open(__c_file* __file, ios_base::openmode); __basic_file* sys_open(int __fd, ios_base::openmode __mode) throw (); __basic_file* close(); _GLIBCXX_PURE bool is_open() const throw (); _GLIBCXX_PURE int fd() throw (); _GLIBCXX_PURE __c_file* file() throw (); ~__basic_file(); streamsize xsputn(const char* __s, streamsize __n); streamsize xsputn_2(const char* __s1, streamsize __n1, const char* __s2, streamsize __n2); streamsize xsgetn(char* __s, streamsize __n); streamoff seekoff(streamoff __off, ios_base::seekdir __way) throw (); int sync(); streamsize showmanyc(); }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/x86_64-redhat-linux/32/bits/gthr-posix.h 0000644 00000057255 15146341150 0014303 0 ustar 00 /* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _GLIBCXX_GCC_GTHR_POSIX_H #define _GLIBCXX_GCC_GTHR_POSIX_H /* POSIX threads specific definitions. Easy, since the interface is just one-to-one mapping. */ #define __GTHREADS 1 #define __GTHREADS_CXX0X 1 #include <pthread.h> #if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \ || !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK)) # include <unistd.h> # if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0 # define _GTHREAD_USE_MUTEX_TIMEDLOCK 1 # else # define _GTHREAD_USE_MUTEX_TIMEDLOCK 0 # endif #endif typedef pthread_t __gthread_t; typedef pthread_key_t __gthread_key_t; typedef pthread_once_t __gthread_once_t; typedef pthread_mutex_t __gthread_mutex_t; typedef pthread_mutex_t __gthread_recursive_mutex_t; typedef pthread_cond_t __gthread_cond_t; typedef struct timespec __gthread_time_t; /* POSIX like conditional variables are supported. Please look at comments in gthr.h for details. */ #define __GTHREAD_HAS_COND 1 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP #else #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function #endif #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER #define __GTHREAD_TIME_INIT {0,0} #ifdef _GTHREAD_USE_MUTEX_INIT_FUNC # undef __GTHREAD_MUTEX_INIT #endif #ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC # undef __GTHREAD_RECURSIVE_MUTEX_INIT # undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION # define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function #endif #ifdef _GTHREAD_USE_COND_INIT_FUNC # undef __GTHREAD_COND_INIT # define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function #endif #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK # ifndef __gthrw_pragma # define __gthrw_pragma(pragma) # endif # define __gthrw2(name,name2,type) \ static __typeof(type) name __attribute__ ((__weakref__(#name2))); \ __gthrw_pragma(weak type) # define __gthrw_(name) __gthrw_ ## name #else # define __gthrw2(name,name2,type) # define __gthrw_(name) name #endif /* Typically, __gthrw_foo is a weak reference to symbol foo. */ #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name) __gthrw(pthread_once) __gthrw(pthread_getspecific) __gthrw(pthread_setspecific) __gthrw(pthread_create) __gthrw(pthread_join) __gthrw(pthread_equal) __gthrw(pthread_self) __gthrw(pthread_detach) #ifndef __BIONIC__ __gthrw(pthread_cancel) #endif __gthrw(sched_yield) __gthrw(pthread_mutex_lock) __gthrw(pthread_mutex_trylock) #if _GTHREAD_USE_MUTEX_TIMEDLOCK __gthrw(pthread_mutex_timedlock) #endif __gthrw(pthread_mutex_unlock) __gthrw(pthread_mutex_init) __gthrw(pthread_mutex_destroy) __gthrw(pthread_cond_init) __gthrw(pthread_cond_broadcast) __gthrw(pthread_cond_signal) __gthrw(pthread_cond_wait) __gthrw(pthread_cond_timedwait) __gthrw(pthread_cond_destroy) __gthrw(pthread_key_create) __gthrw(pthread_key_delete) __gthrw(pthread_mutexattr_init) __gthrw(pthread_mutexattr_settype) __gthrw(pthread_mutexattr_destroy) #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) /* Objective-C. */ __gthrw(pthread_exit) #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING __gthrw(sched_get_priority_max) __gthrw(sched_get_priority_min) #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ __gthrw(pthread_attr_destroy) __gthrw(pthread_attr_init) __gthrw(pthread_attr_setdetachstate) #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING __gthrw(pthread_getschedparam) __gthrw(pthread_setschedparam) #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _LIBOBJC || _LIBOBJC_WEAK */ #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if -pthreads is not specified. The functions are dummies and most return an error value. However pthread_once returns 0 without invoking the routine it is passed so we cannot pretend that the interface is active if -pthreads is not specified. On Solaris 2.5.1, the interface is not exposed at all so we need to play the usual game with weak symbols. On Solaris 10 and up, a working interface is always exposed. On FreeBSD 6 and later, libc also exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc, which means the alternate __gthread_active_p below cannot be used there. */ #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) static volatile int __gthread_active = -1; static void __gthread_trigger (void) { __gthread_active = 1; } static inline int __gthread_active_p (void) { static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT; /* Avoid reading __gthread_active twice on the main code path. */ int __gthread_active_latest_value = __gthread_active; /* This test is not protected to avoid taking a lock on the main code path so every update of __gthread_active in a threaded program must be atomic with regard to the result of the test. */ if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { if (__gthrw_(pthread_once)) { /* If this really is a threaded program, then we must ensure that __gthread_active has been set to 1 before exiting this block. */ __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger); __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); } /* Make sure we'll never enter this block again. */ if (__gthread_active < 0) __gthread_active = 0; __gthread_active_latest_value = __gthread_active; } return __gthread_active_latest_value != 0; } #else /* neither FreeBSD nor Solaris */ /* For a program to be multi-threaded the only thing that it certainly must be using is pthread_create. However, there may be other libraries that intercept pthread_create with their own definitions to wrap pthreads functionality for some purpose. In those cases, pthread_create being defined might not necessarily mean that libpthread is actually linked in. For the GNU C library, we can use a known internal name. This is always available in the ABI, but no other library would define it. That is ideal, since any public pthread function might be intercepted just as pthread_create might be. __pthread_key_create is an "internal" implementation symbol, but it is part of the public exported ABI. Also, it's among the symbols that the static libpthread.a always links in whenever pthread_create is used, so there is no danger of a false negative result in any statically-linked, multi-threaded program. For others, we choose pthread_cancel as a function that seems unlikely to be redefined by an interceptor library. The bionic (Android) C library does not provide pthread_cancel, so we do use pthread_create there (and interceptor libraries lose). */ #ifdef __GLIBC__ __gthrw2(__gthrw_(__pthread_key_create), __pthread_key_create, pthread_key_create) # define GTHR_ACTIVE_PROXY __gthrw_(__pthread_key_create) #elif defined (__BIONIC__) # define GTHR_ACTIVE_PROXY __gthrw_(pthread_create) #else # define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel) #endif static inline int __gthread_active_p (void) { static void *const __gthread_active_ptr = __extension__ (void *) >HR_ACTIVE_PROXY; return __gthread_active_ptr != 0; } #endif /* FreeBSD or Solaris */ #else /* not __GXX_WEAK__ */ /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread calls in shared flavors of the HP-UX C library. Most of the stubs have no functionality. The details are described in the "libc cumulative patch" for each subversion of HP-UX 11. There are two special interfaces provided for checking whether an application is linked to a shared pthread library or not. However, these interfaces aren't available in early libpthread libraries. We also need a test that works for archive libraries. We can't use pthread_once as some libc versions call the init function. We also can't use pthread_create or pthread_attr_init as these create a thread and thereby prevent changing the default stack size. The function pthread_default_stacksize_np is available in both the archive and shared versions of libpthread. It can be used to determine the default pthread stack size. There is a stub in some shared libc versions which returns a zero size if pthreads are not active. We provide an equivalent stub to handle cases where libc doesn't provide one. */ #if defined(__hppa__) && defined(__hpux__) static volatile int __gthread_active = -1; static inline int __gthread_active_p (void) { /* Avoid reading __gthread_active twice on the main code path. */ int __gthread_active_latest_value = __gthread_active; size_t __s; if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { pthread_default_stacksize_np (0, &__s); __gthread_active = __s ? 1 : 0; __gthread_active_latest_value = __gthread_active; } return __gthread_active_latest_value != 0; } #else /* not hppa-hpux */ static inline int __gthread_active_p (void) { return 1; } #endif /* hppa-hpux */ #endif /* __GXX_WEAK__ */ #ifdef _LIBOBJC /* This is the config.h file in libobjc/ */ #include <config.h> #ifdef HAVE_SCHED_H # include <sched.h> #endif /* Key structure for maintaining thread specific storage */ static pthread_key_t _objc_thread_storage; static pthread_attr_t _objc_thread_attribs; /* Thread local storage for a single thread */ static void *thread_local_storage = NULL; /* Backend initialization functions */ /* Initialize the threads subsystem. */ static inline int __gthread_objc_init_thread_system (void) { if (__gthread_active_p ()) { /* Initialize the thread storage key. */ if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) { /* The normal default detach state for threads is * PTHREAD_CREATE_JOINABLE which causes threads to not die * when you think they should. */ if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, PTHREAD_CREATE_DETACHED) == 0) return 0; } } return -1; } /* Close the threads subsystem. */ static inline int __gthread_objc_close_thread_system (void) { if (__gthread_active_p () && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) return 0; return -1; } /* Backend thread functions */ /* Create a new thread of execution. */ static inline objc_thread_t __gthread_objc_thread_detach (void (*func)(void *), void *arg) { objc_thread_t thread_id; pthread_t new_thread_handle; if (!__gthread_active_p ()) return NULL; if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs, (void *) func, arg))) thread_id = (objc_thread_t) new_thread_handle; else thread_id = NULL; return thread_id; } /* Set the current thread's priority. */ static inline int __gthread_objc_thread_set_priority (int priority) { if (!__gthread_active_p ()) return -1; else { #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING pthread_t thread_id = __gthrw_(pthread_self) (); int policy; struct sched_param params; int priority_min, priority_max; if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) { if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) return -1; if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) return -1; if (priority > priority_max) priority = priority_max; else if (priority < priority_min) priority = priority_min; params.sched_priority = priority; /* * The solaris 7 and several other man pages incorrectly state that * this should be a pointer to policy but pthread.h is universally * at odds with this. */ if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) return 0; } #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ return -1; } } /* Return the current thread's priority. */ static inline int __gthread_objc_thread_get_priority (void) { #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING if (__gthread_active_p ()) { int policy; struct sched_param params; if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) return params.sched_priority; else return -1; } else #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ return OBJC_THREAD_INTERACTIVE_PRIORITY; } /* Yield our process time to another thread. */ static inline void __gthread_objc_thread_yield (void) { if (__gthread_active_p ()) __gthrw_(sched_yield) (); } /* Terminate the current thread. */ static inline int __gthread_objc_thread_exit (void) { if (__gthread_active_p ()) /* exit the thread */ __gthrw_(pthread_exit) (&__objc_thread_exit_status); /* Failed if we reached here */ return -1; } /* Returns an integer value which uniquely describes a thread. */ static inline objc_thread_t __gthread_objc_thread_id (void) { if (__gthread_active_p ()) return (objc_thread_t) __gthrw_(pthread_self) (); else return (objc_thread_t) 1; } /* Sets the thread's local storage pointer. */ static inline int __gthread_objc_thread_set_data (void *value) { if (__gthread_active_p ()) return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); else { thread_local_storage = value; return 0; } } /* Returns the thread's local storage pointer. */ static inline void * __gthread_objc_thread_get_data (void) { if (__gthread_active_p ()) return __gthrw_(pthread_getspecific) (_objc_thread_storage); else return thread_local_storage; } /* Backend mutex functions */ /* Allocate a mutex. */ static inline int __gthread_objc_mutex_allocate (objc_mutex_t mutex) { if (__gthread_active_p ()) { mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) { objc_free (mutex->backend); mutex->backend = NULL; return -1; } } return 0; } /* Deallocate a mutex. */ static inline int __gthread_objc_mutex_deallocate (objc_mutex_t mutex) { if (__gthread_active_p ()) { int count; /* * Posix Threads specifically require that the thread be unlocked * for __gthrw_(pthread_mutex_destroy) to work. */ do { count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); if (count < 0) return -1; } while (count); if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) return -1; objc_free (mutex->backend); mutex->backend = NULL; } return 0; } /* Grab a lock on a mutex. */ static inline int __gthread_objc_mutex_lock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Try to grab a lock on a mutex. */ static inline int __gthread_objc_mutex_trylock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Unlock the mutex */ static inline int __gthread_objc_mutex_unlock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Backend condition mutex functions */ /* Allocate a condition. */ static inline int __gthread_objc_condition_allocate (objc_condition_t condition) { if (__gthread_active_p ()) { condition->backend = objc_malloc (sizeof (pthread_cond_t)); if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) { objc_free (condition->backend); condition->backend = NULL; return -1; } } return 0; } /* Deallocate a condition. */ static inline int __gthread_objc_condition_deallocate (objc_condition_t condition) { if (__gthread_active_p ()) { if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) return -1; objc_free (condition->backend); condition->backend = NULL; } return 0; } /* Wait on the condition */ static inline int __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, (pthread_mutex_t *) mutex->backend); else return 0; } /* Wake up all threads waiting on this condition. */ static inline int __gthread_objc_condition_broadcast (objc_condition_t condition) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); else return 0; } /* Wake up one thread waiting on this condition. */ static inline int __gthread_objc_condition_signal (objc_condition_t condition) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); else return 0; } #else /* _LIBOBJC */ static inline int __gthread_create (__gthread_t *__threadid, void *(*__func) (void*), void *__args) { return __gthrw_(pthread_create) (__threadid, NULL, __func, __args); } static inline int __gthread_join (__gthread_t __threadid, void **__value_ptr) { return __gthrw_(pthread_join) (__threadid, __value_ptr); } static inline int __gthread_detach (__gthread_t __threadid) { return __gthrw_(pthread_detach) (__threadid); } static inline int __gthread_equal (__gthread_t __t1, __gthread_t __t2) { return __gthrw_(pthread_equal) (__t1, __t2); } static inline __gthread_t __gthread_self (void) { return __gthrw_(pthread_self) (); } static inline int __gthread_yield (void) { return __gthrw_(sched_yield) (); } static inline int __gthread_once (__gthread_once_t *__once, void (*__func) (void)) { if (__gthread_active_p ()) return __gthrw_(pthread_once) (__once, __func); else return -1; } static inline int __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) { return __gthrw_(pthread_key_create) (__key, __dtor); } static inline int __gthread_key_delete (__gthread_key_t __key) { return __gthrw_(pthread_key_delete) (__key); } static inline void * __gthread_getspecific (__gthread_key_t __key) { return __gthrw_(pthread_getspecific) (__key); } static inline int __gthread_setspecific (__gthread_key_t __key, const void *__ptr) { return __gthrw_(pthread_setspecific) (__key, __ptr); } static inline void __gthread_mutex_init_function (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) __gthrw_(pthread_mutex_init) (__mutex, NULL); } static inline int __gthread_mutex_destroy (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_destroy) (__mutex); else return 0; } static inline int __gthread_mutex_lock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_lock) (__mutex); else return 0; } static inline int __gthread_mutex_trylock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_trylock) (__mutex); else return 0; } #if _GTHREAD_USE_MUTEX_TIMEDLOCK static inline int __gthread_mutex_timedlock (__gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout); else return 0; } #endif static inline int __gthread_mutex_unlock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_unlock) (__mutex); else return 0; } #if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \ || defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC) static inline int __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) { if (__gthread_active_p ()) { pthread_mutexattr_t __attr; int __r; __r = __gthrw_(pthread_mutexattr_init) (&__attr); if (!__r) __r = __gthrw_(pthread_mutexattr_settype) (&__attr, PTHREAD_MUTEX_RECURSIVE); if (!__r) __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr); if (!__r) __r = __gthrw_(pthread_mutexattr_destroy) (&__attr); return __r; } return 0; } #endif static inline int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_lock (__mutex); } static inline int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_trylock (__mutex); } #if _GTHREAD_USE_MUTEX_TIMEDLOCK static inline int __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { return __gthread_mutex_timedlock (__mutex, __abs_timeout); } #endif static inline int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_unlock (__mutex); } static inline int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_destroy (__mutex); } #ifdef _GTHREAD_USE_COND_INIT_FUNC static inline void __gthread_cond_init_function (__gthread_cond_t *__cond) { if (__gthread_active_p ()) __gthrw_(pthread_cond_init) (__cond, NULL); } #endif static inline int __gthread_cond_broadcast (__gthread_cond_t *__cond) { return __gthrw_(pthread_cond_broadcast) (__cond); } static inline int __gthread_cond_signal (__gthread_cond_t *__cond) { return __gthrw_(pthread_cond_signal) (__cond); } static inline int __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex) { return __gthrw_(pthread_cond_wait) (__cond, __mutex); } static inline int __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout); } static inline int __gthread_cond_wait_recursive (__gthread_cond_t *__cond, __gthread_recursive_mutex_t *__mutex) { return __gthread_cond_wait (__cond, __mutex); } static inline int __gthread_cond_destroy (__gthread_cond_t* __cond) { return __gthrw_(pthread_cond_destroy) (__cond); } #endif /* _LIBOBJC */ #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ c++/8/x86_64-redhat-linux/32/bits/opt_random.h 0000644 00000014062 15146341150 0014326 0 ustar 00 // Optimizations for random number functions, x86 version -*- C++ -*- // Copyright (C) 2012-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/opt_random.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{random} */ #ifndef _BITS_OPT_RANDOM_H #define _BITS_OPT_RANDOM_H 1 #ifdef __SSE3__ #include <pmmintrin.h> #endif #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef __SSE3__ template<> template<typename _UniformRandomNumberGenerator> void normal_distribution<double>:: __generate(typename normal_distribution<double>::result_type* __f, typename normal_distribution<double>::result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { typedef uint64_t __uctype; if (__f == __t) return; if (_M_saved_available) { _M_saved_available = false; *__f++ = _M_saved * __param.stddev() + __param.mean(); if (__f == __t) return; } constexpr uint64_t __maskval = 0xfffffffffffffull; static const __m128i __mask = _mm_set1_epi64x(__maskval); static const __m128i __two = _mm_set1_epi64x(0x4000000000000000ull); static const __m128d __three = _mm_set1_pd(3.0); const __m128d __av = _mm_set1_pd(__param.mean()); const __uctype __urngmin = __urng.min(); const __uctype __urngmax = __urng.max(); const __uctype __urngrange = __urngmax - __urngmin; const __uctype __uerngrange = __urngrange + 1; while (__f + 1 < __t) { double __le; __m128d __x; do { union { __m128i __i; __m128d __d; } __v; if (__urngrange > __maskval) { if (__detail::_Power_of_2(__uerngrange)) __v.__i = _mm_and_si128(_mm_set_epi64x(__urng(), __urng()), __mask); else { const __uctype __uerange = __maskval + 1; const __uctype __scaling = __urngrange / __uerange; const __uctype __past = __uerange * __scaling; uint64_t __v1; do __v1 = __uctype(__urng()) - __urngmin; while (__v1 >= __past); __v1 /= __scaling; uint64_t __v2; do __v2 = __uctype(__urng()) - __urngmin; while (__v2 >= __past); __v2 /= __scaling; __v.__i = _mm_set_epi64x(__v1, __v2); } } else if (__urngrange == __maskval) __v.__i = _mm_set_epi64x(__urng(), __urng()); else if ((__urngrange + 2) * __urngrange >= __maskval && __detail::_Power_of_2(__uerngrange)) { uint64_t __v1 = __urng() * __uerngrange + __urng(); uint64_t __v2 = __urng() * __uerngrange + __urng(); __v.__i = _mm_and_si128(_mm_set_epi64x(__v1, __v2), __mask); } else { size_t __nrng = 2; __uctype __high = __maskval / __uerngrange / __uerngrange; while (__high > __uerngrange) { ++__nrng; __high /= __uerngrange; } const __uctype __highrange = __high + 1; const __uctype __scaling = __urngrange / __highrange; const __uctype __past = __highrange * __scaling; __uctype __tmp; uint64_t __v1; do { do __tmp = __uctype(__urng()) - __urngmin; while (__tmp >= __past); __v1 = __tmp / __scaling; for (size_t __cnt = 0; __cnt < __nrng; ++__cnt) { __tmp = __v1; __v1 *= __uerngrange; __v1 += __uctype(__urng()) - __urngmin; } } while (__v1 > __maskval || __v1 < __tmp); uint64_t __v2; do { do __tmp = __uctype(__urng()) - __urngmin; while (__tmp >= __past); __v2 = __tmp / __scaling; for (size_t __cnt = 0; __cnt < __nrng; ++__cnt) { __tmp = __v2; __v2 *= __uerngrange; __v2 += __uctype(__urng()) - __urngmin; } } while (__v2 > __maskval || __v2 < __tmp); __v.__i = _mm_set_epi64x(__v1, __v2); } __v.__i = _mm_or_si128(__v.__i, __two); __x = _mm_sub_pd(__v.__d, __three); __m128d __m = _mm_mul_pd(__x, __x); __le = _mm_cvtsd_f64(_mm_hadd_pd (__m, __m)); } while (__le == 0.0 || __le >= 1.0); double __mult = (std::sqrt(-2.0 * std::log(__le) / __le) * __param.stddev()); __x = _mm_add_pd(_mm_mul_pd(__x, _mm_set1_pd(__mult)), __av); _mm_storeu_pd(__f, __x); __f += 2; } if (__f != __t) { result_type __x, __y, __r2; __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); do { __x = result_type(2.0) * __aurng() - 1.0; __y = result_type(2.0) * __aurng() - 1.0; __r2 = __x * __x + __y * __y; } while (__r2 > 1.0 || __r2 == 0.0); const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); _M_saved = __x * __mult; _M_saved_available = true; *__f = __y * __mult * __param.stddev() + __param.mean(); } } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _BITS_OPT_RANDOM_H c++/8/x86_64-redhat-linux/ext/opt_random.h 0000644 00000011224 15146341150 0013736 0 ustar 00 // Optimizations for random number extensions, x86 version -*- C++ -*- // Copyright (C) 2012-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file ext/random.tcc * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ext/random} */ #ifndef _EXT_OPT_RANDOM_H #define _EXT_OPT_RANDOM_H 1 #pragma GCC system_header #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #ifdef __SSE2__ namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace { template<size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4> inline __m128i __sse2_recursion(__m128i __a, __m128i __b, __m128i __c, __m128i __d) { __m128i __y = _mm_srli_epi32(__b, __sr1); __m128i __z = _mm_srli_si128(__c, __sr2); __m128i __v = _mm_slli_epi32(__d, __sl1); __z = _mm_xor_si128(__z, __a); __z = _mm_xor_si128(__z, __v); __m128i __x = _mm_slli_si128(__a, __sl2); __y = _mm_and_si128(__y, _mm_set_epi32(__msk4, __msk3, __msk2, __msk1)); __z = _mm_xor_si128(__z, __x); return _mm_xor_si128(__z, __y); } } #define _GLIBCXX_OPT_HAVE_RANDOM_SFMT_GEN_READ 1 template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> void simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>:: _M_gen_rand(void) { __m128i __r1 = _mm_load_si128(&_M_state[_M_nstate - 2]); __m128i __r2 = _mm_load_si128(&_M_state[_M_nstate - 1]); size_t __i; for (__i = 0; __i < _M_nstate - __pos1; ++__i) { __m128i __r = __sse2_recursion<__sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4> (_M_state[__i], _M_state[__i + __pos1], __r1, __r2); _mm_store_si128(&_M_state[__i], __r); __r1 = __r2; __r2 = __r; } for (; __i < _M_nstate; ++__i) { __m128i __r = __sse2_recursion<__sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4> (_M_state[__i], _M_state[__i + __pos1 - _M_nstate], __r1, __r2); _mm_store_si128(&_M_state[__i], __r); __r1 = __r2; __r2 = __r; } _M_pos = 0; } #define _GLIBCXX_OPT_HAVE_RANDOM_SFMT_OPERATOREQUAL 1 template<typename _UIntType, size_t __m, size_t __pos1, size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2, uint32_t __msk1, uint32_t __msk2, uint32_t __msk3, uint32_t __msk4, uint32_t __parity1, uint32_t __parity2, uint32_t __parity3, uint32_t __parity4> bool operator==(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) { __m128i __res = _mm_cmpeq_epi8(__lhs._M_state[0], __rhs._M_state[0]); for (size_t __i = 1; __i < __lhs._M_nstate; ++__i) __res = _mm_and_si128(__res, _mm_cmpeq_epi8(__lhs._M_state[__i], __rhs._M_state[__i])); return (_mm_movemask_epi8(__res) == 0xffff && __lhs._M_pos == __rhs._M_pos); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // __SSE2__ #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #endif // _EXT_OPT_RANDOM_H c++/8/x86_64-redhat-linux/bits/extc++.h 0000644 00000005145 15146341150 0013033 0 ustar 00 // C++ includes used for precompiling extensions -*- C++ -*- // Copyright (C) 2006-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file extc++.h * This is an implementation file for a precompiled header. */ #if __cplusplus < 201103L #include <bits/stdtr1c++.h> #else #include <bits/stdc++.h> #endif #include <ext/algorithm> #if __cplusplus >= 201103L # include <ext/aligned_buffer.h> #endif #include <ext/alloc_traits.h> #include <ext/array_allocator.h> #include <ext/atomicity.h> #include <ext/bitmap_allocator.h> #include <ext/cast.h> #if __cplusplus >= 201103L # include <ext/cmath> #endif #include <ext/concurrence.h> #include <ext/debug_allocator.h> #include <ext/extptr_allocator.h> #include <ext/functional> #include <ext/iterator> #include <ext/malloc_allocator.h> #include <ext/memory> #include <ext/mt_allocator.h> #include <ext/new_allocator.h> #include <ext/numeric> #include <ext/numeric_traits.h> #include <ext/pod_char_traits.h> #include <ext/pointer.h> #include <ext/pool_allocator.h> #if __cplusplus >= 201103L # include <ext/random> #endif #include <ext/rb_tree> #include <ext/rope> #include <ext/slist> #include <ext/stdio_filebuf.h> #include <ext/stdio_sync_filebuf.h> #include <ext/throw_allocator.h> #include <ext/typelist.h> #include <ext/type_traits.h> #include <ext/vstring.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/priority_queue.hpp> #include <ext/pb_ds/exception.hpp> #include <ext/pb_ds/hash_policy.hpp> #include <ext/pb_ds/list_update_policy.hpp> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/trie_policy.hpp> #ifdef _GLIBCXX_HAVE_ICONV #include <ext/codecvt_specializations.h> #include <ext/enc_filebuf.h> #endif c++/8/x86_64-redhat-linux/bits/atomic_word.h 0000644 00000002756 15146341150 0014256 0 ustar 00 // Low-level type for atomic operations -*- C++ -*- // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file atomic_word.h * This file is a GNU extension to the Standard C++ Library. */ #ifndef _GLIBCXX_ATOMIC_WORD_H #define _GLIBCXX_ATOMIC_WORD_H 1 typedef int _Atomic_word; // This is a memory order acquire fence. #define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE) // This is a memory order release fence. #define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE) #endif c++/8/x86_64-redhat-linux/bits/stdc++.h 0000644 00000005607 15146341150 0013030 0 ustar 00 // C++ includes used for precompiling -*- C++ -*- // Copyright (C) 2003-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file stdc++.h * This is an implementation file for a precompiled header. */ // 17.4.1.2 Headers // C #ifndef _GLIBCXX_NO_ASSERT #include <cassert> #endif #include <cctype> #include <cerrno> #include <cfloat> #include <ciso646> #include <climits> #include <clocale> #include <cmath> #include <csetjmp> #include <csignal> #include <cstdarg> #include <cstddef> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #if __cplusplus >= 201103L #include <ccomplex> #include <cfenv> #include <cinttypes> #include <cstdalign> #include <cstdbool> #include <cstdint> #include <ctgmath> #include <cuchar> #include <cwchar> #include <cwctype> #endif // C++ #include <algorithm> #include <bitset> #include <complex> #include <deque> #include <exception> #include <fstream> #include <functional> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <iterator> #include <limits> #include <list> #include <locale> #include <map> #include <memory> #include <new> #include <numeric> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stack> #include <stdexcept> #include <streambuf> #include <string> #include <typeinfo> #include <utility> #include <valarray> #include <vector> #if __cplusplus >= 201103L #include <array> #include <atomic> #include <chrono> #include <codecvt> #include <condition_variable> #include <forward_list> #include <future> #include <initializer_list> #include <mutex> #include <random> #include <ratio> #include <regex> #include <scoped_allocator> #include <system_error> #include <thread> #include <tuple> #include <typeindex> #include <type_traits> #include <unordered_map> #include <unordered_set> #endif #if __cplusplus >= 201402L #include <shared_mutex> #endif #if __cplusplus >= 201703L #include <charconv> #include <filesystem> #endif c++/8/x86_64-redhat-linux/bits/cxxabi_tweaks.h 0000644 00000004060 15146341150 0014571 0 ustar 00 // Control various target specific ABI tweaks. Generic version. // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/cxxabi_tweaks.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{cxxabi.h} */ #ifndef _CXXABI_TWEAKS_H #define _CXXABI_TWEAKS_H 1 #ifdef __cplusplus namespace __cxxabiv1 { extern "C" { #endif // The generic ABI uses the first byte of a 64-bit guard variable. #define _GLIBCXX_GUARD_TEST(x) (*(char *) (x) != 0) #define _GLIBCXX_GUARD_SET(x) *(char *) (x) = 1 #define _GLIBCXX_GUARD_BIT __guard_test_bit (0, 1) #define _GLIBCXX_GUARD_PENDING_BIT __guard_test_bit (1, 1) #define _GLIBCXX_GUARD_WAITING_BIT __guard_test_bit (2, 1) __extension__ typedef int __guard __attribute__((mode (__DI__))); // __cxa_vec_ctor has void return type. typedef void __cxa_vec_ctor_return_type; #define _GLIBCXX_CXA_VEC_CTOR_RETURN(x) return // Constructors and destructors do not return a value. typedef void __cxa_cdtor_return_type; #ifdef __cplusplus } } // namespace __cxxabiv1 #endif #endif c++/8/x86_64-redhat-linux/bits/c++io.h 0000644 00000003110 15146341150 0012630 0 ustar 00 // Underlying io library details -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/c++io.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ios} */ // c_io_stdio.h - Defines for using "C" stdio.h #ifndef _GLIBCXX_CXX_IO_H #define _GLIBCXX_CXX_IO_H 1 #include <cstdio> #include <bits/gthr.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef __gthread_mutex_t __c_lock; // for basic_file.h typedef FILE __c_file; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/x86_64-redhat-linux/bits/cpu_defines.h 0000644 00000002465 15146341150 0014230 0 ustar 00 // Specific definitions for generic platforms -*- C++ -*- // Copyright (C) 2005-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/cpu_defines.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iosfwd} */ #ifndef _GLIBCXX_CPU_DEFINES #define _GLIBCXX_CPU_DEFINES 1 #endif c++/8/x86_64-redhat-linux/bits/time_members.h 0000644 00000005554 15146341150 0014416 0 ustar 00 // std::time_get, std::time_put implementation, GNU version -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/time_members.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.2.5.1.2 - time_get functions // ISO C++ 14882: 22.2.5.3.2 - time_put functions // // Written by Benjamin Kosnik <bkoz@redhat.com> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT> __timepunct<_CharT>::__timepunct(size_t __refs) : facet(__refs), _M_data(0), _M_c_locale_timepunct(0), _M_name_timepunct(_S_get_c_name()) { _M_initialize_timepunct(); } template<typename _CharT> __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs) : facet(__refs), _M_data(__cache), _M_c_locale_timepunct(0), _M_name_timepunct(_S_get_c_name()) { _M_initialize_timepunct(); } template<typename _CharT> __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s, size_t __refs) : facet(__refs), _M_data(0), _M_c_locale_timepunct(0), _M_name_timepunct(0) { if (__builtin_strcmp(__s, _S_get_c_name()) != 0) { const size_t __len = __builtin_strlen(__s) + 1; char* __tmp = new char[__len]; __builtin_memcpy(__tmp, __s, __len); _M_name_timepunct = __tmp; } else _M_name_timepunct = _S_get_c_name(); __try { _M_initialize_timepunct(__cloc); } __catch(...) { if (_M_name_timepunct != _S_get_c_name()) delete [] _M_name_timepunct; __throw_exception_again; } } template<typename _CharT> __timepunct<_CharT>::~__timepunct() { if (_M_name_timepunct != _S_get_c_name()) delete [] _M_name_timepunct; delete _M_data; _S_destroy_c_locale(_M_c_locale_timepunct); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/x86_64-redhat-linux/bits/stdtr1c++.h 0000644 00000003315 15146341150 0013451 0 ustar 00 // C++ includes used for precompiling TR1 -*- C++ -*- // Copyright (C) 2006-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file stdtr1c++.h * This is an implementation file for a precompiled header. */ #include <bits/stdc++.h> #include <tr1/array> #include <tr1/cctype> #include <tr1/cfenv> #include <tr1/cfloat> #include <tr1/cinttypes> #include <tr1/climits> #include <tr1/cmath> #include <tr1/complex> #include <tr1/cstdarg> #include <tr1/cstdbool> #include <tr1/cstdint> #include <tr1/cstdio> #include <tr1/cstdlib> #include <tr1/ctgmath> #include <tr1/ctime> #include <tr1/cwchar> #include <tr1/cwctype> #include <tr1/functional> #include <tr1/random> #include <tr1/tuple> #include <tr1/unordered_map> #include <tr1/unordered_set> #include <tr1/utility> c++/8/x86_64-redhat-linux/bits/c++config.h 0000644 00000341407 15146341150 0013504 0 ustar 00 #ifndef _CPP_CPPCONFIG_WRAPPER #define _CPP_CPPCONFIG_WRAPPER 1 #include <bits/wordsize.h> #if __WORDSIZE == 32 // Predefined symbols and macros -*- C++ -*- // Copyright (C) 1997-2018 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++config.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iosfwd} */ #ifndef _GLIBCXX_CXX_CONFIG_H #define _GLIBCXX_CXX_CONFIG_H 1 // The major release number for the GCC release the C++ library belongs to. #define _GLIBCXX_RELEASE 8 // The datestamp of the C++ library in compressed ISO date format. #define __GLIBCXX__ 20210514 // Macros for various attributes. // _GLIBCXX_PURE // _GLIBCXX_CONST // _GLIBCXX_NORETURN // _GLIBCXX_NOTHROW // _GLIBCXX_VISIBILITY #ifndef _GLIBCXX_PURE # define _GLIBCXX_PURE __attribute__ ((__pure__)) #endif #ifndef _GLIBCXX_CONST # define _GLIBCXX_CONST __attribute__ ((__const__)) #endif #ifndef _GLIBCXX_NORETURN # define _GLIBCXX_NORETURN __attribute__ ((__noreturn__)) #endif // See below for C++ #ifndef _GLIBCXX_NOTHROW # ifndef __cplusplus # define _GLIBCXX_NOTHROW __attribute__((__nothrow__)) # endif #endif // Macros for visibility attributes. // _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY // _GLIBCXX_VISIBILITY # define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1 #if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY # define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V))) #else // If this is not supplied by the OS-specific or CPU-specific // headers included below, it will be defined to an empty default. # define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V) #endif // Macros for deprecated attributes. // _GLIBCXX_USE_DEPRECATED // _GLIBCXX_DEPRECATED // _GLIBCXX17_DEPRECATED #ifndef _GLIBCXX_USE_DEPRECATED # define _GLIBCXX_USE_DEPRECATED 1 #endif #if defined(__DEPRECATED) && (__cplusplus >= 201103L) # define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) #else # define _GLIBCXX_DEPRECATED #endif #if defined(__DEPRECATED) && (__cplusplus >= 201703L) # define _GLIBCXX17_DEPRECATED [[__deprecated__]] #else # define _GLIBCXX17_DEPRECATED #endif // Macros for ABI tag attributes. #ifndef _GLIBCXX_ABI_TAG_CXX11 # define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) #endif // Macro to warn about unused results. #if __cplusplus >= 201703L # define _GLIBCXX_NODISCARD [[__nodiscard__]] #else # define _GLIBCXX_NODISCARD #endif #if __cplusplus // Macro for constexpr, to support in mixed 03/0x mode. #ifndef _GLIBCXX_CONSTEXPR # if __cplusplus >= 201103L # define _GLIBCXX_CONSTEXPR constexpr # define _GLIBCXX_USE_CONSTEXPR constexpr # else # define _GLIBCXX_CONSTEXPR # define _GLIBCXX_USE_CONSTEXPR const # endif #endif #ifndef _GLIBCXX14_CONSTEXPR # if __cplusplus >= 201402L # define _GLIBCXX14_CONSTEXPR constexpr # else # define _GLIBCXX14_CONSTEXPR # endif #endif #ifndef _GLIBCXX17_CONSTEXPR # if __cplusplus > 201402L # define _GLIBCXX17_CONSTEXPR constexpr # else # define _GLIBCXX17_CONSTEXPR # endif #endif #ifndef _GLIBCXX17_INLINE # if __cplusplus > 201402L # define _GLIBCXX17_INLINE inline # else # define _GLIBCXX17_INLINE # endif #endif // Macro for noexcept, to support in mixed 03/0x mode. #ifndef _GLIBCXX_NOEXCEPT # if __cplusplus >= 201103L # define _GLIBCXX_NOEXCEPT noexcept # define _GLIBCXX_NOEXCEPT_IF(_COND) noexcept(_COND) # define _GLIBCXX_USE_NOEXCEPT noexcept # define _GLIBCXX_THROW(_EXC) # else # define _GLIBCXX_NOEXCEPT # define _GLIBCXX_NOEXCEPT_IF(_COND) # define _GLIBCXX_USE_NOEXCEPT throw() # define _GLIBCXX_THROW(_EXC) throw(_EXC) # endif #endif #ifndef _GLIBCXX_NOTHROW # define _GLIBCXX_NOTHROW _GLIBCXX_USE_NOEXCEPT #endif #ifndef _GLIBCXX_THROW_OR_ABORT # if __cpp_exceptions # define _GLIBCXX_THROW_OR_ABORT(_EXC) (throw (_EXC)) # else # define _GLIBCXX_THROW_OR_ABORT(_EXC) (__builtin_abort()) # endif #endif #if __cpp_noexcept_function_type #define _GLIBCXX_NOEXCEPT_PARM , bool _NE #define _GLIBCXX_NOEXCEPT_QUAL noexcept (_NE) #else #define _GLIBCXX_NOEXCEPT_PARM #define _GLIBCXX_NOEXCEPT_QUAL #endif // Macro for extern template, ie controlling template linkage via use // of extern keyword on template declaration. As documented in the g++ // manual, it inhibits all implicit instantiations and is used // throughout the library to avoid multiple weak definitions for // required types that are already explicitly instantiated in the // library binary. This substantially reduces the binary size of // resulting executables. // Special case: _GLIBCXX_EXTERN_TEMPLATE == -1 disallows extern // templates only in basic_string, thus activating its debug-mode // checks even at -O0. # define _GLIBCXX_EXTERN_TEMPLATE 1 /* Outline of libstdc++ namespaces. namespace std { namespace __debug { } namespace __parallel { } namespace __profile { } namespace __cxx1998 { } namespace __detail { namespace __variant { } // C++17 } namespace rel_ops { } namespace tr1 { namespace placeholders { } namespace regex_constants { } namespace __detail { } } namespace tr2 { } namespace decimal { } namespace chrono { } // C++11 namespace placeholders { } // C++11 namespace regex_constants { } // C++11 namespace this_thread { } // C++11 inline namespace literals { // C++14 inline namespace chrono_literals { } // C++14 inline namespace complex_literals { } // C++14 inline namespace string_literals { } // C++14 inline namespace string_view_literals { } // C++17 } } namespace abi { } namespace __gnu_cxx { namespace __detail { } } For full details see: http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaces.html */ namespace std { typedef __SIZE_TYPE__ size_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; #if __cplusplus >= 201103L typedef decltype(nullptr) nullptr_t; #endif } # define _GLIBCXX_USE_DUAL_ABI 1 #if ! _GLIBCXX_USE_DUAL_ABI // Ignore any pre-defined value of _GLIBCXX_USE_CXX11_ABI # undef _GLIBCXX_USE_CXX11_ABI #endif #ifndef _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_USE_CXX11_ABI 1 #endif #if _GLIBCXX_USE_CXX11_ABI namespace std { inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } } namespace __gnu_cxx { inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } } # define _GLIBCXX_NAMESPACE_CXX11 __cxx11:: # define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 { # define _GLIBCXX_END_NAMESPACE_CXX11 } # define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11 #else # define _GLIBCXX_NAMESPACE_CXX11 # define _GLIBCXX_BEGIN_NAMESPACE_CXX11 # define _GLIBCXX_END_NAMESPACE_CXX11 # define _GLIBCXX_DEFAULT_ABI_TAG #endif // Defined if inline namespaces are used for versioning. # define _GLIBCXX_INLINE_VERSION 0 // Inline namespace for symbol versioning. #if _GLIBCXX_INLINE_VERSION # define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __8 { # define _GLIBCXX_END_NAMESPACE_VERSION } namespace std { inline _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201402L inline namespace literals { inline namespace chrono_literals { } inline namespace complex_literals { } inline namespace string_literals { } #if __cplusplus > 201402L inline namespace string_view_literals { } #endif // C++17 } #endif // C++14 _GLIBCXX_END_NAMESPACE_VERSION } namespace __gnu_cxx { inline _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION } #else # define _GLIBCXX_BEGIN_NAMESPACE_VERSION # define _GLIBCXX_END_NAMESPACE_VERSION #endif // Inline namespaces for special modes: debug, parallel, profile. #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) \ || defined(_GLIBCXX_PROFILE) namespace std { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Non-inline namespace for components replaced by alternates in active mode. namespace __cxx1998 { # if _GLIBCXX_USE_CXX11_ABI inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } # endif } _GLIBCXX_END_NAMESPACE_VERSION // Inline namespace for debug mode. # ifdef _GLIBCXX_DEBUG inline namespace __debug { } # endif // Inline namespaces for parallel mode. # ifdef _GLIBCXX_PARALLEL inline namespace __parallel { } # endif // Inline namespaces for profile mode # ifdef _GLIBCXX_PROFILE inline namespace __profile { } # endif } // Check for invalid usage and unsupported mixed-mode use. # if defined(_GLIBCXX_DEBUG) && defined(_GLIBCXX_PARALLEL) # error illegal use of multiple inlined namespaces # endif # if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_DEBUG) # error illegal use of multiple inlined namespaces # endif # if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_PARALLEL) # error illegal use of multiple inlined namespaces # endif // Check for invalid use due to lack for weak symbols. # if __NO_INLINE__ && !__GXX_WEAK__ # warning currently using inlined namespace mode which may fail \ without inlining due to lack of weak symbols # endif #endif // Macros for namespace scope. Either namespace std:: or the name // of some nested namespace within it corresponding to the active mode. // _GLIBCXX_STD_A // _GLIBCXX_STD_C // // Macros for opening/closing conditional namespaces. // _GLIBCXX_BEGIN_NAMESPACE_ALGO // _GLIBCXX_END_NAMESPACE_ALGO // _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // _GLIBCXX_END_NAMESPACE_CONTAINER #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PROFILE) # define _GLIBCXX_STD_C __cxx1998 # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER \ namespace _GLIBCXX_STD_C { # define _GLIBCXX_END_NAMESPACE_CONTAINER } #else # define _GLIBCXX_STD_C std # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER # define _GLIBCXX_END_NAMESPACE_CONTAINER #endif #ifdef _GLIBCXX_PARALLEL # define _GLIBCXX_STD_A __cxx1998 # define _GLIBCXX_BEGIN_NAMESPACE_ALGO \ namespace _GLIBCXX_STD_A { # define _GLIBCXX_END_NAMESPACE_ALGO } #else # define _GLIBCXX_STD_A std # define _GLIBCXX_BEGIN_NAMESPACE_ALGO # define _GLIBCXX_END_NAMESPACE_ALGO #endif // GLIBCXX_ABI Deprecated // Define if compatibility should be provided for -mlong-double-64. #undef _GLIBCXX_LONG_DOUBLE_COMPAT // Inline namespace for long double 128 mode. #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ namespace std { inline namespace __gnu_cxx_ldbl128 { } } # define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ldbl128:: # define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ldbl128 { # define _GLIBCXX_END_NAMESPACE_LDBL } #else # define _GLIBCXX_NAMESPACE_LDBL # define _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL #endif #if _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_CXX11 # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11 # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_CXX11 #else # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_LDBL # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_LDBL #endif // Debug Mode implies checking assertions. #if defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_ASSERTIONS) # define _GLIBCXX_ASSERTIONS 1 #endif // Disable std::string explicit instantiation declarations in order to assert. #ifdef _GLIBCXX_ASSERTIONS # undef _GLIBCXX_EXTERN_TEMPLATE # define _GLIBCXX_EXTERN_TEMPLATE -1 #endif // Assert. #if defined(_GLIBCXX_ASSERTIONS) \ || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS) namespace std { // Avoid the use of assert, because we're trying to keep the <cassert> // include out of the mix. inline void __replacement_assert(const char* __file, int __line, const char* __function, const char* __condition) { __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, __function, __condition); __builtin_abort(); } } #define __glibcxx_assert_impl(_Condition) \ do \ { \ if (! (_Condition)) \ std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ #_Condition); \ } while (false) #endif #if defined(_GLIBCXX_ASSERTIONS) # define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition) #else # define __glibcxx_assert(_Condition) #endif // Macros for race detectors. // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain // atomic (lock-free) synchronization to race detectors: // the race detector will infer a happens-before arc from the former to the // latter when they share the same argument pointer. // // The most frequent use case for these macros (and the only case in the // current implementation of the library) is atomic reference counting: // void _M_remove_reference() // { // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount); // if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, -1) <= 0) // { // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount); // _M_destroy(__a); // } // } // The annotations in this example tell the race detector that all memory // accesses occurred when the refcount was positive do not race with // memory accesses which occurred after the refcount became zero. #ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE # define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) #endif #ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER # define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) #endif // Macros for C linkage: define extern "C" linkage only when using C++. # define _GLIBCXX_BEGIN_EXTERN_C extern "C" { # define _GLIBCXX_END_EXTERN_C } # define _GLIBCXX_USE_ALLOCATOR_NEW 1 #else // !__cplusplus # define _GLIBCXX_BEGIN_EXTERN_C # define _GLIBCXX_END_EXTERN_C #endif // First includes. // Pick up any OS-specific definitions. #include <bits/os_defines.h> // Pick up any CPU-specific definitions. #include <bits/cpu_defines.h> // If platform uses neither visibility nor psuedo-visibility, // specify empty default for namespace annotation macros. #ifndef _GLIBCXX_PSEUDO_VISIBILITY # define _GLIBCXX_PSEUDO_VISIBILITY(V) #endif // Certain function definitions that are meant to be overridable from // user code are decorated with this macro. For some targets, this // macro causes these definitions to be weak. #ifndef _GLIBCXX_WEAK_DEFINITION # define _GLIBCXX_WEAK_DEFINITION #endif // By default, we assume that __GXX_WEAK__ also means that there is support // for declaring functions as weak while not defining such functions. This // allows for referring to functions provided by other libraries (e.g., // libitm) without depending on them if the respective features are not used. #ifndef _GLIBCXX_USE_WEAK_REF # define _GLIBCXX_USE_WEAK_REF __GXX_WEAK__ #endif // Conditionally enable annotations for the Transactional Memory TS on C++11. // Most of the following conditions are due to limitations in the current // implementation. #if __cplusplus >= 201103L && _GLIBCXX_USE_CXX11_ABI \ && _GLIBCXX_USE_DUAL_ABI && __cpp_transactional_memory >= 201505L \ && !_GLIBCXX_FULLY_DYNAMIC_STRING && _GLIBCXX_USE_WEAK_REF \ && _GLIBCXX_USE_ALLOCATOR_NEW #define _GLIBCXX_TXN_SAFE transaction_safe #define _GLIBCXX_TXN_SAFE_DYN transaction_safe_dynamic #else #define _GLIBCXX_TXN_SAFE #define _GLIBCXX_TXN_SAFE_DYN #endif #if __cplusplus > 201402L // In C++17 mathematical special functions are in namespace std. # define _GLIBCXX_USE_STD_SPEC_FUNCS 1 #elif __cplusplus >= 201103L && __STDCPP_WANT_MATH_SPEC_FUNCS__ != 0 // For C++11 and C++14 they are in namespace std when requested. # define _GLIBCXX_USE_STD_SPEC_FUNCS 1 #endif // The remainder of the prewritten config is automatic; all the // user hooks are listed above. // Create a boolean flag to be used to determine if --fast-math is set. #ifdef __FAST_MATH__ # define _GLIBCXX_FAST_MATH 1 #else # define _GLIBCXX_FAST_MATH 0 #endif // This marks string literals in header files to be extracted for eventual // translation. It is primarily used for messages in thrown exceptions; see // src/functexcept.cc. We use __N because the more traditional _N is used // for something else under certain OSes (see BADNAMES). #define __N(msgid) (msgid) // For example, <windows.h> is known to #define min and max as macros... #undef min #undef max // N.B. these _GLIBCXX_USE_C99_XXX macros are defined unconditionally // so they should be tested with #if not with #ifdef. #if __cplusplus >= 201103L # ifndef _GLIBCXX_USE_C99_MATH # define _GLIBCXX_USE_C99_MATH _GLIBCXX11_USE_C99_MATH # endif # ifndef _GLIBCXX_USE_C99_COMPLEX # define _GLIBCXX_USE_C99_COMPLEX _GLIBCXX11_USE_C99_COMPLEX # endif # ifndef _GLIBCXX_USE_C99_STDIO # define _GLIBCXX_USE_C99_STDIO _GLIBCXX11_USE_C99_STDIO # endif # ifndef _GLIBCXX_USE_C99_STDLIB # define _GLIBCXX_USE_C99_STDLIB _GLIBCXX11_USE_C99_STDLIB # endif # ifndef _GLIBCXX_USE_C99_WCHAR # define _GLIBCXX_USE_C99_WCHAR _GLIBCXX11_USE_C99_WCHAR # endif #else # ifndef _GLIBCXX_USE_C99_MATH # define _GLIBCXX_USE_C99_MATH _GLIBCXX98_USE_C99_MATH # endif # ifndef _GLIBCXX_USE_C99_COMPLEX # define _GLIBCXX_USE_C99_COMPLEX _GLIBCXX98_USE_C99_COMPLEX # endif # ifndef _GLIBCXX_USE_C99_STDIO # define _GLIBCXX_USE_C99_STDIO _GLIBCXX98_USE_C99_STDIO # endif # ifndef _GLIBCXX_USE_C99_STDLIB # define _GLIBCXX_USE_C99_STDLIB _GLIBCXX98_USE_C99_STDLIB # endif # ifndef _GLIBCXX_USE_C99_WCHAR # define _GLIBCXX_USE_C99_WCHAR _GLIBCXX98_USE_C99_WCHAR # endif #endif /* Define if __float128 is supported on this host. */ #if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) #define _GLIBCXX_USE_FLOAT128 1 #endif // End of prewritten config; the settings discovered at configure time follow. /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `acosf' function. */ #define _GLIBCXX_HAVE_ACOSF 1 /* Define to 1 if you have the `acosl' function. */ #define _GLIBCXX_HAVE_ACOSL 1 /* Define to 1 if you have the `aligned_alloc' function. */ #define _GLIBCXX_HAVE_ALIGNED_ALLOC 1 /* Define to 1 if you have the `asinf' function. */ #define _GLIBCXX_HAVE_ASINF 1 /* Define to 1 if you have the `asinl' function. */ #define _GLIBCXX_HAVE_ASINL 1 /* Define to 1 if the target assembler supports .symver directive. */ #define _GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE 1 /* Define to 1 if you have the `atan2f' function. */ #define _GLIBCXX_HAVE_ATAN2F 1 /* Define to 1 if you have the `atan2l' function. */ #define _GLIBCXX_HAVE_ATAN2L 1 /* Define to 1 if you have the `atanf' function. */ #define _GLIBCXX_HAVE_ATANF 1 /* Define to 1 if you have the `atanl' function. */ #define _GLIBCXX_HAVE_ATANL 1 /* Define to 1 if you have the `at_quick_exit' function. */ #define _GLIBCXX_HAVE_AT_QUICK_EXIT 1 /* Define to 1 if the target assembler supports thread-local storage. */ /* #undef _GLIBCXX_HAVE_CC_TLS */ /* Define to 1 if you have the `ceilf' function. */ #define _GLIBCXX_HAVE_CEILF 1 /* Define to 1 if you have the `ceill' function. */ #define _GLIBCXX_HAVE_CEILL 1 /* Define to 1 if you have the <complex.h> header file. */ #define _GLIBCXX_HAVE_COMPLEX_H 1 /* Define to 1 if you have the `cosf' function. */ #define _GLIBCXX_HAVE_COSF 1 /* Define to 1 if you have the `coshf' function. */ #define _GLIBCXX_HAVE_COSHF 1 /* Define to 1 if you have the `coshl' function. */ #define _GLIBCXX_HAVE_COSHL 1 /* Define to 1 if you have the `cosl' function. */ #define _GLIBCXX_HAVE_COSL 1 /* Define to 1 if you have the <dirent.h> header file. */ #define _GLIBCXX_HAVE_DIRENT_H 1 /* Define to 1 if you have the <dlfcn.h> header file. */ #define _GLIBCXX_HAVE_DLFCN_H 1 /* Define if EBADMSG exists. */ #define _GLIBCXX_HAVE_EBADMSG 1 /* Define if ECANCELED exists. */ #define _GLIBCXX_HAVE_ECANCELED 1 /* Define if ECHILD exists. */ #define _GLIBCXX_HAVE_ECHILD 1 /* Define if EIDRM exists. */ #define _GLIBCXX_HAVE_EIDRM 1 /* Define to 1 if you have the <endian.h> header file. */ #define _GLIBCXX_HAVE_ENDIAN_H 1 /* Define if ENODATA exists. */ #define _GLIBCXX_HAVE_ENODATA 1 /* Define if ENOLINK exists. */ #define _GLIBCXX_HAVE_ENOLINK 1 /* Define if ENOSPC exists. */ #define _GLIBCXX_HAVE_ENOSPC 1 /* Define if ENOSR exists. */ #define _GLIBCXX_HAVE_ENOSR 1 /* Define if ENOSTR exists. */ #define _GLIBCXX_HAVE_ENOSTR 1 /* Define if ENOTRECOVERABLE exists. */ #define _GLIBCXX_HAVE_ENOTRECOVERABLE 1 /* Define if ENOTSUP exists. */ #define _GLIBCXX_HAVE_ENOTSUP 1 /* Define if EOVERFLOW exists. */ #define _GLIBCXX_HAVE_EOVERFLOW 1 /* Define if EOWNERDEAD exists. */ #define _GLIBCXX_HAVE_EOWNERDEAD 1 /* Define if EPERM exists. */ #define _GLIBCXX_HAVE_EPERM 1 /* Define if EPROTO exists. */ #define _GLIBCXX_HAVE_EPROTO 1 /* Define if ETIME exists. */ #define _GLIBCXX_HAVE_ETIME 1 /* Define if ETIMEDOUT exists. */ #define _GLIBCXX_HAVE_ETIMEDOUT 1 /* Define if ETXTBSY exists. */ #define _GLIBCXX_HAVE_ETXTBSY 1 /* Define if EWOULDBLOCK exists. */ #define _GLIBCXX_HAVE_EWOULDBLOCK 1 /* Define to 1 if GCC 4.6 supported std::exception_ptr for the target */ #define _GLIBCXX_HAVE_EXCEPTION_PTR_SINCE_GCC46 1 /* Define to 1 if you have the <execinfo.h> header file. */ #define _GLIBCXX_HAVE_EXECINFO_H 1 /* Define to 1 if you have the `expf' function. */ #define _GLIBCXX_HAVE_EXPF 1 /* Define to 1 if you have the `expl' function. */ #define _GLIBCXX_HAVE_EXPL 1 /* Define to 1 if you have the `fabsf' function. */ #define _GLIBCXX_HAVE_FABSF 1 /* Define to 1 if you have the `fabsl' function. */ #define _GLIBCXX_HAVE_FABSL 1 /* Define to 1 if you have the <fcntl.h> header file. */ #define _GLIBCXX_HAVE_FCNTL_H 1 /* Define to 1 if you have the <fenv.h> header file. */ #define _GLIBCXX_HAVE_FENV_H 1 /* Define to 1 if you have the `finite' function. */ #define _GLIBCXX_HAVE_FINITE 1 /* Define to 1 if you have the `finitef' function. */ #define _GLIBCXX_HAVE_FINITEF 1 /* Define to 1 if you have the `finitel' function. */ #define _GLIBCXX_HAVE_FINITEL 1 /* Define to 1 if you have the <float.h> header file. */ #define _GLIBCXX_HAVE_FLOAT_H 1 /* Define to 1 if you have the `floorf' function. */ #define _GLIBCXX_HAVE_FLOORF 1 /* Define to 1 if you have the `floorl' function. */ #define _GLIBCXX_HAVE_FLOORL 1 /* Define to 1 if you have the `fmodf' function. */ #define _GLIBCXX_HAVE_FMODF 1 /* Define to 1 if you have the `fmodl' function. */ #define _GLIBCXX_HAVE_FMODL 1 /* Define to 1 if you have the `fpclass' function. */ /* #undef _GLIBCXX_HAVE_FPCLASS */ /* Define to 1 if you have the <fp.h> header file. */ /* #undef _GLIBCXX_HAVE_FP_H */ /* Define to 1 if you have the `frexpf' function. */ #define _GLIBCXX_HAVE_FREXPF 1 /* Define to 1 if you have the `frexpl' function. */ #define _GLIBCXX_HAVE_FREXPL 1 /* Define if _Unwind_GetIPInfo is available. */ #define _GLIBCXX_HAVE_GETIPINFO 1 /* Define if gets is available in <stdio.h> before C++14. */ #define _GLIBCXX_HAVE_GETS 1 /* Define to 1 if you have the `hypot' function. */ #define _GLIBCXX_HAVE_HYPOT 1 /* Define to 1 if you have the `hypotf' function. */ #define _GLIBCXX_HAVE_HYPOTF 1 /* Define to 1 if you have the `hypotl' function. */ #define _GLIBCXX_HAVE_HYPOTL 1 /* Define if you have the iconv() function. */ #define _GLIBCXX_HAVE_ICONV 1 /* Define to 1 if you have the <ieeefp.h> header file. */ /* #undef _GLIBCXX_HAVE_IEEEFP_H */ /* Define if int64_t is available in <stdint.h>. */ #define _GLIBCXX_HAVE_INT64_T 1 /* Define if int64_t is a long. */ /* #undef _GLIBCXX_HAVE_INT64_T_LONG */ /* Define if int64_t is a long long. */ #define _GLIBCXX_HAVE_INT64_T_LONG_LONG 1 /* Define to 1 if you have the <inttypes.h> header file. */ #define _GLIBCXX_HAVE_INTTYPES_H 1 /* Define to 1 if you have the `isinf' function. */ /* #undef _GLIBCXX_HAVE_ISINF */ /* Define to 1 if you have the `isinff' function. */ #define _GLIBCXX_HAVE_ISINFF 1 /* Define to 1 if you have the `isinfl' function. */ #define _GLIBCXX_HAVE_ISINFL 1 /* Define to 1 if you have the `isnan' function. */ /* #undef _GLIBCXX_HAVE_ISNAN */ /* Define to 1 if you have the `isnanf' function. */ #define _GLIBCXX_HAVE_ISNANF 1 /* Define to 1 if you have the `isnanl' function. */ #define _GLIBCXX_HAVE_ISNANL 1 /* Defined if iswblank exists. */ #define _GLIBCXX_HAVE_ISWBLANK 1 /* Define if LC_MESSAGES is available in <locale.h>. */ #define _GLIBCXX_HAVE_LC_MESSAGES 1 /* Define to 1 if you have the `ldexpf' function. */ #define _GLIBCXX_HAVE_LDEXPF 1 /* Define to 1 if you have the `ldexpl' function. */ #define _GLIBCXX_HAVE_LDEXPL 1 /* Define to 1 if you have the <libintl.h> header file. */ #define _GLIBCXX_HAVE_LIBINTL_H 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_AS 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_DATA 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_FSIZE 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_RSS 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_VMEM 0 /* Define if futex syscall is available. */ #define _GLIBCXX_HAVE_LINUX_FUTEX 1 /* Define to 1 if you have the <linux/random.h> header file. */ #define _GLIBCXX_HAVE_LINUX_RANDOM_H 1 /* Define to 1 if you have the <linux/types.h> header file. */ #define _GLIBCXX_HAVE_LINUX_TYPES_H 1 /* Define to 1 if you have the <locale.h> header file. */ #define _GLIBCXX_HAVE_LOCALE_H 1 /* Define to 1 if you have the `log10f' function. */ #define _GLIBCXX_HAVE_LOG10F 1 /* Define to 1 if you have the `log10l' function. */ #define _GLIBCXX_HAVE_LOG10L 1 /* Define to 1 if you have the `logf' function. */ #define _GLIBCXX_HAVE_LOGF 1 /* Define to 1 if you have the `logl' function. */ #define _GLIBCXX_HAVE_LOGL 1 /* Define to 1 if you have the <machine/endian.h> header file. */ /* #undef _GLIBCXX_HAVE_MACHINE_ENDIAN_H */ /* Define to 1 if you have the <machine/param.h> header file. */ /* #undef _GLIBCXX_HAVE_MACHINE_PARAM_H */ /* Define if mbstate_t exists in wchar.h. */ #define _GLIBCXX_HAVE_MBSTATE_T 1 /* Define to 1 if you have the `memalign' function. */ #define _GLIBCXX_HAVE_MEMALIGN 1 /* Define to 1 if you have the <memory.h> header file. */ #define _GLIBCXX_HAVE_MEMORY_H 1 /* Define to 1 if you have the `modf' function. */ #define _GLIBCXX_HAVE_MODF 1 /* Define to 1 if you have the `modff' function. */ #define _GLIBCXX_HAVE_MODFF 1 /* Define to 1 if you have the `modfl' function. */ #define _GLIBCXX_HAVE_MODFL 1 /* Define to 1 if you have the <nan.h> header file. */ /* #undef _GLIBCXX_HAVE_NAN_H */ /* Define if <math.h> defines obsolete isinf function. */ /* #undef _GLIBCXX_HAVE_OBSOLETE_ISINF */ /* Define if <math.h> defines obsolete isnan function. */ /* #undef _GLIBCXX_HAVE_OBSOLETE_ISNAN */ /* Define if poll is available in <poll.h>. */ #define _GLIBCXX_HAVE_POLL 1 /* Define to 1 if you have the `posix_memalign' function. */ #define _GLIBCXX_HAVE_POSIX_MEMALIGN 1 /* Define to 1 if you have the `powf' function. */ #define _GLIBCXX_HAVE_POWF 1 /* Define to 1 if you have the `powl' function. */ #define _GLIBCXX_HAVE_POWL 1 /* Define to 1 if you have the `qfpclass' function. */ /* #undef _GLIBCXX_HAVE_QFPCLASS */ /* Define to 1 if you have the `quick_exit' function. */ #define _GLIBCXX_HAVE_QUICK_EXIT 1 /* Define to 1 if you have the `setenv' function. */ #define _GLIBCXX_HAVE_SETENV 1 /* Define to 1 if you have the `sincos' function. */ #define _GLIBCXX_HAVE_SINCOS 1 /* Define to 1 if you have the `sincosf' function. */ #define _GLIBCXX_HAVE_SINCOSF 1 /* Define to 1 if you have the `sincosl' function. */ #define _GLIBCXX_HAVE_SINCOSL 1 /* Define to 1 if you have the `sinf' function. */ #define _GLIBCXX_HAVE_SINF 1 /* Define to 1 if you have the `sinhf' function. */ #define _GLIBCXX_HAVE_SINHF 1 /* Define to 1 if you have the `sinhl' function. */ #define _GLIBCXX_HAVE_SINHL 1 /* Define to 1 if you have the `sinl' function. */ #define _GLIBCXX_HAVE_SINL 1 /* Defined if sleep exists. */ /* #undef _GLIBCXX_HAVE_SLEEP */ /* Define to 1 if you have the `sqrtf' function. */ #define _GLIBCXX_HAVE_SQRTF 1 /* Define to 1 if you have the `sqrtl' function. */ #define _GLIBCXX_HAVE_SQRTL 1 /* Define to 1 if you have the <stdalign.h> header file. */ #define _GLIBCXX_HAVE_STDALIGN_H 1 /* Define to 1 if you have the <stdbool.h> header file. */ #define _GLIBCXX_HAVE_STDBOOL_H 1 /* Define to 1 if you have the <stdint.h> header file. */ #define _GLIBCXX_HAVE_STDINT_H 1 /* Define to 1 if you have the <stdlib.h> header file. */ #define _GLIBCXX_HAVE_STDLIB_H 1 /* Define if strerror_l is available in <string.h>. */ #define _GLIBCXX_HAVE_STRERROR_L 1 /* Define if strerror_r is available in <string.h>. */ #define _GLIBCXX_HAVE_STRERROR_R 1 /* Define to 1 if you have the <strings.h> header file. */ #define _GLIBCXX_HAVE_STRINGS_H 1 /* Define to 1 if you have the <string.h> header file. */ #define _GLIBCXX_HAVE_STRING_H 1 /* Define to 1 if you have the `strtof' function. */ #define _GLIBCXX_HAVE_STRTOF 1 /* Define to 1 if you have the `strtold' function. */ #define _GLIBCXX_HAVE_STRTOLD 1 /* Define to 1 if `d_type' is a member of `struct dirent'. */ #define _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE 1 /* Define if strxfrm_l is available in <string.h>. */ #define _GLIBCXX_HAVE_STRXFRM_L 1 /* Define to 1 if the target runtime linker supports binding the same symbol to different versions. */ #define _GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT 1 /* Define to 1 if you have the <sys/filio.h> header file. */ /* #undef _GLIBCXX_HAVE_SYS_FILIO_H */ /* Define to 1 if you have the <sys/ioctl.h> header file. */ #define _GLIBCXX_HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the <sys/ipc.h> header file. */ #define _GLIBCXX_HAVE_SYS_IPC_H 1 /* Define to 1 if you have the <sys/isa_defs.h> header file. */ /* #undef _GLIBCXX_HAVE_SYS_ISA_DEFS_H */ /* Define to 1 if you have the <sys/machine.h> header file. */ /* #undef _GLIBCXX_HAVE_SYS_MACHINE_H */ /* Define to 1 if you have the <sys/param.h> header file. */ #define _GLIBCXX_HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the <sys/resource.h> header file. */ #define _GLIBCXX_HAVE_SYS_RESOURCE_H 1 /* Define to 1 if you have a suitable <sys/sdt.h> header file */ #define _GLIBCXX_HAVE_SYS_SDT_H 1 /* Define to 1 if you have the <sys/sem.h> header file. */ #define _GLIBCXX_HAVE_SYS_SEM_H 1 /* Define to 1 if you have the <sys/statvfs.h> header file. */ #define _GLIBCXX_HAVE_SYS_STATVFS_H 1 /* Define to 1 if you have the <sys/stat.h> header file. */ #define _GLIBCXX_HAVE_SYS_STAT_H 1 /* Define to 1 if you have the <sys/sysinfo.h> header file. */ #define _GLIBCXX_HAVE_SYS_SYSINFO_H 1 /* Define to 1 if you have the <sys/time.h> header file. */ #define _GLIBCXX_HAVE_SYS_TIME_H 1 /* Define to 1 if you have the <sys/types.h> header file. */ #define _GLIBCXX_HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the <sys/uio.h> header file. */ #define _GLIBCXX_HAVE_SYS_UIO_H 1 /* Define if S_IFREG is available in <sys/stat.h>. */ /* #undef _GLIBCXX_HAVE_S_IFREG */ /* Define if S_ISREG is available in <sys/stat.h>. */ #define _GLIBCXX_HAVE_S_ISREG 1 /* Define to 1 if you have the `tanf' function. */ #define _GLIBCXX_HAVE_TANF 1 /* Define to 1 if you have the `tanhf' function. */ #define _GLIBCXX_HAVE_TANHF 1 /* Define to 1 if you have the `tanhl' function. */ #define _GLIBCXX_HAVE_TANHL 1 /* Define to 1 if you have the `tanl' function. */ #define _GLIBCXX_HAVE_TANL 1 /* Define to 1 if you have the <tgmath.h> header file. */ #define _GLIBCXX_HAVE_TGMATH_H 1 /* Define to 1 if the target supports thread-local storage. */ #define _GLIBCXX_HAVE_TLS 1 /* Define to 1 if you have the <uchar.h> header file. */ #define _GLIBCXX_HAVE_UCHAR_H 1 /* Define to 1 if you have the <unistd.h> header file. */ #define _GLIBCXX_HAVE_UNISTD_H 1 /* Defined if usleep exists. */ /* #undef _GLIBCXX_HAVE_USLEEP */ /* Define to 1 if you have the <utime.h> header file. */ #define _GLIBCXX_HAVE_UTIME_H 1 /* Defined if vfwscanf exists. */ #define _GLIBCXX_HAVE_VFWSCANF 1 /* Defined if vswscanf exists. */ #define _GLIBCXX_HAVE_VSWSCANF 1 /* Defined if vwscanf exists. */ #define _GLIBCXX_HAVE_VWSCANF 1 /* Define to 1 if you have the <wchar.h> header file. */ #define _GLIBCXX_HAVE_WCHAR_H 1 /* Defined if wcstof exists. */ #define _GLIBCXX_HAVE_WCSTOF 1 /* Define to 1 if you have the <wctype.h> header file. */ #define _GLIBCXX_HAVE_WCTYPE_H 1 /* Defined if Sleep exists. */ /* #undef _GLIBCXX_HAVE_WIN32_SLEEP */ /* Define if writev is available in <sys/uio.h>. */ #define _GLIBCXX_HAVE_WRITEV 1 /* Define to 1 if you have the `_acosf' function. */ /* #undef _GLIBCXX_HAVE__ACOSF */ /* Define to 1 if you have the `_acosl' function. */ /* #undef _GLIBCXX_HAVE__ACOSL */ /* Define to 1 if you have the `_aligned_malloc' function. */ /* #undef _GLIBCXX_HAVE__ALIGNED_MALLOC */ /* Define to 1 if you have the `_asinf' function. */ /* #undef _GLIBCXX_HAVE__ASINF */ /* Define to 1 if you have the `_asinl' function. */ /* #undef _GLIBCXX_HAVE__ASINL */ /* Define to 1 if you have the `_atan2f' function. */ /* #undef _GLIBCXX_HAVE__ATAN2F */ /* Define to 1 if you have the `_atan2l' function. */ /* #undef _GLIBCXX_HAVE__ATAN2L */ /* Define to 1 if you have the `_atanf' function. */ /* #undef _GLIBCXX_HAVE__ATANF */ /* Define to 1 if you have the `_atanl' function. */ /* #undef _GLIBCXX_HAVE__ATANL */ /* Define to 1 if you have the `_ceilf' function. */ /* #undef _GLIBCXX_HAVE__CEILF */ /* Define to 1 if you have the `_ceill' function. */ /* #undef _GLIBCXX_HAVE__CEILL */ /* Define to 1 if you have the `_cosf' function. */ /* #undef _GLIBCXX_HAVE__COSF */ /* Define to 1 if you have the `_coshf' function. */ /* #undef _GLIBCXX_HAVE__COSHF */ /* Define to 1 if you have the `_coshl' function. */ /* #undef _GLIBCXX_HAVE__COSHL */ /* Define to 1 if you have the `_cosl' function. */ /* #undef _GLIBCXX_HAVE__COSL */ /* Define to 1 if you have the `_expf' function. */ /* #undef _GLIBCXX_HAVE__EXPF */ /* Define to 1 if you have the `_expl' function. */ /* #undef _GLIBCXX_HAVE__EXPL */ /* Define to 1 if you have the `_fabsf' function. */ /* #undef _GLIBCXX_HAVE__FABSF */ /* Define to 1 if you have the `_fabsl' function. */ /* #undef _GLIBCXX_HAVE__FABSL */ /* Define to 1 if you have the `_finite' function. */ /* #undef _GLIBCXX_HAVE__FINITE */ /* Define to 1 if you have the `_finitef' function. */ /* #undef _GLIBCXX_HAVE__FINITEF */ /* Define to 1 if you have the `_finitel' function. */ /* #undef _GLIBCXX_HAVE__FINITEL */ /* Define to 1 if you have the `_floorf' function. */ /* #undef _GLIBCXX_HAVE__FLOORF */ /* Define to 1 if you have the `_floorl' function. */ /* #undef _GLIBCXX_HAVE__FLOORL */ /* Define to 1 if you have the `_fmodf' function. */ /* #undef _GLIBCXX_HAVE__FMODF */ /* Define to 1 if you have the `_fmodl' function. */ /* #undef _GLIBCXX_HAVE__FMODL */ /* Define to 1 if you have the `_fpclass' function. */ /* #undef _GLIBCXX_HAVE__FPCLASS */ /* Define to 1 if you have the `_frexpf' function. */ /* #undef _GLIBCXX_HAVE__FREXPF */ /* Define to 1 if you have the `_frexpl' function. */ /* #undef _GLIBCXX_HAVE__FREXPL */ /* Define to 1 if you have the `_hypot' function. */ /* #undef _GLIBCXX_HAVE__HYPOT */ /* Define to 1 if you have the `_hypotf' function. */ /* #undef _GLIBCXX_HAVE__HYPOTF */ /* Define to 1 if you have the `_hypotl' function. */ /* #undef _GLIBCXX_HAVE__HYPOTL */ /* Define to 1 if you have the `_isinf' function. */ /* #undef _GLIBCXX_HAVE__ISINF */ /* Define to 1 if you have the `_isinff' function. */ /* #undef _GLIBCXX_HAVE__ISINFF */ /* Define to 1 if you have the `_isinfl' function. */ /* #undef _GLIBCXX_HAVE__ISINFL */ /* Define to 1 if you have the `_isnan' function. */ /* #undef _GLIBCXX_HAVE__ISNAN */ /* Define to 1 if you have the `_isnanf' function. */ /* #undef _GLIBCXX_HAVE__ISNANF */ /* Define to 1 if you have the `_isnanl' function. */ /* #undef _GLIBCXX_HAVE__ISNANL */ /* Define to 1 if you have the `_ldexpf' function. */ /* #undef _GLIBCXX_HAVE__LDEXPF */ /* Define to 1 if you have the `_ldexpl' function. */ /* #undef _GLIBCXX_HAVE__LDEXPL */ /* Define to 1 if you have the `_log10f' function. */ /* #undef _GLIBCXX_HAVE__LOG10F */ /* Define to 1 if you have the `_log10l' function. */ /* #undef _GLIBCXX_HAVE__LOG10L */ /* Define to 1 if you have the `_logf' function. */ /* #undef _GLIBCXX_HAVE__LOGF */ /* Define to 1 if you have the `_logl' function. */ /* #undef _GLIBCXX_HAVE__LOGL */ /* Define to 1 if you have the `_modf' function. */ /* #undef _GLIBCXX_HAVE__MODF */ /* Define to 1 if you have the `_modff' function. */ /* #undef _GLIBCXX_HAVE__MODFF */ /* Define to 1 if you have the `_modfl' function. */ /* #undef _GLIBCXX_HAVE__MODFL */ /* Define to 1 if you have the `_powf' function. */ /* #undef _GLIBCXX_HAVE__POWF */ /* Define to 1 if you have the `_powl' function. */ /* #undef _GLIBCXX_HAVE__POWL */ /* Define to 1 if you have the `_qfpclass' function. */ /* #undef _GLIBCXX_HAVE__QFPCLASS */ /* Define to 1 if you have the `_sincos' function. */ /* #undef _GLIBCXX_HAVE__SINCOS */ /* Define to 1 if you have the `_sincosf' function. */ /* #undef _GLIBCXX_HAVE__SINCOSF */ /* Define to 1 if you have the `_sincosl' function. */ /* #undef _GLIBCXX_HAVE__SINCOSL */ /* Define to 1 if you have the `_sinf' function. */ /* #undef _GLIBCXX_HAVE__SINF */ /* Define to 1 if you have the `_sinhf' function. */ /* #undef _GLIBCXX_HAVE__SINHF */ /* Define to 1 if you have the `_sinhl' function. */ /* #undef _GLIBCXX_HAVE__SINHL */ /* Define to 1 if you have the `_sinl' function. */ /* #undef _GLIBCXX_HAVE__SINL */ /* Define to 1 if you have the `_sqrtf' function. */ /* #undef _GLIBCXX_HAVE__SQRTF */ /* Define to 1 if you have the `_sqrtl' function. */ /* #undef _GLIBCXX_HAVE__SQRTL */ /* Define to 1 if you have the `_tanf' function. */ /* #undef _GLIBCXX_HAVE__TANF */ /* Define to 1 if you have the `_tanhf' function. */ /* #undef _GLIBCXX_HAVE__TANHF */ /* Define to 1 if you have the `_tanhl' function. */ /* #undef _GLIBCXX_HAVE__TANHL */ /* Define to 1 if you have the `_tanl' function. */ /* #undef _GLIBCXX_HAVE__TANL */ /* Define to 1 if you have the `__cxa_thread_atexit' function. */ /* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT */ /* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */ #define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1 /* Define as const if the declaration of iconv() needs const. */ #define _GLIBCXX_ICONV_CONST /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Name of package */ /* #undef _GLIBCXX_PACKAGE */ /* Define to the address where bug reports for this package should be sent. */ #define _GLIBCXX_PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define _GLIBCXX_PACKAGE_NAME "package-unused" /* Define to the full name and version of this package. */ #define _GLIBCXX_PACKAGE_STRING "package-unused version-unused" /* Define to the one symbol short name of this package. */ #define _GLIBCXX_PACKAGE_TARNAME "libstdc++" /* Define to the home page for this package. */ #define _GLIBCXX_PACKAGE_URL "" /* Define to the version of this package. */ #define _GLIBCXX_PACKAGE__GLIBCXX_VERSION "version-unused" /* The size of `char', as computed by sizeof. */ /* #undef SIZEOF_CHAR */ /* The size of `int', as computed by sizeof. */ /* #undef SIZEOF_INT */ /* The size of `long', as computed by sizeof. */ /* #undef SIZEOF_LONG */ /* The size of `short', as computed by sizeof. */ /* #undef SIZEOF_SHORT */ /* The size of `void *', as computed by sizeof. */ /* #undef SIZEOF_VOID_P */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ /* #undef _GLIBCXX_VERSION */ /* Number of bits in a file offset, on hosts where this is settable. */ #define _GLIBCXX_FILE_OFFSET_BITS 64 /* Define if C99 functions in <complex.h> should be used in <complex> for C++11. Using compiler builtins for these functions requires corresponding C99 library functions to be present. */ #define _GLIBCXX11_USE_C99_COMPLEX 1 /* Define if C99 functions or macros in <math.h> should be imported in <cmath> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_MATH 1 /* Define if C99 functions or macros in <stdio.h> should be imported in <cstdio> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_STDIO 1 /* Define if C99 functions or macros in <stdlib.h> should be imported in <cstdlib> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_STDLIB 1 /* Define if C99 functions or macros in <wchar.h> should be imported in <cwchar> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_WCHAR 1 /* Define if C99 functions in <complex.h> should be used in <complex> for C++98. Using compiler builtins for these functions requires corresponding C99 library functions to be present. */ #define _GLIBCXX98_USE_C99_COMPLEX 1 /* Define if C99 functions or macros in <math.h> should be imported in <cmath> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_MATH 1 /* Define if C99 functions or macros in <stdio.h> should be imported in <cstdio> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_STDIO 1 /* Define if C99 functions or macros in <stdlib.h> should be imported in <cstdlib> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_STDLIB 1 /* Define if C99 functions or macros in <wchar.h> should be imported in <cwchar> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_WCHAR 1 /* Define if the compiler supports C++11 atomics. */ #define _GLIBCXX_ATOMIC_BUILTINS 1 /* Define to use concept checking code from the boost libraries. */ /* #undef _GLIBCXX_CONCEPT_CHECKS */ /* Define to 1 if a fully dynamic basic_string is wanted, 0 to disable, undefined for platform defaults */ #define _GLIBCXX_FULLY_DYNAMIC_STRING 0 /* Define if gthreads library is available. */ #define _GLIBCXX_HAS_GTHREADS 1 /* Define to 1 if a full hosted library is built, or 0 if freestanding. */ #define _GLIBCXX_HOSTED 1 /* Define if compatibility should be provided for -mlong-double-64. */ /* Define to the letter to which size_t is mangled. */ #define _GLIBCXX_MANGLE_SIZE_T j /* Define if C99 llrint and llround functions are missing from <math.h>. */ /* #undef _GLIBCXX_NO_C99_ROUNDING_FUNCS */ /* Define if ptrdiff_t is int. */ #define _GLIBCXX_PTRDIFF_T_IS_INT 1 /* Define if using setrlimit to set resource limits during "make check" */ #define _GLIBCXX_RES_LIMITS 1 /* Define if size_t is unsigned int. */ #define _GLIBCXX_SIZE_T_IS_UINT 1 /* Define to the value of the EOF integer constant. */ #define _GLIBCXX_STDIO_EOF -1 /* Define to the value of the SEEK_CUR integer constant. */ #define _GLIBCXX_STDIO_SEEK_CUR 1 /* Define to the value of the SEEK_END integer constant. */ #define _GLIBCXX_STDIO_SEEK_END 2 /* Define to use symbol versioning in the shared library. */ #define _GLIBCXX_SYMVER 1 /* Define to use darwin versioning in the shared library. */ /* #undef _GLIBCXX_SYMVER_DARWIN */ /* Define to use GNU versioning in the shared library. */ #define _GLIBCXX_SYMVER_GNU 1 /* Define to use GNU namespace versioning in the shared library. */ /* #undef _GLIBCXX_SYMVER_GNU_NAMESPACE */ /* Define to use Sun versioning in the shared library. */ /* #undef _GLIBCXX_SYMVER_SUN */ /* Define if C11 functions in <uchar.h> should be imported into namespace std in <cuchar>. */ #define _GLIBCXX_USE_C11_UCHAR_CXX11 1 /* Define if C99 functions or macros from <wchar.h>, <math.h>, <complex.h>, <stdio.h>, and <stdlib.h> can be used or exposed. */ #define _GLIBCXX_USE_C99 1 /* Define if C99 functions in <complex.h> should be used in <tr1/complex>. Using compiler builtins for these functions requires corresponding C99 library functions to be present. */ #define _GLIBCXX_USE_C99_COMPLEX_TR1 1 /* Define if C99 functions in <ctype.h> should be imported in <tr1/cctype> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_CTYPE_TR1 1 /* Define if C99 functions in <fenv.h> should be imported in <tr1/cfenv> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_FENV_TR1 1 /* Define if C99 functions in <inttypes.h> should be imported in <tr1/cinttypes> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_INTTYPES_TR1 1 /* Define if wchar_t C99 functions in <inttypes.h> should be imported in <tr1/cinttypes> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1 1 /* Define if C99 functions or macros in <math.h> should be imported in <tr1/cmath> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_MATH_TR1 1 /* Define if C99 types in <stdint.h> should be imported in <tr1/cstdint> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_STDINT_TR1 1 /* Defined if clock_gettime syscall has monotonic and realtime clock support. */ /* #undef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL */ /* Defined if clock_gettime has monotonic clock support. */ #define _GLIBCXX_USE_CLOCK_MONOTONIC 1 /* Defined if clock_gettime has realtime clock support. */ #define _GLIBCXX_USE_CLOCK_REALTIME 1 /* Define if ISO/IEC TR 24733 decimal floating point types are supported on this host. */ #define _GLIBCXX_USE_DECIMAL_FLOAT 1 /* Define if fchmod is available in <sys/stat.h>. */ #define _GLIBCXX_USE_FCHMOD 1 /* Define if fchmodat is available in <sys/stat.h>. */ #define _GLIBCXX_USE_FCHMODAT 1 /* Defined if gettimeofday is available. */ #define _GLIBCXX_USE_GETTIMEOFDAY 1 /* Define if get_nprocs is available in <sys/sysinfo.h>. */ #define _GLIBCXX_USE_GET_NPROCS 1 /* Define if __int128 is supported on this host. */ /* #undef _GLIBCXX_USE_INT128 */ /* Define if LFS support is available. */ #define _GLIBCXX_USE_LFS 1 /* Define if code specialized for long long should be used. */ #define _GLIBCXX_USE_LONG_LONG 1 /* Defined if nanosleep is available. */ #define _GLIBCXX_USE_NANOSLEEP 1 /* Define if NLS translations are to be used. */ #define _GLIBCXX_USE_NLS 1 /* Define if pthreads_num_processors_np is available in <pthread.h>. */ /* #undef _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP */ /* Define if POSIX read/write locks are available in <gthr.h>. */ #define _GLIBCXX_USE_PTHREAD_RWLOCK_T 1 /* Define if /dev/random and /dev/urandom are available for the random_device of TR1 (Chapter 5.1). */ #define _GLIBCXX_USE_RANDOM_TR1 1 /* Define if usable realpath is available in <stdlib.h>. */ #define _GLIBCXX_USE_REALPATH 1 /* Defined if sched_yield is available. */ #define _GLIBCXX_USE_SCHED_YIELD 1 /* Define if _SC_NPROCESSORS_ONLN is available in <unistd.h>. */ #define _GLIBCXX_USE_SC_NPROCESSORS_ONLN 1 /* Define if _SC_NPROC_ONLN is available in <unistd.h>. */ /* #undef _GLIBCXX_USE_SC_NPROC_ONLN */ /* Define if sendfile is available in <sys/sendfile.h>. */ #define _GLIBCXX_USE_SENDFILE 1 /* Define if struct stat has timespec members. */ #define _GLIBCXX_USE_ST_MTIM 1 /* Define if sysctl(), CTL_HW and HW_NCPU are available in <sys/sysctl.h>. */ /* #undef _GLIBCXX_USE_SYSCTL_HW_NCPU */ /* Define if obsolescent tmpnam is available in <stdio.h>. */ #define _GLIBCXX_USE_TMPNAM 1 /* Define if utimensat and UTIME_OMIT are available in <sys/stat.h> and AT_FDCWD in <fcntl.h>. */ #define _GLIBCXX_USE_UTIMENSAT 1 /* Define if code specialized for wchar_t should be used. */ #define _GLIBCXX_USE_WCHAR_T 1 /* Define to 1 if a verbose library is built, or 0 otherwise. */ #define _GLIBCXX_VERBOSE 1 /* Defined if as can handle rdrand. */ #define _GLIBCXX_X86_RDRAND 1 /* Define to 1 if mutex_timedlock is available. */ #define _GTHREAD_USE_MUTEX_TIMEDLOCK 1 /* Define for large files, on AIX-style hosts. */ /* #undef _GLIBCXX_LARGE_FILES */ /* Define if all C++11 floating point overloads are available in <math.h>. */ #if __cplusplus >= 201103L /* #undef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP */ #endif /* Define if all C++11 integral type overloads are available in <math.h>. */ #if __cplusplus >= 201103L /* #undef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT */ #endif #if defined (_GLIBCXX_HAVE__ACOSF) && ! defined (_GLIBCXX_HAVE_ACOSF) # define _GLIBCXX_HAVE_ACOSF 1 # define acosf _acosf #endif #if defined (_GLIBCXX_HAVE__ACOSL) && ! defined (_GLIBCXX_HAVE_ACOSL) # define _GLIBCXX_HAVE_ACOSL 1 # define acosl _acosl #endif #if defined (_GLIBCXX_HAVE__ASINF) && ! defined (_GLIBCXX_HAVE_ASINF) # define _GLIBCXX_HAVE_ASINF 1 # define asinf _asinf #endif #if defined (_GLIBCXX_HAVE__ASINL) && ! defined (_GLIBCXX_HAVE_ASINL) # define _GLIBCXX_HAVE_ASINL 1 # define asinl _asinl #endif #if defined (_GLIBCXX_HAVE__ATAN2F) && ! defined (_GLIBCXX_HAVE_ATAN2F) # define _GLIBCXX_HAVE_ATAN2F 1 # define atan2f _atan2f #endif #if defined (_GLIBCXX_HAVE__ATAN2L) && ! defined (_GLIBCXX_HAVE_ATAN2L) # define _GLIBCXX_HAVE_ATAN2L 1 # define atan2l _atan2l #endif #if defined (_GLIBCXX_HAVE__ATANF) && ! defined (_GLIBCXX_HAVE_ATANF) # define _GLIBCXX_HAVE_ATANF 1 # define atanf _atanf #endif #if defined (_GLIBCXX_HAVE__ATANL) && ! defined (_GLIBCXX_HAVE_ATANL) # define _GLIBCXX_HAVE_ATANL 1 # define atanl _atanl #endif #if defined (_GLIBCXX_HAVE__CEILF) && ! defined (_GLIBCXX_HAVE_CEILF) # define _GLIBCXX_HAVE_CEILF 1 # define ceilf _ceilf #endif #if defined (_GLIBCXX_HAVE__CEILL) && ! defined (_GLIBCXX_HAVE_CEILL) # define _GLIBCXX_HAVE_CEILL 1 # define ceill _ceill #endif #if defined (_GLIBCXX_HAVE__COSF) && ! defined (_GLIBCXX_HAVE_COSF) # define _GLIBCXX_HAVE_COSF 1 # define cosf _cosf #endif #if defined (_GLIBCXX_HAVE__COSHF) && ! defined (_GLIBCXX_HAVE_COSHF) # define _GLIBCXX_HAVE_COSHF 1 # define coshf _coshf #endif #if defined (_GLIBCXX_HAVE__COSHL) && ! defined (_GLIBCXX_HAVE_COSHL) # define _GLIBCXX_HAVE_COSHL 1 # define coshl _coshl #endif #if defined (_GLIBCXX_HAVE__COSL) && ! defined (_GLIBCXX_HAVE_COSL) # define _GLIBCXX_HAVE_COSL 1 # define cosl _cosl #endif #if defined (_GLIBCXX_HAVE__EXPF) && ! defined (_GLIBCXX_HAVE_EXPF) # define _GLIBCXX_HAVE_EXPF 1 # define expf _expf #endif #if defined (_GLIBCXX_HAVE__EXPL) && ! defined (_GLIBCXX_HAVE_EXPL) # define _GLIBCXX_HAVE_EXPL 1 # define expl _expl #endif #if defined (_GLIBCXX_HAVE__FABSF) && ! defined (_GLIBCXX_HAVE_FABSF) # define _GLIBCXX_HAVE_FABSF 1 # define fabsf _fabsf #endif #if defined (_GLIBCXX_HAVE__FABSL) && ! defined (_GLIBCXX_HAVE_FABSL) # define _GLIBCXX_HAVE_FABSL 1 # define fabsl _fabsl #endif #if defined (_GLIBCXX_HAVE__FINITE) && ! defined (_GLIBCXX_HAVE_FINITE) # define _GLIBCXX_HAVE_FINITE 1 # define finite _finite #endif #if defined (_GLIBCXX_HAVE__FINITEF) && ! defined (_GLIBCXX_HAVE_FINITEF) # define _GLIBCXX_HAVE_FINITEF 1 # define finitef _finitef #endif #if defined (_GLIBCXX_HAVE__FINITEL) && ! defined (_GLIBCXX_HAVE_FINITEL) # define _GLIBCXX_HAVE_FINITEL 1 # define finitel _finitel #endif #if defined (_GLIBCXX_HAVE__FLOORF) && ! defined (_GLIBCXX_HAVE_FLOORF) # define _GLIBCXX_HAVE_FLOORF 1 # define floorf _floorf #endif #if defined (_GLIBCXX_HAVE__FLOORL) && ! defined (_GLIBCXX_HAVE_FLOORL) # define _GLIBCXX_HAVE_FLOORL 1 # define floorl _floorl #endif #if defined (_GLIBCXX_HAVE__FMODF) && ! defined (_GLIBCXX_HAVE_FMODF) # define _GLIBCXX_HAVE_FMODF 1 # define fmodf _fmodf #endif #if defined (_GLIBCXX_HAVE__FMODL) && ! defined (_GLIBCXX_HAVE_FMODL) # define _GLIBCXX_HAVE_FMODL 1 # define fmodl _fmodl #endif #if defined (_GLIBCXX_HAVE__FPCLASS) && ! defined (_GLIBCXX_HAVE_FPCLASS) # define _GLIBCXX_HAVE_FPCLASS 1 # define fpclass _fpclass #endif #if defined (_GLIBCXX_HAVE__FREXPF) && ! defined (_GLIBCXX_HAVE_FREXPF) # define _GLIBCXX_HAVE_FREXPF 1 # define frexpf _frexpf #endif #if defined (_GLIBCXX_HAVE__FREXPL) && ! defined (_GLIBCXX_HAVE_FREXPL) # define _GLIBCXX_HAVE_FREXPL 1 # define frexpl _frexpl #endif #if defined (_GLIBCXX_HAVE__HYPOT) && ! defined (_GLIBCXX_HAVE_HYPOT) # define _GLIBCXX_HAVE_HYPOT 1 # define hypot _hypot #endif #if defined (_GLIBCXX_HAVE__HYPOTF) && ! defined (_GLIBCXX_HAVE_HYPOTF) # define _GLIBCXX_HAVE_HYPOTF 1 # define hypotf _hypotf #endif #if defined (_GLIBCXX_HAVE__HYPOTL) && ! defined (_GLIBCXX_HAVE_HYPOTL) # define _GLIBCXX_HAVE_HYPOTL 1 # define hypotl _hypotl #endif #if defined (_GLIBCXX_HAVE__ISINF) && ! defined (_GLIBCXX_HAVE_ISINF) # define _GLIBCXX_HAVE_ISINF 1 # define isinf _isinf #endif #if defined (_GLIBCXX_HAVE__ISINFF) && ! defined (_GLIBCXX_HAVE_ISINFF) # define _GLIBCXX_HAVE_ISINFF 1 # define isinff _isinff #endif #if defined (_GLIBCXX_HAVE__ISINFL) && ! defined (_GLIBCXX_HAVE_ISINFL) # define _GLIBCXX_HAVE_ISINFL 1 # define isinfl _isinfl #endif #if defined (_GLIBCXX_HAVE__ISNAN) && ! defined (_GLIBCXX_HAVE_ISNAN) # define _GLIBCXX_HAVE_ISNAN 1 # define isnan _isnan #endif #if defined (_GLIBCXX_HAVE__ISNANF) && ! defined (_GLIBCXX_HAVE_ISNANF) # define _GLIBCXX_HAVE_ISNANF 1 # define isnanf _isnanf #endif #if defined (_GLIBCXX_HAVE__ISNANL) && ! defined (_GLIBCXX_HAVE_ISNANL) # define _GLIBCXX_HAVE_ISNANL 1 # define isnanl _isnanl #endif #if defined (_GLIBCXX_HAVE__LDEXPF) && ! defined (_GLIBCXX_HAVE_LDEXPF) # define _GLIBCXX_HAVE_LDEXPF 1 # define ldexpf _ldexpf #endif #if defined (_GLIBCXX_HAVE__LDEXPL) && ! defined (_GLIBCXX_HAVE_LDEXPL) # define _GLIBCXX_HAVE_LDEXPL 1 # define ldexpl _ldexpl #endif #if defined (_GLIBCXX_HAVE__LOG10F) && ! defined (_GLIBCXX_HAVE_LOG10F) # define _GLIBCXX_HAVE_LOG10F 1 # define log10f _log10f #endif #if defined (_GLIBCXX_HAVE__LOG10L) && ! defined (_GLIBCXX_HAVE_LOG10L) # define _GLIBCXX_HAVE_LOG10L 1 # define log10l _log10l #endif #if defined (_GLIBCXX_HAVE__LOGF) && ! defined (_GLIBCXX_HAVE_LOGF) # define _GLIBCXX_HAVE_LOGF 1 # define logf _logf #endif #if defined (_GLIBCXX_HAVE__LOGL) && ! defined (_GLIBCXX_HAVE_LOGL) # define _GLIBCXX_HAVE_LOGL 1 # define logl _logl #endif #if defined (_GLIBCXX_HAVE__MODF) && ! defined (_GLIBCXX_HAVE_MODF) # define _GLIBCXX_HAVE_MODF 1 # define modf _modf #endif #if defined (_GLIBCXX_HAVE__MODFF) && ! defined (_GLIBCXX_HAVE_MODFF) # define _GLIBCXX_HAVE_MODFF 1 # define modff _modff #endif #if defined (_GLIBCXX_HAVE__MODFL) && ! defined (_GLIBCXX_HAVE_MODFL) # define _GLIBCXX_HAVE_MODFL 1 # define modfl _modfl #endif #if defined (_GLIBCXX_HAVE__POWF) && ! defined (_GLIBCXX_HAVE_POWF) # define _GLIBCXX_HAVE_POWF 1 # define powf _powf #endif #if defined (_GLIBCXX_HAVE__POWL) && ! defined (_GLIBCXX_HAVE_POWL) # define _GLIBCXX_HAVE_POWL 1 # define powl _powl #endif #if defined (_GLIBCXX_HAVE__QFPCLASS) && ! defined (_GLIBCXX_HAVE_QFPCLASS) # define _GLIBCXX_HAVE_QFPCLASS 1 # define qfpclass _qfpclass #endif #if defined (_GLIBCXX_HAVE__SINCOS) && ! defined (_GLIBCXX_HAVE_SINCOS) # define _GLIBCXX_HAVE_SINCOS 1 # define sincos _sincos #endif #if defined (_GLIBCXX_HAVE__SINCOSF) && ! defined (_GLIBCXX_HAVE_SINCOSF) # define _GLIBCXX_HAVE_SINCOSF 1 # define sincosf _sincosf #endif #if defined (_GLIBCXX_HAVE__SINCOSL) && ! defined (_GLIBCXX_HAVE_SINCOSL) # define _GLIBCXX_HAVE_SINCOSL 1 # define sincosl _sincosl #endif #if defined (_GLIBCXX_HAVE__SINF) && ! defined (_GLIBCXX_HAVE_SINF) # define _GLIBCXX_HAVE_SINF 1 # define sinf _sinf #endif #if defined (_GLIBCXX_HAVE__SINHF) && ! defined (_GLIBCXX_HAVE_SINHF) # define _GLIBCXX_HAVE_SINHF 1 # define sinhf _sinhf #endif #if defined (_GLIBCXX_HAVE__SINHL) && ! defined (_GLIBCXX_HAVE_SINHL) # define _GLIBCXX_HAVE_SINHL 1 # define sinhl _sinhl #endif #if defined (_GLIBCXX_HAVE__SINL) && ! defined (_GLIBCXX_HAVE_SINL) # define _GLIBCXX_HAVE_SINL 1 # define sinl _sinl #endif #if defined (_GLIBCXX_HAVE__SQRTF) && ! defined (_GLIBCXX_HAVE_SQRTF) # define _GLIBCXX_HAVE_SQRTF 1 # define sqrtf _sqrtf #endif #if defined (_GLIBCXX_HAVE__SQRTL) && ! defined (_GLIBCXX_HAVE_SQRTL) # define _GLIBCXX_HAVE_SQRTL 1 # define sqrtl _sqrtl #endif #if defined (_GLIBCXX_HAVE__STRTOF) && ! defined (_GLIBCXX_HAVE_STRTOF) # define _GLIBCXX_HAVE_STRTOF 1 # define strtof _strtof #endif #if defined (_GLIBCXX_HAVE__STRTOLD) && ! defined (_GLIBCXX_HAVE_STRTOLD) # define _GLIBCXX_HAVE_STRTOLD 1 # define strtold _strtold #endif #if defined (_GLIBCXX_HAVE__TANF) && ! defined (_GLIBCXX_HAVE_TANF) # define _GLIBCXX_HAVE_TANF 1 # define tanf _tanf #endif #if defined (_GLIBCXX_HAVE__TANHF) && ! defined (_GLIBCXX_HAVE_TANHF) # define _GLIBCXX_HAVE_TANHF 1 # define tanhf _tanhf #endif #if defined (_GLIBCXX_HAVE__TANHL) && ! defined (_GLIBCXX_HAVE_TANHL) # define _GLIBCXX_HAVE_TANHL 1 # define tanhl _tanhl #endif #if defined (_GLIBCXX_HAVE__TANL) && ! defined (_GLIBCXX_HAVE_TANL) # define _GLIBCXX_HAVE_TANL 1 # define tanl _tanl #endif #endif // _GLIBCXX_CXX_CONFIG_H #else // Predefined symbols and macros -*- C++ -*- // Copyright (C) 1997-2018 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++config.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iosfwd} */ #ifndef _GLIBCXX_CXX_CONFIG_H #define _GLIBCXX_CXX_CONFIG_H 1 // The major release number for the GCC release the C++ library belongs to. #define _GLIBCXX_RELEASE 8 // The datestamp of the C++ library in compressed ISO date format. #define __GLIBCXX__ 20210514 // Macros for various attributes. // _GLIBCXX_PURE // _GLIBCXX_CONST // _GLIBCXX_NORETURN // _GLIBCXX_NOTHROW // _GLIBCXX_VISIBILITY #ifndef _GLIBCXX_PURE # define _GLIBCXX_PURE __attribute__ ((__pure__)) #endif #ifndef _GLIBCXX_CONST # define _GLIBCXX_CONST __attribute__ ((__const__)) #endif #ifndef _GLIBCXX_NORETURN # define _GLIBCXX_NORETURN __attribute__ ((__noreturn__)) #endif // See below for C++ #ifndef _GLIBCXX_NOTHROW # ifndef __cplusplus # define _GLIBCXX_NOTHROW __attribute__((__nothrow__)) # endif #endif // Macros for visibility attributes. // _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY // _GLIBCXX_VISIBILITY # define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1 #if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY # define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V))) #else // If this is not supplied by the OS-specific or CPU-specific // headers included below, it will be defined to an empty default. # define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V) #endif // Macros for deprecated attributes. // _GLIBCXX_USE_DEPRECATED // _GLIBCXX_DEPRECATED // _GLIBCXX17_DEPRECATED #ifndef _GLIBCXX_USE_DEPRECATED # define _GLIBCXX_USE_DEPRECATED 1 #endif #if defined(__DEPRECATED) && (__cplusplus >= 201103L) # define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) #else # define _GLIBCXX_DEPRECATED #endif #if defined(__DEPRECATED) && (__cplusplus >= 201703L) # define _GLIBCXX17_DEPRECATED [[__deprecated__]] #else # define _GLIBCXX17_DEPRECATED #endif // Macros for ABI tag attributes. #ifndef _GLIBCXX_ABI_TAG_CXX11 # define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) #endif // Macro to warn about unused results. #if __cplusplus >= 201703L # define _GLIBCXX_NODISCARD [[__nodiscard__]] #else # define _GLIBCXX_NODISCARD #endif #if __cplusplus // Macro for constexpr, to support in mixed 03/0x mode. #ifndef _GLIBCXX_CONSTEXPR # if __cplusplus >= 201103L # define _GLIBCXX_CONSTEXPR constexpr # define _GLIBCXX_USE_CONSTEXPR constexpr # else # define _GLIBCXX_CONSTEXPR # define _GLIBCXX_USE_CONSTEXPR const # endif #endif #ifndef _GLIBCXX14_CONSTEXPR # if __cplusplus >= 201402L # define _GLIBCXX14_CONSTEXPR constexpr # else # define _GLIBCXX14_CONSTEXPR # endif #endif #ifndef _GLIBCXX17_CONSTEXPR # if __cplusplus > 201402L # define _GLIBCXX17_CONSTEXPR constexpr # else # define _GLIBCXX17_CONSTEXPR # endif #endif #ifndef _GLIBCXX17_INLINE # if __cplusplus > 201402L # define _GLIBCXX17_INLINE inline # else # define _GLIBCXX17_INLINE # endif #endif // Macro for noexcept, to support in mixed 03/0x mode. #ifndef _GLIBCXX_NOEXCEPT # if __cplusplus >= 201103L # define _GLIBCXX_NOEXCEPT noexcept # define _GLIBCXX_NOEXCEPT_IF(_COND) noexcept(_COND) # define _GLIBCXX_USE_NOEXCEPT noexcept # define _GLIBCXX_THROW(_EXC) # else # define _GLIBCXX_NOEXCEPT # define _GLIBCXX_NOEXCEPT_IF(_COND) # define _GLIBCXX_USE_NOEXCEPT throw() # define _GLIBCXX_THROW(_EXC) throw(_EXC) # endif #endif #ifndef _GLIBCXX_NOTHROW # define _GLIBCXX_NOTHROW _GLIBCXX_USE_NOEXCEPT #endif #ifndef _GLIBCXX_THROW_OR_ABORT # if __cpp_exceptions # define _GLIBCXX_THROW_OR_ABORT(_EXC) (throw (_EXC)) # else # define _GLIBCXX_THROW_OR_ABORT(_EXC) (__builtin_abort()) # endif #endif #if __cpp_noexcept_function_type #define _GLIBCXX_NOEXCEPT_PARM , bool _NE #define _GLIBCXX_NOEXCEPT_QUAL noexcept (_NE) #else #define _GLIBCXX_NOEXCEPT_PARM #define _GLIBCXX_NOEXCEPT_QUAL #endif // Macro for extern template, ie controlling template linkage via use // of extern keyword on template declaration. As documented in the g++ // manual, it inhibits all implicit instantiations and is used // throughout the library to avoid multiple weak definitions for // required types that are already explicitly instantiated in the // library binary. This substantially reduces the binary size of // resulting executables. // Special case: _GLIBCXX_EXTERN_TEMPLATE == -1 disallows extern // templates only in basic_string, thus activating its debug-mode // checks even at -O0. # define _GLIBCXX_EXTERN_TEMPLATE 1 /* Outline of libstdc++ namespaces. namespace std { namespace __debug { } namespace __parallel { } namespace __profile { } namespace __cxx1998 { } namespace __detail { namespace __variant { } // C++17 } namespace rel_ops { } namespace tr1 { namespace placeholders { } namespace regex_constants { } namespace __detail { } } namespace tr2 { } namespace decimal { } namespace chrono { } // C++11 namespace placeholders { } // C++11 namespace regex_constants { } // C++11 namespace this_thread { } // C++11 inline namespace literals { // C++14 inline namespace chrono_literals { } // C++14 inline namespace complex_literals { } // C++14 inline namespace string_literals { } // C++14 inline namespace string_view_literals { } // C++17 } } namespace abi { } namespace __gnu_cxx { namespace __detail { } } For full details see: http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaces.html */ namespace std { typedef __SIZE_TYPE__ size_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; #if __cplusplus >= 201103L typedef decltype(nullptr) nullptr_t; #endif } # define _GLIBCXX_USE_DUAL_ABI 1 #if ! _GLIBCXX_USE_DUAL_ABI // Ignore any pre-defined value of _GLIBCXX_USE_CXX11_ABI # undef _GLIBCXX_USE_CXX11_ABI #endif #ifndef _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_USE_CXX11_ABI 1 #endif #if _GLIBCXX_USE_CXX11_ABI namespace std { inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } } namespace __gnu_cxx { inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } } # define _GLIBCXX_NAMESPACE_CXX11 __cxx11:: # define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 { # define _GLIBCXX_END_NAMESPACE_CXX11 } # define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11 #else # define _GLIBCXX_NAMESPACE_CXX11 # define _GLIBCXX_BEGIN_NAMESPACE_CXX11 # define _GLIBCXX_END_NAMESPACE_CXX11 # define _GLIBCXX_DEFAULT_ABI_TAG #endif // Defined if inline namespaces are used for versioning. # define _GLIBCXX_INLINE_VERSION 0 // Inline namespace for symbol versioning. #if _GLIBCXX_INLINE_VERSION # define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __8 { # define _GLIBCXX_END_NAMESPACE_VERSION } namespace std { inline _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201402L inline namespace literals { inline namespace chrono_literals { } inline namespace complex_literals { } inline namespace string_literals { } #if __cplusplus > 201402L inline namespace string_view_literals { } #endif // C++17 } #endif // C++14 _GLIBCXX_END_NAMESPACE_VERSION } namespace __gnu_cxx { inline _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION } #else # define _GLIBCXX_BEGIN_NAMESPACE_VERSION # define _GLIBCXX_END_NAMESPACE_VERSION #endif // Inline namespaces for special modes: debug, parallel, profile. #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) \ || defined(_GLIBCXX_PROFILE) namespace std { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Non-inline namespace for components replaced by alternates in active mode. namespace __cxx1998 { # if _GLIBCXX_USE_CXX11_ABI inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } # endif } _GLIBCXX_END_NAMESPACE_VERSION // Inline namespace for debug mode. # ifdef _GLIBCXX_DEBUG inline namespace __debug { } # endif // Inline namespaces for parallel mode. # ifdef _GLIBCXX_PARALLEL inline namespace __parallel { } # endif // Inline namespaces for profile mode # ifdef _GLIBCXX_PROFILE inline namespace __profile { } # endif } // Check for invalid usage and unsupported mixed-mode use. # if defined(_GLIBCXX_DEBUG) && defined(_GLIBCXX_PARALLEL) # error illegal use of multiple inlined namespaces # endif # if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_DEBUG) # error illegal use of multiple inlined namespaces # endif # if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_PARALLEL) # error illegal use of multiple inlined namespaces # endif // Check for invalid use due to lack for weak symbols. # if __NO_INLINE__ && !__GXX_WEAK__ # warning currently using inlined namespace mode which may fail \ without inlining due to lack of weak symbols # endif #endif // Macros for namespace scope. Either namespace std:: or the name // of some nested namespace within it corresponding to the active mode. // _GLIBCXX_STD_A // _GLIBCXX_STD_C // // Macros for opening/closing conditional namespaces. // _GLIBCXX_BEGIN_NAMESPACE_ALGO // _GLIBCXX_END_NAMESPACE_ALGO // _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // _GLIBCXX_END_NAMESPACE_CONTAINER #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PROFILE) # define _GLIBCXX_STD_C __cxx1998 # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER \ namespace _GLIBCXX_STD_C { # define _GLIBCXX_END_NAMESPACE_CONTAINER } #else # define _GLIBCXX_STD_C std # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER # define _GLIBCXX_END_NAMESPACE_CONTAINER #endif #ifdef _GLIBCXX_PARALLEL # define _GLIBCXX_STD_A __cxx1998 # define _GLIBCXX_BEGIN_NAMESPACE_ALGO \ namespace _GLIBCXX_STD_A { # define _GLIBCXX_END_NAMESPACE_ALGO } #else # define _GLIBCXX_STD_A std # define _GLIBCXX_BEGIN_NAMESPACE_ALGO # define _GLIBCXX_END_NAMESPACE_ALGO #endif // GLIBCXX_ABI Deprecated // Define if compatibility should be provided for -mlong-double-64. #undef _GLIBCXX_LONG_DOUBLE_COMPAT // Inline namespace for long double 128 mode. #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ namespace std { inline namespace __gnu_cxx_ldbl128 { } } # define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ldbl128:: # define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ldbl128 { # define _GLIBCXX_END_NAMESPACE_LDBL } #else # define _GLIBCXX_NAMESPACE_LDBL # define _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL #endif #if _GLIBCXX_USE_CXX11_ABI # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_CXX11 # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11 # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_CXX11 #else # define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_LDBL # define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_LDBL #endif // Debug Mode implies checking assertions. #if defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_ASSERTIONS) # define _GLIBCXX_ASSERTIONS 1 #endif // Disable std::string explicit instantiation declarations in order to assert. #ifdef _GLIBCXX_ASSERTIONS # undef _GLIBCXX_EXTERN_TEMPLATE # define _GLIBCXX_EXTERN_TEMPLATE -1 #endif // Assert. #if defined(_GLIBCXX_ASSERTIONS) \ || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS) namespace std { // Avoid the use of assert, because we're trying to keep the <cassert> // include out of the mix. inline void __replacement_assert(const char* __file, int __line, const char* __function, const char* __condition) { __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, __function, __condition); __builtin_abort(); } } #define __glibcxx_assert_impl(_Condition) \ do \ { \ if (! (_Condition)) \ std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ #_Condition); \ } while (false) #endif #if defined(_GLIBCXX_ASSERTIONS) # define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition) #else # define __glibcxx_assert(_Condition) #endif // Macros for race detectors. // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain // atomic (lock-free) synchronization to race detectors: // the race detector will infer a happens-before arc from the former to the // latter when they share the same argument pointer. // // The most frequent use case for these macros (and the only case in the // current implementation of the library) is atomic reference counting: // void _M_remove_reference() // { // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount); // if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, -1) <= 0) // { // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount); // _M_destroy(__a); // } // } // The annotations in this example tell the race detector that all memory // accesses occurred when the refcount was positive do not race with // memory accesses which occurred after the refcount became zero. #ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE # define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) #endif #ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER # define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) #endif // Macros for C linkage: define extern "C" linkage only when using C++. # define _GLIBCXX_BEGIN_EXTERN_C extern "C" { # define _GLIBCXX_END_EXTERN_C } # define _GLIBCXX_USE_ALLOCATOR_NEW 1 #else // !__cplusplus # define _GLIBCXX_BEGIN_EXTERN_C # define _GLIBCXX_END_EXTERN_C #endif // First includes. // Pick up any OS-specific definitions. #include <bits/os_defines.h> // Pick up any CPU-specific definitions. #include <bits/cpu_defines.h> // If platform uses neither visibility nor psuedo-visibility, // specify empty default for namespace annotation macros. #ifndef _GLIBCXX_PSEUDO_VISIBILITY # define _GLIBCXX_PSEUDO_VISIBILITY(V) #endif // Certain function definitions that are meant to be overridable from // user code are decorated with this macro. For some targets, this // macro causes these definitions to be weak. #ifndef _GLIBCXX_WEAK_DEFINITION # define _GLIBCXX_WEAK_DEFINITION #endif // By default, we assume that __GXX_WEAK__ also means that there is support // for declaring functions as weak while not defining such functions. This // allows for referring to functions provided by other libraries (e.g., // libitm) without depending on them if the respective features are not used. #ifndef _GLIBCXX_USE_WEAK_REF # define _GLIBCXX_USE_WEAK_REF __GXX_WEAK__ #endif // Conditionally enable annotations for the Transactional Memory TS on C++11. // Most of the following conditions are due to limitations in the current // implementation. #if __cplusplus >= 201103L && _GLIBCXX_USE_CXX11_ABI \ && _GLIBCXX_USE_DUAL_ABI && __cpp_transactional_memory >= 201505L \ && !_GLIBCXX_FULLY_DYNAMIC_STRING && _GLIBCXX_USE_WEAK_REF \ && _GLIBCXX_USE_ALLOCATOR_NEW #define _GLIBCXX_TXN_SAFE transaction_safe #define _GLIBCXX_TXN_SAFE_DYN transaction_safe_dynamic #else #define _GLIBCXX_TXN_SAFE #define _GLIBCXX_TXN_SAFE_DYN #endif #if __cplusplus > 201402L // In C++17 mathematical special functions are in namespace std. # define _GLIBCXX_USE_STD_SPEC_FUNCS 1 #elif __cplusplus >= 201103L && __STDCPP_WANT_MATH_SPEC_FUNCS__ != 0 // For C++11 and C++14 they are in namespace std when requested. # define _GLIBCXX_USE_STD_SPEC_FUNCS 1 #endif // The remainder of the prewritten config is automatic; all the // user hooks are listed above. // Create a boolean flag to be used to determine if --fast-math is set. #ifdef __FAST_MATH__ # define _GLIBCXX_FAST_MATH 1 #else # define _GLIBCXX_FAST_MATH 0 #endif // This marks string literals in header files to be extracted for eventual // translation. It is primarily used for messages in thrown exceptions; see // src/functexcept.cc. We use __N because the more traditional _N is used // for something else under certain OSes (see BADNAMES). #define __N(msgid) (msgid) // For example, <windows.h> is known to #define min and max as macros... #undef min #undef max // N.B. these _GLIBCXX_USE_C99_XXX macros are defined unconditionally // so they should be tested with #if not with #ifdef. #if __cplusplus >= 201103L # ifndef _GLIBCXX_USE_C99_MATH # define _GLIBCXX_USE_C99_MATH _GLIBCXX11_USE_C99_MATH # endif # ifndef _GLIBCXX_USE_C99_COMPLEX # define _GLIBCXX_USE_C99_COMPLEX _GLIBCXX11_USE_C99_COMPLEX # endif # ifndef _GLIBCXX_USE_C99_STDIO # define _GLIBCXX_USE_C99_STDIO _GLIBCXX11_USE_C99_STDIO # endif # ifndef _GLIBCXX_USE_C99_STDLIB # define _GLIBCXX_USE_C99_STDLIB _GLIBCXX11_USE_C99_STDLIB # endif # ifndef _GLIBCXX_USE_C99_WCHAR # define _GLIBCXX_USE_C99_WCHAR _GLIBCXX11_USE_C99_WCHAR # endif #else # ifndef _GLIBCXX_USE_C99_MATH # define _GLIBCXX_USE_C99_MATH _GLIBCXX98_USE_C99_MATH # endif # ifndef _GLIBCXX_USE_C99_COMPLEX # define _GLIBCXX_USE_C99_COMPLEX _GLIBCXX98_USE_C99_COMPLEX # endif # ifndef _GLIBCXX_USE_C99_STDIO # define _GLIBCXX_USE_C99_STDIO _GLIBCXX98_USE_C99_STDIO # endif # ifndef _GLIBCXX_USE_C99_STDLIB # define _GLIBCXX_USE_C99_STDLIB _GLIBCXX98_USE_C99_STDLIB # endif # ifndef _GLIBCXX_USE_C99_WCHAR # define _GLIBCXX_USE_C99_WCHAR _GLIBCXX98_USE_C99_WCHAR # endif #endif /* Define if __float128 is supported on this host. */ #if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) #define _GLIBCXX_USE_FLOAT128 1 #endif // End of prewritten config; the settings discovered at configure time follow. /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `acosf' function. */ #define _GLIBCXX_HAVE_ACOSF 1 /* Define to 1 if you have the `acosl' function. */ #define _GLIBCXX_HAVE_ACOSL 1 /* Define to 1 if you have the `aligned_alloc' function. */ #define _GLIBCXX_HAVE_ALIGNED_ALLOC 1 /* Define to 1 if you have the `asinf' function. */ #define _GLIBCXX_HAVE_ASINF 1 /* Define to 1 if you have the `asinl' function. */ #define _GLIBCXX_HAVE_ASINL 1 /* Define to 1 if the target assembler supports .symver directive. */ #define _GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE 1 /* Define to 1 if you have the `atan2f' function. */ #define _GLIBCXX_HAVE_ATAN2F 1 /* Define to 1 if you have the `atan2l' function. */ #define _GLIBCXX_HAVE_ATAN2L 1 /* Define to 1 if you have the `atanf' function. */ #define _GLIBCXX_HAVE_ATANF 1 /* Define to 1 if you have the `atanl' function. */ #define _GLIBCXX_HAVE_ATANL 1 /* Define to 1 if you have the `at_quick_exit' function. */ #define _GLIBCXX_HAVE_AT_QUICK_EXIT 1 /* Define to 1 if the target assembler supports thread-local storage. */ /* #undef _GLIBCXX_HAVE_CC_TLS */ /* Define to 1 if you have the `ceilf' function. */ #define _GLIBCXX_HAVE_CEILF 1 /* Define to 1 if you have the `ceill' function. */ #define _GLIBCXX_HAVE_CEILL 1 /* Define to 1 if you have the <complex.h> header file. */ #define _GLIBCXX_HAVE_COMPLEX_H 1 /* Define to 1 if you have the `cosf' function. */ #define _GLIBCXX_HAVE_COSF 1 /* Define to 1 if you have the `coshf' function. */ #define _GLIBCXX_HAVE_COSHF 1 /* Define to 1 if you have the `coshl' function. */ #define _GLIBCXX_HAVE_COSHL 1 /* Define to 1 if you have the `cosl' function. */ #define _GLIBCXX_HAVE_COSL 1 /* Define to 1 if you have the <dirent.h> header file. */ #define _GLIBCXX_HAVE_DIRENT_H 1 /* Define to 1 if you have the <dlfcn.h> header file. */ #define _GLIBCXX_HAVE_DLFCN_H 1 /* Define if EBADMSG exists. */ #define _GLIBCXX_HAVE_EBADMSG 1 /* Define if ECANCELED exists. */ #define _GLIBCXX_HAVE_ECANCELED 1 /* Define if ECHILD exists. */ #define _GLIBCXX_HAVE_ECHILD 1 /* Define if EIDRM exists. */ #define _GLIBCXX_HAVE_EIDRM 1 /* Define to 1 if you have the <endian.h> header file. */ #define _GLIBCXX_HAVE_ENDIAN_H 1 /* Define if ENODATA exists. */ #define _GLIBCXX_HAVE_ENODATA 1 /* Define if ENOLINK exists. */ #define _GLIBCXX_HAVE_ENOLINK 1 /* Define if ENOSPC exists. */ #define _GLIBCXX_HAVE_ENOSPC 1 /* Define if ENOSR exists. */ #define _GLIBCXX_HAVE_ENOSR 1 /* Define if ENOSTR exists. */ #define _GLIBCXX_HAVE_ENOSTR 1 /* Define if ENOTRECOVERABLE exists. */ #define _GLIBCXX_HAVE_ENOTRECOVERABLE 1 /* Define if ENOTSUP exists. */ #define _GLIBCXX_HAVE_ENOTSUP 1 /* Define if EOVERFLOW exists. */ #define _GLIBCXX_HAVE_EOVERFLOW 1 /* Define if EOWNERDEAD exists. */ #define _GLIBCXX_HAVE_EOWNERDEAD 1 /* Define if EPERM exists. */ #define _GLIBCXX_HAVE_EPERM 1 /* Define if EPROTO exists. */ #define _GLIBCXX_HAVE_EPROTO 1 /* Define if ETIME exists. */ #define _GLIBCXX_HAVE_ETIME 1 /* Define if ETIMEDOUT exists. */ #define _GLIBCXX_HAVE_ETIMEDOUT 1 /* Define if ETXTBSY exists. */ #define _GLIBCXX_HAVE_ETXTBSY 1 /* Define if EWOULDBLOCK exists. */ #define _GLIBCXX_HAVE_EWOULDBLOCK 1 /* Define to 1 if GCC 4.6 supported std::exception_ptr for the target */ #define _GLIBCXX_HAVE_EXCEPTION_PTR_SINCE_GCC46 1 /* Define to 1 if you have the <execinfo.h> header file. */ #define _GLIBCXX_HAVE_EXECINFO_H 1 /* Define to 1 if you have the `expf' function. */ #define _GLIBCXX_HAVE_EXPF 1 /* Define to 1 if you have the `expl' function. */ #define _GLIBCXX_HAVE_EXPL 1 /* Define to 1 if you have the `fabsf' function. */ #define _GLIBCXX_HAVE_FABSF 1 /* Define to 1 if you have the `fabsl' function. */ #define _GLIBCXX_HAVE_FABSL 1 /* Define to 1 if you have the <fcntl.h> header file. */ #define _GLIBCXX_HAVE_FCNTL_H 1 /* Define to 1 if you have the <fenv.h> header file. */ #define _GLIBCXX_HAVE_FENV_H 1 /* Define to 1 if you have the `finite' function. */ #define _GLIBCXX_HAVE_FINITE 1 /* Define to 1 if you have the `finitef' function. */ #define _GLIBCXX_HAVE_FINITEF 1 /* Define to 1 if you have the `finitel' function. */ #define _GLIBCXX_HAVE_FINITEL 1 /* Define to 1 if you have the <float.h> header file. */ #define _GLIBCXX_HAVE_FLOAT_H 1 /* Define to 1 if you have the `floorf' function. */ #define _GLIBCXX_HAVE_FLOORF 1 /* Define to 1 if you have the `floorl' function. */ #define _GLIBCXX_HAVE_FLOORL 1 /* Define to 1 if you have the `fmodf' function. */ #define _GLIBCXX_HAVE_FMODF 1 /* Define to 1 if you have the `fmodl' function. */ #define _GLIBCXX_HAVE_FMODL 1 /* Define to 1 if you have the `fpclass' function. */ /* #undef _GLIBCXX_HAVE_FPCLASS */ /* Define to 1 if you have the <fp.h> header file. */ /* #undef _GLIBCXX_HAVE_FP_H */ /* Define to 1 if you have the `frexpf' function. */ #define _GLIBCXX_HAVE_FREXPF 1 /* Define to 1 if you have the `frexpl' function. */ #define _GLIBCXX_HAVE_FREXPL 1 /* Define if _Unwind_GetIPInfo is available. */ #define _GLIBCXX_HAVE_GETIPINFO 1 /* Define if gets is available in <stdio.h> before C++14. */ #define _GLIBCXX_HAVE_GETS 1 /* Define to 1 if you have the `hypot' function. */ #define _GLIBCXX_HAVE_HYPOT 1 /* Define to 1 if you have the `hypotf' function. */ #define _GLIBCXX_HAVE_HYPOTF 1 /* Define to 1 if you have the `hypotl' function. */ #define _GLIBCXX_HAVE_HYPOTL 1 /* Define if you have the iconv() function. */ #define _GLIBCXX_HAVE_ICONV 1 /* Define to 1 if you have the <ieeefp.h> header file. */ /* #undef _GLIBCXX_HAVE_IEEEFP_H */ /* Define if int64_t is available in <stdint.h>. */ #define _GLIBCXX_HAVE_INT64_T 1 /* Define if int64_t is a long. */ #define _GLIBCXX_HAVE_INT64_T_LONG 1 /* Define if int64_t is a long long. */ /* #undef _GLIBCXX_HAVE_INT64_T_LONG_LONG */ /* Define to 1 if you have the <inttypes.h> header file. */ #define _GLIBCXX_HAVE_INTTYPES_H 1 /* Define to 1 if you have the `isinf' function. */ /* #undef _GLIBCXX_HAVE_ISINF */ /* Define to 1 if you have the `isinff' function. */ #define _GLIBCXX_HAVE_ISINFF 1 /* Define to 1 if you have the `isinfl' function. */ #define _GLIBCXX_HAVE_ISINFL 1 /* Define to 1 if you have the `isnan' function. */ /* #undef _GLIBCXX_HAVE_ISNAN */ /* Define to 1 if you have the `isnanf' function. */ #define _GLIBCXX_HAVE_ISNANF 1 /* Define to 1 if you have the `isnanl' function. */ #define _GLIBCXX_HAVE_ISNANL 1 /* Defined if iswblank exists. */ #define _GLIBCXX_HAVE_ISWBLANK 1 /* Define if LC_MESSAGES is available in <locale.h>. */ #define _GLIBCXX_HAVE_LC_MESSAGES 1 /* Define to 1 if you have the `ldexpf' function. */ #define _GLIBCXX_HAVE_LDEXPF 1 /* Define to 1 if you have the `ldexpl' function. */ #define _GLIBCXX_HAVE_LDEXPL 1 /* Define to 1 if you have the <libintl.h> header file. */ #define _GLIBCXX_HAVE_LIBINTL_H 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_AS 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_DATA 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_FSIZE 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_RSS 1 /* Only used in build directory testsuite_hooks.h. */ #define _GLIBCXX_HAVE_LIMIT_VMEM 0 /* Define if futex syscall is available. */ #define _GLIBCXX_HAVE_LINUX_FUTEX 1 /* Define to 1 if you have the <linux/random.h> header file. */ #define _GLIBCXX_HAVE_LINUX_RANDOM_H 1 /* Define to 1 if you have the <linux/types.h> header file. */ #define _GLIBCXX_HAVE_LINUX_TYPES_H 1 /* Define to 1 if you have the <locale.h> header file. */ #define _GLIBCXX_HAVE_LOCALE_H 1 /* Define to 1 if you have the `log10f' function. */ #define _GLIBCXX_HAVE_LOG10F 1 /* Define to 1 if you have the `log10l' function. */ #define _GLIBCXX_HAVE_LOG10L 1 /* Define to 1 if you have the `logf' function. */ #define _GLIBCXX_HAVE_LOGF 1 /* Define to 1 if you have the `logl' function. */ #define _GLIBCXX_HAVE_LOGL 1 /* Define to 1 if you have the <machine/endian.h> header file. */ /* #undef _GLIBCXX_HAVE_MACHINE_ENDIAN_H */ /* Define to 1 if you have the <machine/param.h> header file. */ /* #undef _GLIBCXX_HAVE_MACHINE_PARAM_H */ /* Define if mbstate_t exists in wchar.h. */ #define _GLIBCXX_HAVE_MBSTATE_T 1 /* Define to 1 if you have the `memalign' function. */ #define _GLIBCXX_HAVE_MEMALIGN 1 /* Define to 1 if you have the <memory.h> header file. */ #define _GLIBCXX_HAVE_MEMORY_H 1 /* Define to 1 if you have the `modf' function. */ #define _GLIBCXX_HAVE_MODF 1 /* Define to 1 if you have the `modff' function. */ #define _GLIBCXX_HAVE_MODFF 1 /* Define to 1 if you have the `modfl' function. */ #define _GLIBCXX_HAVE_MODFL 1 /* Define to 1 if you have the <nan.h> header file. */ /* #undef _GLIBCXX_HAVE_NAN_H */ /* Define if <math.h> defines obsolete isinf function. */ /* #undef _GLIBCXX_HAVE_OBSOLETE_ISINF */ /* Define if <math.h> defines obsolete isnan function. */ /* #undef _GLIBCXX_HAVE_OBSOLETE_ISNAN */ /* Define if poll is available in <poll.h>. */ #define _GLIBCXX_HAVE_POLL 1 /* Define to 1 if you have the `posix_memalign' function. */ #define _GLIBCXX_HAVE_POSIX_MEMALIGN 1 /* Define to 1 if you have the `powf' function. */ #define _GLIBCXX_HAVE_POWF 1 /* Define to 1 if you have the `powl' function. */ #define _GLIBCXX_HAVE_POWL 1 /* Define to 1 if you have the `qfpclass' function. */ /* #undef _GLIBCXX_HAVE_QFPCLASS */ /* Define to 1 if you have the `quick_exit' function. */ #define _GLIBCXX_HAVE_QUICK_EXIT 1 /* Define to 1 if you have the `setenv' function. */ #define _GLIBCXX_HAVE_SETENV 1 /* Define to 1 if you have the `sincos' function. */ #define _GLIBCXX_HAVE_SINCOS 1 /* Define to 1 if you have the `sincosf' function. */ #define _GLIBCXX_HAVE_SINCOSF 1 /* Define to 1 if you have the `sincosl' function. */ #define _GLIBCXX_HAVE_SINCOSL 1 /* Define to 1 if you have the `sinf' function. */ #define _GLIBCXX_HAVE_SINF 1 /* Define to 1 if you have the `sinhf' function. */ #define _GLIBCXX_HAVE_SINHF 1 /* Define to 1 if you have the `sinhl' function. */ #define _GLIBCXX_HAVE_SINHL 1 /* Define to 1 if you have the `sinl' function. */ #define _GLIBCXX_HAVE_SINL 1 /* Defined if sleep exists. */ /* #undef _GLIBCXX_HAVE_SLEEP */ /* Define to 1 if you have the `sqrtf' function. */ #define _GLIBCXX_HAVE_SQRTF 1 /* Define to 1 if you have the `sqrtl' function. */ #define _GLIBCXX_HAVE_SQRTL 1 /* Define to 1 if you have the <stdalign.h> header file. */ #define _GLIBCXX_HAVE_STDALIGN_H 1 /* Define to 1 if you have the <stdbool.h> header file. */ #define _GLIBCXX_HAVE_STDBOOL_H 1 /* Define to 1 if you have the <stdint.h> header file. */ #define _GLIBCXX_HAVE_STDINT_H 1 /* Define to 1 if you have the <stdlib.h> header file. */ #define _GLIBCXX_HAVE_STDLIB_H 1 /* Define if strerror_l is available in <string.h>. */ #define _GLIBCXX_HAVE_STRERROR_L 1 /* Define if strerror_r is available in <string.h>. */ #define _GLIBCXX_HAVE_STRERROR_R 1 /* Define to 1 if you have the <strings.h> header file. */ #define _GLIBCXX_HAVE_STRINGS_H 1 /* Define to 1 if you have the <string.h> header file. */ #define _GLIBCXX_HAVE_STRING_H 1 /* Define to 1 if you have the `strtof' function. */ #define _GLIBCXX_HAVE_STRTOF 1 /* Define to 1 if you have the `strtold' function. */ #define _GLIBCXX_HAVE_STRTOLD 1 /* Define to 1 if `d_type' is a member of `struct dirent'. */ #define _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE 1 /* Define if strxfrm_l is available in <string.h>. */ #define _GLIBCXX_HAVE_STRXFRM_L 1 /* Define to 1 if the target runtime linker supports binding the same symbol to different versions. */ #define _GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT 1 /* Define to 1 if you have the <sys/filio.h> header file. */ /* #undef _GLIBCXX_HAVE_SYS_FILIO_H */ /* Define to 1 if you have the <sys/ioctl.h> header file. */ #define _GLIBCXX_HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the <sys/ipc.h> header file. */ #define _GLIBCXX_HAVE_SYS_IPC_H 1 /* Define to 1 if you have the <sys/isa_defs.h> header file. */ /* #undef _GLIBCXX_HAVE_SYS_ISA_DEFS_H */ /* Define to 1 if you have the <sys/machine.h> header file. */ /* #undef _GLIBCXX_HAVE_SYS_MACHINE_H */ /* Define to 1 if you have the <sys/param.h> header file. */ #define _GLIBCXX_HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the <sys/resource.h> header file. */ #define _GLIBCXX_HAVE_SYS_RESOURCE_H 1 /* Define to 1 if you have a suitable <sys/sdt.h> header file */ #define _GLIBCXX_HAVE_SYS_SDT_H 1 /* Define to 1 if you have the <sys/sem.h> header file. */ #define _GLIBCXX_HAVE_SYS_SEM_H 1 /* Define to 1 if you have the <sys/statvfs.h> header file. */ #define _GLIBCXX_HAVE_SYS_STATVFS_H 1 /* Define to 1 if you have the <sys/stat.h> header file. */ #define _GLIBCXX_HAVE_SYS_STAT_H 1 /* Define to 1 if you have the <sys/sysinfo.h> header file. */ #define _GLIBCXX_HAVE_SYS_SYSINFO_H 1 /* Define to 1 if you have the <sys/time.h> header file. */ #define _GLIBCXX_HAVE_SYS_TIME_H 1 /* Define to 1 if you have the <sys/types.h> header file. */ #define _GLIBCXX_HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the <sys/uio.h> header file. */ #define _GLIBCXX_HAVE_SYS_UIO_H 1 /* Define if S_IFREG is available in <sys/stat.h>. */ /* #undef _GLIBCXX_HAVE_S_IFREG */ /* Define if S_ISREG is available in <sys/stat.h>. */ #define _GLIBCXX_HAVE_S_ISREG 1 /* Define to 1 if you have the `tanf' function. */ #define _GLIBCXX_HAVE_TANF 1 /* Define to 1 if you have the `tanhf' function. */ #define _GLIBCXX_HAVE_TANHF 1 /* Define to 1 if you have the `tanhl' function. */ #define _GLIBCXX_HAVE_TANHL 1 /* Define to 1 if you have the `tanl' function. */ #define _GLIBCXX_HAVE_TANL 1 /* Define to 1 if you have the <tgmath.h> header file. */ #define _GLIBCXX_HAVE_TGMATH_H 1 /* Define to 1 if the target supports thread-local storage. */ #define _GLIBCXX_HAVE_TLS 1 /* Define to 1 if you have the <uchar.h> header file. */ #define _GLIBCXX_HAVE_UCHAR_H 1 /* Define to 1 if you have the <unistd.h> header file. */ #define _GLIBCXX_HAVE_UNISTD_H 1 /* Defined if usleep exists. */ /* #undef _GLIBCXX_HAVE_USLEEP */ /* Define to 1 if you have the <utime.h> header file. */ #define _GLIBCXX_HAVE_UTIME_H 1 /* Defined if vfwscanf exists. */ #define _GLIBCXX_HAVE_VFWSCANF 1 /* Defined if vswscanf exists. */ #define _GLIBCXX_HAVE_VSWSCANF 1 /* Defined if vwscanf exists. */ #define _GLIBCXX_HAVE_VWSCANF 1 /* Define to 1 if you have the <wchar.h> header file. */ #define _GLIBCXX_HAVE_WCHAR_H 1 /* Defined if wcstof exists. */ #define _GLIBCXX_HAVE_WCSTOF 1 /* Define to 1 if you have the <wctype.h> header file. */ #define _GLIBCXX_HAVE_WCTYPE_H 1 /* Defined if Sleep exists. */ /* #undef _GLIBCXX_HAVE_WIN32_SLEEP */ /* Define if writev is available in <sys/uio.h>. */ #define _GLIBCXX_HAVE_WRITEV 1 /* Define to 1 if you have the `_acosf' function. */ /* #undef _GLIBCXX_HAVE__ACOSF */ /* Define to 1 if you have the `_acosl' function. */ /* #undef _GLIBCXX_HAVE__ACOSL */ /* Define to 1 if you have the `_aligned_malloc' function. */ /* #undef _GLIBCXX_HAVE__ALIGNED_MALLOC */ /* Define to 1 if you have the `_asinf' function. */ /* #undef _GLIBCXX_HAVE__ASINF */ /* Define to 1 if you have the `_asinl' function. */ /* #undef _GLIBCXX_HAVE__ASINL */ /* Define to 1 if you have the `_atan2f' function. */ /* #undef _GLIBCXX_HAVE__ATAN2F */ /* Define to 1 if you have the `_atan2l' function. */ /* #undef _GLIBCXX_HAVE__ATAN2L */ /* Define to 1 if you have the `_atanf' function. */ /* #undef _GLIBCXX_HAVE__ATANF */ /* Define to 1 if you have the `_atanl' function. */ /* #undef _GLIBCXX_HAVE__ATANL */ /* Define to 1 if you have the `_ceilf' function. */ /* #undef _GLIBCXX_HAVE__CEILF */ /* Define to 1 if you have the `_ceill' function. */ /* #undef _GLIBCXX_HAVE__CEILL */ /* Define to 1 if you have the `_cosf' function. */ /* #undef _GLIBCXX_HAVE__COSF */ /* Define to 1 if you have the `_coshf' function. */ /* #undef _GLIBCXX_HAVE__COSHF */ /* Define to 1 if you have the `_coshl' function. */ /* #undef _GLIBCXX_HAVE__COSHL */ /* Define to 1 if you have the `_cosl' function. */ /* #undef _GLIBCXX_HAVE__COSL */ /* Define to 1 if you have the `_expf' function. */ /* #undef _GLIBCXX_HAVE__EXPF */ /* Define to 1 if you have the `_expl' function. */ /* #undef _GLIBCXX_HAVE__EXPL */ /* Define to 1 if you have the `_fabsf' function. */ /* #undef _GLIBCXX_HAVE__FABSF */ /* Define to 1 if you have the `_fabsl' function. */ /* #undef _GLIBCXX_HAVE__FABSL */ /* Define to 1 if you have the `_finite' function. */ /* #undef _GLIBCXX_HAVE__FINITE */ /* Define to 1 if you have the `_finitef' function. */ /* #undef _GLIBCXX_HAVE__FINITEF */ /* Define to 1 if you have the `_finitel' function. */ /* #undef _GLIBCXX_HAVE__FINITEL */ /* Define to 1 if you have the `_floorf' function. */ /* #undef _GLIBCXX_HAVE__FLOORF */ /* Define to 1 if you have the `_floorl' function. */ /* #undef _GLIBCXX_HAVE__FLOORL */ /* Define to 1 if you have the `_fmodf' function. */ /* #undef _GLIBCXX_HAVE__FMODF */ /* Define to 1 if you have the `_fmodl' function. */ /* #undef _GLIBCXX_HAVE__FMODL */ /* Define to 1 if you have the `_fpclass' function. */ /* #undef _GLIBCXX_HAVE__FPCLASS */ /* Define to 1 if you have the `_frexpf' function. */ /* #undef _GLIBCXX_HAVE__FREXPF */ /* Define to 1 if you have the `_frexpl' function. */ /* #undef _GLIBCXX_HAVE__FREXPL */ /* Define to 1 if you have the `_hypot' function. */ /* #undef _GLIBCXX_HAVE__HYPOT */ /* Define to 1 if you have the `_hypotf' function. */ /* #undef _GLIBCXX_HAVE__HYPOTF */ /* Define to 1 if you have the `_hypotl' function. */ /* #undef _GLIBCXX_HAVE__HYPOTL */ /* Define to 1 if you have the `_isinf' function. */ /* #undef _GLIBCXX_HAVE__ISINF */ /* Define to 1 if you have the `_isinff' function. */ /* #undef _GLIBCXX_HAVE__ISINFF */ /* Define to 1 if you have the `_isinfl' function. */ /* #undef _GLIBCXX_HAVE__ISINFL */ /* Define to 1 if you have the `_isnan' function. */ /* #undef _GLIBCXX_HAVE__ISNAN */ /* Define to 1 if you have the `_isnanf' function. */ /* #undef _GLIBCXX_HAVE__ISNANF */ /* Define to 1 if you have the `_isnanl' function. */ /* #undef _GLIBCXX_HAVE__ISNANL */ /* Define to 1 if you have the `_ldexpf' function. */ /* #undef _GLIBCXX_HAVE__LDEXPF */ /* Define to 1 if you have the `_ldexpl' function. */ /* #undef _GLIBCXX_HAVE__LDEXPL */ /* Define to 1 if you have the `_log10f' function. */ /* #undef _GLIBCXX_HAVE__LOG10F */ /* Define to 1 if you have the `_log10l' function. */ /* #undef _GLIBCXX_HAVE__LOG10L */ /* Define to 1 if you have the `_logf' function. */ /* #undef _GLIBCXX_HAVE__LOGF */ /* Define to 1 if you have the `_logl' function. */ /* #undef _GLIBCXX_HAVE__LOGL */ /* Define to 1 if you have the `_modf' function. */ /* #undef _GLIBCXX_HAVE__MODF */ /* Define to 1 if you have the `_modff' function. */ /* #undef _GLIBCXX_HAVE__MODFF */ /* Define to 1 if you have the `_modfl' function. */ /* #undef _GLIBCXX_HAVE__MODFL */ /* Define to 1 if you have the `_powf' function. */ /* #undef _GLIBCXX_HAVE__POWF */ /* Define to 1 if you have the `_powl' function. */ /* #undef _GLIBCXX_HAVE__POWL */ /* Define to 1 if you have the `_qfpclass' function. */ /* #undef _GLIBCXX_HAVE__QFPCLASS */ /* Define to 1 if you have the `_sincos' function. */ /* #undef _GLIBCXX_HAVE__SINCOS */ /* Define to 1 if you have the `_sincosf' function. */ /* #undef _GLIBCXX_HAVE__SINCOSF */ /* Define to 1 if you have the `_sincosl' function. */ /* #undef _GLIBCXX_HAVE__SINCOSL */ /* Define to 1 if you have the `_sinf' function. */ /* #undef _GLIBCXX_HAVE__SINF */ /* Define to 1 if you have the `_sinhf' function. */ /* #undef _GLIBCXX_HAVE__SINHF */ /* Define to 1 if you have the `_sinhl' function. */ /* #undef _GLIBCXX_HAVE__SINHL */ /* Define to 1 if you have the `_sinl' function. */ /* #undef _GLIBCXX_HAVE__SINL */ /* Define to 1 if you have the `_sqrtf' function. */ /* #undef _GLIBCXX_HAVE__SQRTF */ /* Define to 1 if you have the `_sqrtl' function. */ /* #undef _GLIBCXX_HAVE__SQRTL */ /* Define to 1 if you have the `_tanf' function. */ /* #undef _GLIBCXX_HAVE__TANF */ /* Define to 1 if you have the `_tanhf' function. */ /* #undef _GLIBCXX_HAVE__TANHF */ /* Define to 1 if you have the `_tanhl' function. */ /* #undef _GLIBCXX_HAVE__TANHL */ /* Define to 1 if you have the `_tanl' function. */ /* #undef _GLIBCXX_HAVE__TANL */ /* Define to 1 if you have the `__cxa_thread_atexit' function. */ /* #undef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT */ /* Define to 1 if you have the `__cxa_thread_atexit_impl' function. */ #define _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL 1 /* Define as const if the declaration of iconv() needs const. */ #define _GLIBCXX_ICONV_CONST /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Name of package */ /* #undef _GLIBCXX_PACKAGE */ /* Define to the address where bug reports for this package should be sent. */ #define _GLIBCXX_PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define _GLIBCXX_PACKAGE_NAME "package-unused" /* Define to the full name and version of this package. */ #define _GLIBCXX_PACKAGE_STRING "package-unused version-unused" /* Define to the one symbol short name of this package. */ #define _GLIBCXX_PACKAGE_TARNAME "libstdc++" /* Define to the home page for this package. */ #define _GLIBCXX_PACKAGE_URL "" /* Define to the version of this package. */ #define _GLIBCXX_PACKAGE__GLIBCXX_VERSION "version-unused" /* The size of `char', as computed by sizeof. */ /* #undef SIZEOF_CHAR */ /* The size of `int', as computed by sizeof. */ /* #undef SIZEOF_INT */ /* The size of `long', as computed by sizeof. */ /* #undef SIZEOF_LONG */ /* The size of `short', as computed by sizeof. */ /* #undef SIZEOF_SHORT */ /* The size of `void *', as computed by sizeof. */ /* #undef SIZEOF_VOID_P */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ /* #undef _GLIBCXX_VERSION */ /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _GLIBCXX_FILE_OFFSET_BITS */ /* Define if C99 functions in <complex.h> should be used in <complex> for C++11. Using compiler builtins for these functions requires corresponding C99 library functions to be present. */ #define _GLIBCXX11_USE_C99_COMPLEX 1 /* Define if C99 functions or macros in <math.h> should be imported in <cmath> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_MATH 1 /* Define if C99 functions or macros in <stdio.h> should be imported in <cstdio> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_STDIO 1 /* Define if C99 functions or macros in <stdlib.h> should be imported in <cstdlib> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_STDLIB 1 /* Define if C99 functions or macros in <wchar.h> should be imported in <cwchar> in namespace std for C++11. */ #define _GLIBCXX11_USE_C99_WCHAR 1 /* Define if C99 functions in <complex.h> should be used in <complex> for C++98. Using compiler builtins for these functions requires corresponding C99 library functions to be present. */ #define _GLIBCXX98_USE_C99_COMPLEX 1 /* Define if C99 functions or macros in <math.h> should be imported in <cmath> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_MATH 1 /* Define if C99 functions or macros in <stdio.h> should be imported in <cstdio> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_STDIO 1 /* Define if C99 functions or macros in <stdlib.h> should be imported in <cstdlib> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_STDLIB 1 /* Define if C99 functions or macros in <wchar.h> should be imported in <cwchar> in namespace std for C++98. */ #define _GLIBCXX98_USE_C99_WCHAR 1 /* Define if the compiler supports C++11 atomics. */ #define _GLIBCXX_ATOMIC_BUILTINS 1 /* Define to use concept checking code from the boost libraries. */ /* #undef _GLIBCXX_CONCEPT_CHECKS */ /* Define to 1 if a fully dynamic basic_string is wanted, 0 to disable, undefined for platform defaults */ #define _GLIBCXX_FULLY_DYNAMIC_STRING 0 /* Define if gthreads library is available. */ #define _GLIBCXX_HAS_GTHREADS 1 /* Define to 1 if a full hosted library is built, or 0 if freestanding. */ #define _GLIBCXX_HOSTED 1 /* Define if compatibility should be provided for -mlong-double-64. */ /* Define to the letter to which size_t is mangled. */ #define _GLIBCXX_MANGLE_SIZE_T m /* Define if C99 llrint and llround functions are missing from <math.h>. */ /* #undef _GLIBCXX_NO_C99_ROUNDING_FUNCS */ /* Define if ptrdiff_t is int. */ /* #undef _GLIBCXX_PTRDIFF_T_IS_INT */ /* Define if using setrlimit to set resource limits during "make check" */ #define _GLIBCXX_RES_LIMITS 1 /* Define if size_t is unsigned int. */ /* #undef _GLIBCXX_SIZE_T_IS_UINT */ /* Define to the value of the EOF integer constant. */ #define _GLIBCXX_STDIO_EOF -1 /* Define to the value of the SEEK_CUR integer constant. */ #define _GLIBCXX_STDIO_SEEK_CUR 1 /* Define to the value of the SEEK_END integer constant. */ #define _GLIBCXX_STDIO_SEEK_END 2 /* Define to use symbol versioning in the shared library. */ #define _GLIBCXX_SYMVER 1 /* Define to use darwin versioning in the shared library. */ /* #undef _GLIBCXX_SYMVER_DARWIN */ /* Define to use GNU versioning in the shared library. */ #define _GLIBCXX_SYMVER_GNU 1 /* Define to use GNU namespace versioning in the shared library. */ /* #undef _GLIBCXX_SYMVER_GNU_NAMESPACE */ /* Define to use Sun versioning in the shared library. */ /* #undef _GLIBCXX_SYMVER_SUN */ /* Define if C11 functions in <uchar.h> should be imported into namespace std in <cuchar>. */ #define _GLIBCXX_USE_C11_UCHAR_CXX11 1 /* Define if C99 functions or macros from <wchar.h>, <math.h>, <complex.h>, <stdio.h>, and <stdlib.h> can be used or exposed. */ #define _GLIBCXX_USE_C99 1 /* Define if C99 functions in <complex.h> should be used in <tr1/complex>. Using compiler builtins for these functions requires corresponding C99 library functions to be present. */ #define _GLIBCXX_USE_C99_COMPLEX_TR1 1 /* Define if C99 functions in <ctype.h> should be imported in <tr1/cctype> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_CTYPE_TR1 1 /* Define if C99 functions in <fenv.h> should be imported in <tr1/cfenv> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_FENV_TR1 1 /* Define if C99 functions in <inttypes.h> should be imported in <tr1/cinttypes> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_INTTYPES_TR1 1 /* Define if wchar_t C99 functions in <inttypes.h> should be imported in <tr1/cinttypes> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_INTTYPES_WCHAR_T_TR1 1 /* Define if C99 functions or macros in <math.h> should be imported in <tr1/cmath> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_MATH_TR1 1 /* Define if C99 types in <stdint.h> should be imported in <tr1/cstdint> in namespace std::tr1. */ #define _GLIBCXX_USE_C99_STDINT_TR1 1 /* Defined if clock_gettime syscall has monotonic and realtime clock support. */ /* #undef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL */ /* Defined if clock_gettime has monotonic clock support. */ #define _GLIBCXX_USE_CLOCK_MONOTONIC 1 /* Defined if clock_gettime has realtime clock support. */ #define _GLIBCXX_USE_CLOCK_REALTIME 1 /* Define if ISO/IEC TR 24733 decimal floating point types are supported on this host. */ #define _GLIBCXX_USE_DECIMAL_FLOAT 1 /* Define if fchmod is available in <sys/stat.h>. */ #define _GLIBCXX_USE_FCHMOD 1 /* Define if fchmodat is available in <sys/stat.h>. */ #define _GLIBCXX_USE_FCHMODAT 1 /* Defined if gettimeofday is available. */ #define _GLIBCXX_USE_GETTIMEOFDAY 1 /* Define if get_nprocs is available in <sys/sysinfo.h>. */ #define _GLIBCXX_USE_GET_NPROCS 1 /* Define if __int128 is supported on this host. */ #define _GLIBCXX_USE_INT128 1 /* Define if LFS support is available. */ #define _GLIBCXX_USE_LFS 1 /* Define if code specialized for long long should be used. */ #define _GLIBCXX_USE_LONG_LONG 1 /* Defined if nanosleep is available. */ #define _GLIBCXX_USE_NANOSLEEP 1 /* Define if NLS translations are to be used. */ #define _GLIBCXX_USE_NLS 1 /* Define if pthreads_num_processors_np is available in <pthread.h>. */ /* #undef _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP */ /* Define if POSIX read/write locks are available in <gthr.h>. */ #define _GLIBCXX_USE_PTHREAD_RWLOCK_T 1 /* Define if /dev/random and /dev/urandom are available for the random_device of TR1 (Chapter 5.1). */ #define _GLIBCXX_USE_RANDOM_TR1 1 /* Define if usable realpath is available in <stdlib.h>. */ #define _GLIBCXX_USE_REALPATH 1 /* Defined if sched_yield is available. */ #define _GLIBCXX_USE_SCHED_YIELD 1 /* Define if _SC_NPROCESSORS_ONLN is available in <unistd.h>. */ #define _GLIBCXX_USE_SC_NPROCESSORS_ONLN 1 /* Define if _SC_NPROC_ONLN is available in <unistd.h>. */ /* #undef _GLIBCXX_USE_SC_NPROC_ONLN */ /* Define if sendfile is available in <sys/sendfile.h>. */ #define _GLIBCXX_USE_SENDFILE 1 /* Define if struct stat has timespec members. */ #define _GLIBCXX_USE_ST_MTIM 1 /* Define if sysctl(), CTL_HW and HW_NCPU are available in <sys/sysctl.h>. */ /* #undef _GLIBCXX_USE_SYSCTL_HW_NCPU */ /* Define if obsolescent tmpnam is available in <stdio.h>. */ #define _GLIBCXX_USE_TMPNAM 1 /* Define if utimensat and UTIME_OMIT are available in <sys/stat.h> and AT_FDCWD in <fcntl.h>. */ #define _GLIBCXX_USE_UTIMENSAT 1 /* Define if code specialized for wchar_t should be used. */ #define _GLIBCXX_USE_WCHAR_T 1 /* Define to 1 if a verbose library is built, or 0 otherwise. */ #define _GLIBCXX_VERBOSE 1 /* Defined if as can handle rdrand. */ #define _GLIBCXX_X86_RDRAND 1 /* Define to 1 if mutex_timedlock is available. */ #define _GTHREAD_USE_MUTEX_TIMEDLOCK 1 /* Define for large files, on AIX-style hosts. */ /* #undef _GLIBCXX_LARGE_FILES */ /* Define if all C++11 floating point overloads are available in <math.h>. */ #if __cplusplus >= 201103L /* #undef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP */ #endif /* Define if all C++11 integral type overloads are available in <math.h>. */ #if __cplusplus >= 201103L /* #undef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT */ #endif #if defined (_GLIBCXX_HAVE__ACOSF) && ! defined (_GLIBCXX_HAVE_ACOSF) # define _GLIBCXX_HAVE_ACOSF 1 # define acosf _acosf #endif #if defined (_GLIBCXX_HAVE__ACOSL) && ! defined (_GLIBCXX_HAVE_ACOSL) # define _GLIBCXX_HAVE_ACOSL 1 # define acosl _acosl #endif #if defined (_GLIBCXX_HAVE__ASINF) && ! defined (_GLIBCXX_HAVE_ASINF) # define _GLIBCXX_HAVE_ASINF 1 # define asinf _asinf #endif #if defined (_GLIBCXX_HAVE__ASINL) && ! defined (_GLIBCXX_HAVE_ASINL) # define _GLIBCXX_HAVE_ASINL 1 # define asinl _asinl #endif #if defined (_GLIBCXX_HAVE__ATAN2F) && ! defined (_GLIBCXX_HAVE_ATAN2F) # define _GLIBCXX_HAVE_ATAN2F 1 # define atan2f _atan2f #endif #if defined (_GLIBCXX_HAVE__ATAN2L) && ! defined (_GLIBCXX_HAVE_ATAN2L) # define _GLIBCXX_HAVE_ATAN2L 1 # define atan2l _atan2l #endif #if defined (_GLIBCXX_HAVE__ATANF) && ! defined (_GLIBCXX_HAVE_ATANF) # define _GLIBCXX_HAVE_ATANF 1 # define atanf _atanf #endif #if defined (_GLIBCXX_HAVE__ATANL) && ! defined (_GLIBCXX_HAVE_ATANL) # define _GLIBCXX_HAVE_ATANL 1 # define atanl _atanl #endif #if defined (_GLIBCXX_HAVE__CEILF) && ! defined (_GLIBCXX_HAVE_CEILF) # define _GLIBCXX_HAVE_CEILF 1 # define ceilf _ceilf #endif #if defined (_GLIBCXX_HAVE__CEILL) && ! defined (_GLIBCXX_HAVE_CEILL) # define _GLIBCXX_HAVE_CEILL 1 # define ceill _ceill #endif #if defined (_GLIBCXX_HAVE__COSF) && ! defined (_GLIBCXX_HAVE_COSF) # define _GLIBCXX_HAVE_COSF 1 # define cosf _cosf #endif #if defined (_GLIBCXX_HAVE__COSHF) && ! defined (_GLIBCXX_HAVE_COSHF) # define _GLIBCXX_HAVE_COSHF 1 # define coshf _coshf #endif #if defined (_GLIBCXX_HAVE__COSHL) && ! defined (_GLIBCXX_HAVE_COSHL) # define _GLIBCXX_HAVE_COSHL 1 # define coshl _coshl #endif #if defined (_GLIBCXX_HAVE__COSL) && ! defined (_GLIBCXX_HAVE_COSL) # define _GLIBCXX_HAVE_COSL 1 # define cosl _cosl #endif #if defined (_GLIBCXX_HAVE__EXPF) && ! defined (_GLIBCXX_HAVE_EXPF) # define _GLIBCXX_HAVE_EXPF 1 # define expf _expf #endif #if defined (_GLIBCXX_HAVE__EXPL) && ! defined (_GLIBCXX_HAVE_EXPL) # define _GLIBCXX_HAVE_EXPL 1 # define expl _expl #endif #if defined (_GLIBCXX_HAVE__FABSF) && ! defined (_GLIBCXX_HAVE_FABSF) # define _GLIBCXX_HAVE_FABSF 1 # define fabsf _fabsf #endif #if defined (_GLIBCXX_HAVE__FABSL) && ! defined (_GLIBCXX_HAVE_FABSL) # define _GLIBCXX_HAVE_FABSL 1 # define fabsl _fabsl #endif #if defined (_GLIBCXX_HAVE__FINITE) && ! defined (_GLIBCXX_HAVE_FINITE) # define _GLIBCXX_HAVE_FINITE 1 # define finite _finite #endif #if defined (_GLIBCXX_HAVE__FINITEF) && ! defined (_GLIBCXX_HAVE_FINITEF) # define _GLIBCXX_HAVE_FINITEF 1 # define finitef _finitef #endif #if defined (_GLIBCXX_HAVE__FINITEL) && ! defined (_GLIBCXX_HAVE_FINITEL) # define _GLIBCXX_HAVE_FINITEL 1 # define finitel _finitel #endif #if defined (_GLIBCXX_HAVE__FLOORF) && ! defined (_GLIBCXX_HAVE_FLOORF) # define _GLIBCXX_HAVE_FLOORF 1 # define floorf _floorf #endif #if defined (_GLIBCXX_HAVE__FLOORL) && ! defined (_GLIBCXX_HAVE_FLOORL) # define _GLIBCXX_HAVE_FLOORL 1 # define floorl _floorl #endif #if defined (_GLIBCXX_HAVE__FMODF) && ! defined (_GLIBCXX_HAVE_FMODF) # define _GLIBCXX_HAVE_FMODF 1 # define fmodf _fmodf #endif #if defined (_GLIBCXX_HAVE__FMODL) && ! defined (_GLIBCXX_HAVE_FMODL) # define _GLIBCXX_HAVE_FMODL 1 # define fmodl _fmodl #endif #if defined (_GLIBCXX_HAVE__FPCLASS) && ! defined (_GLIBCXX_HAVE_FPCLASS) # define _GLIBCXX_HAVE_FPCLASS 1 # define fpclass _fpclass #endif #if defined (_GLIBCXX_HAVE__FREXPF) && ! defined (_GLIBCXX_HAVE_FREXPF) # define _GLIBCXX_HAVE_FREXPF 1 # define frexpf _frexpf #endif #if defined (_GLIBCXX_HAVE__FREXPL) && ! defined (_GLIBCXX_HAVE_FREXPL) # define _GLIBCXX_HAVE_FREXPL 1 # define frexpl _frexpl #endif #if defined (_GLIBCXX_HAVE__HYPOT) && ! defined (_GLIBCXX_HAVE_HYPOT) # define _GLIBCXX_HAVE_HYPOT 1 # define hypot _hypot #endif #if defined (_GLIBCXX_HAVE__HYPOTF) && ! defined (_GLIBCXX_HAVE_HYPOTF) # define _GLIBCXX_HAVE_HYPOTF 1 # define hypotf _hypotf #endif #if defined (_GLIBCXX_HAVE__HYPOTL) && ! defined (_GLIBCXX_HAVE_HYPOTL) # define _GLIBCXX_HAVE_HYPOTL 1 # define hypotl _hypotl #endif #if defined (_GLIBCXX_HAVE__ISINF) && ! defined (_GLIBCXX_HAVE_ISINF) # define _GLIBCXX_HAVE_ISINF 1 # define isinf _isinf #endif #if defined (_GLIBCXX_HAVE__ISINFF) && ! defined (_GLIBCXX_HAVE_ISINFF) # define _GLIBCXX_HAVE_ISINFF 1 # define isinff _isinff #endif #if defined (_GLIBCXX_HAVE__ISINFL) && ! defined (_GLIBCXX_HAVE_ISINFL) # define _GLIBCXX_HAVE_ISINFL 1 # define isinfl _isinfl #endif #if defined (_GLIBCXX_HAVE__ISNAN) && ! defined (_GLIBCXX_HAVE_ISNAN) # define _GLIBCXX_HAVE_ISNAN 1 # define isnan _isnan #endif #if defined (_GLIBCXX_HAVE__ISNANF) && ! defined (_GLIBCXX_HAVE_ISNANF) # define _GLIBCXX_HAVE_ISNANF 1 # define isnanf _isnanf #endif #if defined (_GLIBCXX_HAVE__ISNANL) && ! defined (_GLIBCXX_HAVE_ISNANL) # define _GLIBCXX_HAVE_ISNANL 1 # define isnanl _isnanl #endif #if defined (_GLIBCXX_HAVE__LDEXPF) && ! defined (_GLIBCXX_HAVE_LDEXPF) # define _GLIBCXX_HAVE_LDEXPF 1 # define ldexpf _ldexpf #endif #if defined (_GLIBCXX_HAVE__LDEXPL) && ! defined (_GLIBCXX_HAVE_LDEXPL) # define _GLIBCXX_HAVE_LDEXPL 1 # define ldexpl _ldexpl #endif #if defined (_GLIBCXX_HAVE__LOG10F) && ! defined (_GLIBCXX_HAVE_LOG10F) # define _GLIBCXX_HAVE_LOG10F 1 # define log10f _log10f #endif #if defined (_GLIBCXX_HAVE__LOG10L) && ! defined (_GLIBCXX_HAVE_LOG10L) # define _GLIBCXX_HAVE_LOG10L 1 # define log10l _log10l #endif #if defined (_GLIBCXX_HAVE__LOGF) && ! defined (_GLIBCXX_HAVE_LOGF) # define _GLIBCXX_HAVE_LOGF 1 # define logf _logf #endif #if defined (_GLIBCXX_HAVE__LOGL) && ! defined (_GLIBCXX_HAVE_LOGL) # define _GLIBCXX_HAVE_LOGL 1 # define logl _logl #endif #if defined (_GLIBCXX_HAVE__MODF) && ! defined (_GLIBCXX_HAVE_MODF) # define _GLIBCXX_HAVE_MODF 1 # define modf _modf #endif #if defined (_GLIBCXX_HAVE__MODFF) && ! defined (_GLIBCXX_HAVE_MODFF) # define _GLIBCXX_HAVE_MODFF 1 # define modff _modff #endif #if defined (_GLIBCXX_HAVE__MODFL) && ! defined (_GLIBCXX_HAVE_MODFL) # define _GLIBCXX_HAVE_MODFL 1 # define modfl _modfl #endif #if defined (_GLIBCXX_HAVE__POWF) && ! defined (_GLIBCXX_HAVE_POWF) # define _GLIBCXX_HAVE_POWF 1 # define powf _powf #endif #if defined (_GLIBCXX_HAVE__POWL) && ! defined (_GLIBCXX_HAVE_POWL) # define _GLIBCXX_HAVE_POWL 1 # define powl _powl #endif #if defined (_GLIBCXX_HAVE__QFPCLASS) && ! defined (_GLIBCXX_HAVE_QFPCLASS) # define _GLIBCXX_HAVE_QFPCLASS 1 # define qfpclass _qfpclass #endif #if defined (_GLIBCXX_HAVE__SINCOS) && ! defined (_GLIBCXX_HAVE_SINCOS) # define _GLIBCXX_HAVE_SINCOS 1 # define sincos _sincos #endif #if defined (_GLIBCXX_HAVE__SINCOSF) && ! defined (_GLIBCXX_HAVE_SINCOSF) # define _GLIBCXX_HAVE_SINCOSF 1 # define sincosf _sincosf #endif #if defined (_GLIBCXX_HAVE__SINCOSL) && ! defined (_GLIBCXX_HAVE_SINCOSL) # define _GLIBCXX_HAVE_SINCOSL 1 # define sincosl _sincosl #endif #if defined (_GLIBCXX_HAVE__SINF) && ! defined (_GLIBCXX_HAVE_SINF) # define _GLIBCXX_HAVE_SINF 1 # define sinf _sinf #endif #if defined (_GLIBCXX_HAVE__SINHF) && ! defined (_GLIBCXX_HAVE_SINHF) # define _GLIBCXX_HAVE_SINHF 1 # define sinhf _sinhf #endif #if defined (_GLIBCXX_HAVE__SINHL) && ! defined (_GLIBCXX_HAVE_SINHL) # define _GLIBCXX_HAVE_SINHL 1 # define sinhl _sinhl #endif #if defined (_GLIBCXX_HAVE__SINL) && ! defined (_GLIBCXX_HAVE_SINL) # define _GLIBCXX_HAVE_SINL 1 # define sinl _sinl #endif #if defined (_GLIBCXX_HAVE__SQRTF) && ! defined (_GLIBCXX_HAVE_SQRTF) # define _GLIBCXX_HAVE_SQRTF 1 # define sqrtf _sqrtf #endif #if defined (_GLIBCXX_HAVE__SQRTL) && ! defined (_GLIBCXX_HAVE_SQRTL) # define _GLIBCXX_HAVE_SQRTL 1 # define sqrtl _sqrtl #endif #if defined (_GLIBCXX_HAVE__STRTOF) && ! defined (_GLIBCXX_HAVE_STRTOF) # define _GLIBCXX_HAVE_STRTOF 1 # define strtof _strtof #endif #if defined (_GLIBCXX_HAVE__STRTOLD) && ! defined (_GLIBCXX_HAVE_STRTOLD) # define _GLIBCXX_HAVE_STRTOLD 1 # define strtold _strtold #endif #if defined (_GLIBCXX_HAVE__TANF) && ! defined (_GLIBCXX_HAVE_TANF) # define _GLIBCXX_HAVE_TANF 1 # define tanf _tanf #endif #if defined (_GLIBCXX_HAVE__TANHF) && ! defined (_GLIBCXX_HAVE_TANHF) # define _GLIBCXX_HAVE_TANHF 1 # define tanhf _tanhf #endif #if defined (_GLIBCXX_HAVE__TANHL) && ! defined (_GLIBCXX_HAVE_TANHL) # define _GLIBCXX_HAVE_TANHL 1 # define tanhl _tanhl #endif #if defined (_GLIBCXX_HAVE__TANL) && ! defined (_GLIBCXX_HAVE_TANL) # define _GLIBCXX_HAVE_TANL 1 # define tanl _tanl #endif #endif // _GLIBCXX_CXX_CONFIG_H #endif #endif c++/8/x86_64-redhat-linux/bits/gthr-single.h 0000644 00000015230 15146341150 0014161 0 ustar 00 /* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _GLIBCXX_GCC_GTHR_SINGLE_H #define _GLIBCXX_GCC_GTHR_SINGLE_H /* Just provide compatibility for mutex handling. */ typedef int __gthread_key_t; typedef int __gthread_once_t; typedef int __gthread_mutex_t; typedef int __gthread_recursive_mutex_t; #define __GTHREAD_ONCE_INIT 0 #define __GTHREAD_MUTEX_INIT 0 #define __GTHREAD_MUTEX_INIT_FUNCTION(mx) do {} while (0) #define __GTHREAD_RECURSIVE_MUTEX_INIT 0 #define _GLIBCXX_UNUSED __attribute__((__unused__)) #ifdef _LIBOBJC /* Thread local storage for a single thread */ static void *thread_local_storage = NULL; /* Backend initialization functions */ /* Initialize the threads subsystem. */ static inline int __gthread_objc_init_thread_system (void) { /* No thread support available */ return -1; } /* Close the threads subsystem. */ static inline int __gthread_objc_close_thread_system (void) { /* No thread support available */ return -1; } /* Backend thread functions */ /* Create a new thread of execution. */ static inline objc_thread_t __gthread_objc_thread_detach (void (* func)(void *), void * arg _GLIBCXX_UNUSED) { /* No thread support available */ return NULL; } /* Set the current thread's priority. */ static inline int __gthread_objc_thread_set_priority (int priority _GLIBCXX_UNUSED) { /* No thread support available */ return -1; } /* Return the current thread's priority. */ static inline int __gthread_objc_thread_get_priority (void) { return OBJC_THREAD_INTERACTIVE_PRIORITY; } /* Yield our process time to another thread. */ static inline void __gthread_objc_thread_yield (void) { return; } /* Terminate the current thread. */ static inline int __gthread_objc_thread_exit (void) { /* No thread support available */ /* Should we really exit the program */ /* exit (&__objc_thread_exit_status); */ return -1; } /* Returns an integer value which uniquely describes a thread. */ static inline objc_thread_t __gthread_objc_thread_id (void) { /* No thread support, use 1. */ return (objc_thread_t) 1; } /* Sets the thread's local storage pointer. */ static inline int __gthread_objc_thread_set_data (void *value) { thread_local_storage = value; return 0; } /* Returns the thread's local storage pointer. */ static inline void * __gthread_objc_thread_get_data (void) { return thread_local_storage; } /* Backend mutex functions */ /* Allocate a mutex. */ static inline int __gthread_objc_mutex_allocate (objc_mutex_t mutex _GLIBCXX_UNUSED) { return 0; } /* Deallocate a mutex. */ static inline int __gthread_objc_mutex_deallocate (objc_mutex_t mutex _GLIBCXX_UNUSED) { return 0; } /* Grab a lock on a mutex. */ static inline int __gthread_objc_mutex_lock (objc_mutex_t mutex _GLIBCXX_UNUSED) { /* There can only be one thread, so we always get the lock */ return 0; } /* Try to grab a lock on a mutex. */ static inline int __gthread_objc_mutex_trylock (objc_mutex_t mutex _GLIBCXX_UNUSED) { /* There can only be one thread, so we always get the lock */ return 0; } /* Unlock the mutex */ static inline int __gthread_objc_mutex_unlock (objc_mutex_t mutex _GLIBCXX_UNUSED) { return 0; } /* Backend condition mutex functions */ /* Allocate a condition. */ static inline int __gthread_objc_condition_allocate (objc_condition_t condition _GLIBCXX_UNUSED) { return 0; } /* Deallocate a condition. */ static inline int __gthread_objc_condition_deallocate (objc_condition_t condition _GLIBCXX_UNUSED) { return 0; } /* Wait on the condition */ static inline int __gthread_objc_condition_wait (objc_condition_t condition _GLIBCXX_UNUSED, objc_mutex_t mutex _GLIBCXX_UNUSED) { return 0; } /* Wake up all threads waiting on this condition. */ static inline int __gthread_objc_condition_broadcast (objc_condition_t condition _GLIBCXX_UNUSED) { return 0; } /* Wake up one thread waiting on this condition. */ static inline int __gthread_objc_condition_signal (objc_condition_t condition _GLIBCXX_UNUSED) { return 0; } #else /* _LIBOBJC */ static inline int __gthread_active_p (void) { return 0; } static inline int __gthread_once (__gthread_once_t *__once _GLIBCXX_UNUSED, void (*__func) (void) _GLIBCXX_UNUSED) { return 0; } static inline int _GLIBCXX_UNUSED __gthread_key_create (__gthread_key_t *__key _GLIBCXX_UNUSED, void (*__func) (void *) _GLIBCXX_UNUSED) { return 0; } static int _GLIBCXX_UNUSED __gthread_key_delete (__gthread_key_t __key _GLIBCXX_UNUSED) { return 0; } static inline void * __gthread_getspecific (__gthread_key_t __key _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_setspecific (__gthread_key_t __key _GLIBCXX_UNUSED, const void *__v _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_mutex_destroy (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_mutex_lock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_mutex_trylock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_mutex_unlock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED) { return 0; } static inline int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_lock (__mutex); } static inline int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_trylock (__mutex); } static inline int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_unlock (__mutex); } static inline int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_destroy (__mutex); } #endif /* _LIBOBJC */ #undef _GLIBCXX_UNUSED #endif /* ! _GLIBCXX_GCC_GTHR_SINGLE_H */ c++/8/x86_64-redhat-linux/bits/messages_members.h 0000644 00000010644 15146341150 0015263 0 ustar 00 // std::messages implementation details, GNU version -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/messages_members.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.2.7.1.2 messages functions // // Written by Benjamin Kosnik <bkoz@redhat.com> #include <libintl.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Non-virtual member functions. template<typename _CharT> messages<_CharT>::messages(size_t __refs) : facet(__refs), _M_c_locale_messages(_S_get_c_locale()), _M_name_messages(_S_get_c_name()) { } template<typename _CharT> messages<_CharT>::messages(__c_locale __cloc, const char* __s, size_t __refs) : facet(__refs), _M_c_locale_messages(0), _M_name_messages(0) { if (__builtin_strcmp(__s, _S_get_c_name()) != 0) { const size_t __len = __builtin_strlen(__s) + 1; char* __tmp = new char[__len]; __builtin_memcpy(__tmp, __s, __len); _M_name_messages = __tmp; } else _M_name_messages = _S_get_c_name(); // Last to avoid leaking memory if new throws. _M_c_locale_messages = _S_clone_c_locale(__cloc); } template<typename _CharT> typename messages<_CharT>::catalog messages<_CharT>::open(const basic_string<char>& __s, const locale& __loc, const char* __dir) const { bindtextdomain(__s.c_str(), __dir); return this->do_open(__s, __loc); } // Virtual member functions. template<typename _CharT> messages<_CharT>::~messages() { if (_M_name_messages != _S_get_c_name()) delete [] _M_name_messages; _S_destroy_c_locale(_M_c_locale_messages); } template<typename _CharT> typename messages<_CharT>::catalog messages<_CharT>::do_open(const basic_string<char>& __s, const locale&) const { // No error checking is done, assume the catalog exists and can // be used. textdomain(__s.c_str()); return 0; } template<typename _CharT> void messages<_CharT>::do_close(catalog) const { } // messages_byname template<typename _CharT> messages_byname<_CharT>::messages_byname(const char* __s, size_t __refs) : messages<_CharT>(__refs) { if (this->_M_name_messages != locale::facet::_S_get_c_name()) { delete [] this->_M_name_messages; if (__builtin_strcmp(__s, locale::facet::_S_get_c_name()) != 0) { const size_t __len = __builtin_strlen(__s) + 1; char* __tmp = new char[__len]; __builtin_memcpy(__tmp, __s, __len); this->_M_name_messages = __tmp; } else this->_M_name_messages = locale::facet::_S_get_c_name(); } if (__builtin_strcmp(__s, "C") != 0 && __builtin_strcmp(__s, "POSIX") != 0) { this->_S_destroy_c_locale(this->_M_c_locale_messages); this->_S_create_c_locale(this->_M_c_locale_messages, __s); } } //Specializations. template<> typename messages<char>::catalog messages<char>::do_open(const basic_string<char>&, const locale&) const; template<> void messages<char>::do_close(catalog) const; #ifdef _GLIBCXX_USE_WCHAR_T template<> typename messages<wchar_t>::catalog messages<wchar_t>::do_open(const basic_string<char>&, const locale&) const; template<> void messages<wchar_t>::do_close(catalog) const; #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/x86_64-redhat-linux/bits/c++locale.h 0000644 00000006353 15146341150 0013474 0 ustar 00 // Wrapper for underlying C-language localization -*- C++ -*- // Copyright (C) 2001-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/c++locale.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.8 Standard locale categories. // // Written by Benjamin Kosnik <bkoz@redhat.com> #ifndef _GLIBCXX_CXX_LOCALE_H #define _GLIBCXX_CXX_LOCALE_H 1 #pragma GCC system_header #include <clocale> #define _GLIBCXX_C_LOCALE_GNU 1 #define _GLIBCXX_NUM_CATEGORIES 6 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION extern "C" __typeof(uselocale) __uselocale; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef __locale_t __c_locale; // Convert numeric value of type double and long double to string and // return length of string. If vsnprintf is available use it, otherwise // fall back to the unsafe vsprintf which, in general, can be dangerous // and should be avoided. inline int __convert_from_v(const __c_locale& __cloc __attribute__ ((__unused__)), char* __out, const int __size __attribute__ ((__unused__)), const char* __fmt, ...) { #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) __c_locale __old = __gnu_cxx::__uselocale(__cloc); #else char* __old = std::setlocale(LC_NUMERIC, 0); char* __sav = 0; if (__builtin_strcmp(__old, "C")) { const size_t __len = __builtin_strlen(__old) + 1; __sav = new char[__len]; __builtin_memcpy(__sav, __old, __len); std::setlocale(LC_NUMERIC, "C"); } #endif __builtin_va_list __args; __builtin_va_start(__args, __fmt); #if _GLIBCXX_USE_C99_STDIO const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args); #else const int __ret = __builtin_vsprintf(__out, __fmt, __args); #endif __builtin_va_end(__args); #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) __gnu_cxx::__uselocale(__old); #else if (__sav) { std::setlocale(LC_NUMERIC, __sav); delete [] __sav; } #endif return __ret; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/x86_64-redhat-linux/bits/c++allocator.h 0000644 00000003673 15146341150 0014217 0 ustar 00 // Base to std::allocator -*- C++ -*- // Copyright (C) 2004-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/c++allocator.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{memory} */ #ifndef _GLIBCXX_CXX_ALLOCATOR_H #define _GLIBCXX_CXX_ALLOCATOR_H 1 #include <ext/new_allocator.h> #if __cplusplus >= 201103L namespace std { /** * @brief An alias to the base class for std::allocator. * @ingroup allocators * * Used to set the std::allocator base class to * __gnu_cxx::new_allocator. * * @tparam _Tp Type of allocated object. */ template<typename _Tp> using __allocator_base = __gnu_cxx::new_allocator<_Tp>; } #else // Define new_allocator as the base class to std::allocator. # define __allocator_base __gnu_cxx::new_allocator #endif #if defined(__SANITIZE_ADDRESS__) && !defined(_GLIBCXX_SANITIZE_STD_ALLOCATOR) # define _GLIBCXX_SANITIZE_STD_ALLOCATOR 1 #endif #endif c++/8/x86_64-redhat-linux/bits/gthr.h 0000644 00000012750 15146341150 0012706 0 ustar 00 /* Threads compatibility routines for libgcc2. */ /* Compile this one with gcc. */ /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _GLIBCXX_GCC_GTHR_H #define _GLIBCXX_GCC_GTHR_H #ifndef _GLIBCXX_HIDE_EXPORTS #pragma GCC visibility push(default) #endif /* If this file is compiled with threads support, it must #define __GTHREADS 1 to indicate that threads support is present. Also it has define function int __gthread_active_p () that returns 1 if thread system is active, 0 if not. The threads interface must define the following types: __gthread_key_t __gthread_once_t __gthread_mutex_t __gthread_recursive_mutex_t The threads interface must define the following macros: __GTHREAD_ONCE_INIT to initialize __gthread_once_t __GTHREAD_MUTEX_INIT to initialize __gthread_mutex_t to get a fast non-recursive mutex. __GTHREAD_MUTEX_INIT_FUNCTION to initialize __gthread_mutex_t to get a fast non-recursive mutex. Define this to a function which looks like this: void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *) Some systems can't initialize a mutex without a function call. Don't define __GTHREAD_MUTEX_INIT in this case. __GTHREAD_RECURSIVE_MUTEX_INIT __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION as above, but for a recursive mutex. The threads interface must define the following static functions: int __gthread_once (__gthread_once_t *once, void (*func) ()) int __gthread_key_create (__gthread_key_t *keyp, void (*dtor) (void *)) int __gthread_key_delete (__gthread_key_t key) void *__gthread_getspecific (__gthread_key_t key) int __gthread_setspecific (__gthread_key_t key, const void *ptr) int __gthread_mutex_destroy (__gthread_mutex_t *mutex); int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *mutex); int __gthread_mutex_lock (__gthread_mutex_t *mutex); int __gthread_mutex_trylock (__gthread_mutex_t *mutex); int __gthread_mutex_unlock (__gthread_mutex_t *mutex); int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex); int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex); int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex); The following are supported in POSIX threads only. They are required to fix a deadlock in static initialization inside libsupc++. The header file gthr-posix.h defines a symbol __GTHREAD_HAS_COND to signify that these extra features are supported. Types: __gthread_cond_t Macros: __GTHREAD_COND_INIT __GTHREAD_COND_INIT_FUNCTION Interface: int __gthread_cond_broadcast (__gthread_cond_t *cond); int __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex); int __gthread_cond_wait_recursive (__gthread_cond_t *cond, __gthread_recursive_mutex_t *mutex); All functions returning int should return zero on success or the error number. If the operation is not supported, -1 is returned. If the following are also defined, you should #define __GTHREADS_CXX0X 1 to enable the c++0x thread library. Types: __gthread_t __gthread_time_t Interface: int __gthread_create (__gthread_t *thread, void *(*func) (void*), void *args); int __gthread_join (__gthread_t thread, void **value_ptr); int __gthread_detach (__gthread_t thread); int __gthread_equal (__gthread_t t1, __gthread_t t2); __gthread_t __gthread_self (void); int __gthread_yield (void); int __gthread_mutex_timedlock (__gthread_mutex_t *m, const __gthread_time_t *abs_timeout); int __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *m, const __gthread_time_t *abs_time); int __gthread_cond_signal (__gthread_cond_t *cond); int __gthread_cond_timedwait (__gthread_cond_t *cond, __gthread_mutex_t *mutex, const __gthread_time_t *abs_timeout); */ #if __GXX_WEAK__ /* The pe-coff weak support isn't fully compatible to ELF's weak. For static libraries it might would work, but as we need to deal with shared versions too, we disable it for mingw-targets. */ #ifdef __MINGW32__ #undef _GLIBCXX_GTHREAD_USE_WEAK #define _GLIBCXX_GTHREAD_USE_WEAK 0 #endif #ifndef _GLIBCXX_GTHREAD_USE_WEAK #define _GLIBCXX_GTHREAD_USE_WEAK 1 #endif #endif #include <bits/gthr-default.h> #ifndef _GLIBCXX_HIDE_EXPORTS #pragma GCC visibility pop #endif #endif /* ! _GLIBCXX_GCC_GTHR_H */ c++/8/x86_64-redhat-linux/bits/error_constants.h 0000644 00000012067 15146341150 0015170 0 ustar 00 // Specific definitions for generic platforms -*- C++ -*- // Copyright (C) 2007-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/error_constants.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{system_error} */ #ifndef _GLIBCXX_ERROR_CONSTANTS #define _GLIBCXX_ERROR_CONSTANTS 1 #include <bits/c++config.h> #include <cerrno> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION enum class errc { address_family_not_supported = EAFNOSUPPORT, address_in_use = EADDRINUSE, address_not_available = EADDRNOTAVAIL, already_connected = EISCONN, argument_list_too_long = E2BIG, argument_out_of_domain = EDOM, bad_address = EFAULT, bad_file_descriptor = EBADF, #ifdef _GLIBCXX_HAVE_EBADMSG bad_message = EBADMSG, #endif broken_pipe = EPIPE, connection_aborted = ECONNABORTED, connection_already_in_progress = EALREADY, connection_refused = ECONNREFUSED, connection_reset = ECONNRESET, cross_device_link = EXDEV, destination_address_required = EDESTADDRREQ, device_or_resource_busy = EBUSY, directory_not_empty = ENOTEMPTY, executable_format_error = ENOEXEC, file_exists = EEXIST, file_too_large = EFBIG, filename_too_long = ENAMETOOLONG, function_not_supported = ENOSYS, host_unreachable = EHOSTUNREACH, #ifdef _GLIBCXX_HAVE_EIDRM identifier_removed = EIDRM, #endif illegal_byte_sequence = EILSEQ, inappropriate_io_control_operation = ENOTTY, interrupted = EINTR, invalid_argument = EINVAL, invalid_seek = ESPIPE, io_error = EIO, is_a_directory = EISDIR, message_size = EMSGSIZE, network_down = ENETDOWN, network_reset = ENETRESET, network_unreachable = ENETUNREACH, no_buffer_space = ENOBUFS, no_child_process = ECHILD, #ifdef _GLIBCXX_HAVE_ENOLINK no_link = ENOLINK, #endif no_lock_available = ENOLCK, #ifdef _GLIBCXX_HAVE_ENODATA no_message_available = ENODATA, #endif no_message = ENOMSG, no_protocol_option = ENOPROTOOPT, no_space_on_device = ENOSPC, #ifdef _GLIBCXX_HAVE_ENOSR no_stream_resources = ENOSR, #endif no_such_device_or_address = ENXIO, no_such_device = ENODEV, no_such_file_or_directory = ENOENT, no_such_process = ESRCH, not_a_directory = ENOTDIR, not_a_socket = ENOTSOCK, #ifdef _GLIBCXX_HAVE_ENOSTR not_a_stream = ENOSTR, #endif not_connected = ENOTCONN, not_enough_memory = ENOMEM, #ifdef _GLIBCXX_HAVE_ENOTSUP not_supported = ENOTSUP, #endif #ifdef _GLIBCXX_HAVE_ECANCELED operation_canceled = ECANCELED, #endif operation_in_progress = EINPROGRESS, operation_not_permitted = EPERM, operation_not_supported = EOPNOTSUPP, operation_would_block = EWOULDBLOCK, #ifdef _GLIBCXX_HAVE_EOWNERDEAD owner_dead = EOWNERDEAD, #endif permission_denied = EACCES, #ifdef _GLIBCXX_HAVE_EPROTO protocol_error = EPROTO, #endif protocol_not_supported = EPROTONOSUPPORT, read_only_file_system = EROFS, resource_deadlock_would_occur = EDEADLK, resource_unavailable_try_again = EAGAIN, result_out_of_range = ERANGE, #ifdef _GLIBCXX_HAVE_ENOTRECOVERABLE state_not_recoverable = ENOTRECOVERABLE, #endif #ifdef _GLIBCXX_HAVE_ETIME stream_timeout = ETIME, #endif #ifdef _GLIBCXX_HAVE_ETXTBSY text_file_busy = ETXTBSY, #endif timed_out = ETIMEDOUT, too_many_files_open_in_system = ENFILE, too_many_files_open = EMFILE, too_many_links = EMLINK, too_many_symbolic_link_levels = ELOOP, #ifdef _GLIBCXX_HAVE_EOVERFLOW value_too_large = EOVERFLOW, #endif wrong_protocol_type = EPROTOTYPE }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/x86_64-redhat-linux/bits/gthr-default.h 0000644 00000057255 15146341150 0014341 0 ustar 00 /* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _GLIBCXX_GCC_GTHR_POSIX_H #define _GLIBCXX_GCC_GTHR_POSIX_H /* POSIX threads specific definitions. Easy, since the interface is just one-to-one mapping. */ #define __GTHREADS 1 #define __GTHREADS_CXX0X 1 #include <pthread.h> #if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \ || !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK)) # include <unistd.h> # if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0 # define _GTHREAD_USE_MUTEX_TIMEDLOCK 1 # else # define _GTHREAD_USE_MUTEX_TIMEDLOCK 0 # endif #endif typedef pthread_t __gthread_t; typedef pthread_key_t __gthread_key_t; typedef pthread_once_t __gthread_once_t; typedef pthread_mutex_t __gthread_mutex_t; typedef pthread_mutex_t __gthread_recursive_mutex_t; typedef pthread_cond_t __gthread_cond_t; typedef struct timespec __gthread_time_t; /* POSIX like conditional variables are supported. Please look at comments in gthr.h for details. */ #define __GTHREAD_HAS_COND 1 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP #else #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function #endif #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER #define __GTHREAD_TIME_INIT {0,0} #ifdef _GTHREAD_USE_MUTEX_INIT_FUNC # undef __GTHREAD_MUTEX_INIT #endif #ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC # undef __GTHREAD_RECURSIVE_MUTEX_INIT # undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION # define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function #endif #ifdef _GTHREAD_USE_COND_INIT_FUNC # undef __GTHREAD_COND_INIT # define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function #endif #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK # ifndef __gthrw_pragma # define __gthrw_pragma(pragma) # endif # define __gthrw2(name,name2,type) \ static __typeof(type) name __attribute__ ((__weakref__(#name2))); \ __gthrw_pragma(weak type) # define __gthrw_(name) __gthrw_ ## name #else # define __gthrw2(name,name2,type) # define __gthrw_(name) name #endif /* Typically, __gthrw_foo is a weak reference to symbol foo. */ #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name) __gthrw(pthread_once) __gthrw(pthread_getspecific) __gthrw(pthread_setspecific) __gthrw(pthread_create) __gthrw(pthread_join) __gthrw(pthread_equal) __gthrw(pthread_self) __gthrw(pthread_detach) #ifndef __BIONIC__ __gthrw(pthread_cancel) #endif __gthrw(sched_yield) __gthrw(pthread_mutex_lock) __gthrw(pthread_mutex_trylock) #if _GTHREAD_USE_MUTEX_TIMEDLOCK __gthrw(pthread_mutex_timedlock) #endif __gthrw(pthread_mutex_unlock) __gthrw(pthread_mutex_init) __gthrw(pthread_mutex_destroy) __gthrw(pthread_cond_init) __gthrw(pthread_cond_broadcast) __gthrw(pthread_cond_signal) __gthrw(pthread_cond_wait) __gthrw(pthread_cond_timedwait) __gthrw(pthread_cond_destroy) __gthrw(pthread_key_create) __gthrw(pthread_key_delete) __gthrw(pthread_mutexattr_init) __gthrw(pthread_mutexattr_settype) __gthrw(pthread_mutexattr_destroy) #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) /* Objective-C. */ __gthrw(pthread_exit) #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING __gthrw(sched_get_priority_max) __gthrw(sched_get_priority_min) #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ __gthrw(pthread_attr_destroy) __gthrw(pthread_attr_init) __gthrw(pthread_attr_setdetachstate) #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING __gthrw(pthread_getschedparam) __gthrw(pthread_setschedparam) #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _LIBOBJC || _LIBOBJC_WEAK */ #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if -pthreads is not specified. The functions are dummies and most return an error value. However pthread_once returns 0 without invoking the routine it is passed so we cannot pretend that the interface is active if -pthreads is not specified. On Solaris 2.5.1, the interface is not exposed at all so we need to play the usual game with weak symbols. On Solaris 10 and up, a working interface is always exposed. On FreeBSD 6 and later, libc also exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc, which means the alternate __gthread_active_p below cannot be used there. */ #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) static volatile int __gthread_active = -1; static void __gthread_trigger (void) { __gthread_active = 1; } static inline int __gthread_active_p (void) { static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT; /* Avoid reading __gthread_active twice on the main code path. */ int __gthread_active_latest_value = __gthread_active; /* This test is not protected to avoid taking a lock on the main code path so every update of __gthread_active in a threaded program must be atomic with regard to the result of the test. */ if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { if (__gthrw_(pthread_once)) { /* If this really is a threaded program, then we must ensure that __gthread_active has been set to 1 before exiting this block. */ __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger); __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); } /* Make sure we'll never enter this block again. */ if (__gthread_active < 0) __gthread_active = 0; __gthread_active_latest_value = __gthread_active; } return __gthread_active_latest_value != 0; } #else /* neither FreeBSD nor Solaris */ /* For a program to be multi-threaded the only thing that it certainly must be using is pthread_create. However, there may be other libraries that intercept pthread_create with their own definitions to wrap pthreads functionality for some purpose. In those cases, pthread_create being defined might not necessarily mean that libpthread is actually linked in. For the GNU C library, we can use a known internal name. This is always available in the ABI, but no other library would define it. That is ideal, since any public pthread function might be intercepted just as pthread_create might be. __pthread_key_create is an "internal" implementation symbol, but it is part of the public exported ABI. Also, it's among the symbols that the static libpthread.a always links in whenever pthread_create is used, so there is no danger of a false negative result in any statically-linked, multi-threaded program. For others, we choose pthread_cancel as a function that seems unlikely to be redefined by an interceptor library. The bionic (Android) C library does not provide pthread_cancel, so we do use pthread_create there (and interceptor libraries lose). */ #ifdef __GLIBC__ __gthrw2(__gthrw_(__pthread_key_create), __pthread_key_create, pthread_key_create) # define GTHR_ACTIVE_PROXY __gthrw_(__pthread_key_create) #elif defined (__BIONIC__) # define GTHR_ACTIVE_PROXY __gthrw_(pthread_create) #else # define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel) #endif static inline int __gthread_active_p (void) { static void *const __gthread_active_ptr = __extension__ (void *) >HR_ACTIVE_PROXY; return __gthread_active_ptr != 0; } #endif /* FreeBSD or Solaris */ #else /* not __GXX_WEAK__ */ /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread calls in shared flavors of the HP-UX C library. Most of the stubs have no functionality. The details are described in the "libc cumulative patch" for each subversion of HP-UX 11. There are two special interfaces provided for checking whether an application is linked to a shared pthread library or not. However, these interfaces aren't available in early libpthread libraries. We also need a test that works for archive libraries. We can't use pthread_once as some libc versions call the init function. We also can't use pthread_create or pthread_attr_init as these create a thread and thereby prevent changing the default stack size. The function pthread_default_stacksize_np is available in both the archive and shared versions of libpthread. It can be used to determine the default pthread stack size. There is a stub in some shared libc versions which returns a zero size if pthreads are not active. We provide an equivalent stub to handle cases where libc doesn't provide one. */ #if defined(__hppa__) && defined(__hpux__) static volatile int __gthread_active = -1; static inline int __gthread_active_p (void) { /* Avoid reading __gthread_active twice on the main code path. */ int __gthread_active_latest_value = __gthread_active; size_t __s; if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { pthread_default_stacksize_np (0, &__s); __gthread_active = __s ? 1 : 0; __gthread_active_latest_value = __gthread_active; } return __gthread_active_latest_value != 0; } #else /* not hppa-hpux */ static inline int __gthread_active_p (void) { return 1; } #endif /* hppa-hpux */ #endif /* __GXX_WEAK__ */ #ifdef _LIBOBJC /* This is the config.h file in libobjc/ */ #include <config.h> #ifdef HAVE_SCHED_H # include <sched.h> #endif /* Key structure for maintaining thread specific storage */ static pthread_key_t _objc_thread_storage; static pthread_attr_t _objc_thread_attribs; /* Thread local storage for a single thread */ static void *thread_local_storage = NULL; /* Backend initialization functions */ /* Initialize the threads subsystem. */ static inline int __gthread_objc_init_thread_system (void) { if (__gthread_active_p ()) { /* Initialize the thread storage key. */ if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) { /* The normal default detach state for threads is * PTHREAD_CREATE_JOINABLE which causes threads to not die * when you think they should. */ if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, PTHREAD_CREATE_DETACHED) == 0) return 0; } } return -1; } /* Close the threads subsystem. */ static inline int __gthread_objc_close_thread_system (void) { if (__gthread_active_p () && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) return 0; return -1; } /* Backend thread functions */ /* Create a new thread of execution. */ static inline objc_thread_t __gthread_objc_thread_detach (void (*func)(void *), void *arg) { objc_thread_t thread_id; pthread_t new_thread_handle; if (!__gthread_active_p ()) return NULL; if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs, (void *) func, arg))) thread_id = (objc_thread_t) new_thread_handle; else thread_id = NULL; return thread_id; } /* Set the current thread's priority. */ static inline int __gthread_objc_thread_set_priority (int priority) { if (!__gthread_active_p ()) return -1; else { #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING pthread_t thread_id = __gthrw_(pthread_self) (); int policy; struct sched_param params; int priority_min, priority_max; if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) { if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) return -1; if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) return -1; if (priority > priority_max) priority = priority_max; else if (priority < priority_min) priority = priority_min; params.sched_priority = priority; /* * The solaris 7 and several other man pages incorrectly state that * this should be a pointer to policy but pthread.h is universally * at odds with this. */ if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) return 0; } #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ return -1; } } /* Return the current thread's priority. */ static inline int __gthread_objc_thread_get_priority (void) { #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING if (__gthread_active_p ()) { int policy; struct sched_param params; if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) return params.sched_priority; else return -1; } else #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ return OBJC_THREAD_INTERACTIVE_PRIORITY; } /* Yield our process time to another thread. */ static inline void __gthread_objc_thread_yield (void) { if (__gthread_active_p ()) __gthrw_(sched_yield) (); } /* Terminate the current thread. */ static inline int __gthread_objc_thread_exit (void) { if (__gthread_active_p ()) /* exit the thread */ __gthrw_(pthread_exit) (&__objc_thread_exit_status); /* Failed if we reached here */ return -1; } /* Returns an integer value which uniquely describes a thread. */ static inline objc_thread_t __gthread_objc_thread_id (void) { if (__gthread_active_p ()) return (objc_thread_t) __gthrw_(pthread_self) (); else return (objc_thread_t) 1; } /* Sets the thread's local storage pointer. */ static inline int __gthread_objc_thread_set_data (void *value) { if (__gthread_active_p ()) return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); else { thread_local_storage = value; return 0; } } /* Returns the thread's local storage pointer. */ static inline void * __gthread_objc_thread_get_data (void) { if (__gthread_active_p ()) return __gthrw_(pthread_getspecific) (_objc_thread_storage); else return thread_local_storage; } /* Backend mutex functions */ /* Allocate a mutex. */ static inline int __gthread_objc_mutex_allocate (objc_mutex_t mutex) { if (__gthread_active_p ()) { mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) { objc_free (mutex->backend); mutex->backend = NULL; return -1; } } return 0; } /* Deallocate a mutex. */ static inline int __gthread_objc_mutex_deallocate (objc_mutex_t mutex) { if (__gthread_active_p ()) { int count; /* * Posix Threads specifically require that the thread be unlocked * for __gthrw_(pthread_mutex_destroy) to work. */ do { count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); if (count < 0) return -1; } while (count); if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) return -1; objc_free (mutex->backend); mutex->backend = NULL; } return 0; } /* Grab a lock on a mutex. */ static inline int __gthread_objc_mutex_lock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Try to grab a lock on a mutex. */ static inline int __gthread_objc_mutex_trylock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Unlock the mutex */ static inline int __gthread_objc_mutex_unlock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Backend condition mutex functions */ /* Allocate a condition. */ static inline int __gthread_objc_condition_allocate (objc_condition_t condition) { if (__gthread_active_p ()) { condition->backend = objc_malloc (sizeof (pthread_cond_t)); if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) { objc_free (condition->backend); condition->backend = NULL; return -1; } } return 0; } /* Deallocate a condition. */ static inline int __gthread_objc_condition_deallocate (objc_condition_t condition) { if (__gthread_active_p ()) { if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) return -1; objc_free (condition->backend); condition->backend = NULL; } return 0; } /* Wait on the condition */ static inline int __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, (pthread_mutex_t *) mutex->backend); else return 0; } /* Wake up all threads waiting on this condition. */ static inline int __gthread_objc_condition_broadcast (objc_condition_t condition) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); else return 0; } /* Wake up one thread waiting on this condition. */ static inline int __gthread_objc_condition_signal (objc_condition_t condition) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); else return 0; } #else /* _LIBOBJC */ static inline int __gthread_create (__gthread_t *__threadid, void *(*__func) (void*), void *__args) { return __gthrw_(pthread_create) (__threadid, NULL, __func, __args); } static inline int __gthread_join (__gthread_t __threadid, void **__value_ptr) { return __gthrw_(pthread_join) (__threadid, __value_ptr); } static inline int __gthread_detach (__gthread_t __threadid) { return __gthrw_(pthread_detach) (__threadid); } static inline int __gthread_equal (__gthread_t __t1, __gthread_t __t2) { return __gthrw_(pthread_equal) (__t1, __t2); } static inline __gthread_t __gthread_self (void) { return __gthrw_(pthread_self) (); } static inline int __gthread_yield (void) { return __gthrw_(sched_yield) (); } static inline int __gthread_once (__gthread_once_t *__once, void (*__func) (void)) { if (__gthread_active_p ()) return __gthrw_(pthread_once) (__once, __func); else return -1; } static inline int __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) { return __gthrw_(pthread_key_create) (__key, __dtor); } static inline int __gthread_key_delete (__gthread_key_t __key) { return __gthrw_(pthread_key_delete) (__key); } static inline void * __gthread_getspecific (__gthread_key_t __key) { return __gthrw_(pthread_getspecific) (__key); } static inline int __gthread_setspecific (__gthread_key_t __key, const void *__ptr) { return __gthrw_(pthread_setspecific) (__key, __ptr); } static inline void __gthread_mutex_init_function (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) __gthrw_(pthread_mutex_init) (__mutex, NULL); } static inline int __gthread_mutex_destroy (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_destroy) (__mutex); else return 0; } static inline int __gthread_mutex_lock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_lock) (__mutex); else return 0; } static inline int __gthread_mutex_trylock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_trylock) (__mutex); else return 0; } #if _GTHREAD_USE_MUTEX_TIMEDLOCK static inline int __gthread_mutex_timedlock (__gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout); else return 0; } #endif static inline int __gthread_mutex_unlock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_unlock) (__mutex); else return 0; } #if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \ || defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC) static inline int __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) { if (__gthread_active_p ()) { pthread_mutexattr_t __attr; int __r; __r = __gthrw_(pthread_mutexattr_init) (&__attr); if (!__r) __r = __gthrw_(pthread_mutexattr_settype) (&__attr, PTHREAD_MUTEX_RECURSIVE); if (!__r) __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr); if (!__r) __r = __gthrw_(pthread_mutexattr_destroy) (&__attr); return __r; } return 0; } #endif static inline int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_lock (__mutex); } static inline int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_trylock (__mutex); } #if _GTHREAD_USE_MUTEX_TIMEDLOCK static inline int __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { return __gthread_mutex_timedlock (__mutex, __abs_timeout); } #endif static inline int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_unlock (__mutex); } static inline int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_destroy (__mutex); } #ifdef _GTHREAD_USE_COND_INIT_FUNC static inline void __gthread_cond_init_function (__gthread_cond_t *__cond) { if (__gthread_active_p ()) __gthrw_(pthread_cond_init) (__cond, NULL); } #endif static inline int __gthread_cond_broadcast (__gthread_cond_t *__cond) { return __gthrw_(pthread_cond_broadcast) (__cond); } static inline int __gthread_cond_signal (__gthread_cond_t *__cond) { return __gthrw_(pthread_cond_signal) (__cond); } static inline int __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex) { return __gthrw_(pthread_cond_wait) (__cond, __mutex); } static inline int __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout); } static inline int __gthread_cond_wait_recursive (__gthread_cond_t *__cond, __gthread_recursive_mutex_t *__mutex) { return __gthread_cond_wait (__cond, __mutex); } static inline int __gthread_cond_destroy (__gthread_cond_t* __cond) { return __gthrw_(pthread_cond_destroy) (__cond); } #endif /* _LIBOBJC */ #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ c++/8/x86_64-redhat-linux/bits/ctype_base.h 0000644 00000004414 15146341150 0014056 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/ctype_base.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.1 Locales // // Information as gleaned from /usr/include/ctype.h namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @brief Base class for ctype. struct ctype_base { // Non-standard typedefs. typedef const int* __to_type; // NB: Offsets into ctype<char>::_M_table force a particular size // on the mask type. Because of this, we don't use an enum. typedef unsigned short mask; static const mask upper = _ISupper; static const mask lower = _ISlower; static const mask alpha = _ISalpha; static const mask digit = _ISdigit; static const mask xdigit = _ISxdigit; static const mask space = _ISspace; static const mask print = _ISprint; static const mask graph = _ISalpha | _ISdigit | _ISpunct; static const mask cntrl = _IScntrl; static const mask punct = _ISpunct; static const mask alnum = _ISalpha | _ISdigit; #if __cplusplus >= 201103L static const mask blank = _ISblank; #endif }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/x86_64-redhat-linux/bits/ctype_inline.h 0000644 00000004354 15146341150 0014425 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/ctype_inline.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{locale} */ // // ISO C++ 14882: 22.1 Locales // // ctype bits to be inlined go here. Non-inlinable (ie virtual do_*) // functions go in ctype.cc namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION bool ctype<char>:: is(mask __m, char __c) const { return _M_table[static_cast<unsigned char>(__c)] & __m; } const char* ctype<char>:: is(const char* __low, const char* __high, mask* __vec) const { while (__low < __high) *__vec++ = _M_table[static_cast<unsigned char>(*__low++)]; return __high; } const char* ctype<char>:: scan_is(mask __m, const char* __low, const char* __high) const { while (__low < __high && !(_M_table[static_cast<unsigned char>(*__low)] & __m)) ++__low; return __low; } const char* ctype<char>:: scan_not(mask __m, const char* __low, const char* __high) const { while (__low < __high && (_M_table[static_cast<unsigned char>(*__low)] & __m) != 0) ++__low; return __low; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace c++/8/x86_64-redhat-linux/bits/os_defines.h 0000644 00000003727 15146341150 0014064 0 ustar 00 // Specific definitions for GNU/Linux -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/os_defines.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{iosfwd} */ #ifndef _GLIBCXX_OS_DEFINES #define _GLIBCXX_OS_DEFINES 1 // System-specific #define, typedefs, corrections, etc, go here. This // file will come before all others. // This keeps isanum, et al from being propagated as macros. #define __NO_CTYPE 1 #include <features.h> // Provide a declaration for the possibly deprecated gets function, as // glibc 2.15 and later does not declare gets for ISO C11 when // __GNU_SOURCE is defined. #if __GLIBC_PREREQ(2,15) && defined(_GNU_SOURCE) # undef _GLIBCXX_HAVE_GETS #endif // Glibc 2.23 removed the obsolete isinf and isnan declarations. Check the // version dynamically in case it has changed since libstdc++ was configured. #define _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC __GLIBC_PREREQ(2,23) #endif c++/8/x86_64-redhat-linux/bits/basic_file.h 0000644 00000006553 15146341150 0014026 0 ustar 00 // Wrapper of C-language FILE struct -*- C++ -*- // Copyright (C) 2000-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. // // ISO C++ 14882: 27.8 File-based streams // /** @file bits/basic_file.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{ios} */ #ifndef _GLIBCXX_BASIC_FILE_STDIO_H #define _GLIBCXX_BASIC_FILE_STDIO_H 1 #pragma GCC system_header #include <bits/c++config.h> #include <bits/c++io.h> // for __c_lock and __c_file #include <bits/move.h> // for swap #include <ios> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // Generic declaration. template<typename _CharT> class __basic_file; // Specialization. template<> class __basic_file<char> { // Underlying data source/sink. __c_file* _M_cfile; // True iff we opened _M_cfile, and thus must close it ourselves. bool _M_cfile_created; public: __basic_file(__c_lock* __lock = 0) throw (); #if __cplusplus >= 201103L __basic_file(__basic_file&& __rv, __c_lock* = 0) noexcept : _M_cfile(__rv._M_cfile), _M_cfile_created(__rv._M_cfile_created) { __rv._M_cfile = nullptr; __rv._M_cfile_created = false; } __basic_file& operator=(const __basic_file&) = delete; __basic_file& operator=(__basic_file&&) = delete; void swap(__basic_file& __f) noexcept { std::swap(_M_cfile, __f._M_cfile); std::swap(_M_cfile_created, __f._M_cfile_created); } #endif __basic_file* open(const char* __name, ios_base::openmode __mode, int __prot = 0664); __basic_file* sys_open(__c_file* __file, ios_base::openmode); __basic_file* sys_open(int __fd, ios_base::openmode __mode) throw (); __basic_file* close(); _GLIBCXX_PURE bool is_open() const throw (); _GLIBCXX_PURE int fd() throw (); _GLIBCXX_PURE __c_file* file() throw (); ~__basic_file(); streamsize xsputn(const char* __s, streamsize __n); streamsize xsputn_2(const char* __s1, streamsize __n1, const char* __s2, streamsize __n2); streamsize xsgetn(char* __s, streamsize __n); streamoff seekoff(streamoff __off, ios_base::seekdir __way) throw (); int sync(); streamsize showmanyc(); }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif c++/8/x86_64-redhat-linux/bits/gthr-posix.h 0000644 00000057255 15146341150 0014057 0 ustar 00 /* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ /* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _GLIBCXX_GCC_GTHR_POSIX_H #define _GLIBCXX_GCC_GTHR_POSIX_H /* POSIX threads specific definitions. Easy, since the interface is just one-to-one mapping. */ #define __GTHREADS 1 #define __GTHREADS_CXX0X 1 #include <pthread.h> #if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \ || !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK)) # include <unistd.h> # if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0 # define _GTHREAD_USE_MUTEX_TIMEDLOCK 1 # else # define _GTHREAD_USE_MUTEX_TIMEDLOCK 0 # endif #endif typedef pthread_t __gthread_t; typedef pthread_key_t __gthread_key_t; typedef pthread_once_t __gthread_once_t; typedef pthread_mutex_t __gthread_mutex_t; typedef pthread_mutex_t __gthread_recursive_mutex_t; typedef pthread_cond_t __gthread_cond_t; typedef struct timespec __gthread_time_t; /* POSIX like conditional variables are supported. Please look at comments in gthr.h for details. */ #define __GTHREAD_HAS_COND 1 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP #else #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function #endif #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER #define __GTHREAD_TIME_INIT {0,0} #ifdef _GTHREAD_USE_MUTEX_INIT_FUNC # undef __GTHREAD_MUTEX_INIT #endif #ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC # undef __GTHREAD_RECURSIVE_MUTEX_INIT # undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION # define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function #endif #ifdef _GTHREAD_USE_COND_INIT_FUNC # undef __GTHREAD_COND_INIT # define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function #endif #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK # ifndef __gthrw_pragma # define __gthrw_pragma(pragma) # endif # define __gthrw2(name,name2,type) \ static __typeof(type) name __attribute__ ((__weakref__(#name2))); \ __gthrw_pragma(weak type) # define __gthrw_(name) __gthrw_ ## name #else # define __gthrw2(name,name2,type) # define __gthrw_(name) name #endif /* Typically, __gthrw_foo is a weak reference to symbol foo. */ #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name) __gthrw(pthread_once) __gthrw(pthread_getspecific) __gthrw(pthread_setspecific) __gthrw(pthread_create) __gthrw(pthread_join) __gthrw(pthread_equal) __gthrw(pthread_self) __gthrw(pthread_detach) #ifndef __BIONIC__ __gthrw(pthread_cancel) #endif __gthrw(sched_yield) __gthrw(pthread_mutex_lock) __gthrw(pthread_mutex_trylock) #if _GTHREAD_USE_MUTEX_TIMEDLOCK __gthrw(pthread_mutex_timedlock) #endif __gthrw(pthread_mutex_unlock) __gthrw(pthread_mutex_init) __gthrw(pthread_mutex_destroy) __gthrw(pthread_cond_init) __gthrw(pthread_cond_broadcast) __gthrw(pthread_cond_signal) __gthrw(pthread_cond_wait) __gthrw(pthread_cond_timedwait) __gthrw(pthread_cond_destroy) __gthrw(pthread_key_create) __gthrw(pthread_key_delete) __gthrw(pthread_mutexattr_init) __gthrw(pthread_mutexattr_settype) __gthrw(pthread_mutexattr_destroy) #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK) /* Objective-C. */ __gthrw(pthread_exit) #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING __gthrw(sched_get_priority_max) __gthrw(sched_get_priority_min) #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ __gthrw(pthread_attr_destroy) __gthrw(pthread_attr_init) __gthrw(pthread_attr_setdetachstate) #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING __gthrw(pthread_getschedparam) __gthrw(pthread_setschedparam) #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _LIBOBJC || _LIBOBJC_WEAK */ #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if -pthreads is not specified. The functions are dummies and most return an error value. However pthread_once returns 0 without invoking the routine it is passed so we cannot pretend that the interface is active if -pthreads is not specified. On Solaris 2.5.1, the interface is not exposed at all so we need to play the usual game with weak symbols. On Solaris 10 and up, a working interface is always exposed. On FreeBSD 6 and later, libc also exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc, which means the alternate __gthread_active_p below cannot be used there. */ #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) static volatile int __gthread_active = -1; static void __gthread_trigger (void) { __gthread_active = 1; } static inline int __gthread_active_p (void) { static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT; /* Avoid reading __gthread_active twice on the main code path. */ int __gthread_active_latest_value = __gthread_active; /* This test is not protected to avoid taking a lock on the main code path so every update of __gthread_active in a threaded program must be atomic with regard to the result of the test. */ if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { if (__gthrw_(pthread_once)) { /* If this really is a threaded program, then we must ensure that __gthread_active has been set to 1 before exiting this block. */ __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex); __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger); __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex); } /* Make sure we'll never enter this block again. */ if (__gthread_active < 0) __gthread_active = 0; __gthread_active_latest_value = __gthread_active; } return __gthread_active_latest_value != 0; } #else /* neither FreeBSD nor Solaris */ /* For a program to be multi-threaded the only thing that it certainly must be using is pthread_create. However, there may be other libraries that intercept pthread_create with their own definitions to wrap pthreads functionality for some purpose. In those cases, pthread_create being defined might not necessarily mean that libpthread is actually linked in. For the GNU C library, we can use a known internal name. This is always available in the ABI, but no other library would define it. That is ideal, since any public pthread function might be intercepted just as pthread_create might be. __pthread_key_create is an "internal" implementation symbol, but it is part of the public exported ABI. Also, it's among the symbols that the static libpthread.a always links in whenever pthread_create is used, so there is no danger of a false negative result in any statically-linked, multi-threaded program. For others, we choose pthread_cancel as a function that seems unlikely to be redefined by an interceptor library. The bionic (Android) C library does not provide pthread_cancel, so we do use pthread_create there (and interceptor libraries lose). */ #ifdef __GLIBC__ __gthrw2(__gthrw_(__pthread_key_create), __pthread_key_create, pthread_key_create) # define GTHR_ACTIVE_PROXY __gthrw_(__pthread_key_create) #elif defined (__BIONIC__) # define GTHR_ACTIVE_PROXY __gthrw_(pthread_create) #else # define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel) #endif static inline int __gthread_active_p (void) { static void *const __gthread_active_ptr = __extension__ (void *) >HR_ACTIVE_PROXY; return __gthread_active_ptr != 0; } #endif /* FreeBSD or Solaris */ #else /* not __GXX_WEAK__ */ /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread calls in shared flavors of the HP-UX C library. Most of the stubs have no functionality. The details are described in the "libc cumulative patch" for each subversion of HP-UX 11. There are two special interfaces provided for checking whether an application is linked to a shared pthread library or not. However, these interfaces aren't available in early libpthread libraries. We also need a test that works for archive libraries. We can't use pthread_once as some libc versions call the init function. We also can't use pthread_create or pthread_attr_init as these create a thread and thereby prevent changing the default stack size. The function pthread_default_stacksize_np is available in both the archive and shared versions of libpthread. It can be used to determine the default pthread stack size. There is a stub in some shared libc versions which returns a zero size if pthreads are not active. We provide an equivalent stub to handle cases where libc doesn't provide one. */ #if defined(__hppa__) && defined(__hpux__) static volatile int __gthread_active = -1; static inline int __gthread_active_p (void) { /* Avoid reading __gthread_active twice on the main code path. */ int __gthread_active_latest_value = __gthread_active; size_t __s; if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { pthread_default_stacksize_np (0, &__s); __gthread_active = __s ? 1 : 0; __gthread_active_latest_value = __gthread_active; } return __gthread_active_latest_value != 0; } #else /* not hppa-hpux */ static inline int __gthread_active_p (void) { return 1; } #endif /* hppa-hpux */ #endif /* __GXX_WEAK__ */ #ifdef _LIBOBJC /* This is the config.h file in libobjc/ */ #include <config.h> #ifdef HAVE_SCHED_H # include <sched.h> #endif /* Key structure for maintaining thread specific storage */ static pthread_key_t _objc_thread_storage; static pthread_attr_t _objc_thread_attribs; /* Thread local storage for a single thread */ static void *thread_local_storage = NULL; /* Backend initialization functions */ /* Initialize the threads subsystem. */ static inline int __gthread_objc_init_thread_system (void) { if (__gthread_active_p ()) { /* Initialize the thread storage key. */ if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0) { /* The normal default detach state for threads is * PTHREAD_CREATE_JOINABLE which causes threads to not die * when you think they should. */ if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0 && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs, PTHREAD_CREATE_DETACHED) == 0) return 0; } } return -1; } /* Close the threads subsystem. */ static inline int __gthread_objc_close_thread_system (void) { if (__gthread_active_p () && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0 && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0) return 0; return -1; } /* Backend thread functions */ /* Create a new thread of execution. */ static inline objc_thread_t __gthread_objc_thread_detach (void (*func)(void *), void *arg) { objc_thread_t thread_id; pthread_t new_thread_handle; if (!__gthread_active_p ()) return NULL; if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs, (void *) func, arg))) thread_id = (objc_thread_t) new_thread_handle; else thread_id = NULL; return thread_id; } /* Set the current thread's priority. */ static inline int __gthread_objc_thread_set_priority (int priority) { if (!__gthread_active_p ()) return -1; else { #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING pthread_t thread_id = __gthrw_(pthread_self) (); int policy; struct sched_param params; int priority_min, priority_max; if (__gthrw_(pthread_getschedparam) (thread_id, &policy, ¶ms) == 0) { if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1) return -1; if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1) return -1; if (priority > priority_max) priority = priority_max; else if (priority < priority_min) priority = priority_min; params.sched_priority = priority; /* * The solaris 7 and several other man pages incorrectly state that * this should be a pointer to policy but pthread.h is universally * at odds with this. */ if (__gthrw_(pthread_setschedparam) (thread_id, policy, ¶ms) == 0) return 0; } #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ return -1; } } /* Return the current thread's priority. */ static inline int __gthread_objc_thread_get_priority (void) { #ifdef _POSIX_PRIORITY_SCHEDULING #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING if (__gthread_active_p ()) { int policy; struct sched_param params; if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, ¶ms) == 0) return params.sched_priority; else return -1; } else #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ #endif /* _POSIX_PRIORITY_SCHEDULING */ return OBJC_THREAD_INTERACTIVE_PRIORITY; } /* Yield our process time to another thread. */ static inline void __gthread_objc_thread_yield (void) { if (__gthread_active_p ()) __gthrw_(sched_yield) (); } /* Terminate the current thread. */ static inline int __gthread_objc_thread_exit (void) { if (__gthread_active_p ()) /* exit the thread */ __gthrw_(pthread_exit) (&__objc_thread_exit_status); /* Failed if we reached here */ return -1; } /* Returns an integer value which uniquely describes a thread. */ static inline objc_thread_t __gthread_objc_thread_id (void) { if (__gthread_active_p ()) return (objc_thread_t) __gthrw_(pthread_self) (); else return (objc_thread_t) 1; } /* Sets the thread's local storage pointer. */ static inline int __gthread_objc_thread_set_data (void *value) { if (__gthread_active_p ()) return __gthrw_(pthread_setspecific) (_objc_thread_storage, value); else { thread_local_storage = value; return 0; } } /* Returns the thread's local storage pointer. */ static inline void * __gthread_objc_thread_get_data (void) { if (__gthread_active_p ()) return __gthrw_(pthread_getspecific) (_objc_thread_storage); else return thread_local_storage; } /* Backend mutex functions */ /* Allocate a mutex. */ static inline int __gthread_objc_mutex_allocate (objc_mutex_t mutex) { if (__gthread_active_p ()) { mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL)) { objc_free (mutex->backend); mutex->backend = NULL; return -1; } } return 0; } /* Deallocate a mutex. */ static inline int __gthread_objc_mutex_deallocate (objc_mutex_t mutex) { if (__gthread_active_p ()) { int count; /* * Posix Threads specifically require that the thread be unlocked * for __gthrw_(pthread_mutex_destroy) to work. */ do { count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend); if (count < 0) return -1; } while (count); if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend)) return -1; objc_free (mutex->backend); mutex->backend = NULL; } return 0; } /* Grab a lock on a mutex. */ static inline int __gthread_objc_mutex_lock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Try to grab a lock on a mutex. */ static inline int __gthread_objc_mutex_trylock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Unlock the mutex */ static inline int __gthread_objc_mutex_unlock (objc_mutex_t mutex) { if (__gthread_active_p () && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0) { return -1; } return 0; } /* Backend condition mutex functions */ /* Allocate a condition. */ static inline int __gthread_objc_condition_allocate (objc_condition_t condition) { if (__gthread_active_p ()) { condition->backend = objc_malloc (sizeof (pthread_cond_t)); if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL)) { objc_free (condition->backend); condition->backend = NULL; return -1; } } return 0; } /* Deallocate a condition. */ static inline int __gthread_objc_condition_deallocate (objc_condition_t condition) { if (__gthread_active_p ()) { if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend)) return -1; objc_free (condition->backend); condition->backend = NULL; } return 0; } /* Wait on the condition */ static inline int __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend, (pthread_mutex_t *) mutex->backend); else return 0; } /* Wake up all threads waiting on this condition. */ static inline int __gthread_objc_condition_broadcast (objc_condition_t condition) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend); else return 0; } /* Wake up one thread waiting on this condition. */ static inline int __gthread_objc_condition_signal (objc_condition_t condition) { if (__gthread_active_p ()) return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend); else return 0; } #else /* _LIBOBJC */ static inline int __gthread_create (__gthread_t *__threadid, void *(*__func) (void*), void *__args) { return __gthrw_(pthread_create) (__threadid, NULL, __func, __args); } static inline int __gthread_join (__gthread_t __threadid, void **__value_ptr) { return __gthrw_(pthread_join) (__threadid, __value_ptr); } static inline int __gthread_detach (__gthread_t __threadid) { return __gthrw_(pthread_detach) (__threadid); } static inline int __gthread_equal (__gthread_t __t1, __gthread_t __t2) { return __gthrw_(pthread_equal) (__t1, __t2); } static inline __gthread_t __gthread_self (void) { return __gthrw_(pthread_self) (); } static inline int __gthread_yield (void) { return __gthrw_(sched_yield) (); } static inline int __gthread_once (__gthread_once_t *__once, void (*__func) (void)) { if (__gthread_active_p ()) return __gthrw_(pthread_once) (__once, __func); else return -1; } static inline int __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) { return __gthrw_(pthread_key_create) (__key, __dtor); } static inline int __gthread_key_delete (__gthread_key_t __key) { return __gthrw_(pthread_key_delete) (__key); } static inline void * __gthread_getspecific (__gthread_key_t __key) { return __gthrw_(pthread_getspecific) (__key); } static inline int __gthread_setspecific (__gthread_key_t __key, const void *__ptr) { return __gthrw_(pthread_setspecific) (__key, __ptr); } static inline void __gthread_mutex_init_function (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) __gthrw_(pthread_mutex_init) (__mutex, NULL); } static inline int __gthread_mutex_destroy (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_destroy) (__mutex); else return 0; } static inline int __gthread_mutex_lock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_lock) (__mutex); else return 0; } static inline int __gthread_mutex_trylock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_trylock) (__mutex); else return 0; } #if _GTHREAD_USE_MUTEX_TIMEDLOCK static inline int __gthread_mutex_timedlock (__gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout); else return 0; } #endif static inline int __gthread_mutex_unlock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) return __gthrw_(pthread_mutex_unlock) (__mutex); else return 0; } #if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \ || defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC) static inline int __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) { if (__gthread_active_p ()) { pthread_mutexattr_t __attr; int __r; __r = __gthrw_(pthread_mutexattr_init) (&__attr); if (!__r) __r = __gthrw_(pthread_mutexattr_settype) (&__attr, PTHREAD_MUTEX_RECURSIVE); if (!__r) __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr); if (!__r) __r = __gthrw_(pthread_mutexattr_destroy) (&__attr); return __r; } return 0; } #endif static inline int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_lock (__mutex); } static inline int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_trylock (__mutex); } #if _GTHREAD_USE_MUTEX_TIMEDLOCK static inline int __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { return __gthread_mutex_timedlock (__mutex, __abs_timeout); } #endif static inline int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_unlock (__mutex); } static inline int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_destroy (__mutex); } #ifdef _GTHREAD_USE_COND_INIT_FUNC static inline void __gthread_cond_init_function (__gthread_cond_t *__cond) { if (__gthread_active_p ()) __gthrw_(pthread_cond_init) (__cond, NULL); } #endif static inline int __gthread_cond_broadcast (__gthread_cond_t *__cond) { return __gthrw_(pthread_cond_broadcast) (__cond); } static inline int __gthread_cond_signal (__gthread_cond_t *__cond) { return __gthrw_(pthread_cond_signal) (__cond); } static inline int __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex) { return __gthrw_(pthread_cond_wait) (__cond, __mutex); } static inline int __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout); } static inline int __gthread_cond_wait_recursive (__gthread_cond_t *__cond, __gthread_recursive_mutex_t *__mutex) { return __gthread_cond_wait (__cond, __mutex); } static inline int __gthread_cond_destroy (__gthread_cond_t* __cond) { return __gthrw_(pthread_cond_destroy) (__cond); } #endif /* _LIBOBJC */ #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */ c++/8/x86_64-redhat-linux/bits/opt_random.h 0000644 00000014062 15146341150 0014102 0 ustar 00 // Optimizations for random number functions, x86 version -*- C++ -*- // Copyright (C) 2012-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /** @file bits/opt_random.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{random} */ #ifndef _BITS_OPT_RANDOM_H #define _BITS_OPT_RANDOM_H 1 #ifdef __SSE3__ #include <pmmintrin.h> #endif #pragma GCC system_header namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef __SSE3__ template<> template<typename _UniformRandomNumberGenerator> void normal_distribution<double>:: __generate(typename normal_distribution<double>::result_type* __f, typename normal_distribution<double>::result_type* __t, _UniformRandomNumberGenerator& __urng, const param_type& __param) { typedef uint64_t __uctype; if (__f == __t) return; if (_M_saved_available) { _M_saved_available = false; *__f++ = _M_saved * __param.stddev() + __param.mean(); if (__f == __t) return; } constexpr uint64_t __maskval = 0xfffffffffffffull; static const __m128i __mask = _mm_set1_epi64x(__maskval); static const __m128i __two = _mm_set1_epi64x(0x4000000000000000ull); static const __m128d __three = _mm_set1_pd(3.0); const __m128d __av = _mm_set1_pd(__param.mean()); const __uctype __urngmin = __urng.min(); const __uctype __urngmax = __urng.max(); const __uctype __urngrange = __urngmax - __urngmin; const __uctype __uerngrange = __urngrange + 1; while (__f + 1 < __t) { double __le; __m128d __x; do { union { __m128i __i; __m128d __d; } __v; if (__urngrange > __maskval) { if (__detail::_Power_of_2(__uerngrange)) __v.__i = _mm_and_si128(_mm_set_epi64x(__urng(), __urng()), __mask); else { const __uctype __uerange = __maskval + 1; const __uctype __scaling = __urngrange / __uerange; const __uctype __past = __uerange * __scaling; uint64_t __v1; do __v1 = __uctype(__urng()) - __urngmin; while (__v1 >= __past); __v1 /= __scaling; uint64_t __v2; do __v2 = __uctype(__urng()) - __urngmin; while (__v2 >= __past); __v2 /= __scaling; __v.__i = _mm_set_epi64x(__v1, __v2); } } else if (__urngrange == __maskval) __v.__i = _mm_set_epi64x(__urng(), __urng()); else if ((__urngrange + 2) * __urngrange >= __maskval && __detail::_Power_of_2(__uerngrange)) { uint64_t __v1 = __urng() * __uerngrange + __urng(); uint64_t __v2 = __urng() * __uerngrange + __urng(); __v.__i = _mm_and_si128(_mm_set_epi64x(__v1, __v2), __mask); } else { size_t __nrng = 2; __uctype __high = __maskval / __uerngrange / __uerngrange; while (__high > __uerngrange) { ++__nrng; __high /= __uerngrange; } const __uctype __highrange = __high + 1; const __uctype __scaling = __urngrange / __highrange; const __uctype __past = __highrange * __scaling; __uctype __tmp; uint64_t __v1; do { do __tmp = __uctype(__urng()) - __urngmin; while (__tmp >= __past); __v1 = __tmp / __scaling; for (size_t __cnt = 0; __cnt < __nrng; ++__cnt) { __tmp = __v1; __v1 *= __uerngrange; __v1 += __uctype(__urng()) - __urngmin; } } while (__v1 > __maskval || __v1 < __tmp); uint64_t __v2; do { do __tmp = __uctype(__urng()) - __urngmin; while (__tmp >= __past); __v2 = __tmp / __scaling; for (size_t __cnt = 0; __cnt < __nrng; ++__cnt) { __tmp = __v2; __v2 *= __uerngrange; __v2 += __uctype(__urng()) - __urngmin; } } while (__v2 > __maskval || __v2 < __tmp); __v.__i = _mm_set_epi64x(__v1, __v2); } __v.__i = _mm_or_si128(__v.__i, __two); __x = _mm_sub_pd(__v.__d, __three); __m128d __m = _mm_mul_pd(__x, __x); __le = _mm_cvtsd_f64(_mm_hadd_pd (__m, __m)); } while (__le == 0.0 || __le >= 1.0); double __mult = (std::sqrt(-2.0 * std::log(__le) / __le) * __param.stddev()); __x = _mm_add_pd(_mm_mul_pd(__x, _mm_set1_pd(__mult)), __av); _mm_storeu_pd(__f, __x); __f += 2; } if (__f != __t) { result_type __x, __y, __r2; __detail::_Adaptor<_UniformRandomNumberGenerator, result_type> __aurng(__urng); do { __x = result_type(2.0) * __aurng() - 1.0; __y = result_type(2.0) * __aurng() - 1.0; __r2 = __x * __x + __y * __y; } while (__r2 > 1.0 || __r2 == 0.0); const result_type __mult = std::sqrt(-2 * std::log(__r2) / __r2); _M_saved = __x * __mult; _M_saved_available = true; *__f = __y * __mult * __param.stddev() + __param.mean(); } } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _BITS_OPT_RANDOM_H c++/8/ctime 0000644 00000004115 15146341150 0006310 0 ustar 00 // -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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/ctime * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c time.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 20.5 Date and time // #pragma GCC system_header #include <bits/c++config.h> #include <time.h> #ifndef _GLIBCXX_CTIME #define _GLIBCXX_CTIME 1 // Get rid of those macros defined in <time.h> in lieu of real functions. #undef clock #undef difftime #undef mktime #undef time #undef asctime #undef ctime #undef gmtime #undef localtime #undef strftime namespace std { using ::clock_t; using ::time_t; using ::tm; using ::clock; using ::difftime; using ::mktime; using ::time; using ::asctime; using ::ctime; using ::gmtime; using ::localtime; using ::strftime; } // namespace #endif c++/8/complex.h 0000644 00000003074 15146341150 0007107 0 ustar 00 // -*- C++ -*- compatibility header. // Copyright (C) 2007-2018 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 complex.h * This is a Standard C++ Library header. */ #include <bits/c++config.h> #if __cplusplus >= 201103L # include <ccomplex> #endif #if __cplusplus >= 201103L && defined(__STRICT_ANSI__) // For strict modes do not include the C library's <complex.h>, see PR 82417. #elif _GLIBCXX_HAVE_COMPLEX_H # include_next <complex.h> # ifdef _GLIBCXX_COMPLEX // See PR56111, keep the macro in C++03 if possible. # undef complex # endif #endif #ifndef _GLIBCXX_COMPLEX_H #define _GLIBCXX_COMPLEX_H 1 #endif c++/8/cerrno 0000644 00000003352 15146341150 0006501 0 ustar 00 // The -*- C++ -*- forwarding header. // Copyright (C) 1997-2018 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 cerrno * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c errno.h, * and its contents are (mostly) the same as that header, but are all * contained in the namespace @c std (except for names which are defined * as macros in C). */ // // ISO C++ 14882: 19.3 Error numbers // #pragma GCC system_header #include <bits/c++config.h> #include <errno.h> #ifndef _GLIBCXX_CERRNO #define _GLIBCXX_CERRNO 1 // Adhere to section 17.4.1.2 clause 5 of ISO 14882:1998 #ifndef errno #define errno errno #endif #endif c++/8/charconv 0000644 00000040504 15146341150 0007014 0 ustar 00 // Primitive numeric conversions (to_chars and from_chars) -*- C++ -*- // Copyright (C) 2017-2018 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/charconv * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CHARCONV #define _GLIBCXX_CHARCONV 1 #pragma GCC system_header #if __cplusplus >= 201402L #include <type_traits> #include <limits> #include <cctype> #include <bits/error_constants.h> // for std::errc namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Result type of std::to_chars struct to_chars_result { char* ptr; errc ec; }; /// Result type of std::from_chars struct from_chars_result { const char* ptr; errc ec; }; namespace __detail { template<typename _Tp, typename... _Types> using __is_one_of = __or_<is_same<_Tp, _Types>...>; template<typename _Tp> using __is_int_to_chars_type = __and_<is_integral<_Tp>, __not_<__is_one_of<_Tp, bool, char16_t, char32_t #if _GLIBCXX_USE_WCHAR_T , wchar_t #endif >>>; template<typename _Tp> using __integer_to_chars_result_type = enable_if_t<__is_int_to_chars_type<_Tp>::value, to_chars_result>; template<typename _Tp> using __unsigned_least_t = conditional_t<(sizeof(_Tp) <= sizeof(int)), unsigned int, conditional_t<(sizeof(_Tp) <= sizeof(long)), unsigned long, conditional_t<(sizeof(_Tp) <= sizeof(long long)), unsigned long long, #if _GLIBCXX_USE_INT128 conditional_t<(sizeof(_Tp) <= sizeof(__int128)), unsigned __int128, #endif void #if _GLIBCXX_USE_INT128 > #endif >>>; // Generic implementation for arbitrary bases. template<typename _Tp> constexpr unsigned __to_chars_len(_Tp __value, int __base = 10) noexcept { static_assert(is_integral<_Tp>::value, "implementation bug"); static_assert(is_unsigned<_Tp>::value, "implementation bug"); unsigned __n = 1; const int __b2 = __base * __base; const int __b3 = __b2 * __base; const int __b4 = __b3 * __base; for (;;) { if (__value < __base) return __n; if (__value < __b2) return __n + 1; if (__value < __b3) return __n + 2; if (__value < __b4) return __n + 3; __value /= (unsigned)__b4; __n += 4; } } template<typename _Tp> constexpr unsigned __to_chars_len_2(_Tp __value) noexcept { static_assert(is_integral<_Tp>::value, "implementation bug"); static_assert(is_unsigned<_Tp>::value, "implementation bug"); constexpr size_t __nbits = __CHAR_BIT__ * sizeof(_Tp); // N.B. __builtin_clzll is undefined if __value == 0, but std::to_chars // handles zero values directly. // For sizeof(_Tp) > 1 this is an order of magnitude faster than // the generic __to_chars_len. return __nbits - (__builtin_clzll(__value) - ((__CHAR_BIT__ * sizeof(long long)) - __nbits)); } template<typename _Tp> constexpr unsigned __to_chars_len_8(_Tp __value) noexcept { static_assert(is_integral<_Tp>::value, "implementation bug"); static_assert(is_unsigned<_Tp>::value, "implementation bug"); constexpr size_t __nbits = __CHAR_BIT__ * sizeof(_Tp); if _GLIBCXX17_CONSTEXPR (__nbits <= 16) { return __value > 077777u ? 6u : __value > 07777u ? 5u : __value > 0777u ? 4u : __value > 077u ? 3u : __value > 07u ? 2u : 1u; } else return __to_chars_len(__value, 8); } // Generic implementation for arbitrary bases. template<typename _Tp> to_chars_result __to_chars(char* __first, char* __last, _Tp __val, int __base) noexcept { static_assert(is_integral<_Tp>::value, "implementation bug"); static_assert(is_unsigned<_Tp>::value, "implementation bug"); to_chars_result __res; const unsigned __len = __to_chars_len(__val, __base); if (__builtin_expect((__last - __first) < __len, 0)) { __res.ptr = __last; __res.ec = errc::value_too_large; return __res; } unsigned __pos = __len - 1; static constexpr char __digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; while (__val >= __base) { auto const __quo = __val / __base; auto const __rem = __val % __base; __first[__pos--] = __digits[__rem]; __val = __quo; } *__first = __digits[__val]; __res.ptr = __first + __len; __res.ec = {}; return __res; } template<typename _Tp> __integer_to_chars_result_type<_Tp> __to_chars_16(char* __first, char* __last, _Tp __val) noexcept { static_assert(is_integral<_Tp>::value, "implementation bug"); static_assert(is_unsigned<_Tp>::value, "implementation bug"); to_chars_result __res; const unsigned __len = __to_chars_len(__val, 0x10); if (__builtin_expect((__last - __first) < __len, 0)) { __res.ptr = __last; __res.ec = errc::value_too_large; return __res; } static constexpr char __digits[513] = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf" "e0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; unsigned __pos = __len - 1; while (__val >= 0x100) { auto const __num = (__val % 0x100) * 2; __val /= 0x100; __first[__pos] = __digits[__num + 1]; __first[__pos - 1] = __digits[__num]; __pos -= 2; } if (__val >= 0x10) { auto const __num = __val * 2; __first[__pos] = __digits[__num + 1]; __first[__pos - 1] = __digits[__num]; } else __first[__pos] = "0123456789abcdef"[__val]; __res.ptr = __first + __len; __res.ec = {}; return __res; } template<typename _Tp> __integer_to_chars_result_type<_Tp> __to_chars_10(char* __first, char* __last, _Tp __val) noexcept { static_assert(is_integral<_Tp>::value, "implementation bug"); static_assert(is_unsigned<_Tp>::value, "implementation bug"); to_chars_result __res; const unsigned __len = __to_chars_len(__val, 10); if (__builtin_expect((__last - __first) < __len, 0)) { __res.ptr = __last; __res.ec = errc::value_too_large; return __res; } static constexpr char __digits[201] = "0001020304050607080910111213141516171819" "2021222324252627282930313233343536373839" "4041424344454647484950515253545556575859" "6061626364656667686970717273747576777879" "8081828384858687888990919293949596979899"; unsigned __pos = __len - 1; while (__val >= 100) { auto const __num = (__val % 100) * 2; __val /= 100; __first[__pos] = __digits[__num + 1]; __first[__pos - 1] = __digits[__num]; __pos -= 2; } if (__val >= 10) { auto const __num = __val * 2; __first[__pos] = __digits[__num + 1]; __first[__pos - 1] = __digits[__num]; } else __first[__pos] = '0' + __val; __res.ptr = __first + __len; __res.ec = {}; return __res; } template<typename _Tp> __integer_to_chars_result_type<_Tp> __to_chars_8(char* __first, char* __last, _Tp __val) noexcept { static_assert(is_integral<_Tp>::value, "implementation bug"); static_assert(is_unsigned<_Tp>::value, "implementation bug"); to_chars_result __res; const unsigned __len = __to_chars_len_8(__val); if (__builtin_expect((__last - __first) < __len, 0)) { __res.ptr = __last; __res.ec = errc::value_too_large; return __res; } static constexpr char __digits[129] = "00010203040506071011121314151617" "20212223242526273031323334353637" "40414243444546475051525354555657" "60616263646566677071727374757677"; unsigned __pos = __len - 1; while (__val >= 0100) { auto const __num = (__val % 0100) * 2; __val /= 0100; __first[__pos] = __digits[__num + 1]; __first[__pos - 1] = __digits[__num]; __pos -= 2; } if (__val >= 010) { auto const __num = __val * 2; __first[__pos] = __digits[__num + 1]; __first[__pos - 1] = __digits[__num]; } else __first[__pos] = '0' + __val; __res.ptr = __first + __len; __res.ec = {}; return __res; } template<typename _Tp> __integer_to_chars_result_type<_Tp> __to_chars_2(char* __first, char* __last, _Tp __val) noexcept { static_assert(is_integral<_Tp>::value, "implementation bug"); static_assert(is_unsigned<_Tp>::value, "implementation bug"); to_chars_result __res; const unsigned __len = __to_chars_len_2(__val); if (__builtin_expect((__last - __first) < __len, 0)) { __res.ptr = __last; __res.ec = errc::value_too_large; return __res; } unsigned __pos = __len - 1; while (__pos) { __first[__pos--] = '0' + (__val & 1); __val >>= 1; } *__first = '0' + (__val & 1); __res.ptr = __first + __len; __res.ec = {}; return __res; } } // namespace __detail template<typename _Tp> __detail::__integer_to_chars_result_type<_Tp> to_chars(char* __first, char* __last, _Tp __value, int __base = 10) { __glibcxx_assert(2 <= __base && __base <= 36); using _Up = __detail::__unsigned_least_t<_Tp>; _Up __unsigned_val = __value; if (__value == 0 && __first != __last) { *__first = '0'; return { __first + 1, errc{} }; } if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) if (__value < 0) { if (__builtin_expect(__first != __last, 1)) *__first++ = '-'; __unsigned_val = _Up(~__value) + _Up(1); } switch (__base) { case 16: return __detail::__to_chars_16(__first, __last, __unsigned_val); case 10: return __detail::__to_chars_10(__first, __last, __unsigned_val); case 8: return __detail::__to_chars_8(__first, __last, __unsigned_val); case 2: return __detail::__to_chars_2(__first, __last, __unsigned_val); default: return __detail::__to_chars(__first, __last, __unsigned_val, __base); } } namespace __detail { template<typename _Tp> bool __raise_and_add(_Tp& __val, int __base, unsigned char __c) { if (__builtin_mul_overflow(__val, __base, &__val) || __builtin_add_overflow(__val, __c, &__val)) return false; return true; } /// std::from_chars implementation for integers in base 2. template<typename _Tp> bool __from_chars_binary(const char*& __first, const char* __last, _Tp& __val) { static_assert(is_integral<_Tp>::value, "implementation bug"); static_assert(is_unsigned<_Tp>::value, "implementation bug"); const ptrdiff_t __len = __last - __first; int __i = 0; while (__i < __len) { const unsigned char __c = (unsigned)__first[__i] - '0'; if (__c < 2) __val = (__val << 1) | __c; else break; __i++; } __first += __i; return __i <= (sizeof(_Tp) * __CHAR_BIT__); } /// std::from_chars implementation for integers in bases 3 to 10. template<typename _Tp> bool __from_chars_digit(const char*& __first, const char* __last, _Tp& __val, int __base) { static_assert(is_integral<_Tp>::value, "implementation bug"); static_assert(is_unsigned<_Tp>::value, "implementation bug"); auto __matches = [__base](char __c) { return '0' <= __c && __c <= ('0' + (__base - 1)); }; while (__first != __last) { const char __c = *__first; if (__matches(__c)) { if (!__raise_and_add(__val, __base, __c - '0')) { while (++__first != __last && __matches(*__first)) ; return false; } __first++; } else return true; } return true; } constexpr unsigned char __from_chars_alpha_to_num(char __c) { switch (__c) { case 'a': case 'A': return 10; case 'b': case 'B': return 11; case 'c': case 'C': return 12; case 'd': case 'D': return 13; case 'e': case 'E': return 14; case 'f': case 'F': return 15; case 'g': case 'G': return 16; case 'h': case 'H': return 17; case 'i': case 'I': return 18; case 'j': case 'J': return 19; case 'k': case 'K': return 20; case 'l': case 'L': return 21; case 'm': case 'M': return 22; case 'n': case 'N': return 23; case 'o': case 'O': return 24; case 'p': case 'P': return 25; case 'q': case 'Q': return 26; case 'r': case 'R': return 27; case 's': case 'S': return 28; case 't': case 'T': return 29; case 'u': case 'U': return 30; case 'v': case 'V': return 31; case 'w': case 'W': return 32; case 'x': case 'X': return 33; case 'y': case 'Y': return 34; case 'z': case 'Z': return 35; } return std::numeric_limits<unsigned char>::max(); } /// std::from_chars implementation for integers in bases 11 to 26. template<typename _Tp> bool __from_chars_alnum(const char*& __first, const char* __last, _Tp& __val, int __base) { bool __valid = true; while (__first != __last) { unsigned char __c = *__first; if (std::isdigit(__c)) __c -= '0'; else { __c = __from_chars_alpha_to_num(__c); if (__c >= __base) break; } if (__builtin_expect(__valid, 1)) __valid = __raise_and_add(__val, __base, __c); __first++; } return __valid; } template<typename _Tp> using __integer_from_chars_result_type = enable_if_t<__is_int_to_chars_type<_Tp>::value, from_chars_result>; } // namespace __detail /// std::from_chars for integral types. template<typename _Tp> __detail::__integer_from_chars_result_type<_Tp> from_chars(const char* __first, const char* __last, _Tp& __value, int __base = 10) { __glibcxx_assert(2 <= __base && __base <= 36); from_chars_result __res{__first, {}}; int __sign = 1; if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) if (__first != __last && *__first == '-') { __sign = -1; ++__first; } using _Up = __detail::__unsigned_least_t<_Tp>; _Up __val = 0; const auto __start = __first; bool __valid; if (__base == 2) __valid = __detail::__from_chars_binary(__first, __last, __val); else if (__base <= 10) __valid = __detail::__from_chars_digit(__first, __last, __val, __base); else __valid = __detail::__from_chars_alnum(__first, __last, __val, __base); if (__builtin_expect(__first == __start, 0)) __res.ec = errc::invalid_argument; else { __res.ptr = __first; if (!__valid) __res.ec = errc::result_out_of_range; else { if _GLIBCXX17_CONSTEXPR (std::is_signed<_Tp>::value) { _Tp __tmp; if (__builtin_mul_overflow(__val, __sign, &__tmp)) __res.ec = errc::result_out_of_range; else __value = __tmp; } else { if _GLIBCXX17_CONSTEXPR (numeric_limits<_Up>::max() > numeric_limits<_Tp>::max()) { if (__val > numeric_limits<_Tp>::max()) __res.ec = errc::result_out_of_range; else __value = __val; } else __value = __val; } } } return __res; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++14 #endif // _GLIBCXX_CHARCONV c++/8/ostream 0000644 00000053113 15146341150 0006663 0 ustar 00 // Output streams -*- C++ -*- // Copyright (C) 1997-2018 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/ostream * This is a Standard C++ Library header. */ // // ISO C++ 14882: 27.6.2 Output streams // #ifndef _GLIBCXX_OSTREAM #define _GLIBCXX_OSTREAM 1 #pragma GCC system_header #include <ios> #include <bits/ostream_insert.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Template class basic_ostream. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This is the base class for all output streams. It provides text * formatting of all builtin types, and communicates with any class * derived from basic_streambuf to do the actual output. */ template<typename _CharT, typename _Traits> class basic_ostream : virtual public basic_ios<_CharT, _Traits> { public: // Types (inherited from basic_ios): 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; // Non-standard Types: typedef basic_streambuf<_CharT, _Traits> __streambuf_type; typedef basic_ios<_CharT, _Traits> __ios_type; typedef basic_ostream<_CharT, _Traits> __ostream_type; typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > __num_put_type; typedef ctype<_CharT> __ctype_type; /** * @brief Base constructor. * * This ctor is almost never called by the user directly, rather from * derived classes' initialization lists, which pass a pointer to * their own stream buffer. */ explicit basic_ostream(__streambuf_type* __sb) { this->init(__sb); } /** * @brief Base destructor. * * This does very little apart from providing a virtual base dtor. */ virtual ~basic_ostream() { } /// Safe prefix/suffix operations. class sentry; friend class sentry; //@{ /** * @brief Interface for manipulators. * * Manipulators such as @c std::endl and @c std::hex use these * functions in constructs like "std::cout << std::endl". For more * information, see the iomanip header. */ __ostream_type& operator<<(__ostream_type& (*__pf)(__ostream_type&)) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // The inserters for manipulators are *not* formatted output functions. return __pf(*this); } __ostream_type& operator<<(__ios_type& (*__pf)(__ios_type&)) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // The inserters for manipulators are *not* formatted output functions. __pf(*this); return *this; } __ostream_type& operator<<(ios_base& (*__pf) (ios_base&)) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 60. What is a formatted input function? // The inserters for manipulators are *not* formatted output functions. __pf(*this); return *this; } //@} //@{ /** * @name Inserters * * All the @c operator<< functions (aka <em>formatted output * functions</em>) have some common behavior. Each starts by * constructing a temporary object of type std::basic_ostream::sentry. * This can have several effects, concluding with the setting of a * status flag; see the sentry documentation for more. * * If the sentry status is good, the function tries to generate * whatever data is appropriate for the type of the argument. * * If an exception is thrown during insertion, ios_base::badbit * will be turned on in the stream's error state without causing an * ios_base::failure to be thrown. The original exception will then * be rethrown. */ //@{ /** * @brief Integer arithmetic inserters * @param __n A variable of builtin integral type. * @return @c *this if successful * * These functions use the stream's current locale (specifically, the * @c num_get facet) to perform numeric formatting. */ __ostream_type& operator<<(long __n) { return _M_insert(__n); } __ostream_type& operator<<(unsigned long __n) { return _M_insert(__n); } __ostream_type& operator<<(bool __n) { return _M_insert(__n); } __ostream_type& operator<<(short __n); __ostream_type& operator<<(unsigned short __n) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 117. basic_ostream uses nonexistent num_put member functions. return _M_insert(static_cast<unsigned long>(__n)); } __ostream_type& operator<<(int __n); __ostream_type& operator<<(unsigned int __n) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 117. basic_ostream uses nonexistent num_put member functions. return _M_insert(static_cast<unsigned long>(__n)); } #ifdef _GLIBCXX_USE_LONG_LONG __ostream_type& operator<<(long long __n) { return _M_insert(__n); } __ostream_type& operator<<(unsigned long long __n) { return _M_insert(__n); } #endif //@} //@{ /** * @brief Floating point arithmetic inserters * @param __f A variable of builtin floating point type. * @return @c *this if successful * * These functions use the stream's current locale (specifically, the * @c num_get facet) to perform numeric formatting. */ __ostream_type& operator<<(double __f) { return _M_insert(__f); } __ostream_type& operator<<(float __f) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 117. basic_ostream uses nonexistent num_put member functions. return _M_insert(static_cast<double>(__f)); } __ostream_type& operator<<(long double __f) { return _M_insert(__f); } //@} /** * @brief Pointer arithmetic inserters * @param __p A variable of pointer type. * @return @c *this if successful * * These functions use the stream's current locale (specifically, the * @c num_get facet) to perform numeric formatting. */ __ostream_type& operator<<(const void* __p) { return _M_insert(__p); } /** * @brief Extracting from another streambuf. * @param __sb A pointer to a streambuf * * This function behaves like one of the basic arithmetic extractors, * in that it also constructs a sentry object and has the same error * handling behavior. * * If @p __sb is NULL, the stream will set failbit in its error state. * * Characters are extracted from @p __sb and inserted into @c *this * until one of the following occurs: * * - the input stream reaches end-of-file, * - insertion into the output sequence fails (in this case, the * character that would have been inserted is not extracted), or * - an exception occurs while getting a character from @p __sb, which * sets failbit in the error state * * If the function inserts no characters, failbit is set. */ __ostream_type& operator<<(__streambuf_type* __sb); //@} //@{ /** * @name Unformatted Output Functions * * All the unformatted output functions have some common behavior. * Each starts by constructing a temporary object of type * std::basic_ostream::sentry. This has several effects, concluding * with the setting of a status flag; see the sentry documentation * for more. * * If the sentry status is good, the function tries to generate * whatever data is appropriate for the type of the argument. * * If an exception is thrown during insertion, ios_base::badbit * will be turned on in the stream's error state. If badbit is on in * the stream's exceptions mask, the exception will be rethrown * without completing its actions. */ /** * @brief Simple insertion. * @param __c The character to insert. * @return *this * * Tries to insert @p __c. * * @note This function is not overloaded on signed char and * unsigned char. */ __ostream_type& put(char_type __c); /** * @brief Core write functionality, without sentry. * @param __s The array to insert. * @param __n Maximum number of characters to insert. */ void _M_write(const char_type* __s, streamsize __n) { const streamsize __put = this->rdbuf()->sputn(__s, __n); if (__put != __n) this->setstate(ios_base::badbit); } /** * @brief Character string insertion. * @param __s The array to insert. * @param __n Maximum number of characters to insert. * @return *this * * Characters are copied from @p __s and inserted into the stream until * one of the following happens: * * - @p __n characters are inserted * - inserting into the output sequence fails (in this case, badbit * will be set in the stream's error state) * * @note This function is not overloaded on signed char and * unsigned char. */ __ostream_type& write(const char_type* __s, streamsize __n); //@} /** * @brief Synchronizing the stream buffer. * @return *this * * If @c rdbuf() is a null pointer, changes nothing. * * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1, * sets badbit. */ __ostream_type& flush(); /** * @brief Getting the current write position. * @return A file position object. * * If @c fail() is not false, returns @c pos_type(-1) to indicate * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,out). */ pos_type tellp(); /** * @brief Changing the current write position. * @param __pos A file position object. * @return *this * * If @c fail() is not true, calls @c rdbuf()->pubseekpos(pos). If * that function fails, sets failbit. */ __ostream_type& seekp(pos_type); /** * @brief Changing the current write position. * @param __off A file offset object. * @param __dir The direction in which to seek. * @return *this * * If @c fail() is not true, calls @c rdbuf()->pubseekoff(off,dir). * If that function fails, sets failbit. */ __ostream_type& seekp(off_type, ios_base::seekdir); protected: basic_ostream() { this->init(0); } #if __cplusplus >= 201103L // Non-standard constructor that does not call init() basic_ostream(basic_iostream<_CharT, _Traits>&) { } basic_ostream(const basic_ostream&) = delete; basic_ostream(basic_ostream&& __rhs) : __ios_type() { __ios_type::move(__rhs); } // 27.7.3.3 Assign/swap basic_ostream& operator=(const basic_ostream&) = delete; basic_ostream& operator=(basic_ostream&& __rhs) { swap(__rhs); return *this; } void swap(basic_ostream& __rhs) { __ios_type::swap(__rhs); } #endif template<typename _ValueT> __ostream_type& _M_insert(_ValueT __v); }; /** * @brief Performs setup work for output streams. * * Objects of this class are created before all of the standard * inserters are run. It is responsible for <em>exception-safe prefix and * suffix operations</em>. */ template <typename _CharT, typename _Traits> class basic_ostream<_CharT, _Traits>::sentry { // Data Members. bool _M_ok; basic_ostream<_CharT, _Traits>& _M_os; public: /** * @brief The constructor performs preparatory work. * @param __os The output stream to guard. * * If the stream state is good (@a __os.good() is true), then if the * stream is tied to another output stream, @c is.tie()->flush() * is called to synchronize the output sequences. * * If the stream state is still good, then the sentry state becomes * true (@a okay). */ explicit sentry(basic_ostream<_CharT, _Traits>& __os); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" /** * @brief Possibly flushes the stream. * * If @c ios_base::unitbuf is set in @c os.flags(), and * @c std::uncaught_exception() is true, the sentry destructor calls * @c flush() on the output stream. */ ~sentry() { // XXX MT if (bool(_M_os.flags() & ios_base::unitbuf) && !uncaught_exception()) { // Can't call flush directly or else will get into recursive lock. if (_M_os.rdbuf() && _M_os.rdbuf()->pubsync() == -1) _M_os.setstate(ios_base::badbit); } } #pragma GCC diagnostic pop /** * @brief Quick status checking. * @return The sentry state. * * For ease of use, sentries may be converted to booleans. The * return value is that of the sentry state (true == okay). */ #if __cplusplus >= 201103L explicit #endif operator bool() const { return _M_ok; } }; //@{ /** * @brief Character inserters * @param __out An output stream. * @param __c A character. * @return out * * Behaves like one of the formatted arithmetic inserters described in * std::basic_ostream. After constructing a sentry object with good * status, this function inserts a single character and any required * padding (as determined by [22.2.2.2.2]). @c __out.width(0) is then * called. * * If @p __c is of type @c char and the character type of the stream is not * @c char, the character is widened before insertion. */ template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) { return __ostream_insert(__out, &__c, 1); } template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __out, char __c) { return (__out << __out.widen(__c)); } // Specialization template <class _Traits> inline basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>& __out, char __c) { return __ostream_insert(__out, &__c, 1); } // Signed and unsigned template<class _Traits> inline basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>& __out, signed char __c) { return (__out << static_cast<char>(__c)); } template<class _Traits> inline basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c) { return (__out << static_cast<char>(__c)); } //@} //@{ /** * @brief String inserters * @param __out An output stream. * @param __s A character string. * @return out * @pre @p __s must be a non-NULL pointer * * Behaves like one of the formatted arithmetic inserters described in * std::basic_ostream. After constructing a sentry object with good * status, this function inserts @c traits::length(__s) characters starting * at @p __s, widened if necessary, followed by any required padding (as * determined by [22.2.2.2.2]). @c __out.width(0) is then called. */ template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) { if (!__s) __out.setstate(ios_base::badbit); else __ostream_insert(__out, __s, static_cast<streamsize>(_Traits::length(__s))); return __out; } template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits> & operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s); // Partial specializations template<class _Traits> inline basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>& __out, const char* __s) { if (!__s) __out.setstate(ios_base::badbit); else __ostream_insert(__out, __s, static_cast<streamsize>(_Traits::length(__s))); return __out; } // Signed and unsigned template<class _Traits> inline basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s) { return (__out << reinterpret_cast<const char*>(__s)); } template<class _Traits> inline basic_ostream<char, _Traits> & operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s) { return (__out << reinterpret_cast<const char*>(__s)); } //@} // Standard basic_ostream manipulators /** * @brief Write a newline and flush the stream. * * This manipulator is often mistakenly used when a simple newline is * desired, leading to poor buffering performance. See * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering * for more on this subject. */ template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& endl(basic_ostream<_CharT, _Traits>& __os) { return flush(__os.put(__os.widen('\n'))); } /** * @brief Write a null character into the output sequence. * * <em>Null character</em> is @c CharT() by definition. For CharT * of @c char, this correctly writes the ASCII @c NUL character * string terminator. */ template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& ends(basic_ostream<_CharT, _Traits>& __os) { return __os.put(_CharT()); } /** * @brief Flushes the output stream. * * This manipulator simply calls the stream's @c flush() member function. */ template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& flush(basic_ostream<_CharT, _Traits>& __os) { return __os.flush(); } #if __cplusplus >= 201103L template<typename _Ch, typename _Up> basic_ostream<_Ch, _Up>& __is_convertible_to_basic_ostream_test(basic_ostream<_Ch, _Up>*); template<typename _Tp, typename = void> struct __is_convertible_to_basic_ostream_impl { using __ostream_type = void; }; template<typename _Tp> using __do_is_convertible_to_basic_ostream_impl = decltype(__is_convertible_to_basic_ostream_test (declval<typename remove_reference<_Tp>::type*>())); template<typename _Tp> struct __is_convertible_to_basic_ostream_impl <_Tp, __void_t<__do_is_convertible_to_basic_ostream_impl<_Tp>>> { using __ostream_type = __do_is_convertible_to_basic_ostream_impl<_Tp>; }; template<typename _Tp> struct __is_convertible_to_basic_ostream : __is_convertible_to_basic_ostream_impl<_Tp> { public: using type = __not_<is_void< typename __is_convertible_to_basic_ostream_impl<_Tp>::__ostream_type>>; constexpr static bool value = type::value; }; template<typename _Ostream, typename _Tp, typename = void> struct __is_insertable : false_type {}; template<typename _Ostream, typename _Tp> struct __is_insertable<_Ostream, _Tp, __void_t<decltype(declval<_Ostream&>() << declval<const _Tp&>())>> : true_type {}; template<typename _Ostream> using __rvalue_ostream_type = typename __is_convertible_to_basic_ostream< _Ostream>::__ostream_type; /** * @brief Generic inserter for rvalue stream * @param __os An input stream. * @param __x A reference to the object being inserted. * @return os * * This is just a forwarding function to allow insertion to * rvalue streams since they won't bind to the inserter functions * that take an lvalue reference. */ template<typename _Ostream, typename _Tp> inline typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>, __is_convertible_to_basic_ostream<_Ostream>, __is_insertable< __rvalue_ostream_type<_Ostream>, const _Tp&>>::value, __rvalue_ostream_type<_Ostream>>::type operator<<(_Ostream&& __os, const _Tp& __x) { __rvalue_ostream_type<_Ostream> __ret_os = __os; __ret_os << __x; return __ret_os; } #endif // C++11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #include <bits/ostream.tcc> #endif /* _GLIBCXX_OSTREAM */ c++/8/locale 0000644 00000002720 15146341150 0006446 0 ustar 00 // Locale support -*- C++ -*- // Copyright (C) 1997-2018 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. // // ISO C++ 14882: 22.1 Locales // /** @file include/locale * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_LOCALE #define _GLIBCXX_LOCALE 1 #pragma GCC system_header #include <bits/localefwd.h> #include <bits/locale_classes.h> #include <bits/locale_facets.h> #include <bits/locale_facets_nonio.h> #if __cplusplus >= 201103L # include <bits/locale_conv.h> #endif #endif /* _GLIBCXX_LOCALE */ c++/8/regex 0000644 00000003546 15146341150 0006330 0 ustar 00 // <regex> -*- C++ -*- // Copyright (C) 2007-2018 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/regex * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_REGEX #define _GLIBCXX_REGEX 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <algorithm> #include <bitset> #ifdef _GLIBCXX_DEBUG # include <iosfwd> #endif #include <iterator> #include <locale> #include <memory> #include <sstream> #include <stack> #include <stdexcept> #include <string> #include <utility> #include <vector> #include <map> #include <cstring> #include <ext/aligned_buffer.h> #include <bits/std_function.h> #include <bits/regex_constants.h> #include <bits/regex_error.h> #include <bits/regex_automaton.h> #include <bits/regex_scanner.h> #include <bits/regex_compiler.h> #include <bits/regex.h> #include <bits/regex_executor.h> #endif // C++11 #endif // _GLIBCXX_REGEX c++/8/exception 0000644 00000011303 15146341150 0007202 0 ustar 00 // Exception Handling support header for -*- C++ -*- // Copyright (C) 1995-2018 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 exception * This is a Standard C++ Library header. */ #ifndef __EXCEPTION__ #define __EXCEPTION__ #pragma GCC system_header #pragma GCC visibility push(default) #include <bits/c++config.h> #include <bits/exception.h> extern "C++" { namespace std { /** If an %exception is thrown which is not listed in a function's * %exception specification, one of these may be thrown. */ class bad_exception : public exception { public: bad_exception() _GLIBCXX_USE_NOEXCEPT { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; // See comment in eh_exception.cc. virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT; }; /// If you write a replacement %terminate handler, it must be of this type. typedef void (*terminate_handler) (); /// If you write a replacement %unexpected handler, it must be of this type. typedef void (*unexpected_handler) (); /// Takes a new handler function as an argument, returns the old function. terminate_handler set_terminate(terminate_handler) _GLIBCXX_USE_NOEXCEPT; #if __cplusplus >= 201103L /// Return the current terminate handler. terminate_handler get_terminate() noexcept; #endif /** The runtime will call this function if %exception handling must be * abandoned for any reason. It can also be called by the user. */ void terminate() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__)); /// Takes a new handler function as an argument, returns the old function. unexpected_handler set_unexpected(unexpected_handler) _GLIBCXX_USE_NOEXCEPT; #if __cplusplus >= 201103L /// Return the current unexpected handler. unexpected_handler get_unexpected() noexcept; #endif /** The runtime will call this function if an %exception is thrown which * violates the function's %exception specification. */ void unexpected() __attribute__ ((__noreturn__)); /** [18.6.4]/1: 'Returns true after completing evaluation of a * throw-expression until either completing initialization of the * exception-declaration in the matching handler or entering @c unexpected() * due to the throw; or after entering @c terminate() for any reason * other than an explicit call to @c terminate(). [Note: This includes * stack unwinding [15.2]. end note]' * * 2: 'When @c uncaught_exception() is true, throwing an * %exception can result in a call of @c terminate() * (15.5.1).' */ _GLIBCXX17_DEPRECATED bool uncaught_exception() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); #if __cplusplus >= 201703L || !defined(__STRICT_ANSI__) // c++17 or gnu++98 #define __cpp_lib_uncaught_exceptions 201411L /// The number of uncaught exceptions. int uncaught_exceptions() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__)); #endif // @} group exceptions } // namespace std namespace __gnu_cxx { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief A replacement for the standard terminate_handler which * prints more information about the terminating exception (if any) * on stderr. * * @ingroup exceptions * * Call * @code * std::set_terminate(__gnu_cxx::__verbose_terminate_handler) * @endcode * to use. For more info, see * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt02ch06s02.html * * In 3.4 and later, this is on by default. */ void __verbose_terminate_handler(); _GLIBCXX_END_NAMESPACE_VERSION } // namespace } // extern "C++" #pragma GCC visibility pop #if (__cplusplus >= 201103L) #include <bits/exception_ptr.h> #include <bits/nested_exception.h> #endif #endif c++/8/forward_list 0000644 00000003051 15146341150 0007704 0 ustar 00 // <forward_list> -*- C++ -*- // Copyright (C) 2008-2018 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/forward_list * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_FORWARD_LIST #define _GLIBCXX_FORWARD_LIST 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <bits/forward_list.h> #include <bits/range_access.h> #include <bits/forward_list.tcc> #ifdef _GLIBCXX_DEBUG # include <debug/forward_list> #endif #ifdef _GLIBCXX_PROFILE # include <profile/forward_list> #endif #endif // C++11 #endif // _GLIBCXX_FORWARD_LIST c++/8/iostream 0000644 00000005207 15146341150 0007035 0 ustar 00 // Standard iostream objects -*- C++ -*- // Copyright (C) 1997-2018 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/iostream * This is a Standard C++ Library header. */ // // ISO C++ 14882: 27.3 Standard iostream objects // #ifndef _GLIBCXX_IOSTREAM #define _GLIBCXX_IOSTREAM 1 #pragma GCC system_header #include <bits/c++config.h> #include <ostream> #include <istream> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @name Standard Stream Objects * * The <iostream> header declares the eight <em>standard stream * objects</em>. For other declarations, see * http://gcc.gnu.org/onlinedocs/libstdc++/manual/io.html * and the @link iosfwd I/O forward declarations @endlink * * They are required by default to cooperate with the global C * library's @c FILE streams, and to be available during program * startup and termination. For more information, see the section of the * manual linked to above. */ //@{ extern istream cin; /// Linked to standard input extern ostream cout; /// Linked to standard output extern ostream cerr; /// Linked to standard error (unbuffered) extern ostream clog; /// Linked to standard error (buffered) #ifdef _GLIBCXX_USE_WCHAR_T extern wistream wcin; /// Linked to standard input extern wostream wcout; /// Linked to standard output extern wostream wcerr; /// Linked to standard error (unbuffered) extern wostream wclog; /// Linked to standard error (buffered) #endif //@} // For construction of filebuffers for cout, cin, cerr, clog et. al. static ios_base::Init __ioinit; _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif /* _GLIBCXX_IOSTREAM */ c++/8/memory 0000644 00000011147 15146341150 0006522 0 ustar 00 // <memory> -*- C++ -*- // Copyright (C) 2001-2018 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) 1997-1999 * 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/memory * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_MEMORY #define _GLIBCXX_MEMORY 1 #pragma GCC system_header /** * @defgroup memory Memory * @ingroup utilities * * Components for memory allocation, deallocation, and management. */ /** * @defgroup pointer_abstractions Pointer Abstractions * @ingroup memory * * Smart pointers, etc. */ #include <bits/stl_algobase.h> #include <bits/allocator.h> #include <bits/stl_construct.h> #include <bits/stl_uninitialized.h> #include <bits/stl_tempbuf.h> #include <bits/stl_raw_storage_iter.h> #if __cplusplus >= 201103L # include <exception> // std::exception # include <typeinfo> // std::type_info in get_deleter # include <iosfwd> // std::basic_ostream # include <ext/atomicity.h> # include <ext/concurrence.h> # include <bits/functexcept.h> # include <bits/stl_function.h> // std::less # include <bits/uses_allocator.h> # include <type_traits> # include <debug/debug.h> # include <bits/unique_ptr.h> # include <bits/shared_ptr.h> # include <bits/shared_ptr_atomic.h> # if _GLIBCXX_USE_DEPRECATED # include <backward/auto_ptr.h> # endif #else # include <backward/auto_ptr.h> #endif #if __cplusplus >= 201103L # include <cstdint> # ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Fit aligned storage in buffer. * * [ptr.align] * * 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. * * @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. */ inline void* align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept { const auto __intptr = reinterpret_cast<uintptr_t>(__ptr); const auto __aligned = (__intptr - 1u + __align) & -__align; const auto __diff = __aligned - __intptr; if ((__size + __diff) > __space) return nullptr; else { __space -= __diff; return __ptr = reinterpret_cast<void*>(__aligned); } } // 20.7.4 [util.dynamic.safety], pointer safety enum class pointer_safety { relaxed, preferred, strict }; inline void declare_reachable(void*) { } template <typename _Tp> inline _Tp* undeclare_reachable(_Tp* __p) { return __p; } inline void declare_no_pointers(char*, size_t) { } inline void undeclare_no_pointers(char*, size_t) { } inline pointer_safety get_pointer_safety() noexcept { return pointer_safety::relaxed; } _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // _GLIBCXX_USE_C99_STDINT_TR1 #endif // C++11 #endif /* _GLIBCXX_MEMORY */ c++/8/fstream 0000644 00000107663 15146341150 0006664 0 ustar 00 // File based streams -*- C++ -*- // Copyright (C) 1997-2018 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/fstream * This is a Standard C++ Library header. */ // // ISO C++ 14882: 27.8 File-based streams // #ifndef _GLIBCXX_FSTREAM #define _GLIBCXX_FSTREAM 1 #pragma GCC system_header #include <istream> #include <ostream> #include <bits/codecvt.h> #include <cstdio> // For BUFSIZ #include <bits/basic_file.h> // For __basic_file, __c_lock #if __cplusplus >= 201103L #include <string> // For std::string overloads. #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201703L // Enable if _Path is a filesystem::path or experimental::filesystem::path template<typename _Path, typename _Result = _Path, typename _Path2 = decltype(std::declval<_Path&>().make_preferred().filename())> using _If_fs_path = enable_if_t<is_same_v<_Path, _Path2>, _Result>; #endif // C++17 // [27.8.1.1] template class basic_filebuf /** * @brief The actual work of input and output (for files). * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class associates both its input and output sequence with an * external disk file, and maintains a joint file position for both * sequences. Many of its semantics are described in terms of similar * behavior in the Standard C Library's @c FILE streams. * * Requirements on traits_type, specific to this class: * - traits_type::pos_type must be fpos<traits_type::state_type> * - traits_type::off_type must be streamoff * - traits_type::state_type must be Assignable and DefaultConstructible, * - traits_type::state_type() must be the initial state for codecvt. */ template<typename _CharT, typename _Traits> class basic_filebuf : public basic_streambuf<_CharT, _Traits> { #if __cplusplus >= 201103L template<typename _Tp> using __chk_state = __and_<is_copy_assignable<_Tp>, is_copy_constructible<_Tp>, is_default_constructible<_Tp>>; static_assert(__chk_state<typename _Traits::state_type>::value, "state_type must be CopyAssignable, CopyConstructible" " and DefaultConstructible"); static_assert(is_same<typename _Traits::pos_type, fpos<typename _Traits::state_type>>::value, "pos_type must be fpos<state_type>"); #endif public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; typedef basic_streambuf<char_type, traits_type> __streambuf_type; typedef basic_filebuf<char_type, traits_type> __filebuf_type; typedef __basic_file<char> __file_type; typedef typename traits_type::state_type __state_type; typedef codecvt<char_type, char, __state_type> __codecvt_type; friend class ios_base; // For sync_with_stdio. protected: // Data Members: // MT lock inherited from libio or other low-level io library. __c_lock _M_lock; // External buffer. __file_type _M_file; /// Place to stash in || out || in | out settings for current filebuf. ios_base::openmode _M_mode; // Beginning state type for codecvt. __state_type _M_state_beg; // During output, the state that corresponds to pptr(), // during input, the state that corresponds to egptr() and // _M_ext_next. __state_type _M_state_cur; // Not used for output. During input, the state that corresponds // to eback() and _M_ext_buf. __state_type _M_state_last; /// Pointer to the beginning of internal buffer. char_type* _M_buf; /** * Actual size of internal buffer. This number is equal to the size * of the put area + 1 position, reserved for the overflow char of * a full area. */ size_t _M_buf_size; // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer. bool _M_buf_allocated; /** * _M_reading == false && _M_writing == false for @b uncommitted mode; * _M_reading == true for @b read mode; * _M_writing == true for @b write mode; * * NB: _M_reading == true && _M_writing == true is unused. */ bool _M_reading; bool _M_writing; //@{ /** * Necessary bits for putback buffer management. * * @note pbacks of over one character are not currently supported. */ char_type _M_pback; char_type* _M_pback_cur_save; char_type* _M_pback_end_save; bool _M_pback_init; //@} // Cached codecvt facet. const __codecvt_type* _M_codecvt; /** * Buffer for external characters. Used for input when * codecvt::always_noconv() == false. When valid, this corresponds * to eback(). */ char* _M_ext_buf; /** * Size of buffer held by _M_ext_buf. */ streamsize _M_ext_buf_size; /** * Pointers into the buffer held by _M_ext_buf that delimit a * subsequence of bytes that have been read but not yet converted. * When valid, _M_ext_next corresponds to egptr(). */ const char* _M_ext_next; char* _M_ext_end; /** * Initializes pback buffers, and moves normal buffers to safety. * Assumptions: * _M_in_cur has already been moved back */ void _M_create_pback() { if (!_M_pback_init) { _M_pback_cur_save = this->gptr(); _M_pback_end_save = this->egptr(); this->setg(&_M_pback, &_M_pback, &_M_pback + 1); _M_pback_init = true; } } /** * Deactivates pback buffer contents, and restores normal buffer. * Assumptions: * The pback buffer has only moved forward. */ void _M_destroy_pback() throw() { if (_M_pback_init) { // Length _M_in_cur moved in the pback buffer. _M_pback_cur_save += this->gptr() != this->eback(); this->setg(_M_buf, _M_pback_cur_save, _M_pback_end_save); _M_pback_init = false; } } public: // Constructors/destructor: /** * @brief Does not open any files. * * The default constructor initializes the parent class using its * own default ctor. */ basic_filebuf(); #if __cplusplus >= 201103L basic_filebuf(const basic_filebuf&) = delete; basic_filebuf(basic_filebuf&&); #endif /** * @brief The destructor closes the file first. */ virtual ~basic_filebuf() { this->close(); } #if __cplusplus >= 201103L basic_filebuf& operator=(const basic_filebuf&) = delete; basic_filebuf& operator=(basic_filebuf&&); void swap(basic_filebuf&); #endif // Members: /** * @brief Returns true if the external file is open. */ bool is_open() const throw() { return _M_file.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * @return @c this on success, NULL on failure * * If a file is already open, this function immediately fails. * Otherwise it tries to open the file named @a __s using the flags * given in @a __mode. * * Table 92, adapted here, gives the relation between openmode * combinations and the equivalent @c fopen() flags. * (NB: lines app, in|out|app, in|app, binary|app, binary|in|out|app, * and binary|in|app per DR 596) * <pre> * +---------------------------------------------------------+ * | ios_base Flag combination stdio equivalent | * |binary in out trunc app | * +---------------------------------------------------------+ * | + w | * | + + a | * | + a | * | + + w | * | + r | * | + + r+ | * | + + + w+ | * | + + + a+ | * | + + a+ | * +---------------------------------------------------------+ * | + + wb | * | + + + ab | * | + + ab | * | + + + wb | * | + + rb | * | + + + r+b | * | + + + + w+b | * | + + + + a+b | * | + + + a+b | * +---------------------------------------------------------+ * </pre> */ __filebuf_type* open(const char* __s, ios_base::openmode __mode); #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * @return @c this on success, NULL on failure */ __filebuf_type* open(const std::string& __s, ios_base::openmode __mode) { return open(__s.c_str(), __mode); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * @return @c this on success, NULL on failure */ template<typename _Path> _If_fs_path<_Path, __filebuf_type*> open(const _Path& __s, ios_base::openmode __mode) { return open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Closes the currently associated file. * @return @c this on success, NULL on failure * * If no file is currently open, this function immediately fails. * * If a <em>put buffer area</em> exists, @c overflow(eof) is * called to flush all the characters. The file is then * closed. * * If any operations fail, this function also fails. */ __filebuf_type* close(); protected: void _M_allocate_internal_buffer(); void _M_destroy_internal_buffer() throw(); // [27.8.1.4] overridden virtual functions virtual streamsize showmanyc(); // Stroustrup, 1998, p. 628 // underflow() and uflow() functions are called to get the next // character from the real input source when the buffer is empty. // Buffered input uses underflow() virtual int_type underflow(); virtual int_type pbackfail(int_type __c = _Traits::eof()); // Stroustrup, 1998, p 648 // The overflow() function is called to transfer characters to the // real output destination when the buffer is full. A call to // overflow(c) outputs the contents of the buffer plus the // character c. // 27.5.2.4.5 // Consume some sequence of the characters in the pending sequence. virtual int_type overflow(int_type __c = _Traits::eof()); // Convert internal byte sequence to external, char-based // sequence via codecvt. bool _M_convert_to_external(char_type*, streamsize); /** * @brief Manipulates the buffer. * @param __s Pointer to a buffer area. * @param __n Size of @a __s. * @return @c this * * If no file has been opened, and both @a __s and @a __n are zero, then * the stream becomes unbuffered. Otherwise, @c __s is used as a * buffer; see * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering * for more. */ virtual __streambuf_type* setbuf(char_type* __s, streamsize __n); virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, 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); // Common code for seekoff, seekpos, and overflow pos_type _M_seek(off_type __off, ios_base::seekdir __way, __state_type __state); int _M_get_ext_pos(__state_type &__state); virtual int sync(); virtual void imbue(const locale& __loc); virtual streamsize xsgetn(char_type* __s, streamsize __n); virtual streamsize xsputn(const char_type* __s, streamsize __n); // Flushes output buffer, then writes unshift sequence. bool _M_terminate_output(); /** * This function sets the pointers of the internal buffer, both get * and put areas. Typically: * * __off == egptr() - eback() upon underflow/uflow (@b read mode); * __off == 0 upon overflow (@b write mode); * __off == -1 upon open, setbuf, seekoff/pos (@b uncommitted mode). * * NB: epptr() - pbase() == _M_buf_size - 1, since _M_buf_size * reflects the actual allocated memory and the last cell is reserved * for the overflow char of a full put area. */ void _M_set_buffer(streamsize __off) { const bool __testin = _M_mode & ios_base::in; const bool __testout = (_M_mode & ios_base::out || _M_mode & ios_base::app); if (__testin && __off > 0) this->setg(_M_buf, _M_buf, _M_buf + __off); else this->setg(_M_buf, _M_buf, _M_buf); if (__testout && __off == 0 && _M_buf_size > 1 ) this->setp(_M_buf, _M_buf + _M_buf_size - 1); else this->setp(0, 0); } }; // [27.8.1.5] Template class basic_ifstream /** * @brief Controlling input for files. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class supports reading from named files, using the inherited * functions from std::basic_istream. To control the associated * sequence, an instance of std::basic_filebuf is used, which this page * refers to as @c sb. */ template<typename _CharT, typename _Traits> class basic_ifstream : public basic_istream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_filebuf<char_type, traits_type> __filebuf_type; typedef basic_istream<char_type, traits_type> __istream_type; private: __filebuf_type _M_filebuf; public: // Constructors/Destructors: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_ifstream() : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an input file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::in is automatically included in @a __mode. */ explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201103L /** * @brief Create an input file stream. * @param __s std::string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::in is automatically included in @a __mode. */ explicit basic_ifstream(const std::string& __s, ios_base::openmode __mode = ios_base::in) : __istream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201703L /** * @param Create an input file stream. * @param __s filesystem::path specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::in is automatically included in @a __mode. */ template<typename _Path, typename _Require = _If_fs_path<_Path>> basic_ifstream(const _Path& __s, ios_base::openmode __mode = ios_base::in) : basic_ifstream(__s.c_str(), __mode) { } #endif // C++17 basic_ifstream(const basic_ifstream&) = delete; basic_ifstream(basic_ifstream&& __rhs) : __istream_type(std::move(__rhs)), _M_filebuf(std::move(__rhs._M_filebuf)) { __istream_type::set_rdbuf(&_M_filebuf); } #endif // C++11 /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_ifstream() { } #if __cplusplus >= 201103L // 27.8.3.2 Assign and swap: basic_ifstream& operator=(const basic_ifstream&) = delete; basic_ifstream& operator=(basic_ifstream&& __rhs) { __istream_type::operator=(std::move(__rhs)); _M_filebuf = std::move(__rhs._M_filebuf); return *this; } void swap(basic_ifstream& __rhs) { __istream_type::swap(__rhs); _M_filebuf.swap(__rhs._M_filebuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(s,__mode|in). If that function * fails, @c failbit is set in the stream's error state. */ void open(const char* __s, ios_base::openmode __mode = ios_base::in) { if (!_M_filebuf.open(__s, __mode | ios_base::in)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function * fails, @c failbit is set in the stream's error state. */ void open(const std::string& __s, ios_base::openmode __mode = ios_base::in) { if (!_M_filebuf.open(__s, __mode | ios_base::in)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|in). If that function * fails, @c failbit is set in the stream's error state. */ template<typename _Path> _If_fs_path<_Path, void> open(const _Path& __s, ios_base::openmode __mode = ios_base::in) { open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(ios_base::failbit); } }; // [27.8.1.8] Template class basic_ofstream /** * @brief Controlling output for files. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class supports reading from named files, using the inherited * functions from std::basic_ostream. To control the associated * sequence, an instance of std::basic_filebuf is used, which this page * refers to as @c sb. */ template<typename _CharT, typename _Traits> class basic_ofstream : public basic_ostream<_CharT,_Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_filebuf<char_type, traits_type> __filebuf_type; typedef basic_ostream<char_type, traits_type> __ostream_type; private: __filebuf_type _M_filebuf; public: // Constructors: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_ofstream(): __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an output file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::out is automatically included in @a __mode. */ explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201103L /** * @brief Create an output file stream. * @param __s std::string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::out is automatically included in @a __mode. */ explicit basic_ofstream(const std::string& __s, ios_base::openmode __mode = ios_base::out) : __ostream_type(), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201703L /** * @param Create an output file stream. * @param __s filesystem::path specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). * * @c ios_base::out is automatically included in @a __mode. */ template<typename _Path, typename _Require = _If_fs_path<_Path>> basic_ofstream(const _Path& __s, ios_base::openmode __mode = ios_base::out) : basic_ofstream(__s.c_str(), __mode) { } #endif // C++17 basic_ofstream(const basic_ofstream&) = delete; basic_ofstream(basic_ofstream&& __rhs) : __ostream_type(std::move(__rhs)), _M_filebuf(std::move(__rhs._M_filebuf)) { __ostream_type::set_rdbuf(&_M_filebuf); } #endif /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_ofstream() { } #if __cplusplus >= 201103L // 27.8.3.2 Assign and swap: basic_ofstream& operator=(const basic_ofstream&) = delete; basic_ofstream& operator=(basic_ofstream&& __rhs) { __ostream_type::operator=(std::move(__rhs)); _M_filebuf = std::move(__rhs._M_filebuf); return *this; } void swap(basic_ofstream& __rhs) { __ostream_type::swap(__rhs); _M_filebuf.swap(__rhs._M_filebuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|out). If that * function fails, @c failbit is set in the stream's error state. */ void open(const char* __s, ios_base::openmode __mode = ios_base::out) { if (!_M_filebuf.open(__s, __mode | ios_base::out)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(s,mode|out). If that * function fails, @c failbit is set in the stream's error state. */ void open(const std::string& __s, ios_base::openmode __mode = ios_base::out) { if (!_M_filebuf.open(__s, __mode | ios_base::out)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode|out). If that * function fails, @c failbit is set in the stream's error state. */ template<typename _Path> _If_fs_path<_Path, void> open(const _Path& __s, ios_base::openmode __mode = ios_base::out) { open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(ios_base::failbit); } }; // [27.8.1.11] Template class basic_fstream /** * @brief Controlling input and output for files. * @ingroup io * * @tparam _CharT Type of character stream. * @tparam _Traits Traits for character type, defaults to * char_traits<_CharT>. * * This class supports reading from and writing to named files, using * the inherited functions from std::basic_iostream. To control the * associated sequence, an instance of std::basic_filebuf is used, which * this page refers to as @c sb. */ template<typename _CharT, typename _Traits> class basic_fstream : public basic_iostream<_CharT, _Traits> { public: // Types: typedef _CharT char_type; typedef _Traits traits_type; typedef typename traits_type::int_type int_type; typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; // Non-standard types: typedef basic_filebuf<char_type, traits_type> __filebuf_type; typedef basic_ios<char_type, traits_type> __ios_type; typedef basic_iostream<char_type, traits_type> __iostream_type; private: __filebuf_type _M_filebuf; public: // Constructors/destructor: /** * @brief Default constructor. * * Initializes @c sb using its default constructor, and passes * @c &sb to the base class initializer. Does not open any files * (you haven't given it a filename to open). */ basic_fstream() : __iostream_type(), _M_filebuf() { this->init(&_M_filebuf); } /** * @brief Create an input/output file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). */ explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out) : __iostream_type(0), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201103L /** * @brief Create an input/output file stream. * @param __s Null terminated string specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). */ explicit basic_fstream(const std::string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) : __iostream_type(0), _M_filebuf() { this->init(&_M_filebuf); this->open(__s, __mode); } #if __cplusplus >= 201703L /** * @param Create an input/output file stream. * @param __s filesystem::path specifying the filename. * @param __mode Open file in specified mode (see std::ios_base). */ template<typename _Path, typename _Require = _If_fs_path<_Path>> basic_fstream(const _Path& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) : basic_fstream(__s.c_str(), __mode) { } #endif // C++17 basic_fstream(const basic_fstream&) = delete; basic_fstream(basic_fstream&& __rhs) : __iostream_type(std::move(__rhs)), _M_filebuf(std::move(__rhs._M_filebuf)) { __iostream_type::set_rdbuf(&_M_filebuf); } #endif /** * @brief The destructor does nothing. * * The file is closed by the filebuf object, not the formatting * stream. */ ~basic_fstream() { } #if __cplusplus >= 201103L // 27.8.3.2 Assign and swap: basic_fstream& operator=(const basic_fstream&) = delete; basic_fstream& operator=(basic_fstream&& __rhs) { __iostream_type::operator=(std::move(__rhs)); _M_filebuf = std::move(__rhs._M_filebuf); return *this; } void swap(basic_fstream& __rhs) { __iostream_type::swap(__rhs); _M_filebuf.swap(__rhs._M_filebuf); } #endif // Members: /** * @brief Accessing the underlying buffer. * @return The current basic_filebuf buffer. * * This hides both signatures of std::basic_ios::rdbuf(). */ __filebuf_type* rdbuf() const { return const_cast<__filebuf_type*>(&_M_filebuf); } /** * @brief Wrapper to test for an open file. * @return @c rdbuf()->is_open() */ bool is_open() { return _M_filebuf.is_open(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // 365. Lack of const-qualification in clause 27 bool is_open() const { return _M_filebuf.is_open(); } /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode). If that * function fails, @c failbit is set in the stream's error state. */ void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out) { if (!_M_filebuf.open(__s, __mode)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201103L /** * @brief Opens an external file. * @param __s The name of the file. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode). If that * function fails, @c failbit is set in the stream's error state. */ void open(const std::string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) { if (!_M_filebuf.open(__s, __mode)) this->setstate(ios_base::failbit); else // _GLIBCXX_RESOLVE_LIB_DEFECTS // 409. Closing an fstream should clear error state this->clear(); } #if __cplusplus >= 201703L /** * @brief Opens an external file. * @param __s The name of the file, as a filesystem::path. * @param __mode The open mode flags. * * Calls @c std::basic_filebuf::open(__s,__mode). If that * function fails, @c failbit is set in the stream's error state. */ template<typename _Path> _If_fs_path<_Path, void> open(const _Path& __s, ios_base::openmode __mode = ios_base::in | ios_base::out) { open(__s.c_str(), __mode); } #endif // C++17 #endif // C++11 /** * @brief Close the file. * * Calls @c std::basic_filebuf::close(). If that function * fails, @c failbit is set in the stream's error state. */ void close() { if (!_M_filebuf.close()) this->setstate(ios_base::failbit); } }; #if __cplusplus >= 201103L /// Swap specialization for filebufs. template <class _CharT, class _Traits> inline void swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) { __x.swap(__y); } /// Swap specialization for ifstreams. template <class _CharT, class _Traits> inline void swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) { __x.swap(__y); } /// Swap specialization for ofstreams. template <class _CharT, class _Traits> inline void swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) { __x.swap(__y); } /// Swap specialization for fstreams. template <class _CharT, class _Traits> inline void swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) { __x.swap(__y); } #endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace #include <bits/fstream.tcc> #endif /* _GLIBCXX_FSTREAM */ c++/8/queue 0000644 00000004643 15146341150 0006341 0 ustar 00 // <queue> -*- C++ -*- // Copyright (C) 2001-2018 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/queue * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_QUEUE #define _GLIBCXX_QUEUE 1 #pragma GCC system_header #include <deque> #include <vector> #include <bits/stl_heap.h> #include <bits/stl_function.h> #include <bits/stl_queue.h> #endif /* _GLIBCXX_QUEUE */ c++/8/typeindex 0000644 00000006025 15146341150 0007222 0 ustar 00 // C++11 <typeindex> -*- C++ -*- // Copyright (C) 2010-2018 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/typeindex * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_TYPEINDEX #define _GLIBCXX_TYPEINDEX 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <typeinfo> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @brief Class type_index * @ingroup utilities * * The class type_index provides a simple wrapper for type_info * which can be used as an index type in associative containers * (23.6) and in unordered associative containers (23.7). */ struct type_index { type_index(const type_info& __rhs) noexcept : _M_target(&__rhs) { } bool operator==(const type_index& __rhs) const noexcept { return *_M_target == *__rhs._M_target; } bool operator!=(const type_index& __rhs) const noexcept { return *_M_target != *__rhs._M_target; } bool operator<(const type_index& __rhs) const noexcept { return _M_target->before(*__rhs._M_target); } bool operator<=(const type_index& __rhs) const noexcept { return !__rhs._M_target->before(*_M_target); } bool operator>(const type_index& __rhs) const noexcept { return __rhs._M_target->before(*_M_target); } bool operator>=(const type_index& __rhs) const noexcept { return !_M_target->before(*__rhs._M_target); } size_t hash_code() const noexcept { return _M_target->hash_code(); } const char* name() const noexcept { return _M_target->name(); } private: const type_info* _M_target; }; template<typename _Tp> struct hash; /// std::hash specialization for type_index. template<> struct hash<type_index> { typedef size_t result_type; typedef type_index argument_type; size_t operator()(const type_index& __ti) const noexcept { return __ti.hash_code(); } }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_TYPEINDEX c++/8/stack 0000644 00000004527 15146341150 0006323 0 ustar 00 // <stack> -*- C++ -*- // Copyright (C) 2001-2018 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/stack * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_STACK #define _GLIBCXX_STACK 1 #pragma GCC system_header #include <deque> #include <bits/stl_stack.h> #endif /* _GLIBCXX_STACK */ c++/8/shared_mutex 0000644 00000045721 15146341150 0007707 0 ustar 00 // <shared_mutex> -*- C++ -*- // Copyright (C) 2013-2018 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/shared_mutex * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_SHARED_MUTEX #define _GLIBCXX_SHARED_MUTEX 1 #pragma GCC system_header #if __cplusplus >= 201402L #include <bits/c++config.h> #include <condition_variable> #include <bits/functexcept.h> namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @ingroup mutexes * @{ */ #ifdef _GLIBCXX_USE_C99_STDINT_TR1 #ifdef _GLIBCXX_HAS_GTHREADS #if __cplusplus >= 201703L #define __cpp_lib_shared_mutex 201505 class shared_mutex; #endif #define __cpp_lib_shared_timed_mutex 201402 class shared_timed_mutex; #if _GLIBCXX_USE_PTHREAD_RWLOCK_T /// A shared mutex type implemented using pthread_rwlock_t. class __shared_mutex_pthread { friend class shared_timed_mutex; #ifdef PTHREAD_RWLOCK_INITIALIZER pthread_rwlock_t _M_rwlock = PTHREAD_RWLOCK_INITIALIZER; public: __shared_mutex_pthread() = default; ~__shared_mutex_pthread() = default; #else pthread_rwlock_t _M_rwlock; public: __shared_mutex_pthread() { int __ret = pthread_rwlock_init(&_M_rwlock, NULL); if (__ret == ENOMEM) __throw_bad_alloc(); else if (__ret == EAGAIN) __throw_system_error(int(errc::resource_unavailable_try_again)); else if (__ret == EPERM) __throw_system_error(int(errc::operation_not_permitted)); // Errors not handled: EBUSY, EINVAL __glibcxx_assert(__ret == 0); } ~__shared_mutex_pthread() { int __ret __attribute((__unused__)) = pthread_rwlock_destroy(&_M_rwlock); // Errors not handled: EBUSY, EINVAL __glibcxx_assert(__ret == 0); } #endif __shared_mutex_pthread(const __shared_mutex_pthread&) = delete; __shared_mutex_pthread& operator=(const __shared_mutex_pthread&) = delete; void lock() { int __ret = pthread_rwlock_wrlock(&_M_rwlock); if (__ret == EDEADLK) __throw_system_error(int(errc::resource_deadlock_would_occur)); // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); } bool try_lock() { int __ret = pthread_rwlock_trywrlock(&_M_rwlock); if (__ret == EBUSY) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } void unlock() { int __ret __attribute((__unused__)) = pthread_rwlock_unlock(&_M_rwlock); // Errors not handled: EPERM, EBUSY, EINVAL __glibcxx_assert(__ret == 0); } // Shared ownership void lock_shared() { int __ret; // We retry if we exceeded the maximum number of read locks supported by // the POSIX implementation; this can result in busy-waiting, but this // is okay based on the current specification of forward progress // guarantees by the standard. do __ret = pthread_rwlock_rdlock(&_M_rwlock); while (__ret == EAGAIN); if (__ret == EDEADLK) __throw_system_error(int(errc::resource_deadlock_would_occur)); // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); } bool try_lock_shared() { int __ret = pthread_rwlock_tryrdlock(&_M_rwlock); // If the maximum number of read locks has been exceeded, we just fail // to acquire the lock. Unlike for lock(), we are not allowed to throw // an exception. if (__ret == EBUSY || __ret == EAGAIN) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } void unlock_shared() { unlock(); } void* native_handle() { return &_M_rwlock; } }; #endif #if ! (_GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK) /// A shared mutex type implemented using std::condition_variable. class __shared_mutex_cv { friend class shared_timed_mutex; // Based on Howard Hinnant's reference implementation from N2406. // The high bit of _M_state is the write-entered flag which is set to // indicate a writer has taken the lock or is queuing to take the lock. // The remaining bits are the count of reader locks. // // To take a reader lock, block on gate1 while the write-entered flag is // set or the maximum number of reader locks is held, then increment the // reader lock count. // To release, decrement the count, then if the write-entered flag is set // and the count is zero then signal gate2 to wake a queued writer, // otherwise if the maximum number of reader locks was held signal gate1 // to wake a reader. // // To take a writer lock, block on gate1 while the write-entered flag is // set, then set the write-entered flag to start queueing, then block on // gate2 while the number of reader locks is non-zero. // To release, unset the write-entered flag and signal gate1 to wake all // blocked readers and writers. // // This means that when no reader locks are held readers and writers get // equal priority. When one or more reader locks is held a writer gets // priority and no more reader locks can be taken while the writer is // queued. // Only locked when accessing _M_state or waiting on condition variables. mutex _M_mut; // Used to block while write-entered is set or reader count at maximum. condition_variable _M_gate1; // Used to block queued writers while reader count is non-zero. condition_variable _M_gate2; // The write-entered flag and reader count. unsigned _M_state; static constexpr unsigned _S_write_entered = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1); static constexpr unsigned _S_max_readers = ~_S_write_entered; // Test whether the write-entered flag is set. _M_mut must be locked. bool _M_write_entered() const { return _M_state & _S_write_entered; } // The number of reader locks currently held. _M_mut must be locked. unsigned _M_readers() const { return _M_state & _S_max_readers; } public: __shared_mutex_cv() : _M_state(0) {} ~__shared_mutex_cv() { __glibcxx_assert( _M_state == 0 ); } __shared_mutex_cv(const __shared_mutex_cv&) = delete; __shared_mutex_cv& operator=(const __shared_mutex_cv&) = delete; // Exclusive ownership void lock() { unique_lock<mutex> __lk(_M_mut); // Wait until we can set the write-entered flag. _M_gate1.wait(__lk, [=]{ return !_M_write_entered(); }); _M_state |= _S_write_entered; // Then wait until there are no more readers. _M_gate2.wait(__lk, [=]{ return _M_readers() == 0; }); } bool try_lock() { unique_lock<mutex> __lk(_M_mut, try_to_lock); if (__lk.owns_lock() && _M_state == 0) { _M_state = _S_write_entered; return true; } return false; } void unlock() { lock_guard<mutex> __lk(_M_mut); __glibcxx_assert( _M_write_entered() ); _M_state = 0; // call notify_all() while mutex is held so that another thread can't // lock and unlock the mutex then destroy *this before we make the call. _M_gate1.notify_all(); } // Shared ownership void lock_shared() { unique_lock<mutex> __lk(_M_mut); _M_gate1.wait(__lk, [=]{ return _M_state < _S_max_readers; }); ++_M_state; } bool try_lock_shared() { unique_lock<mutex> __lk(_M_mut, try_to_lock); if (!__lk.owns_lock()) return false; if (_M_state < _S_max_readers) { ++_M_state; return true; } return false; } void unlock_shared() { lock_guard<mutex> __lk(_M_mut); __glibcxx_assert( _M_readers() > 0 ); auto __prev = _M_state--; if (_M_write_entered()) { // Wake the queued writer if there are no more readers. if (_M_readers() == 0) _M_gate2.notify_one(); // No need to notify gate1 because we give priority to the queued // writer, and that writer will eventually notify gate1 after it // clears the write-entered flag. } else { // Wake any thread that was blocked on reader overflow. if (__prev == _S_max_readers) _M_gate1.notify_one(); } } }; #endif #if __cplusplus > 201402L /// The standard shared mutex type. class shared_mutex { public: shared_mutex() = default; ~shared_mutex() = default; shared_mutex(const shared_mutex&) = delete; shared_mutex& operator=(const shared_mutex&) = delete; // Exclusive ownership void lock() { _M_impl.lock(); } bool try_lock() { return _M_impl.try_lock(); } void unlock() { _M_impl.unlock(); } // Shared ownership void lock_shared() { _M_impl.lock_shared(); } bool try_lock_shared() { return _M_impl.try_lock_shared(); } void unlock_shared() { _M_impl.unlock_shared(); } #if _GLIBCXX_USE_PTHREAD_RWLOCK_T typedef void* native_handle_type; native_handle_type native_handle() { return _M_impl.native_handle(); } private: __shared_mutex_pthread _M_impl; #else private: __shared_mutex_cv _M_impl; #endif }; #endif // C++17 #if _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK using __shared_timed_mutex_base = __shared_mutex_pthread; #else using __shared_timed_mutex_base = __shared_mutex_cv; #endif /// The standard shared timed mutex type. class shared_timed_mutex : private __shared_timed_mutex_base { using _Base = __shared_timed_mutex_base; // Must use the same clock as condition_variable for __shared_mutex_cv. typedef chrono::system_clock __clock_t; public: shared_timed_mutex() = default; ~shared_timed_mutex() = default; shared_timed_mutex(const shared_timed_mutex&) = delete; shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; // Exclusive ownership void lock() { _Base::lock(); } bool try_lock() { return _Base::try_lock(); } void unlock() { _Base::unlock(); } template<typename _Rep, typename _Period> bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) { return try_lock_until(__clock_t::now() + __rel_time); } // Shared ownership void lock_shared() { _Base::lock_shared(); } bool try_lock_shared() { return _Base::try_lock_shared(); } void unlock_shared() { _Base::unlock_shared(); } template<typename _Rep, typename _Period> bool try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time) { return try_lock_shared_until(__clock_t::now() + __rel_time); } #if _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK // Exclusive ownership template<typename _Duration> bool try_lock_until(const chrono::time_point<__clock_t, _Duration>& __atime) { 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()) }; int __ret = pthread_rwlock_timedwrlock(&_M_rwlock, &__ts); // On self-deadlock, we just fail to acquire the lock. Technically, // the program violated the precondition. if (__ret == ETIMEDOUT || __ret == EDEADLK) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } template<typename _Clock, typename _Duration> bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __abs_time - __c_entry; const auto __s_atime = __s_entry + __delta; return try_lock_until(__s_atime); } // Shared ownership template<typename _Duration> bool try_lock_shared_until(const chrono::time_point<__clock_t, _Duration>& __atime) { 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()) }; int __ret; // Unlike for lock(), we are not allowed to throw an exception so if // the maximum number of read locks has been exceeded, or we would // deadlock, we just try to acquire the lock again (and will time out // eventually). // In cases where we would exceed the maximum number of read locks // throughout the whole time until the timeout, we will fail to // acquire the lock even if it would be logically free; however, this // is allowed by the standard, and we made a "strong effort" // (see C++14 30.4.1.4p26). // For cases where the implementation detects a deadlock we // intentionally block and timeout so that an early return isn't // mistaken for a spurious failure, which might help users realise // there is a deadlock. do __ret = pthread_rwlock_timedrdlock(&_M_rwlock, &__ts); while (__ret == EAGAIN || __ret == EDEADLK); if (__ret == ETIMEDOUT) return false; // Errors not handled: EINVAL __glibcxx_assert(__ret == 0); return true; } template<typename _Clock, typename _Duration> bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __abs_time - __c_entry; const auto __s_atime = __s_entry + __delta; return try_lock_shared_until(__s_atime); } #else // ! (_GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK) // Exclusive ownership template<typename _Clock, typename _Duration> bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { unique_lock<mutex> __lk(_M_mut); if (!_M_gate1.wait_until(__lk, __abs_time, [=]{ return !_M_write_entered(); })) { return false; } _M_state |= _S_write_entered; if (!_M_gate2.wait_until(__lk, __abs_time, [=]{ return _M_readers() == 0; })) { _M_state ^= _S_write_entered; // Wake all threads blocked while the write-entered flag was set. _M_gate1.notify_all(); return false; } return true; } // Shared ownership template <typename _Clock, typename _Duration> bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { unique_lock<mutex> __lk(_M_mut); if (!_M_gate1.wait_until(__lk, __abs_time, [=]{ return _M_state < _S_max_readers; })) { return false; } ++_M_state; return true; } #endif // _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK }; #endif // _GLIBCXX_HAS_GTHREADS /// shared_lock template<typename _Mutex> class shared_lock { public: typedef _Mutex mutex_type; // Shared locking shared_lock() noexcept : _M_pm(nullptr), _M_owns(false) { } explicit shared_lock(mutex_type& __m) : _M_pm(std::__addressof(__m)), _M_owns(true) { __m.lock_shared(); } shared_lock(mutex_type& __m, defer_lock_t) noexcept : _M_pm(std::__addressof(__m)), _M_owns(false) { } shared_lock(mutex_type& __m, try_to_lock_t) : _M_pm(std::__addressof(__m)), _M_owns(__m.try_lock_shared()) { } shared_lock(mutex_type& __m, adopt_lock_t) : _M_pm(std::__addressof(__m)), _M_owns(true) { } template<typename _Clock, typename _Duration> shared_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __abs_time) : _M_pm(std::__addressof(__m)), _M_owns(__m.try_lock_shared_until(__abs_time)) { } template<typename _Rep, typename _Period> shared_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rel_time) : _M_pm(std::__addressof(__m)), _M_owns(__m.try_lock_shared_for(__rel_time)) { } ~shared_lock() { if (_M_owns) _M_pm->unlock_shared(); } shared_lock(shared_lock const&) = delete; shared_lock& operator=(shared_lock const&) = delete; shared_lock(shared_lock&& __sl) noexcept : shared_lock() { swap(__sl); } shared_lock& operator=(shared_lock&& __sl) noexcept { shared_lock(std::move(__sl)).swap(*this); return *this; } void lock() { _M_lockable(); _M_pm->lock_shared(); _M_owns = true; } bool try_lock() { _M_lockable(); return _M_owns = _M_pm->try_lock_shared(); } template<typename _Rep, typename _Period> bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) { _M_lockable(); return _M_owns = _M_pm->try_lock_shared_for(__rel_time); } template<typename _Clock, typename _Duration> bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { _M_lockable(); return _M_owns = _M_pm->try_lock_shared_until(__abs_time); } void unlock() { if (!_M_owns) __throw_system_error(int(errc::resource_deadlock_would_occur)); _M_pm->unlock_shared(); _M_owns = false; } // Setters void swap(shared_lock& __u) noexcept { std::swap(_M_pm, __u._M_pm); std::swap(_M_owns, __u._M_owns); } mutex_type* release() noexcept { _M_owns = false; return std::exchange(_M_pm, nullptr); } // Getters bool owns_lock() const noexcept { return _M_owns; } explicit operator bool() const noexcept { return _M_owns; } mutex_type* mutex() const noexcept { return _M_pm; } private: void _M_lockable() const { if (_M_pm == nullptr) __throw_system_error(int(errc::operation_not_permitted)); if (_M_owns) __throw_system_error(int(errc::resource_deadlock_would_occur)); } mutex_type* _M_pm; bool _M_owns; }; /// Swap specialization for shared_lock template<typename _Mutex> void swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) noexcept { __x.swap(__y); } #endif // _GLIBCXX_USE_C99_STDINT_TR1 // @} group mutexes _GLIBCXX_END_NAMESPACE_VERSION } // namespace #endif // C++14 #endif // _GLIBCXX_SHARED_MUTEX c++/8/ciso646 0000644 00000002670 15146341150 0006410 0 ustar 00 // -*- C++ -*- forwarding header. // Copyright (C) 2001-2018 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 ciso646 * This is a Standard C++ Library file. You should @c \#include this file * in your programs, rather than any of the @a *.h implementation files. * * This is the C++ version of the Standard C Library header @c iso646.h, * which is empty in C++. */ #ifndef _GLIBCXX_CISO646 #define _GLIBCXX_CISO646 #pragma GCC system_header #include <bits/c++config.h> #endif c++/8/condition_variable 0000644 00000021372 15146341150 0011046 0 ustar 00 // <condition_variable> -*- C++ -*- // Copyright (C) 2008-2018 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/condition_variable * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_CONDITION_VARIABLE #define _GLIBCXX_CONDITION_VARIABLE 1 #pragma GCC system_header #if __cplusplus < 201103L # include <bits/c++0x_warning.h> #else #include <chrono> #include <bits/std_mutex.h> #include <ext/concurrence.h> #include <bits/alloc_traits.h> #include <bits/allocator.h> #include <bits/unique_ptr.h> #include <bits/shared_ptr.h> #include <bits/cxxabi_forced.h> #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup condition_variables Condition Variables * @ingroup concurrency * * Classes for condition_variable support. * @{ */ /// cv_status enum class cv_status { no_timeout, timeout }; /// condition_variable class condition_variable { typedef chrono::system_clock __clock_t; typedef __gthread_cond_t __native_type; #ifdef __GTHREAD_COND_INIT __native_type _M_cond = __GTHREAD_COND_INIT; #else __native_type _M_cond; #endif public: typedef __native_type* native_handle_type; condition_variable() noexcept; ~condition_variable() noexcept; condition_variable(const condition_variable&) = delete; condition_variable& operator=(const condition_variable&) = delete; void notify_one() noexcept; void notify_all() noexcept; void wait(unique_lock<mutex>& __lock) noexcept; template<typename _Predicate> void wait(unique_lock<mutex>& __lock, _Predicate __p) { while (!__p()) wait(__lock); } template<typename _Duration> cv_status wait_until(unique_lock<mutex>& __lock, const chrono::time_point<__clock_t, _Duration>& __atime) { return __wait_until_impl(__lock, __atime); } template<typename _Clock, typename _Duration> cv_status wait_until(unique_lock<mutex>& __lock, const chrono::time_point<_Clock, _Duration>& __atime) { // DR 887 - Sync unknown clock to known clock. const typename _Clock::time_point __c_entry = _Clock::now(); const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __atime - __c_entry; const auto __s_atime = __s_entry + __delta; return __wait_until_impl(__lock, __s_atime); } template<typename _Clock, typename _Duration, typename _Predicate> bool wait_until(unique_lock<mutex>& __lock, const chrono::time_point<_Clock, _Duration>& __atime, _Predicate __p) { while (!__p()) if (wait_until(__lock, __atime) == cv_status::timeout) return __p(); return true; } template<typename _Rep, typename _Period> cv_status wait_for(unique_lock<mutex>& __lock, const chrono::duration<_Rep, _Period>& __rtime) { using __dur = typename __clock_t::duration; auto __reltime = chrono::duration_cast<__dur>(__rtime); if (__reltime < __rtime) ++__reltime; return wait_until(__lock, __clock_t::now() + __reltime); } template<typename _Rep, typename _Period, typename _Predicate> bool wait_for(unique_lock<mutex>& __lock, const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p) { using __dur = typename __clock_t::duration; auto __reltime = chrono::duration_cast<__dur>(__rtime); if (__reltime < __rtime) ++__reltime; return wait_until(__lock, __clock_t::now() + __reltime, std::move(__p)); } native_handle_type native_handle() { return &_M_cond; } private: template<typename _Dur> cv_status __wait_until_impl(unique_lock<mutex>& __lock, const chrono::time_point<__clock_t, _Dur>& __atime) { auto __s = chrono::time_point_cast<chrono::seconds>(__atime); auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s); __gthread_time_t __ts = { static_cast<std::time_t>(__s.time_since_epoch().count()), static_cast<long>(__ns.count()) }; __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(), &__ts); return (__clock_t::now() < __atime ? cv_status::no_timeout : cv_status::timeout); } }; void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>); struct __at_thread_exit_elt { __at_thread_exit_elt* _M_next; void (*_M_cb)(void*); }; inline namespace _V2 { /// condition_variable_any // Like above, but mutex is not required to have try_lock. class condition_variable_any { typedef chrono::system_clock __clock_t; condition_variable _M_cond; shared_ptr<mutex> _M_mutex; // scoped unlock - unlocks in ctor, re-locks in dtor template<typename _Lock> struct _Unlock { explicit _Unlock(_Lock& __lk) : _M_lock(__lk) { __lk.unlock(); } ~_Unlock() noexcept(false) { if (uncaught_exception()) { __try { _M_lock.lock(); } __catch(const __cxxabiv1::__forced_unwind&) { __throw_exception_again; } __catch(...) { } } else _M_lock.lock(); } _Unlock(const _Unlock&) = delete; _Unlock& operator=(const _Unlock&) = delete; _Lock&